s3:net conf: reduce memory usage of "net conf import".
authorMichael Adam <obnox@samba.org>
Wed, 4 Mar 2009 20:46:32 +0000 (21:46 +0100)
committerMichael Adam <obnox@samba.org>
Wed, 4 Mar 2009 21:49:24 +0000 (22:49 +0100)
"net conf import" was wrapped in one big transaction.
This lead to MAX_TALLOC_SIZE being exceeded at roughly
1500 shares. This patch resolves that problem by
limiting the top level transactions in "net conf import"
to 100 shares.

Michael

source3/utils/net_conf.c

index 05b552c00def11f67cdfb313ac7c719c2a814a43..38a2553e53a1280e51aeec563f95937e42c9886b 100644 (file)
@@ -331,12 +331,6 @@ static int net_conf_import(struct net_context *c, struct smbconf_ctx *conf_ctx,
                         "would import the following configuration:\n\n");
        }
 
                         "would import the following configuration:\n\n");
        }
 
-       werr = smbconf_transaction_start(conf_ctx);
-       if (!W_ERROR_IS_OK(werr)) {
-               d_printf("error starting transaction: %s\n", win_errstr(werr));
-               goto done;
-       }
-
        if (servicename != NULL) {
                struct smbconf_service *service = NULL;
 
        if (servicename != NULL) {
                struct smbconf_service *service = NULL;
 
@@ -366,12 +360,45 @@ static int net_conf_import(struct net_context *c, struct smbconf_ctx *conf_ctx,
                                goto cancel;
                        }
                }
                                goto cancel;
                        }
                }
+
+               /*
+                * Wrap the importing of shares into a transaction,
+                * but only 100 at a time, in order to serve memory.
+                * The allocated memory accumulates across the actions
+                * within the transaction, and for me, some 1500
+                * imported shares, the MAX_TALLOC_SIZE of 256 MB
+                * was exceeded.
+                */
+               werr = smbconf_transaction_start(conf_ctx);
+               if (!W_ERROR_IS_OK(werr)) {
+                       d_printf("error starting transaction: %s\n",
+                                win_errstr(werr));
+                       goto done;
+               }
+
                for (sidx = 0; sidx < num_shares; sidx++) {
                        werr = import_process_service(c, conf_ctx,
                                                      services[sidx]);
                        if (!W_ERROR_IS_OK(werr)) {
                                goto cancel;
                        }
                for (sidx = 0; sidx < num_shares; sidx++) {
                        werr = import_process_service(c, conf_ctx,
                                                      services[sidx]);
                        if (!W_ERROR_IS_OK(werr)) {
                                goto cancel;
                        }
+
+                       if (sidx % 100) {
+                               continue;
+                       }
+
+                       werr = smbconf_transaction_commit(conf_ctx);
+                       if (!W_ERROR_IS_OK(werr)) {
+                               d_printf("error committing transaction: %s\n",
+                                        win_errstr(werr));
+                               goto done;
+                       }
+                       werr = smbconf_transaction_start(conf_ctx);
+                       if (!W_ERROR_IS_OK(werr)) {
+                               d_printf("error starting transaction: %s\n",
+                                        win_errstr(werr));
+                               goto done;
+                       }
                }
        }
 
                }
        }