samba-cvs.cvs
[Top] [All Lists]

svn commit: samba r12071 - in branches/SAMBA_4_0/source/wrepl_server: .

Subject: svn commit: samba r12071 - in branches/SAMBA_4_0/source/wrepl_server: .
From:
Date: Mon, 5 Dec 2005 12:25:21 +0000 GMT
Author: metze
Date: 2005-12-05 12:25:19 +0000 (Mon, 05 Dec 2005)
New Revision: 12071

WebSVN: 
http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=12071

Log:
- implement MHOMED merging
- implement late release demands

we now pass the full NBT-WINSREPLICATION torture test
but only with non-socket_wrapper mode

metze
Modified:
   branches/SAMBA_4_0/source/wrepl_server/wrepl_apply_records.c


Changeset:
Modified: branches/SAMBA_4_0/source/wrepl_server/wrepl_apply_records.c
===================================================================
--- branches/SAMBA_4_0/source/wrepl_server/wrepl_apply_records.c        
2005-12-05 12:18:16 UTC (rev 12070)
+++ branches/SAMBA_4_0/source/wrepl_server/wrepl_apply_records.c        
2005-12-05 12:25:19 UTC (rev 12071)
@@ -729,6 +729,89 @@
        return NT_STATUS_OK;
 }
 
+/* 
+Test Replica vs. owned active: some more MHOMED combinations
+_MA_MA_SP_U<00>: C:MHOMED vs. B:ALL => B:ALL => REPLACE
+_MA_MA_SM_U<00>: C:MHOMED vs. B:MHOMED => B:MHOMED => REPLACE
+_MA_MA_SB_P<00>: C:MHOMED vs. B:BEST (C:MHOMED) => B:MHOMED => MHOMED_MERGE
+_MA_MA_SB_A<00>: C:MHOMED vs. B:BEST (C:ALL) => B:MHOMED => MHOMED_MERGE
+_MA_MA_SB_PRA<00>: C:MHOMED vs. B:BEST (C:BEST) => C:MHOMED => NOT REPLACE
+_MA_MA_SB_O<00>: C:MHOMED vs. B:BEST (B:B_3_4) =>C:MHOMED => NOT REPLACE
+_MA_MA_SB_N<00>: C:MHOMED vs. B:BEST (NEGATIVE) => B:BEST => REPLACE
+Test Replica vs. owned active: some more UNIQUE,MHOMED combinations
+_MA_UA_SB_P<00>: C:MHOMED vs. B:UNIQUE,BEST (C:MHOMED) => B:MHOMED => 
MHOMED_MERGE
+_UA_UA_DI_PRA<00>: C:BEST vs. B:BEST2 (C:BEST2,LR:BEST2) => C:BEST => NOT 
REPLACE
+_UA_UA_DI_A<00>: C:BEST vs. B:BEST2 (C:ALL) => B:MHOMED => MHOMED_MERGE
+_UA_MA_DI_A<00>: C:BEST vs. B:BEST2 (C:ALL) => B:MHOMED => MHOMED_MERGE
+*/
+static NTSTATUS r_do_mhomed_merge(struct wreplsrv_partner *partner,
+                                 TALLOC_CTX *mem_ctx,
+                                 struct winsdb_record *rec,
+                                 struct wrepl_wins_owner *owner,
+                                 struct wrepl_name *replica)
+{
+       struct winsdb_record *merge;
+       uint32_t i,j;
+       uint8_t ret;
+       size_t len;
+
+       merge = talloc(mem_ctx, struct winsdb_record);
+       NT_STATUS_HAVE_NO_MEMORY(merge);
+
+       merge->name             = &replica->name;
+       merge->type             = WREPL_TYPE_MHOMED;
+       merge->state            = replica->state;
+       merge->node             = replica->node;
+       merge->is_static        = replica->is_static;
+       merge->expire_time      = time(NULL) + 
partner->service->config.verify_interval;
+       merge->version          = replica->version_id;
+       merge->wins_owner       = replica->owner;
+       merge->addresses        = winsdb_addr_list_make(merge);
+       NT_STATUS_HAVE_NO_MEMORY(merge->addresses);
+       merge->registered_by = NULL;
+
+       for (i=0; i < replica->num_addresses; i++) {
+               /* TODO: find out if rec->expire_time is correct here */
+               merge->addresses = winsdb_addr_list_add(merge->addresses,
+                                                       
replica->addresses[i].address,
+                                                       
replica->addresses[i].owner,
+                                                       merge->expire_time);
+               NT_STATUS_HAVE_NO_MEMORY(merge->addresses);
+       }
+
+       len = winsdb_addr_list_length(rec->addresses);
+
+       for (i=0; i < len; i++) {
+               BOOL found = False;
+               for (j=0; j < replica->num_addresses; j++) {
+                       if (strcmp(replica->addresses[j].address, 
rec->addresses[i]->address) == 0) {
+                               found = True;
+                               break;
+                       }
+               }
+               if (found) continue;
+
+               /* TODO: find out if rec->expire_time is correct here */
+               merge->addresses = winsdb_addr_list_add(merge->addresses,
+                                                       
rec->addresses[i]->address,
+                                                       
rec->addresses[i]->wins_owner,
+                                                       merge->expire_time);
+               NT_STATUS_HAVE_NO_MEMORY(merge->addresses);
+       }
+
+       ret = winsdb_modify(partner->service->wins_db, merge, 0);
+       if (ret != NBT_RCODE_OK) {
+               DEBUG(0,("Failed to modify mhomed merge record %s: %u\n",
+                       nbt_name_string(mem_ctx, &replica->name), ret));
+               return NT_STATUS_FOOBAR;
+       }
+
+       DEBUG(4,("mhomed merge record %s\n",
+               nbt_name_string(mem_ctx, &replica->name)));
+
+       return NT_STATUS_OK;
+}
+
 struct r_do_challenge_state {
        struct messaging_context *msg_ctx;
        struct wreplsrv_partner *partner;
@@ -738,11 +821,77 @@
        struct nbtd_proxy_wins_challenge r;
 };
 
