diff options
author | Stefan Metzmacher <metze@samba.org> | 2006-01-23 16:04:27 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:51:24 -0500 |
commit | a9109089c3709f21bc9723336c5bbab22f3e527a (patch) | |
tree | 1493975eb93f51e969d8a009961a1871eebfe57c | |
parent | dd5afc5a775e64bd9b8f8bb57d015e4fb0532f3e (diff) | |
download | samba-a9109089c3709f21bc9723336c5bbab22f3e527a.tar.gz samba-a9109089c3709f21bc9723336c5bbab22f3e527a.tar.bz2 samba-a9109089c3709f21bc9723336c5bbab22f3e527a.zip |
r13088: - handle non-active static entries
- improve verifiying a replica with a remote wins server
we now take the ownership of replica records that doesn't match
the answer from the wins owner and make the record tombstone.
this hopefully causes the original wins owner to propagate its
new record, so that it will be replicated back to us
metze
(This used to be commit 49199477f225f3d22b3c70bb4626b92ed096f310)
-rw-r--r-- | source4/wrepl_server/wrepl_scavenging.c | 114 |
1 files changed, 57 insertions, 57 deletions
diff --git a/source4/wrepl_server/wrepl_scavenging.c b/source4/wrepl_server/wrepl_scavenging.c index a251fcba52..a4c4c480e0 100644 --- a/source4/wrepl_server/wrepl_scavenging.c +++ b/source4/wrepl_server/wrepl_scavenging.c @@ -57,6 +57,7 @@ static NTSTATUS wreplsrv_scavenging_owned_records(struct wreplsrv_service *servi const char *now_timestr; const char *action; const char *old_state; + const char *new_state; uint32_t modify_flags; BOOL modify_record; BOOL delete_record; @@ -70,7 +71,7 @@ static NTSTATUS wreplsrv_scavenging_owned_records(struct wreplsrv_service *servi NT_STATUS_HAVE_NO_MEMORY(owner_filter); filter = talloc_asprintf(tmp_mem, "(&%s(objectClass=winsRecord)" - "(expireTime<=%s)(!(isStatic=1)))", + "(expireTime<=%s))", owner_filter, now_timestr); NT_STATUS_HAVE_NO_MEMORY(filter); ret = ldb_search(service->wins_db->ldb, NULL, LDB_SCOPE_SUBTREE, filter, NULL, &res); @@ -92,18 +93,6 @@ static NTSTATUS wreplsrv_scavenging_owned_records(struct wreplsrv_service *servi NT_STATUS_NOT_OK_RETURN(status); talloc_free(res->msgs[i]); - if (rec->is_static) { - DEBUG(0,("%s: corrupted record: %s\n", - __location__, nbt_name_string(rec, rec->name))); - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - - if (rec->expire_time > now) { - DEBUG(0,("%s: corrupted record: %s\n", - __location__, nbt_name_string(rec, rec->name))); - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - modify_flags = 0; modify_record = False; delete_record = False; @@ -111,14 +100,19 @@ static NTSTATUS wreplsrv_scavenging_owned_records(struct wreplsrv_service *servi switch (rec->state) { case WREPL_STATE_ACTIVE: old_state = "active"; - rec->state = WREPL_STATE_RELEASED; - rec->expire_time= service->config.tombstone_interval + now; + new_state = "active"; + if (!rec->is_static) { + new_state = "released"; + rec->state = WREPL_STATE_RELEASED; + rec->expire_time= service->config.tombstone_interval + now; + } modify_flags = 0; modify_record = True; break; case WREPL_STATE_RELEASED: old_state = "released"; + new_state = "tombstone"; rec->state = WREPL_STATE_TOMBSTONE; rec->expire_time= service->config.tombstone_timeout + now; modify_flags = WINSDB_FLAG_ALLOC_VERSION | WINSDB_FLAG_TAKE_OWNERSHIP; @@ -127,7 +121,9 @@ static NTSTATUS wreplsrv_scavenging_owned_records(struct wreplsrv_service *servi case WREPL_STATE_TOMBSTONE: old_state = "tombstone"; + new_state = "tombstone"; if (!delete_tombstones) break; + new_state = "deleted"; delete_record = True; break; @@ -149,11 +145,11 @@ static NTSTATUS wreplsrv_scavenging_owned_records(struct wreplsrv_service *servi } if (ret != NBT_RCODE_OK) { - DEBUG(1,("WINS scavenging: failed to %s name %s (owned:%s): error:%u\n", - action, nbt_name_string(rec, rec->name), old_state, ret)); + DEBUG(1,("WINS scavenging: failed to %s name %s (owned:%s -> owned:%s): error:%u\n", + action, nbt_name_string(rec, rec->name), old_state, new_state, ret)); } else { - DEBUG(4,("WINS scavenging: %s name: %s (owned:%s)\n", - action, nbt_name_string(rec, rec->name), old_state)); + DEBUG(4,("WINS scavenging: %s name: %s (owned:%s -> owned:%s)\n", + action, nbt_name_string(rec, rec->name), old_state, new_state)); } talloc_free(rec); @@ -175,6 +171,7 @@ static NTSTATUS wreplsrv_scavenging_replica_non_active_records(struct wreplsrv_s const char *now_timestr; const char *action; const char *old_state; + const char *new_state; uint32_t modify_flags; BOOL modify_record; BOOL delete_record; @@ -188,7 +185,7 @@ static NTSTATUS wreplsrv_scavenging_replica_non_active_records(struct wreplsrv_s NT_STATUS_HAVE_NO_MEMORY(owner_filter); filter = talloc_asprintf(tmp_mem, "(&(!%s)(objectClass=winsRecord)" - "(!(recordState=%u))(expireTime<=%s)(!(isStatic=1)))", + "(!(recordState=%u))(expireTime<=%s))", owner_filter, WREPL_STATE_ACTIVE, now_timestr); NT_STATUS_HAVE_NO_MEMORY(filter); ret = ldb_search(service->wins_db->ldb, NULL, LDB_SCOPE_SUBTREE, filter, NULL, &res); @@ -210,18 +207,6 @@ static NTSTATUS wreplsrv_scavenging_replica_non_active_records(struct wreplsrv_s NT_STATUS_NOT_OK_RETURN(status); talloc_free(res->msgs[i]); - if (rec->is_static) { - DEBUG(0,("%s: corrupted record: %s\n", - __location__, nbt_name_string(rec, rec->name))); - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - - if (rec->expire_time > now) { - DEBUG(0,("%s: corrupted record: %s\n", - __location__, nbt_name_string(rec, rec->name))); - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - modify_flags = 0; modify_record = False; delete_record = False; @@ -234,6 +219,7 @@ static NTSTATUS wreplsrv_scavenging_replica_non_active_records(struct wreplsrv_s case WREPL_STATE_RELEASED: old_state = "released"; + new_state = "tombstone"; rec->state = WREPL_STATE_TOMBSTONE; rec->expire_time= service->config.tombstone_timeout + now; modify_flags = 0; @@ -242,7 +228,9 @@ static NTSTATUS wreplsrv_scavenging_replica_non_active_records(struct wreplsrv_s case WREPL_STATE_TOMBSTONE: old_state = "tombstone"; + new_state = "tombstone"; if (!delete_tombstones) break; + new_state = "deleted"; delete_record = True; break; @@ -264,11 +252,11 @@ static NTSTATUS wreplsrv_scavenging_replica_non_active_records(struct wreplsrv_s } if (ret != NBT_RCODE_OK) { - DEBUG(1,("WINS scavenging: failed to %s name %s (replica:%s): error:%u\n", - action, nbt_name_string(rec, rec->name), old_state, ret)); + DEBUG(1,("WINS scavenging: failed to %s name %s (replica:%s -> replica:%s): error:%u\n", + action, nbt_name_string(rec, rec->name), old_state, new_state, ret)); } else { - DEBUG(4,("WINS scavenging: %s name: %s (replica:%s)\n", - action, nbt_name_string(rec, rec->name), old_state)); + DEBUG(4,("WINS scavenging: %s name: %s (replica:%s -> replica:%s)\n", + action, nbt_name_string(rec, rec->name), old_state, new_state)); } talloc_free(rec); @@ -291,6 +279,9 @@ static void verify_handler(struct irpc_request *ireq) struct winsdb_record *rec = s->rec; const char *action; const char *old_state = "active"; + const char *new_state = "active"; + const char *new_owner = "replica"; + uint32_t modify_flags = 0; BOOL modify_record = False; BOOL delete_record = False; BOOL different = False; @@ -308,6 +299,7 @@ static void verify_handler(struct irpc_request *ireq) status = irpc_call_recv(ireq); if (NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) { delete_record = True; + new_state = "deleted"; } else if (NT_STATUS_IS_OK(status) && rec->type != WREPL_TYPE_GROUP) { for (i=0; i < s->r.out.num_addrs; i++) { BOOL found = False; @@ -329,20 +321,39 @@ static void verify_handler(struct irpc_request *ireq) } if (different) { - DEBUG(0,("WINS scavenging: replica %s verify got different addresses from winsserver: %s: deleting record\n", + /* + * if the reply from the owning wins server has different addresses + * then take the ownership of the record and make it a tombstone + * this will then hopefully replicated to the original owner of the record + * which will then propagate it's own record, so that the current record will + * be replicated to to us + */ + DEBUG(0,("WINS scavenging: replica %s verify got different addresses from winsserver: %s: tombstoning record\n", nbt_name_string(rec, rec->name), rec->wins_owner)); - delete_record = True; + + rec->state = WREPL_STATE_TOMBSTONE; + rec->expire_time= time(NULL) + s->service->config.tombstone_timeout; + for (i=0; rec->addresses[i]; i++) { + rec->addresses[i]->expire_time = rec->expire_time; + } + modify_record = True; + modify_flags = WINSDB_FLAG_ALLOC_VERSION | WINSDB_FLAG_TAKE_OWNERSHIP; + new_state = "tombstone"; + new_owner = "owned"; } else if (NT_STATUS_IS_OK(status)) { + /* if the addresses are the same, just update the timestamps */ rec->expire_time = time(NULL) + s->service->config.verify_interval; for (i=0; rec->addresses[i]; i++) { rec->addresses[i]->expire_time = rec->expire_time; } - modify_record = True; + modify_record = True; + modify_flags = 0; + new_state = "active"; } if (modify_record) { action = "modify"; - ret = winsdb_modify(s->service->wins_db, rec, 0); + ret = winsdb_modify(s->service->wins_db, rec, modify_flags); } else if (delete_record) { action = "delete"; ret = winsdb_delete(s->service->wins_db, rec); @@ -352,11 +363,12 @@ static void verify_handler(struct irpc_request *ireq) } if (ret != NBT_RCODE_OK) { - DEBUG(1,("WINS scavenging: failed to %s name %s (replica:%s): error:%u\n", - action, nbt_name_string(rec, rec->name), old_state, ret)); + DEBUG(1,("WINS scavenging: failed to %s name %s (replica:%s -> %s:%s): error:%u\n", + action, nbt_name_string(rec, rec->name), old_state, new_owner, new_state, ret)); } else { - DEBUG(4,("WINS scavenging: %s name: %s (replica:%s): %s: %s\n", - action, nbt_name_string(rec, rec->name), old_state, rec->wins_owner, nt_errstr(status))); + DEBUG(4,("WINS scavenging: %s name: %s (replica:%s -> %s:%s): %s: %s\n", + action, nbt_name_string(rec, rec->name), old_state, new_owner, new_state, + rec->wins_owner, nt_errstr(status))); } talloc_free(s); @@ -389,7 +401,7 @@ static NTSTATUS wreplsrv_scavenging_replica_active_records(struct wreplsrv_servi NT_STATUS_HAVE_NO_MEMORY(owner_filter); filter = talloc_asprintf(tmp_mem, "(&(!%s)(objectClass=winsRecord)" - "(recordState=%u)(expireTime<=%s)(!(isStatic=1)))", + "(recordState=%u)(expireTime<=%s))", owner_filter, WREPL_STATE_ACTIVE, now_timestr); NT_STATUS_HAVE_NO_MEMORY(filter); ret = ldb_search(service->wins_db->ldb, NULL, LDB_SCOPE_SUBTREE, filter, NULL, &res); @@ -406,18 +418,6 @@ static NTSTATUS wreplsrv_scavenging_replica_active_records(struct wreplsrv_servi NT_STATUS_NOT_OK_RETURN(status); talloc_free(res->msgs[i]); - if (rec->is_static) { - DEBUG(0,("%s: corrupted record: %s\n", - __location__, nbt_name_string(rec, rec->name))); - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - - if (rec->expire_time > now) { - DEBUG(0,("%s: corrupted record: %s\n", - __location__, nbt_name_string(rec, rec->name))); - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - if (rec->state != WREPL_STATE_ACTIVE) { DEBUG(0,("%s: corrupted record: %s\n", __location__, nbt_name_string(rec, rec->name))); |