diff options
author | Noriko Hosoi <nhosoi@redhat.com> | 2010-03-05 15:06:43 -0800 |
---|---|---|
committer | Noriko Hosoi <nhosoi@redhat.com> | 2010-03-05 15:06:43 -0800 |
commit | f2a04fdc45cc8a408267019990504354282c4303 (patch) | |
tree | ee12336cc445506eeabdff62d22558e3f962d36a | |
parent | f4b90ed5e43fa06ea6185cf17073b7a32db6ef4c (diff) | |
parent | 0b95451c7e50cb6b2d0cb310dddca18336e1b2ac (diff) | |
download | ds-f2a04fdc45cc8a408267019990504354282c4303.tar.gz ds-f2a04fdc45cc8a408267019990504354282c4303.tar.xz ds-f2a04fdc45cc8a408267019990504354282c4303.zip |
Merge branch '547503'
-rw-r--r-- | ldap/servers/plugins/replication/repl5.h | 6 | ||||
-rw-r--r-- | ldap/servers/plugins/replication/repl5_protocol.c | 28 | ||||
-rw-r--r-- | ldap/servers/plugins/replication/repl_extop.c | 24 |
3 files changed, 58 insertions, 0 deletions
diff --git a/ldap/servers/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h index 97ce5569..c6859ddb 100644 --- a/ldap/servers/plugins/replication/repl5.h +++ b/ldap/servers/plugins/replication/repl5.h @@ -521,6 +521,12 @@ void replica_write_ruv (Replica *r); #define REPLICA_INCREMENTAL_IN_PROGRESS 2 /* Set only between start and stop inc */ #define REPLICA_TOTAL_IN_PROGRESS 4 /* Set only between start and stop total */ #define REPLICA_AGREEMENTS_DISABLED 8 /* Replica is offline */ +#define REPLICA_TOTAL_EXCL_SEND 16 /* The server is either sending or receiving + the total update. Introducing it if SEND + is active, RECV should back off. And + vice versa. But SEND can coexist. */ +#define REPLICA_TOTAL_EXCL_RECV 32 /* ditto */ + PRBool replica_is_state_flag_set(Replica *r, PRInt32 flag); void replica_set_state_flag (Replica *r, PRUint32 flag, PRBool clear); void replica_set_tombstone_reap_stop(Replica *r, PRBool val); diff --git a/ldap/servers/plugins/replication/repl5_protocol.c b/ldap/servers/plugins/replication/repl5_protocol.c index 927c450a..efb32716 100644 --- a/ldap/servers/plugins/replication/repl5_protocol.c +++ b/ldap/servers/plugins/replication/repl5_protocol.c @@ -317,6 +317,28 @@ prot_thread_main(void *arg) dev_debug("prot_thread_main(STATE_PERFORMING_INCREMENTAL_UPDATE): end"); break; case STATE_PERFORMING_TOTAL_UPDATE: + { + Slapi_DN *dn = agmt_get_replarea(agmt); + Replica *replica = NULL; + Object *replica_obj = replica_get_replica_from_dn(dn); + if (replica_obj) + { + replica = (Replica*) object_get_data (replica_obj); + /* If total update against this replica is in progress, + * we should not initiate the total update to other replicas. */ + if (replica_is_state_flag_set(replica, REPLICA_TOTAL_EXCL_RECV)) + { + object_release(replica_obj); + slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, + "%s: total update on the replica is in progress. Cannot initiate the total update.\n", agmt_get_long_name(rp->agmt)); + break; + } + else + { + replica_set_state_flag (replica, REPLICA_TOTAL_EXCL_SEND, 0); + } + } + PR_Lock(rp->lock); /* stop incremental protocol if running */ @@ -332,7 +354,13 @@ prot_thread_main(void *arg) replica initialization is completed. */ agmt_replica_init_done (agmt); + if (replica_obj) + { + replica_set_state_flag (replica, REPLICA_TOTAL_EXCL_SEND, 1); + object_release(replica_obj); + } break; + } case STATE_FINISHED: dev_debug("prot_thread_main(STATE_FINISHED): exiting prot_thread_main"); done = 1; diff --git a/ldap/servers/plugins/replication/repl_extop.c b/ldap/servers/plugins/replication/repl_extop.c index b65c6c8f..c47ea93d 100644 --- a/ldap/servers/plugins/replication/repl_extop.c +++ b/ldap/servers/plugins/replication/repl_extop.c @@ -678,6 +678,25 @@ multimaster_extop_StartNSDS50ReplicationRequest(Slapi_PBlock *pb) goto send_response; } + if (REPL_PROTOCOL_50_TOTALUPDATE == connext->repl_protocol_version) + { + /* If total update has been initiated against other replicas or + * this replica is already being initialized, we should return + * an error immediately. */ + if (replica_is_state_flag_set(replica, + REPLICA_TOTAL_EXCL_SEND|REPLICA_TOTAL_EXCL_RECV)) + { + slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, + "%s: total update on is initiated on the replica. Cannot execute the total update from other master.\n", repl_root); + response = NSDS50_REPL_REPLICA_BUSY; + goto send_response; + } + else + { + replica_set_state_flag (replica, REPLICA_TOTAL_EXCL_RECV, 0); + } + } + /* check that this replica is not a 4.0 consumer */ if (replica_is_legacy_consumer (replica)) { @@ -861,6 +880,11 @@ multimaster_extop_StartNSDS50ReplicationRequest(Slapi_PBlock *pb) slapi_pblock_get(pb, SLAPI_CONNECTION, &connext->connection); send_response: + if (connext && replica && + (REPL_PROTOCOL_50_TOTALUPDATE == connext->repl_protocol_version)) + { + replica_set_state_flag (replica, REPLICA_TOTAL_EXCL_RECV, 1); + } if (response != NSDS50_REPL_REPLICA_READY) { int resp_log_level = SLAPI_LOG_FATAL; |