[SCM] Samba Shared Repository - branch master updated
Andrew Tridgell
tridge at samba.org
Fri Oct 1 19:46:01 MDT 2010
The branch, master has been updated
via 23a8fad s4-drs: fixed comparison login in replicated renames
via 6e846ca s4-kcc: remove stale repsTo entries in the KCC
from faa993d autobuild: fixed tuple count for retry
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 23a8fad22bbcd41ee2583d96831295887fe48edc
Author: Andrew Tridgell <tridge at samba.org>
Date: Fri Oct 1 16:19:28 2010 -0700
s4-drs: fixed comparison login in replicated renames
we need to ensure we only ever compare USNs from the same originating
invocation ID.
Autobuild-User: Andrew Tridgell <tridge at samba.org>
Autobuild-Date: Sat Oct 2 01:45:19 UTC 2010 on sn-devel-104
commit 6e846ca1f3bd812bdba22101d8326987a0013858
Author: Andrew Tridgell <tridge at samba.org>
Date: Fri Oct 1 14:20:57 2010 -0700
s4-kcc: remove stale repsTo entries in the KCC
Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>
-----------------------------------------------------------------------
Summary of changes:
source4/dsdb/kcc/kcc_periodic.c | 32 ++++++
source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 117 ++++++++++++++---------
2 files changed, 104 insertions(+), 45 deletions(-)
Changeset truncated at 500 lines:
diff --git a/source4/dsdb/kcc/kcc_periodic.c b/source4/dsdb/kcc/kcc_periodic.c
index b6db0a7..d9ca618 100644
--- a/source4/dsdb/kcc/kcc_periodic.c
+++ b/source4/dsdb/kcc/kcc_periodic.c
@@ -260,6 +260,38 @@ static NTSTATUS kccsrv_add_repsFrom(struct kccsrv_service *s, TALLOC_CTX *mem_ct
/* dreplsrv should refresh its state */
notify_dreplsrv = true;
}
+
+ /* remove stale repsTo entries */
+ modified = false;
+ werr = dsdb_loadreps(s->samdb, mem_ctx, p->dn, "repsTo", &our_reps, &our_count);
+ if (!W_ERROR_IS_OK(werr)) {
+ DEBUG(0,(__location__ ": Failed to load repsTo from %s - %s\n",
+ ldb_dn_get_linearized(p->dn), ldb_errstring(s->samdb)));
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+
+ /* remove any stale ones */
+ for (i=0; i<our_count; i++) {
+ if (!reps_in_list(&our_reps[i], reps, count)) {
+ DEBUG(4,(__location__ ": Removed repsTo for %s\n",
+ our_reps[i].ctr.ctr1.other_info->dns_name));
+ memmove(&our_reps[i], &our_reps[i+1], (our_count-(i+1))*sizeof(our_reps[0]));
+ our_count--;
+ i--;
+ modified = true;
+ }
+ }
+
+ if (modified) {
+ werr = dsdb_savereps(s->samdb, mem_ctx, p->dn, "repsTo", our_reps, our_count);
+ if (!W_ERROR_IS_OK(werr)) {
+ DEBUG(0,(__location__ ": Failed to save repsTo to %s - %s\n",
+ ldb_dn_get_linearized(p->dn), ldb_errstring(s->samdb)));
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+ /* dreplsrv should refresh its state */
+ notify_dreplsrv = true;
+ }
}
/* notify dreplsrv toplogy has changed */
diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
index 198bb80..b459405 100644
--- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
+++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
@@ -2896,19 +2896,23 @@ static bool replmd_update_is_newer(const struct GUID *current_invocation_id,
const struct GUID *update_invocation_id,
uint32_t current_version,
uint32_t update_version,
+ uint32_t current_usn,
+ uint32_t update_usn,
NTTIME current_change_time,
NTTIME update_change_time)
{
- if (update_version != current_version) {
- return update_version > current_version;
+ if (GUID_compare(update_invocation_id, current_invocation_id) == 0) {
+ if (update_usn != current_usn) {
+ return update_usn >= current_usn;
+ }
}
- if (update_change_time > current_change_time) {
- return true;
+ if (update_version != current_version) {
+ return update_version >= current_version;
}
- if (update_change_time == current_change_time) {
- return GUID_compare(update_invocation_id, current_invocation_id) > 0;
+ if (update_change_time != current_change_time) {
+ return update_change_time >= current_change_time;
}
- return false;
+ return GUID_compare(update_invocation_id, current_invocation_id) >= 0;
}
static bool replmd_replPropertyMetaData1_is_newer(struct replPropertyMetaData1 *cur_m,
@@ -2918,6 +2922,8 @@ static bool replmd_replPropertyMetaData1_is_newer(struct replPropertyMetaData1 *
&new_m->originating_invocation_id,
cur_m->version,
new_m->version,
+ cur_m->originating_usn,
+ new_m->originating_usn,
cur_m->originating_change_time,
new_m->originating_change_time);
}
@@ -2937,6 +2943,52 @@ replmd_replPropertyMetaData1_find_attid(struct replPropertyMetaDataBlob *md_blob
return NULL;
}
+
+/*
+ handle renames that come in over DRS replication
+ */
+static int replmd_replicated_handle_rename(struct replmd_replicated_request *ar,
+ struct ldb_message *msg,
+ struct replPropertyMetaDataBlob *rmd,
+ struct replPropertyMetaDataBlob *omd)
+{
+ struct replPropertyMetaData1 *md_remote;
+ struct replPropertyMetaData1 *md_local;
+
+ if (ldb_dn_compare(msg->dn, ar->search_msg->dn) == 0) {
+ /* no rename */
+ return LDB_SUCCESS;
+ }
+
+ /* now we need to check for double renames. We could have a
+ * local rename pending which our replication partner hasn't
+ * received yet. We choose which one wins by looking at the
+ * attribute stamps on the two objects, the newer one wins
+ */
+ md_remote = replmd_replPropertyMetaData1_find_attid(rmd, DRSUAPI_ATTRIBUTE_name);
+ md_local = replmd_replPropertyMetaData1_find_attid(omd, DRSUAPI_ATTRIBUTE_name);
+ /* if there is no name attribute then we have to assume the
+ object we've received is in fact newer */
+ if (!md_remote || !md_local ||
+ replmd_replPropertyMetaData1_is_newer(md_local, md_remote)) {
+ DEBUG(4,("replmd_replicated_request rename %s => %s\n",
+ ldb_dn_get_linearized(ar->search_msg->dn),
+ ldb_dn_get_linearized(msg->dn)));
+ /* pass rename to the next module
+ * so it doesn't appear as an originating update */
+ return dsdb_module_rename(ar->module,
+ ar->search_msg->dn, msg->dn,
+ DSDB_FLAG_NEXT_MODULE | DSDB_MODIFY_RELAX);
+ }
+
+ /* we're going to keep our old object */
+ DEBUG(4,(__location__ ": Keeping object %s and rejecting older rename to %s\n",
+ ldb_dn_get_linearized(ar->search_msg->dn),
+ ldb_dn_get_linearized(msg->dn)));
+ return LDB_SUCCESS;
+}
+
+
static int replmd_replicated_apply_merge(struct replmd_replicated_request *ar)
{
struct ldb_context *ldb;
@@ -2948,8 +3000,6 @@ static int replmd_replicated_apply_merge(struct replmd_replicated_request *ar)
const struct ldb_val *omd_value;
struct replPropertyMetaDataBlob nmd;
struct ldb_val nmd_value;
- struct replPropertyMetaData1 *md_remote;
- struct replPropertyMetaData1 *md_local;
unsigned int i;
uint32_t j,ni=0;
unsigned int removed_attrs = 0;
@@ -2976,42 +3026,15 @@ static int replmd_replicated_apply_merge(struct replmd_replicated_request *ar)
}
}
- /* check if remote 'name' has change,
- * which indicates a rename operation */
- md_remote = replmd_replPropertyMetaData1_find_attid(rmd, DRSUAPI_ATTRIBUTE_name);
- if (md_remote) {
- md_local = replmd_replPropertyMetaData1_find_attid(&omd, DRSUAPI_ATTRIBUTE_name);
- if (!md_local) {
- DEBUG(0,(__location__ ": No md_local in RPMD\n"));
- return replmd_replicated_request_werror(ar, WERR_DS_DRA_INTERNAL_ERROR);
- }
- if (replmd_replPropertyMetaData1_is_newer(md_local, md_remote)) {
- if (ldb_dn_compare(msg->dn, ar->search_msg->dn) != 0) {
- DEBUG(0,(__location__ ": DNs don't match in RPMD: %s %s\n",
- ldb_dn_get_linearized(msg->dn),
- ldb_dn_get_linearized(ar->search_msg->dn)));
- return replmd_replicated_request_werror(ar, WERR_DS_DRA_INTERNAL_ERROR);
- }
- /* TODO: Find appropriate local name (dn) for the object
- * and modify msg->dn appropriately */
-
- DEBUG(4,("replmd_replicated_request rename %s => %s\n",
- ldb_dn_get_linearized(ar->search_msg->dn),
- ldb_dn_get_linearized(msg->dn)));
- /* pass rename to the next module
- * so it doesn't appear as an originating update */
- ret = dsdb_module_rename(ar->module,
- ar->search_msg->dn, msg->dn,
- DSDB_FLAG_NEXT_MODULE);
- if (ret != LDB_SUCCESS) {
- ldb_debug(ldb, LDB_DEBUG_FATAL,
- "replmd_replicated_request rename %s => %s failed - %s\n",
- ldb_dn_get_linearized(ar->search_msg->dn),
- ldb_dn_get_linearized(msg->dn),
- ldb_errstring(ldb));
- return replmd_replicated_request_werror(ar, WERR_DS_DRA_DB_ERROR);
- }
- }
+ /* handle renames that come in over DRS */
+ ret = replmd_replicated_handle_rename(ar, msg, rmd, &omd);
+ if (ret != LDB_SUCCESS) {
+ ldb_debug(ldb, LDB_DEBUG_FATAL,
+ "replmd_replicated_request rename %s => %s failed - %s\n",
+ ldb_dn_get_linearized(ar->search_msg->dn),
+ ldb_dn_get_linearized(msg->dn),
+ ldb_errstring(ldb));
+ return replmd_replicated_request_werror(ar, WERR_DS_DRA_DB_ERROR);
}
ZERO_STRUCT(nmd);
@@ -3920,17 +3943,21 @@ linked_attributes[0]:
/* see if this update is newer than what we have already */
struct GUID invocation_id = GUID_zero();
uint32_t version = 0;
+ uint32_t originating_usn = 0;
NTTIME change_time = 0;
uint32_t rmd_flags = dsdb_dn_rmd_flags(pdn->dsdb_dn->dn);
dsdb_get_extended_dn_guid(pdn->dsdb_dn->dn, &invocation_id, "RMD_INVOCID");
dsdb_get_extended_dn_uint32(pdn->dsdb_dn->dn, &version, "RMD_VERSION");
+ dsdb_get_extended_dn_uint32(pdn->dsdb_dn->dn, &originating_usn, "RMD_ORIGINATING_USN");
dsdb_get_extended_dn_nttime(pdn->dsdb_dn->dn, &change_time, "RMD_CHANGETIME");
if (!replmd_update_is_newer(&invocation_id,
&la->meta_data.originating_invocation_id,
version,
la->meta_data.version,
+ originating_usn,
+ la->meta_data.originating_usn,
change_time,
la->meta_data.originating_change_time)) {
DEBUG(3,("Discarding older DRS linked attribute update to %s on %s from %s\n",
--
Samba Shared Repository
More information about the samba-cvs
mailing list