+static void r_do_late_release_demand_handler(struct irpc_request *ireq)
+{
+       NTSTATUS status;
+       struct r_do_challenge_state *state = 
talloc_get_type(ireq->async.private,
+                                                            struct 
r_do_challenge_state);
+
+       status = irpc_call_recv(ireq);
+       /* don't care about the result */
+       talloc_free(state);
+}
+
+static NTSTATUS r_do_late_release_demand(struct r_do_challenge_state *state)
+{
+       struct irpc_request *ireq;
+       uint32_t *nbt_servers;
+       struct nbtd_proxy_wins_release_demand r;
+       uint32_t i;
+
+       DEBUG(4,("late release demand record %s\n",
+                nbt_name_string(state, &state->replica.name)));
+
+       nbt_servers = irpc_servers_byname(state->msg_ctx, "nbt_server");
+       if ((nbt_servers == NULL) || (nbt_servers[0] == 0)) {
+               return NT_STATUS_INTERNAL_ERROR;
+       }
+
+       r.in.name       = state->replica.name;
+       r.in.num_addrs  = state->r.out.num_addrs;
+       r.in.addrs      = talloc_array(state, struct nbtd_proxy_wins_addr, 
r.in.num_addrs);
+       NT_STATUS_HAVE_NO_MEMORY(r.in.addrs);
+       /* TODO: fix pidl to handle inline ipv4address arrays */
+       for (i=0; i < r.in.num_addrs; i++) {
+               r.in.addrs[i].addr = state->r.out.addrs[i].addr;
+       }
+
+       ireq = IRPC_CALL_SEND(state->msg_ctx, nbt_servers[0],
+                             irpc, NBTD_PROXY_WINS_RELEASE_DEMAND,
+                             &r, state);
+       NT_STATUS_HAVE_NO_MEMORY(ireq);
+
+       ireq->async.fn          = r_do_late_release_demand_handler;
+       ireq->async.private     = state;
+
+       return NT_STATUS_OK;
+}
+
+/* 
+Test Replica vs. owned active: some more MHOMED combinations
+_MA_MA_SP_U<00>: C:MHOMED vs. B:ALL => B:ALL => REPLACE
+_MA_MA_SM_U<00>: C:MHOMED vs. B:MHOMED => B:MHOMED => REPLACE
+_MA_MA_SB_P<00>: C:MHOMED vs. B:BEST (C:MHOMED) => B:MHOMED => MHOMED_MERGE
+_MA_MA_SB_A<00>: C:MHOMED vs. B:BEST (C:ALL) => B:MHOMED => MHOMED_MERGE
+_MA_MA_SB_PRA<00>: C:MHOMED vs. B:BEST (C:BEST) => C:MHOMED => NOT REPLACE
+_MA_MA_SB_O<00>: C:MHOMED vs. B:BEST (B:B_3_4) =>C:MHOMED => NOT REPLACE
+_MA_MA_SB_N<00>: C:MHOMED vs. B:BEST (NEGATIVE) => B:BEST => REPLACE
+Test Replica vs. owned active: some more UNIQUE,MHOMED combinations
+_MA_UA_SB_P<00>: C:MHOMED vs. B:UNIQUE,BEST (C:MHOMED) => B:MHOMED => 
MHOMED_MERGE
+_UA_UA_DI_PRA<00>: C:BEST vs. B:BEST2 (C:BEST2,LR:BEST2) => C:BEST => NOT 
REPLACE
+_UA_UA_DI_A<00>: C:BEST vs. B:BEST2 (C:ALL) => B:MHOMED => MHOMED_MERGE
+_UA_MA_DI_A<00>: C:BEST vs. B:BEST2 (C:ALL) => B:MHOMED => MHOMED_MERGE
+*/
 static void r_do_challenge_handler(struct irpc_request *ireq)
 {
        NTSTATUS status;
        struct r_do_challenge_state *state = 
talloc_get_type(ireq->async.private,
                                                             struct 
r_do_challenge_state);
+       BOOL old_is_subset = False;
+       BOOL new_is_subset = False;;
+       BOOL found = False;
+       uint32_t i,j;
+       uint32_t num_rec_addrs;
 
        status = irpc_call_recv(ireq);
 
@@ -752,12 +901,58 @@
        if (NT_STATUS_EQUAL(NT_STATUS_IO_TIMEOUT, status) ||
            NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) {
                r_do_replace(state->partner, state, state->rec, &state->owner, 
&state->replica);
+               talloc_free(state);
                return;
        }
 
-       DEBUG(0,("TODO: r_do_challenge_handler: do MHOMED merging for %s: 
%s\n", 
-                nbt_name_string(state, &state->replica.name), 
nt_errstr(status)));
-       /* TODO: handle MHOMED merging */
+       for (i=0; i < state->replica.num_addresses; i++) {
+               found = False;
+               new_is_subset = True;
+               for (j=0; j < state->r.out.num_addrs; j++) {
+                       if (strcmp(state->replica.addresses[i].address, 
state->r.out.addrs[j].addr) == 0) {
+                               found = True;
+                               break;
+                       }
+               }
+               if (found) continue;
+
+               new_is_subset = False;
+               break;
+       }
+
+       if (!new_is_subset) {
+               r_not_replace(state->partner, state, state->rec, &state->owner, 
&state->replica);
+               talloc_free(state);
+               return;
+       }
+
+       num_rec_addrs = winsdb_addr_list_length(state->rec->addresses);
+       for (i=0; i < num_rec_addrs; i++) {
+               found = False;
+               old_is_subset = True;
+               for (j=0; j < state->r.out.num_addrs; j++) {
+                       if (strcmp(state->rec->addresses[i]->address, 
state->r.out.addrs[j].addr) == 0) {
+                               found = True;
+                               break;
+                       }
+               }
+               if (found) continue;
+
+               old_is_subset = False;
+               break;
+       }
+
+       if (!old_is_subset) {
+               r_do_late_release_demand(state);
+               /* 
+                * don't free state here, because we pass it down,
+                * and r_do_late_release_demand() will free it
+                */
+               return;
+       }
+
+       r_do_mhomed_merge(state->partner, state, state->rec, &state->owner, 
&state->replica);
+       talloc_free(state);
 }
 
 static NTSTATUS r_do_challenge(struct wreplsrv_partner *partner,

<Prev in Thread] Current Thread [Next in Thread>
  • svn commit: samba r12071 - in branches/SAMBA_4_0/source/wrepl_server: ., metze <=