From 7876d188934cfa05ba7dbbc9e8c60f79317a1018 Mon Sep 17 00:00:00 2001 From: root Date: Apr 26 2012 16:27:18 +0000 Subject: Ticket #216 - RFE - Disable replication agreements Bug Description: Allow replication agreements to be disabled. Fix Description: Created a new repl agmt attribute: nsds5ReplicaEnabled to control the agreement state. https://fedorahosted.org/389/ticket/216 Reviewed by: Noriko! --- diff --git a/ldap/schema/01core389.ldif b/ldap/schema/01core389.ldif index f1e7543..ebd626f 100644 --- a/ldap/schema/01core389.ldif +++ b/ldap/schema/01core389.ldif @@ -100,6 +100,7 @@ attributeTypes: ( 2.16.840.1.113730.3.1.687 NAME 'nsds5replicaChangesSentSinceSt attributeTypes: ( 2.16.840.1.113730.3.1.688 NAME 'nsds5replicaLastUpdateStatus' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE NO-USER-MODIFICATION X-ORIGIN 'Netscape Directory Server' ) attributeTypes: ( 2.16.840.1.113730.3.1.689 NAME 'nsds5replicaUpdateInProgress' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE NO-USER-MODIFICATION X-ORIGIN 'Netscape Directory Server' ) attributeTypes: ( 2.16.840.1.113730.3.1.802 NAME 'nsds5ReplicaLegacyConsumer' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' ) +attributeTypes: ( 2.16.840.1.113730.3.1.2132 NAME 'nsds5ReplicaEnabled' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' ) attributeTypes: ( 2.16.840.1.113730.3.1.804 NAME 'nsSchemaCSN' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE USAGE directoryOperation X-ORIGIN 'Netscape Directory Server' ) attributeTypes: ( 2.16.840.1.113730.3.1.805 NAME 'nsds5replicaTimeout' DESC 'Netscape defined attribute type' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' ) attributeTypes: ( 2.16.840.1.113730.3.1.807 NAME 'nsds5replicaLastInitStart' DESC 'Netscape defined attribute type' EQUALITY generalizedTimeMatch ORDERING generalizedTimeOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE NO-USER-MODIFICATION X-ORIGIN 'Netscape Directory Server' ) @@ -151,7 +152,7 @@ objectClasses: ( 2.16.840.1.113730.3.2.110 NAME 'nsMappingTree' DESC 'Netscape d objectClasses: ( 2.16.840.1.113730.3.2.104 NAME 'nsContainer' DESC 'Netscape defined objectclass' SUP top MUST ( CN ) X-ORIGIN 'Netscape Directory Server' ) objectClasses: ( 2.16.840.1.113730.3.2.108 NAME 'nsDS5Replica' DESC 'Netscape defined objectclass' SUP top MUST ( nsDS5ReplicaRoot $ nsDS5ReplicaId ) MAY (cn $ nsDS5ReplicaType $ nsDS5ReplicaBindDN $ nsState $ nsDS5ReplicaName $ nsDS5Flags $ nsDS5Task $ nsDS5ReplicaReferral $ nsDS5ReplicaAutoReferral $ nsds5ReplicaPurgeDelay $ nsds5ReplicaTombstonePurgeInterval $ nsds5ReplicaChangeCount $ nsds5ReplicaLegacyConsumer) X-ORIGIN 'Netscape Directory Server' ) objectClasses: ( 2.16.840.1.113730.3.2.113 NAME 'nsTombstone' DESC 'Netscape defined objectclass' SUP top MAY ( nsParentUniqueId $ nscpEntryDN ) X-ORIGIN 'Netscape Directory Server' ) -objectClasses: ( 2.16.840.1.113730.3.2.103 NAME 'nsDS5ReplicationAgreement' DESC 'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( nsDS5ReplicaHost $ nsDS5ReplicaPort $ nsDS5ReplicaTransportInfo $ nsDS5ReplicaBindDN $ nsDS5ReplicaCredentials $ nsDS5ReplicaBindMethod $ nsDS5ReplicaRoot $ nsDS5ReplicatedAttributeList $ nsDS5ReplicatedAttributeListTotal $ nsDS5ReplicaUpdateSchedule $ nsds5BeginReplicaRefresh $ description $ nsds50ruv $ nsruvReplicaLastModified $ nsds5ReplicaTimeout $ nsds5replicaChangesSentSinceStartup $ nsds5replicaLastUpdateEnd $ nsds5replicaLastUpdateStart $ nsds5replicaLastUpdateStatus $ nsds5replicaUpdateInProgress $ nsds5replicaLastInitEnd $ nsds5replicaLastInitStart $ nsds5replicaLastInitStatus $ nsds5debugreplicatimeout $ nsds5replicaBusyWaitTime $ nsds5replicaSessionPauseTime ) X-ORIGIN 'Netscape Directory Server' ) +objectClasses: ( 2.16.840.1.113730.3.2.103 NAME 'nsDS5ReplicationAgreement' DESC 'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( nsDS5ReplicaHost $ nsDS5ReplicaPort $ nsDS5ReplicaTransportInfo $ nsDS5ReplicaBindDN $ nsDS5ReplicaCredentials $ nsDS5ReplicaBindMethod $ nsDS5ReplicaRoot $ nsDS5ReplicatedAttributeList $ nsDS5ReplicatedAttributeListTotal $ nsDS5ReplicaUpdateSchedule $ nsds5BeginReplicaRefresh $ description $ nsds50ruv $ nsruvReplicaLastModified $ nsds5ReplicaTimeout $ nsds5replicaChangesSentSinceStartup $ nsds5replicaLastUpdateEnd $ nsds5replicaLastUpdateStart $ nsds5replicaLastUpdateStatus $ nsds5replicaUpdateInProgress $ nsds5replicaLastInitEnd $ nsds5ReplicaEnabled $ nsds5replicaLastInitStart $ nsds5replicaLastInitStatus $ nsds5debugreplicatimeout $ nsds5replicaBusyWaitTime $ nsds5replicaSessionPauseTime ) X-ORIGIN 'Netscape Directory Server' ) objectClasses: ( 2.16.840.1.113730.3.2.39 NAME 'nsslapdConfig' DESC 'Netscape defined objectclass' SUP top MAY ( cn ) X-ORIGIN 'Netscape Directory Server' ) objectClasses: ( 2.16.840.1.113730.3.2.317 NAME 'nsSaslMapping' DESC 'Netscape defined objectclass' SUP top MUST ( cn $ nsSaslMapRegexString $ nsSaslMapBaseDNTemplate $ nsSaslMapFilterTemplate ) X-ORIGIN 'Netscape Directory Server' ) objectClasses: ( 2.16.840.1.113730.3.2.43 NAME 'nsSNMP' DESC 'Netscape defined objectclass' SUP top MUST ( cn $ nsSNMPEnabled ) MAY ( nsSNMPOrganization $ nsSNMPLocation $ nsSNMPContact $ nsSNMPDescription $ nsSNMPName $ nsSNMPMasterHost $ nsSNMPMasterPort ) X-ORIGIN 'Netscape Directory Server' ) diff --git a/ldap/servers/plugins/replication/cl5_api.c b/ldap/servers/plugins/replication/cl5_api.c index 03d50ca..4c23af5 100644 --- a/ldap/servers/plugins/replication/cl5_api.c +++ b/ldap/servers/plugins/replication/cl5_api.c @@ -3998,6 +3998,11 @@ static int _cl5GetRUV2Purge2 (Object *fileObj, RUV **ruv) agmt = (Repl_Agmt*)object_get_data (agmtObj); PR_ASSERT (agmt); + if(!agmt_is_enabled(agmt)){ + agmtObj = agmtlist_get_next_agreement_for_replica(r, agmtObj); + continue; + } + consRUVObj = agmt_get_consumer_ruv (agmt); if (consRUVObj) { diff --git a/ldap/servers/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h index e315150..23d9753 100644 --- a/ldap/servers/plugins/replication/repl5.h +++ b/ldap/servers/plugins/replication/repl5.h @@ -155,6 +155,7 @@ extern const char *type_nsds5ReplicaInitialize; extern const char *type_nsds5ReplicaTimeout; extern const char *type_nsds5ReplicaBusyWaitTime; extern const char *type_nsds5ReplicaSessionPauseTime; +extern const char *type_nsds5ReplicaEnabled; /* Attribute names for windows replication agreements */ extern const char *type_nsds7WindowsReplicaArea; @@ -353,6 +354,8 @@ void agmt_set_priv (Repl_Agmt *agmt, void* priv); int get_agmt_agreement_type ( Repl_Agmt *agmt); void* agmt_get_connection( Repl_Agmt *ra); int agmt_has_protocol(Repl_Agmt *agmt); +PRBool agmt_is_enabled(Repl_Agmt *ra); +int agmt_set_enabled_from_entry(Repl_Agmt *ra, Slapi_Entry *e); typedef struct replica Replica; diff --git a/ldap/servers/plugins/replication/repl5_agmt.c b/ldap/servers/plugins/replication/repl5_agmt.c index 8714021..bfde962 100644 --- a/ldap/servers/plugins/replication/repl5_agmt.c +++ b/ldap/servers/plugins/replication/repl5_agmt.c @@ -117,6 +117,7 @@ typedef struct repl5agmt { time_t last_update_end_time; /* Local end time of last update session */ char last_update_status[STATUS_LEN]; /* Status of last update. Format = numeric code textual description */ PRBool update_in_progress; + PRBool is_enabled; time_t last_init_start_time; /* Local start time of last total init */ time_t last_init_end_time; /* Local end time of last total init */ char last_init_status[STATUS_LEN]; /* Status of last total init. Format = numeric code textual description */ @@ -317,6 +318,19 @@ agmt_new_from_entry(Slapi_Entry *e) ra->replarea = slapi_sdn_new_dn_passin(tmpstr); } + /* Replica enabled */ + tmpstr = slapi_entry_attr_get_charptr(e, type_nsds5ReplicaEnabled); + if (NULL != tmpstr) + { + if(strcasecmp(tmpstr, "on") == 0){ + ra->is_enabled = PR_TRUE; + } else { + ra->is_enabled = PR_FALSE; + } + } else { + ra->is_enabled = PR_TRUE; + } + /* Replication schedule */ ra->schedule = schedule_new(update_window_state_change_callback, ra, agmt_get_long_name(ra)); if (slapi_entry_attr_find(e, type_nsds5ReplicaUpdateSchedule, &sattr) == 0) @@ -2442,3 +2456,58 @@ agmt_has_protocol(Repl_Agmt *agmt) } return 0; } + +PRBool +agmt_is_enabled(Repl_Agmt *ra) +{ + PRBool state; + PR_Lock(ra->lock); + state = ra->is_enabled; + PR_Unlock(ra->lock); + + return state; +} + +int +agmt_set_enabled_from_entry(Repl_Agmt *ra, Slapi_Entry *e){ + char *attr_val = NULL; + int rc = 0; + + if(ra == NULL){ + return -1; + } + + PR_Lock(ra->lock); + attr_val = slapi_entry_attr_get_charptr(e, type_nsds5ReplicaEnabled); + if(attr_val){ + if(strcasecmp(attr_val,"on") == 0){ + if(!ra->is_enabled){ + ra->is_enabled = PR_TRUE; + slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmt_set_enabled_from_entry: " + "agreement is now enabled (%s)\n",ra->long_name); + PR_Unlock(ra->lock); + agmt_start(ra); + slapi_ch_free_string(&attr_val); + return rc; + } + } else { + if(ra->is_enabled){ + ra->is_enabled = PR_FALSE; + slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmt_set_enabled_from_entry: " + "agreement is now disabled (%s)\n",ra->long_name); + PR_Unlock(ra->lock); + agmt_stop(ra); + agmt_update_consumer_ruv(ra); + agmt_set_last_update_status(ra,0,0,"agreement disabled"); + slapi_ch_free_string(&attr_val); + return rc; + } + } + } else { + rc = -1; + } + PR_Unlock(ra->lock); + + return rc; +} + diff --git a/ldap/servers/plugins/replication/repl5_agmtlist.c b/ldap/servers/plugins/replication/repl5_agmtlist.c index 8a98c21..1c18a85 100644 --- a/ldap/servers/plugins/replication/repl5_agmtlist.c +++ b/ldap/servers/plugins/replication/repl5_agmtlist.c @@ -154,7 +154,9 @@ add_new_agreement(Slapi_Entry *e) Object *repl_obj = NULL; Object *ro = NULL; - if (ra == NULL) return 1; /* tell search result handler callback this entry was not sent */ + /* tell search result handler callback this entry was not sent */ + if (ra == NULL) + return 1; ro = object_new((void *)ra, agmt_delete); objset_add_obj(agmt_set, ro); @@ -488,6 +490,15 @@ agmtlist_modify_callback(Slapi_PBlock *pb, Slapi_Entry *entryBefore, Slapi_Entry /* ignore modifier's name and timestamp attributes and the description. */ continue; } + else if (slapi_attr_types_equivalent(mods[i]->mod_type, type_nsds5ReplicaEnabled)) + { + if(agmt_set_enabled_from_entry(agmt, e) != 0){ + slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmtlist_modify_callback: " + "failed to set replica agmt state \"enabled/disabled\" for %s\n",agmt_get_long_name(agmt)); + *returncode = LDAP_OPERATIONS_ERROR; + rc = SLAPI_DSE_CALLBACK_ERROR; + } + } else if (0 == windows_handle_modify_agreement(agmt, mods[i]->mod_type, e)) { slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmtlist_modify_callback: " diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c index c2e69f8..6434dbd 100644 --- a/ldap/servers/plugins/replication/repl5_replica.c +++ b/ldap/servers/plugins/replication/repl5_replica.c @@ -3445,12 +3445,12 @@ start_agreements_for_replica (Replica *r, PRBool start) { agmt = (Repl_Agmt*)object_get_data (agmt_obj); PR_ASSERT (agmt); - - if (start) - agmt_start (agmt); - else /* stop */ - agmt_stop (agmt); - + if(agmt_is_enabled(agmt)){ + if (start) + agmt_start (agmt); + else /* stop */ + agmt_stop (agmt); + } agmt_obj = agmtlist_get_next_agreement_for_replica (r, agmt_obj); } } @@ -3463,7 +3463,7 @@ int replica_start_agreement(Replica *r, Repl_Agmt *ra) PR_Lock(r->agmt_lock); - if (!replica_is_state_flag_set(r, REPLICA_AGREEMENTS_DISABLED)) { + if (!replica_is_state_flag_set(r, REPLICA_AGREEMENTS_DISABLED) && agmt_is_enabled(ra)) { ret = agmt_start(ra); /* Start the replication agreement */ } diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c index 78a948b..5a3ed07 100644 --- a/ldap/servers/plugins/replication/repl5_replica_config.c +++ b/ldap/servers/plugins/replication/repl5_replica_config.c @@ -1218,6 +1218,10 @@ replica_execute_cleanall_ruv_task (Object *r, ReplicaId rid, char *returntext) while (agmt_obj) { agmt = (Repl_Agmt*)object_get_data (agmt_obj); + if(!agmt_is_enabled(agmt)){ + agmt_obj = agmtlist_get_next_agreement_for_replica (replica, agmt_obj); + continue; + } dn = agmt_get_dn_byref(agmt); conn = (Repl_Connection *)agmt_get_connection(agmt); if(conn == NULL){ @@ -1311,6 +1315,10 @@ replica_execute_release_ruv_task(Object *r, ReplicaId rid, char *returntext) while (agmt_obj) { agmt = (Repl_Agmt*)object_get_data (agmt_obj); + if(!agmt_is_enabled(agmt)){ + agmt_obj = agmtlist_get_next_agreement_for_replica (replica, agmt_obj); + continue; + } dn = agmt_get_dn_byref(agmt); conn = (Repl_Connection *)agmt_get_connection(agmt); if(conn == NULL){ diff --git a/ldap/servers/plugins/replication/repl_extop.c b/ldap/servers/plugins/replication/repl_extop.c index 7e2ebbd..31a9ad0 100644 --- a/ldap/servers/plugins/replication/repl_extop.c +++ b/ldap/servers/plugins/replication/repl_extop.c @@ -1458,6 +1458,10 @@ multimaster_extop_cleanruv(Slapi_PBlock *pb){ while (agmt_obj) { agmt = (Repl_Agmt*)object_get_data (agmt_obj); + if(!agmt_is_enabled(agmt)){ + agmt_obj = agmtlist_get_next_agreement_for_replica (r, agmt_obj); + continue; + } dn = agmt_get_dn_byref(agmt); conn = (Repl_Connection *)agmt_get_connection(agmt); if(conn == NULL){ @@ -1594,6 +1598,10 @@ multimaster_extop_releaseruv(Slapi_PBlock *pb){ while (agmt_obj) { agmt = (Repl_Agmt*)object_get_data (agmt_obj); + if(!agmt_is_enabled(agmt)){ + agmt_obj = agmtlist_get_next_agreement_for_replica (r, agmt_obj); + continue; + } dn = agmt_get_dn_byref(agmt); conn = (Repl_Connection *)agmt_get_connection(agmt); if(conn == NULL){ diff --git a/ldap/servers/plugins/replication/repl_globals.c b/ldap/servers/plugins/replication/repl_globals.c index f0aea12..d2d2318 100644 --- a/ldap/servers/plugins/replication/repl_globals.c +++ b/ldap/servers/plugins/replication/repl_globals.c @@ -126,6 +126,7 @@ const char *type_nsds5ReplicaInitialize = "nsds5BeginReplicaRefresh"; const char *type_nsds5ReplicaTimeout = "nsds5ReplicaTimeout"; const char *type_nsds5ReplicaBusyWaitTime = "nsds5ReplicaBusyWaitTime"; const char *type_nsds5ReplicaSessionPauseTime = "nsds5ReplicaSessionPauseTime"; +const char *type_nsds5ReplicaEnabled = "nsds5ReplicaEnabled"; /* windows sync specific attributes */ const char *type_nsds7WindowsReplicaArea = "nsds7WindowsReplicaSubtree";