[SCM] Samba Shared Repository - branch master updated

Andrew Bartlett abartlet at samba.org
Sat Aug 11 02:32:02 MDT 2012


The branch, master has been updated
       via  4631723 s4-dsdb: Take more care in handling of global schema memory
       via  329e374 s4-dsdb: Remove support for per-partition sequence numbers
       via  2d21a9b s4-dsdb: Use only the replication USN for schema reload.
      from  f36e28d s3-nfs4acls: Remove lookup_sid and sidmap from NFSv4 ACL mapping and check gid first

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 4631723c988b46be8af4e67f5aea9187b08b9187
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Sat Aug 11 12:29:06 2012 +1000

    s4-dsdb: Take more care in handling of global schema memory
    
    This reworks dsdb_replicated_objects_commit() to have a proper local tmp_ctx and
    to be more careful about what schema is set (only setting a global schema if
    the original schema was global).
    
    In particular, the new working_schema is not given a talloc reference
    to the old schema.  This ensures that the old schema can go away when
    no longer used.
    
    Andrew Bartlett
    
    Autobuild-User(master): Andrew Bartlett <abartlet at samba.org>
    Autobuild-Date(master): Sat Aug 11 10:31:57 CEST 2012 on sn-devel-104

commit 329e3749381fee4182fdbf6015a42e4bdca07168
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Sat Aug 11 11:00:53 2012 +1000

    s4-dsdb: Remove support for per-partition sequence numbers
    
    These sequence numbers were only used for telling if the schema was
    changed, and are no longer directly related to the replication USN.
    
    The per-partition replication USN can be obtained from the
    @REPLCHANGED record on the per-partition database, and this is done
    with an ldb_search().
    
    Andrew Bartlett

commit 2d21a9bf5eeb88d738e998ee8f1720487b55e12e
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Sat Aug 11 10:56:58 2012 +1000

    s4-dsdb: Use only the replication USN for schema reload.
    
    This way we do not track both the partition seq number and the
    replication USN for schema reload purposes.
    
    We only need one indication of actual data change, and the replication
    per-partition sequence number is no more expensive to obtain than the
    ldb per-partition sequence number.
    
    Andrew Bartlett

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

Summary of changes:
 source4/dsdb/repl/replicated_objects.c       |   88 ++++++++++++++++++--------
 source4/dsdb/samdb/ldb_modules/partition.c   |   23 -------
 source4/dsdb/samdb/ldb_modules/schema_load.c |   64 +------------------
 source4/dsdb/schema/schema.h                 |    6 --
 4 files changed, 64 insertions(+), 117 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source4/dsdb/repl/replicated_objects.c b/source4/dsdb/repl/replicated_objects.c
