summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNoriko Hosoi <nhosoi@redhat.com>2010-03-05 15:06:43 -0800
committerNoriko Hosoi <nhosoi@redhat.com>2010-03-05 15:06:43 -0800
commitf2a04fdc45cc8a408267019990504354282c4303 (patch)
treeee12336cc445506eeabdff62d22558e3f962d36a
parentf4b90ed5e43fa06ea6185cf17073b7a32db6ef4c (diff)
parent0b95451c7e50cb6b2d0cb310dddca18336e1b2ac (diff)
downloadds-f2a04fdc45cc8a408267019990504354282c4303.tar.gz
ds-f2a04fdc45cc8a408267019990504354282c4303.tar.xz
ds-f2a04fdc45cc8a408267019990504354282c4303.zip
Merge branch '547503'
-rw-r--r--ldap/servers/plugins/replication/repl5.h6
-rw-r--r--ldap/servers/plugins/replication/repl5_protocol.c28
-rw-r--r--ldap/servers/plugins/replication/repl_extop.c24
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;