[SCM] SAMBA-CTDB repository - branch v3-2-ctdb updated - build_3.2.7_ctdb.54-125-gfd61f11

Michael Adam obnox at samba.org
Thu Feb 19 21:10:49 GMT 2009


The branch, v3-2-ctdb has been updated
       via  fd61f118a3842f1c5fd8f51efefb0b63247deeab (commit)
       via  8f4b7a74644e7091f8575b581002048a08c5135d (commit)
      from  6654bd91b08a181ebef5acf89c6fb5cf96a48703 (commit)

http://gitweb.samba.org/?p=obnox/samba-ctdb.git;a=shortlog;h=v3-2-ctdb


- Log -----------------------------------------------------------------
commit fd61f118a3842f1c5fd8f51efefb0b63247deeab
Author: Volker Lendecke <vl at samba.org>
Date:   Thu Feb 19 20:03:06 2009 +0100

    Fix a O(n^2) algorithm in regdb_fetch_keys()
    (cherry picked from commit d98c43982c56ef788144a3fd67cdd65a9f95f2be)
    
    Signed-off-by: Michael Adam <obnox at samba.org>

commit 8f4b7a74644e7091f8575b581002048a08c5135d
Author: Volker Lendecke <vl at samba.org>
Date:   Thu Feb 19 14:16:44 2009 +0100

    Fix a buffer handling bug when adding lots of registry keys
    
    This is *ancient*... From 2002, and nobody noticed until someone added lots of
    shares using net conf... :-)
    (cherry picked from commit 36ae846d15027df5e3a02ffabb08183dad9f6517)
    
    Signed-off-by: Michael Adam <obnox at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 source/registry/reg_backend_db.c |   65 +++++++++++++++++++++++++++++--------
 1 files changed, 51 insertions(+), 14 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source/registry/reg_backend_db.c b/source/registry/reg_backend_db.c
index a1093db..e8d165d 100644
--- a/source/registry/reg_backend_db.c
+++ b/source/registry/reg_backend_db.c
@@ -528,21 +528,36 @@ static bool regdb_store_keys_internal(const char *key, REGSUBKEY_CTR *ctr)
 	/* pack all the strings */
 
 	for (i=0; i<num_subkeys; i++) {
-		len += tdb_pack(buffer+len, buflen-len, "f",
-				regsubkey_ctr_specific_key(ctr, i));
-		if (len > buflen) {
-			/* allocate some extra space */
-			buffer = (uint8 *)SMB_REALLOC(buffer, len*2);
+		size_t thistime;
+
+		thistime = tdb_pack(buffer+len, buflen-len, "f",
+				    regsubkey_ctr_specific_key(ctr, i));
+		if (len+thistime > buflen) {
+			size_t thistime2;
+			/*
+			 * tdb_pack hasn't done anything because of the short
+			 * buffer, allocate extra space.
+			 */
+			buffer = SMB_REALLOC_ARRAY(buffer, uint8_t,
+						   (len+thistime)*2);
 			if(buffer == NULL) {
 				DEBUG(0, ("regdb_store_keys: Failed to realloc "
-					  "memory of size [%d]\n", len*2));
+					  "memory of size [%d]\n",
+					  (len+thistime)*2));
+				ret = false;
+				goto done;
+			}
+			buflen = (len+thistime)*2;
+			thistime2 = tdb_pack(
+				buffer+len, buflen-len, "f",
+				regsubkey_ctr_specific_key(ctr, i));
+			if (thistime2 != thistime) {
+				DEBUG(0, ("tdb_pack failed\n"));
 				ret = false;
 				goto done;
 			}
-			buflen = len*2;
-			len = tdb_pack(buffer+len, buflen-len, "f",
-				       regsubkey_ctr_specific_key(ctr, i));
 		}
+		len += thistime;
 	}
 
 	/* finally write out the data */
@@ -919,7 +934,6 @@ done:
 
 int regdb_fetch_keys(const char *key, REGSUBKEY_CTR *ctr)
 {
-	WERROR werr;
 	uint32 num_items;
 	uint8 *buf;
 	uint32 buflen, len;
@@ -950,12 +964,35 @@ int regdb_fetch_keys(const char *key, REGSUBKEY_CTR *ctr)
 	buflen = value.dsize;
 	len = tdb_unpack( buf, buflen, "d", &num_items);
 
+	/*
+	 * The following code breaks the abstraction that reg_objects.c sets
+	 * up with regsubkey_ctr_addkey(). But if we use that with the current
+	 * data structure of ctr->subkeys being an unsorted array, we end up
+	 * with an O(n^2) algorithm for retrieving keys from the tdb
+	 * file. This is pretty pointless, as we have to trust the data
+	 * structure on disk not to have duplicates anyway. The alternative to
+	 * breaking this abstraction would be to set up a more sophisticated
+	 * data structure in REGSUBKEY_CTR.
+	 *
+	 * This makes "net conf list" for a registry with >1000 shares
+	 * actually usable :-)
+	 */
+
+	ctr->subkeys = talloc_array(ctr, char *, num_items);
+	if (ctr->subkeys == NULL) {
+		DEBUG(5, ("regdb_fetch_keys: could not allocate subkeys\n"));
+		goto done;
+	}
+	ctr->num_subkeys = num_items;
+
 	for (i=0; i<num_items; i++) {
 		len += tdb_unpack(buf+len, buflen-len, "f", subkeyname);
-		werr = regsubkey_ctr_addkey(ctr, subkeyname);
-		if (!W_ERROR_IS_OK(werr)) {
-			DEBUG(5, ("regdb_fetch_keys: regsubkey_ctr_addkey "
-				  "failed: %s\n", dos_errstr(werr)));
+		ctr->subkeys[i] = talloc_strdup(ctr->subkeys, subkeyname);
+		if (ctr->subkeys[i] == NULL) {
+			DEBUG(5, ("regdb_fetch_keys: could not allocate "
+				  "subkeyname\n"));
+			TALLOC_FREE(ctr->subkeys);
+			ctr->num_subkeys = 0;
 			goto done;
 		}
 	}


-- 
SAMBA-CTDB repository


More information about the samba-cvs mailing list