index a8c210f..564befe 100644
--- a/source4/dsdb/repl/replicated_objects.c
+++ b/source4/dsdb/repl/replicated_objects.c
@@ -543,8 +543,16 @@ WERROR dsdb_replicated_objects_commit(struct ldb_context *ldb,
 	WERROR werr;
 	struct ldb_result *ext_res;
 	struct dsdb_schema *cur_schema = NULL;
+	struct dsdb_schema *new_schema = NULL;
 	int ret;
 	uint64_t seq_num1, seq_num2;
+	bool used_global_schema = false;
+
+	TALLOC_CTX *tmp_ctx = talloc_new(objects);
+	if (!tmp_ctx) {
+		DEBUG(0,("Failed to start talloc\n"));
+		return WERR_NOMEM;
+	}
 
 	/* TODO: handle linked attributes */
 
@@ -561,6 +569,7 @@ WERROR dsdb_replicated_objects_commit(struct ldb_context *ldb,
 	if (ret != LDB_SUCCESS) {
 		DEBUG(0,(__location__ " Failed to load partition uSN\n"));
 		ldb_transaction_cancel(ldb);
+		TALLOC_FREE(tmp_ctx);
 		return WERR_FOOBAR;		
 	}
 
@@ -572,7 +581,8 @@ WERROR dsdb_replicated_objects_commit(struct ldb_context *ldb,
 	 */
 	if (working_schema) {
 		/* store current schema so we can fall back in case of failure */
-		cur_schema = dsdb_get_schema(ldb, working_schema);
+		cur_schema = dsdb_get_schema(ldb, tmp_ctx);
+		used_global_schema = dsdb_uses_global_schema(ldb);
 
 		ret = dsdb_reference_schema(ldb, working_schema, false);
 		if (ret != LDB_SUCCESS) {
@@ -580,6 +590,7 @@ WERROR dsdb_replicated_objects_commit(struct ldb_context *ldb,
 				 ldb_strerror(ret)));
 			/* TODO: Map LDB Error to NTSTATUS? */
 			ldb_transaction_cancel(ldb);
+			TALLOC_FREE(tmp_ctx);
 			return WERR_INTERNAL_ERROR;
 		}
 	}
@@ -587,14 +598,16 @@ WERROR dsdb_replicated_objects_commit(struct ldb_context *ldb,
 	ret = ldb_extended(ldb, DSDB_EXTENDED_REPLICATED_OBJECTS_OID, objects, &ext_res);
 	if (ret != LDB_SUCCESS) {
 		/* restore previous schema */
-		if (cur_schema ) {
+		if (used_global_schema) { 
+			dsdb_set_global_schema(ldb);
+		} else if (cur_schema) {
 			dsdb_reference_schema(ldb, cur_schema, false);
-			dsdb_make_schema_global(ldb, cur_schema);
 		}
 
 		DEBUG(0,("Failed to apply records: %s: %s\n",
 			 ldb_errstring(ldb), ldb_strerror(ret)));
 		ldb_transaction_cancel(ldb);
+		TALLOC_FREE(tmp_ctx);
 		return WERR_FOOBAR;
 	}
 	talloc_free(ext_res);
@@ -606,12 +619,14 @@ WERROR dsdb_replicated_objects_commit(struct ldb_context *ldb,
 							      working_schema);
 		if (!W_ERROR_IS_OK(werr)) {
 			/* restore previous schema */
-			if (cur_schema ) {
+			if (used_global_schema) { 
+				dsdb_set_global_schema(ldb);
+			} else if (cur_schema ) {
 				dsdb_reference_schema(ldb, cur_schema, false);
-				dsdb_make_schema_global(ldb, cur_schema);
 			}
 			DEBUG(0,("Failed to save updated prefixMap: %s\n",
 				 win_errstr(werr)));
+			TALLOC_FREE(tmp_ctx);
 			return werr;
 		}
 	}
@@ -619,24 +634,28 @@ WERROR dsdb_replicated_objects_commit(struct ldb_context *ldb,
 	ret = ldb_transaction_prepare_commit(ldb);
 	if (ret != LDB_SUCCESS) {
 		/* restore previous schema */
-		if (cur_schema ) {
+		if (used_global_schema) { 
+			dsdb_set_global_schema(ldb);
+		} else if (cur_schema ) {
 			dsdb_reference_schema(ldb, cur_schema, false);
-			dsdb_make_schema_global(ldb, cur_schema);
 		}
 		DEBUG(0,(__location__ " Failed to prepare commit of transaction: %s\n",
 			 ldb_errstring(ldb)));
+		TALLOC_FREE(tmp_ctx);
 		return WERR_FOOBAR;
 	}
 
 	ret = dsdb_load_partition_usn(ldb, objects->partition_dn, &seq_num2, NULL);
 	if (ret != LDB_SUCCESS) {
 		/* restore previous schema */
-		if (cur_schema ) {
+		if (used_global_schema) { 
+			dsdb_set_global_schema(ldb);
+		} else if (cur_schema ) {
 			dsdb_reference_schema(ldb, cur_schema, false);
-			dsdb_make_schema_global(ldb, cur_schema);
 		}
 		DEBUG(0,(__location__ " Failed to load partition uSN\n"));
 		ldb_transaction_cancel(ldb);
+		TALLOC_FREE(tmp_ctx);
 		return WERR_FOOBAR;		
 	}
 
@@ -650,11 +669,13 @@ WERROR dsdb_replicated_objects_commit(struct ldb_context *ldb,
 	ret = ldb_transaction_commit(ldb);
 	if (ret != LDB_SUCCESS) {
 		/* restore previous schema */
-		if (cur_schema ) {
+		if (used_global_schema) { 
+			dsdb_set_global_schema(ldb);
+		} else if (cur_schema ) {
 			dsdb_reference_schema(ldb, cur_schema, false);
-			dsdb_make_schema_global(ldb, cur_schema);
 		}
 		DEBUG(0,(__location__ " Failed to commit transaction\n"));
+		TALLOC_FREE(tmp_ctx);
 		return WERR_FOOBAR;
 	}
 
@@ -668,29 +689,43 @@ WERROR dsdb_replicated_objects_commit(struct ldb_context *ldb,
 
 		/* Force a reload */
 		working_schema->last_refresh = 0;
-		cur_schema = dsdb_get_schema(ldb, NULL);
-		/* TODO: What we do in case dsdb_get_schema() fail?
-		 *       We can't fallback at this point anymore */
-		if (cur_schema) {
-			dsdb_make_schema_global(ldb, cur_schema);
+		new_schema = dsdb_get_schema(ldb, tmp_ctx);
+		/* TODO: 
+		 * If dsdb_get_schema() fails, we just fall back
+		 * to what we had.  However, the database is probably
+		 * unable to operate for other users from this
+		 * point... */
+		if (new_schema && used_global_schema) {
+			dsdb_make_schema_global(ldb, new_schema);
+		} else if (used_global_schema) { 
+			DEBUG(0,("Failed to re-load schema after commit of transaction\n"));
+			dsdb_set_global_schema(ldb);
+			TALLOC_FREE(tmp_ctx);
+			return WERR_INTERNAL_ERROR;
+		} else {
+			DEBUG(0,("Failed to re-load schema after commit of transaction\n"));
+			dsdb_reference_schema(ldb, cur_schema, false);
+			TALLOC_FREE(tmp_ctx);
+			return WERR_INTERNAL_ERROR;
 		}
-		msg = ldb_msg_new(ldb);
+		msg = ldb_msg_new(tmp_ctx);
 		if (msg == NULL) {
+			TALLOC_FREE(tmp_ctx);
 			return WERR_NOMEM;
 		}
 		msg->dn = ldb_dn_new(msg, ldb, "");
 		if (msg->dn == NULL) {
-			talloc_free(msg);
+			TALLOC_FREE(tmp_ctx);
 			return WERR_NOMEM;
 		}
 
 		ret = ldb_msg_add_string(msg, "schemaUpdateNow", "1");
 		if (ret != LDB_SUCCESS) {
-			talloc_free(msg);
+			TALLOC_FREE(tmp_ctx);
 			return WERR_INTERNAL_ERROR;
 		}
 
-		ret = ldb_build_mod_req(&req, ldb, ldb,
+		ret = ldb_build_mod_req(&req, ldb, objects,
 				msg,
 				LDB_SCOPE_BASE,
 				NULL,
@@ -698,14 +733,13 @@ WERROR dsdb_replicated_objects_commit(struct ldb_context *ldb,
 				NULL);
 
 		if (ret != LDB_SUCCESS) {
-			talloc_free(msg);
+			TALLOC_FREE(tmp_ctx);
 			return WERR_DS_DRA_INTERNAL_ERROR;
 		}
 
 		ret = ldb_transaction_start(ldb);
 		if (ret != LDB_SUCCESS) {
-			talloc_free(msg);
-			talloc_free(req);
+			TALLOC_FREE(tmp_ctx);
 			DEBUG(0, ("Autotransaction start failed\n"));
 			return WERR_DS_DRA_INTERNAL_ERROR;
 		}
@@ -718,14 +752,13 @@ WERROR dsdb_replicated_objects_commit(struct ldb_context *ldb,
 		if (ret == LDB_SUCCESS) {
 			ret = ldb_transaction_commit(ldb);
 		} else {
-			DEBUG(0, ("Schema update now failed: %s\n", ldb_strerror(ret)));
+			DEBUG(0, ("Schema update now failed: %s\n", ldb_errstring(ret)));
 			ldb_transaction_cancel(ldb);
 		}
 
-		talloc_free(msg);
-		talloc_free(req);
 		if (ret != LDB_SUCCESS) {
-			DEBUG(0, ("Commit failed: %s\n", ldb_strerror(ret)));
+			DEBUG(0, ("Commit failed: %s\n", ldb_errstring(ldb)));
+			TALLOC_FREE(tmp_ctx);
 			return WERR_DS_INTERNAL_FAILURE;
 		}
 	}
@@ -734,6 +767,7 @@ WERROR dsdb_replicated_objects_commit(struct ldb_context *ldb,
 		 objects->num_objects, objects->linked_attributes_count,
 		 ldb_dn_get_linearized(objects->partition_dn)));
 		 
+	TALLOC_FREE(tmp_ctx);
 	return WERR_OK;
 }
 
diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c
index f980b67..435a791 100644
--- a/source4/dsdb/samdb/ldb_modules/partition.c
+++ b/source4/dsdb/samdb/ldb_modules/partition.c
@@ -1061,14 +1061,6 @@ int partition_sequence_number_from_partitions(struct ldb_module *module,
 		if (ret != LDB_SUCCESS) {
 			talloc_free(res);
 			return ret;
-			}
-		
-		ret = ldb_request_add_control(treq,
-					      DSDB_CONTROL_CURRENT_PARTITION_OID,
-					      false, data->partitions[i]->ctrl);
-		if (ret != LDB_SUCCESS) {
-			talloc_free(res);
-			return ret;
 		}
 		
 		ret = partition_request(data->partitions[i]->module, treq);
@@ -1116,21 +1108,6 @@ static int partition_sequence_number(struct ldb_module *module, struct ldb_reque
 		break;
 
 	case LDB_SEQ_HIGHEST_SEQ:
-
-		/* 
-		 * We can only query per-partition the individual
-		 * partition sequence number, so we don't need to run
-		 * this reload for every query of the next global seq
-		 * number 
-		 */
-		p = find_partition(data, NULL, req);
-		if (p != NULL) {
-			/* the caller specified what partition they want the
-			 * sequence number operation on - just pass it on
-			 */
-			return ldb_next_request(p->module, req);
-		}
-
 		ret = partition_metadata_sequence_number(module, &seq_number);
 		if (ret != LDB_SUCCESS) {
 			return ret;
diff --git a/source4/dsdb/samdb/ldb_modules/schema_load.c b/source4/dsdb/samdb/ldb_modules/schema_load.c
index 0ba0180..82ae7d8 100644
--- a/source4/dsdb/samdb/ldb_modules/schema_load.c
+++ b/source4/dsdb/samdb/ldb_modules/schema_load.c
@@ -188,30 +188,6 @@ static struct dsdb_schema *dsdb_schema_refresh(struct ldb_module *module, struct
 		return schema;
 	}
 
-	res = talloc_zero(schema, struct ldb_result);
-	if (res == NULL) {
-		return NULL;
-	}
-	tseq = talloc_zero(res, struct ldb_seqnum_request);
-	if (tseq == NULL) {
-		talloc_free(res);
-		return NULL;
-	}
-	tseq->type = LDB_SEQ_HIGHEST_SEQ;
-	
-	ret = ldb_build_extended_req(&treq, ldb_module_get_ctx(module), res,
-				     LDB_EXTENDED_SEQUENCE_NUMBER,
-				     tseq,
-				     NULL,
-				     res,
-				     ldb_extended_default_callback,
-				     NULL);
-	LDB_REQ_SET_LOCATION(treq);
-	if (ret != LDB_SUCCESS) {
-		talloc_free(res);
-		return NULL;
-	}
-
 	/*
 	 * We update right now the last refresh timestamp so that if
 	 * the schema partition hasn't change we don't keep on retrying.
@@ -230,42 +206,6 @@ static struct dsdb_schema *dsdb_schema_refresh(struct ldb_module *module, struct
 	}
 	schema->last_refresh = ts;
 
-	ctrl = talloc(treq, struct dsdb_control_current_partition);
-	if (!ctrl) {
-		talloc_free(res);
-		return NULL;
-	}
-	ctrl->version = DSDB_CONTROL_CURRENT_PARTITION_VERSION;
-	ctrl->dn = schema->base_dn;
-	
-	ret = ldb_request_add_control(treq,
-				      DSDB_CONTROL_CURRENT_PARTITION_OID,
-				      false, ctrl);
-	if (ret != LDB_SUCCESS) {
-		talloc_free(res);
-		return NULL;
-	}
-	
-	ret = ldb_next_request(module, treq);
-	if (ret != LDB_SUCCESS) {
-		talloc_free(res);
-		return NULL;
-	}
-	ret = ldb_wait(treq->handle, LDB_WAIT_ALL);
-	if (ret != LDB_SUCCESS) {
-		talloc_free(res);
-		return NULL;
-	}
-	tseqr = talloc_get_type(res->extended->data,
-				struct ldb_seqnum_result);
-	if (tseqr->seq_num == schema->reload_seq_number) {
-		talloc_free(res);
-		return schema;
-	}
-
-	schema->reload_seq_number = tseqr->seq_num;
-	talloc_free(res);
-		
 	ret = dsdb_module_load_partition_usn(module, schema->base_dn, &current_usn, NULL, NULL);
 	if (ret != LDB_SUCCESS || current_usn == schema->loaded_usn) {
 		return schema;
@@ -380,7 +320,9 @@ static int dsdb_schema_from_db(struct ldb_module *module, struct ldb_dn *schema_
 		goto failed;
 	}
 
-	/* Ensure this module won't go away before the callback */
+	/* Ensure this module won't go away before the callback.  This
+	 * causes every schema to have the LDB that originally loaded
+	 * the first schema as a talloc child. */
 	if (talloc_reference(*schema, ldb) == NULL) {
 		ldb_oom(ldb);
 		ret = LDB_ERR_OPERATIONS_ERROR;
diff --git a/source4/dsdb/schema/schema.h b/source4/dsdb/schema/schema.h
index 54903f5..81ac129 100644
--- a/source4/dsdb/schema/schema.h
+++ b/source4/dsdb/schema/schema.h
@@ -252,12 +252,6 @@ struct dsdb_schema {
 	 * requested to reload the schema (either due through DRS or via the schemaUpdateNow).
 	 */
 	uint64_t metadata_usn;
-	/* an 'opaque' sequence number that corresponds to the highest USN of the schema
-	 * partition it used in the reload to check if a reload
-	 * should really be performed. As the schema is periodically reloaded this
-	 * is still needed in order to avoid costly complete schema reload.
-	 */
-	uint64_t reload_seq_number;
 
 	/* Should the syntax handlers in this case handle all incoming OIDs automatically, assigning them as an OID if no text name is known? */
 	bool relax_OID_conversions;


-- 
Samba Shared Repository


More information about the samba-cvs mailing list