The branch, master has been updated via 7157221 s4-drepl: During Schema replication, we need to save updated prefixMap if everything is OK via 5bc0848 s4-dsdb_schema: Copy info needed for Schema refresh in dsdb_schema_copy_shallow via 214b129 s4-devel/pfm_verify: Extend the tool to verify schemaInfo attribute value via bd6f9ef s4-drepl: Make refreshed schema a global one from 09a2f14 pyrpc: Add prototype for init function.
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 7157221da5bc6787b08ab26c9e83c08208b41d8a Author: Kamen Mazdrashki <kame...@samba.org> Date: Sat Dec 18 05:30:08 2010 +0200 s4-drepl: During Schema replication, we need to save updated prefixMap if everything is OK Autobuild-User: Kamen Mazdrashki <kame...@samba.org> Autobuild-Date: Sat Dec 18 05:53:48 CET 2010 on sn-devel-104 commit 5bc0848fc73f96879fdb5d398272ead7fee39157 Author: Kamen Mazdrashki <kame...@samba.org> Date: Sat Dec 18 05:29:20 2010 +0200 s4-dsdb_schema: Copy info needed for Schema refresh in dsdb_schema_copy_shallow Just 'refresh_fn' and 'loaded_from_module' are copied. I left 'reload_seq_number' set to 0 intentionally, so that this Schema cache will looks like a very old one to ,refresh_fn'. This way, if this shallow copy is attached to LDB, it will be refreshed as soon as possible by 'refresh_fn'. commit 214b12973d71fc9c2b6221fe9f41d1e725e96612 Author: Kamen Mazdrashki <kame...@samba.org> Date: Sat Dec 18 05:21:09 2010 +0200 s4-devel/pfm_verify: Extend the tool to verify schemaInfo attribute value commit bd6f9efc1e993d41d14da3ac56307ed424745153 Author: Kamen Mazdrashki <kame...@samba.org> Date: Thu Dec 16 22:31:28 2010 +0200 s4-drepl: Make refreshed schema a global one We need to do this as dsdb_reference_schema() function clears "use_global_schema" ldb flag. Basically what is going to happen is that after dsdb_reference_schema() global_schema pointer will continue to point at old schema cache, while "dsdb_schema" for LDB will point at the working_schema. After replication is done, we reset "dsdb_schema" for the ldb with an updated Schema cache, but this leaves global_schema pointer with its old value, which is not up to date. So we need to call dsdb_make_schema_global() again so that global_schema points to a valid Schema cache. ----------------------------------------------------------------------- Summary of changes: source4/dsdb/repl/replicated_objects.c | 25 ++++++++++++++++ source4/dsdb/schema/schema_init.c | 4 ++ source4/scripting/devel/pfm_verify.py | 49 ++++++++++++++++++++++++++++---- 3 files changed, 72 insertions(+), 6 deletions(-) Changeset truncated at 500 lines: diff --git a/source4/dsdb/repl/replicated_objects.c b/source4/dsdb/repl/replicated_objects.c index d01d3c1..0def815 100644 --- a/source4/dsdb/repl/replicated_objects.c +++ b/source4/dsdb/repl/replicated_objects.c @@ -445,6 +445,7 @@ WERROR dsdb_replicated_objects_commit(struct ldb_context *ldb, struct dsdb_extended_replicated_objects *objects, uint64_t *notify_uSN) { + WERROR werr; struct ldb_result *ext_res; struct dsdb_schema *cur_schema = NULL; int ret; @@ -493,6 +494,7 @@ WERROR dsdb_replicated_objects_commit(struct ldb_context *ldb, /* restore previous schema */ 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", @@ -502,11 +504,29 @@ WERROR dsdb_replicated_objects_commit(struct ldb_context *ldb, } talloc_free(ext_res); + /* Save our updated prefixMap */ + if (working_schema) { + werr = dsdb_write_prefixes_from_schema_to_ldb(working_schema, + ldb, + working_schema); + if (!W_ERROR_IS_OK(werr)) { + /* restore previous schema */ + 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))); + return werr; + } + } + ret = ldb_transaction_prepare_commit(ldb); if (ret != LDB_SUCCESS) { /* restore previous schema */ 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))); @@ -518,6 +538,7 @@ WERROR dsdb_replicated_objects_commit(struct ldb_context *ldb, /* restore previous schema */ 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); @@ -536,6 +557,7 @@ WERROR dsdb_replicated_objects_commit(struct ldb_context *ldb, /* restore previous schema */ 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")); return WERR_FOOBAR; @@ -549,6 +571,9 @@ WERROR dsdb_replicated_objects_commit(struct ldb_context *ldb, 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); + } } DEBUG(2,("Replicated %u objects (%u linked attributes) for %s\n", diff --git a/source4/dsdb/schema/schema_init.c b/source4/dsdb/schema/schema_init.c index 00170a2..62111c5 100644 --- a/source4/dsdb/schema/schema_init.c +++ b/source4/dsdb/schema/schema_init.c @@ -99,6 +99,10 @@ struct dsdb_schema *dsdb_schema_copy_shallow(TALLOC_CTX *mem_ctx, goto failed; } + /* leave reload_seq_number = 0 so it will be refresh ASAP */ + schema_copy->refresh_fn = schema->refresh_fn; + schema_copy->loaded_from_module = schema->loaded_from_module; + return schema_copy; failed: diff --git a/source4/scripting/devel/pfm_verify.py b/source4/scripting/devel/pfm_verify.py index a7314d9..300fd05 100755 --- a/source4/scripting/devel/pfm_verify.py +++ b/source4/scripting/devel/pfm_verify.py @@ -42,7 +42,14 @@ def _samdb_fetch_pfm(samdb): assert len(res) == 1 pfm = ndr_unpack(drsblobs.prefixMapBlob, str(res[0]['prefixMap'])) - return pfm.ctr + pfm_schi = None + if 'schemaInfo' in res[0]: + pfm_schi = pfm_schi = ndr_unpack(drsblobs.schemaInfoBlob, + str(res[0]['schemaInfo'])) + else: + pfm_schi = drsblobs.schemaInfoBlob() + pfm_schi.marker = 0xFF; + return (pfm.ctr, pfm_schi) def _drs_fetch_pfm(server, samdb, creds, lp): """Fetch prefixMap using DRS interface""" @@ -82,10 +89,14 @@ def _drs_fetch_pfm(server, samdb, creds, lp): pfm_it = pfm.mappings[-1] assert pfm_it.id_prefix == 0 assert pfm_it.oid.length == 21 - assert pfm_it.oid.binary_oid[0] == 255 + s = '' + for x in pfm_it.oid.binary_oid: + s += chr(x) + pfm_schi = ndr_unpack(drsblobs.schemaInfoBlob, s) + assert pfm_schi.marker == 0xFF # remove schemaInfo element pfm.num_mappings -= 1 - return pfm + return (pfm, pfm_schi) def _pfm_verify(drs_pfm, ldb_pfm): errors = [] @@ -107,6 +118,21 @@ def _pfm_verify(drs_pfm, ldb_pfm): errors.append("[%2d] differences in (%s)" % (i, it_err)) return errors +def _pfm_schi_verify(drs_schi, ldb_schi): + errors = [] + print drs_schi.revision + print drs_schi.invocation_id + if drs_schi.marker != ldb_schi.marker: + errors.append("Different marker in schemaInfo: drs = %d, ldb = %d" + % (drs_schi.marker, ldb_schi.marker)) + if drs_schi.revision != ldb_schi.revision: + errors.append("Different revision in schemaInfo: drs = %d, ldb = %d" + % (drs_schi.revision, ldb_schi.revision)) + if drs_schi.invocation_id != ldb_schi.invocation_id: + errors.append("Different invocation_id in schemaInfo: drs = %s, ldb = %s" + % (drs_schi.invocation_id, ldb_schi.invocation_id)) + return errors + ########### main code ########### if __name__ == "__main__": # command line parsing @@ -137,10 +163,21 @@ if __name__ == "__main__": session_info=system_session(lp), credentials=creds, lp=lp) - drs_pfm = _drs_fetch_pfm(server, samdb, creds, lp) - ldb_pfm = _samdb_fetch_pfm(samdb) + exit_code = 0 + (drs_pfm, drs_schi) = _drs_fetch_pfm(server, samdb, creds, lp) + (ldb_pfm, ldb_schi) = _samdb_fetch_pfm(samdb) + # verify prefixMaps errors = _pfm_verify(drs_pfm, ldb_pfm) if len(errors): print "prefixMap verification errors:" print "%s" % errors - sys.exit(1) + exit_code = 1 + # verify schemaInfos + errors = _pfm_schi_verify(drs_schi, ldb_schi) + if len(errors): + print "schemaInfo verification errors:" + print "%s" % errors + exit_code = 2 + + if exit_code != 0: + sys.exit(exit_code) -- Samba Shared Repository