ldap/servers
by Mark Reynolds
ldap/servers/plugins/dna/dna.c | 4 ++
ldap/servers/slapd/add.c | 63 ++++++++++++++++++++++++++++++++-----
ldap/servers/slapd/configdse.c | 1
ldap/servers/slapd/opshared.c | 15 +++++---
ldap/servers/slapd/proto-slap.h | 1
ldap/servers/slapd/slapi-private.h | 6 +++
6 files changed, 76 insertions(+), 14 deletions(-)
New commits:
commit f33e73fe45225c0c7413d74dc846cead3214a404
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Fri Oct 19 15:55:54 2012 -0400
Ticket 495 - internalModifiersname not updated by DNA plugin
Bug Description: If you are using the "nsslapd-plugin-binddn-tracking", and the DNA plugin
modifiers the entry, the internalmodifiersname is not updated.
Fix Description: This is because the DNA plugin directly modifies the entry, and does not
use the internal modify functions that would trigger the last mod attributes
to be updated. So we have to call the last mod update function directly from
the dna plugin.
There is also a slight change to the behavior now. The internalModifiersname &
internalCreatorsname will never be the bind dn, but instead it will be the plugin
that actually did the update. So if a entry was not touched by a DS plugin, then
the "database" plugin would be the internal modifier/creator:
cn=ldbm database,cn=plugins,cn=config
This would also allow us to detect if someone replaced the default backend.
https://fedorahosted.org/389/ticket/495
Reviewed by: nhosoi & richm(Thanks!)
diff --git a/ldap/servers/plugins/dna/dna.c b/ldap/servers/plugins/dna/dna.c
index 34d67ab..2b56967 100644
--- a/ldap/servers/plugins/dna/dna.c
+++ b/ldap/servers/plugins/dna/dna.c
@@ -2853,6 +2853,8 @@ _dna_pre_op_add(Slapi_PBlock *pb, Slapi_Entry *e)
/* no need to dup */
DNA_NEEDS_UPDATE);
}
+ /* Update the internalModifiersname for this add op */
+ add_internal_modifiersname(pb, e);
/* Make sure we don't generate for this
* type again by keeping a list of types
@@ -3106,6 +3108,8 @@ _dna_pre_op_modify(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Mods *smods)
/* no need to dup */
DNA_NEEDS_UPDATE);
}
+ /* Update the internalModifersname for this mod op */
+ modify_update_last_modified_attr(pb, smods);
/* Make sure we don't generate for this
* type again by keeping a list of types
diff --git a/ldap/servers/slapd/add.c b/ldap/servers/slapd/add.c
index d1d23b3..2a70f64 100644
--- a/ldap/servers/slapd/add.c
+++ b/ldap/servers/slapd/add.c
@@ -73,7 +73,7 @@
/* Forward declarations */
static int add_internal_pb (Slapi_PBlock *pb);
static void op_shared_add (Slapi_PBlock *pb);
-static int add_created_attrs(Operation *op, Slapi_Entry *e);
+static int add_created_attrs(Slapi_PBlock *pb, Slapi_Entry *e);
static int check_rdn_for_created_attrs(Slapi_Entry *e);
static void handle_fast_add(Slapi_PBlock *pb, Slapi_Entry *entry);
static int add_uniqueid (Slapi_Entry *e);
@@ -684,7 +684,7 @@ static void op_shared_add (Slapi_PBlock *pb)
/* can get lastmod only after backend is selected */
slapi_pblock_get(pb, SLAPI_BE_LASTMOD, &lastmod);
- if (lastmod && add_created_attrs(operation, e) != 0)
+ if (lastmod && add_created_attrs(pb, e) != 0)
{
send_ldap_result(pb, LDAP_UNWILLING_TO_PERFORM, NULL,
"cannot insert computed attributes", 0, NULL);
@@ -797,32 +797,51 @@ done:
}
static int
-add_created_attrs(Operation *op, Slapi_Entry *e)
+add_created_attrs(Slapi_PBlock *pb, Slapi_Entry *e)
{
char buf[20];
char *binddn = NULL;
+ char *plugin_dn = NULL;
struct berval bv;
struct berval *bvals[2];
time_t curtime;
struct tm ltm;
+ Operation *op;
+ struct slapdplugin *plugin = NULL;
+ struct slapi_componentid *cid = NULL;
slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
LDAPDebug(LDAP_DEBUG_TRACE, "add_created_attrs\n", 0, 0, 0);
bvals[0] = &bv;
bvals[1] = NULL;
+ slapi_pblock_get(pb, SLAPI_OPERATION, &op);
if(slapdFrontendConfig->plugin_track){
/* plugin bindDN tracking is enabled, grab the dn from thread local storage */
if(slapi_sdn_isempty(&op->o_sdn)){
bv.bv_val = "";
- bv.bv_len = strlen(bv.bv_val);
+ bv.bv_len = 0;
} else {
- bv.bv_val = (char*)slapi_sdn_get_dn(&op->o_sdn);
- bv.bv_len = strlen(bv.bv_val);
+ slapi_pblock_get (pb, SLAPI_PLUGIN_IDENTITY, &cid);
+ if (cid){
+ plugin=(struct slapdplugin *) cid->sci_plugin;
+ } else {
+ slapi_pblock_get (pb, SLAPI_PLUGIN, &plugin);
+ }
+ if(plugin)
+ plugin_dn = plugin_get_dn (plugin);
+ if(plugin_dn){
+ bv.bv_val = plugin_dn;
+ bv.bv_len = strlen(bv.bv_val);
+ } else {
+ bv.bv_val = (char*)slapi_sdn_get_dn(&op->o_sdn);
+ bv.bv_len = strlen(bv.bv_val);
+ }
}
slapi_entry_attr_replace(e, "internalCreatorsName", bvals);
slapi_entry_attr_replace(e, "internalModifiersName", bvals);
+ slapi_ch_free_string(&plugin_dn);
/* Grab the thread data(binddn) */
slapi_td_get_dn(&binddn);
@@ -830,7 +849,7 @@ add_created_attrs(Operation *op, Slapi_Entry *e)
if(binddn == NULL){
/* anonymous bind */
bv.bv_val = "";
- bv.bv_len = strlen(bv.bv_val);
+ bv.bv_len = 0;
} else {
bv.bv_val = binddn;
bv.bv_len = strlen(bv.bv_val);
@@ -838,7 +857,7 @@ add_created_attrs(Operation *op, Slapi_Entry *e)
} else {
if (slapi_sdn_isempty(&op->o_sdn)) {
bv.bv_val = "";
- bv.bv_len = strlen(bv.bv_val);
+ bv.bv_len = 0;
} else {
bv.bv_val = (char*)slapi_sdn_get_dn(&op->o_sdn);
bv.bv_len = strlen(bv.bv_val);
@@ -1023,3 +1042,31 @@ check_oc_subentry(Slapi_Entry *e, struct berval **vals, char *normtype) {
}
return subentry;
}
+
+/*
+ * Used by plugins that modify entries on add operations, otherwise the internalModifiersname
+ * would not be set the the correct plugin name.
+ */
+void
+add_internal_modifiersname(Slapi_PBlock *pb, Slapi_Entry *e)
+{
+ slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+ struct slapi_componentid *cid = NULL;
+ struct slapdplugin *plugin = NULL;
+ char *plugin_dn = NULL;
+
+ if(slapdFrontendConfig->plugin_track){
+ slapi_pblock_get (pb, SLAPI_PLUGIN_IDENTITY, &cid);
+ if (cid){
+ plugin=(struct slapdplugin *) cid->sci_plugin;
+ } else {
+ slapi_pblock_get (pb, SLAPI_PLUGIN, &plugin);
+ }
+ if(plugin)
+ plugin_dn = plugin_get_dn (plugin);
+ if(plugin_dn){
+ slapi_entry_attr_set_charptr(e, "internalModifiersname", plugin_dn);
+ slapi_ch_free_string(&plugin_dn);
+ }
+ }
+}
diff --git a/ldap/servers/slapd/configdse.c b/ldap/servers/slapd/configdse.c
index 51f9165..b54062d 100644
--- a/ldap/servers/slapd/configdse.c
+++ b/ldap/servers/slapd/configdse.c
@@ -117,6 +117,7 @@ ignore_attr_type(const char *attr_type)
(strcasecmp (attr_type, "objectclass") == 0) ||
(strcasecmp (attr_type, "numsubordinates") == 0) ||
(strcasecmp (attr_type, "internalModifiersname") == 0) ||
+ (strcasecmp (attr_type, "internalCreatorsname") == 0) ||
(strcasecmp (attr_type, "modifytimestamp") == 0) ||
(strcasecmp (attr_type, "modifiersname") == 0)) {
return 1;
diff --git a/ldap/servers/slapd/opshared.c b/ldap/servers/slapd/opshared.c
index 019fe20..afd81ac 100644
--- a/ldap/servers/slapd/opshared.c
+++ b/ldap/servers/slapd/opshared.c
@@ -135,7 +135,8 @@ do_ps_service(Slapi_Entry *e, Slapi_Entry *eprev, ber_int_t chgtype, ber_int_t c
(ps_service_fn)(e, eprev, chgtype, chgnum);
}
-void modify_update_last_modified_attr(Slapi_PBlock *pb, Slapi_Mods *smods)
+void
+modify_update_last_modified_attr(Slapi_PBlock *pb, Slapi_Mods *smods)
{
char buf[20];
char *plugin_dn = NULL;
@@ -159,11 +160,14 @@ void modify_update_last_modified_attr(Slapi_PBlock *pb, Slapi_Mods *smods)
/* plugin bindDN tracking is enabled, grab the bind dn from thread local storage */
if(slapi_sdn_isempty(&op->o_sdn)){
bv.bv_val = "";
- bv.bv_len = strlen(bv.bv_val);
+ bv.bv_len = 0;
} else {
slapi_pblock_get (pb, SLAPI_PLUGIN_IDENTITY, &cid);
- if (cid)
+ if (cid){
plugin=(struct slapdplugin *) cid->sci_plugin;
+ } else {
+ slapi_pblock_get (pb, SLAPI_PLUGIN, &plugin);
+ }
if(plugin)
plugin_dn = plugin_get_dn (plugin);
if(plugin_dn){
@@ -176,6 +180,7 @@ void modify_update_last_modified_attr(Slapi_PBlock *pb, Slapi_Mods *smods)
}
slapi_mods_add_modbvps(smods, LDAP_MOD_REPLACE | LDAP_MOD_BVALUES,
"internalModifiersName", bvals);
+ slapi_ch_free_string(&plugin_dn);
/* Grab the thread data(binddn) */
slapi_td_get_dn(&binddn);
@@ -183,7 +188,7 @@ void modify_update_last_modified_attr(Slapi_PBlock *pb, Slapi_Mods *smods)
if(binddn == NULL){
/* anonymous bind */
bv.bv_val = "";
- bv.bv_len = strlen(bv.bv_val);
+ bv.bv_len = 0;
} else {
bv.bv_val = binddn;
bv.bv_len = strlen(bv.bv_val);
@@ -192,7 +197,7 @@ void modify_update_last_modified_attr(Slapi_PBlock *pb, Slapi_Mods *smods)
/* fill in modifiersname */
if (slapi_sdn_isempty(&op->o_sdn)) {
bv.bv_val = "";
- bv.bv_len = strlen(bv.bv_val);
+ bv.bv_len = 0;
} else {
bv.bv_val = (char*)slapi_sdn_get_dn(&op->o_sdn);
bv.bv_len = strlen(bv.bv_val);
diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h
index 905b0f4..19c06a2 100644
--- a/ldap/servers/slapd/proto-slap.h
+++ b/ldap/servers/slapd/proto-slap.h
@@ -1290,7 +1290,6 @@ void set_config_params (Slapi_PBlock *pb);
/* set parameters common for all internal operations */
void set_common_params (Slapi_PBlock *pb);
void do_ps_service(Slapi_Entry *e, Slapi_Entry *eprev, ber_int_t chgtype, ber_int_t chgnum);
-void modify_update_last_modified_attr(Slapi_PBlock *pb, Slapi_Mods *smods);
/*
* debugdump.cpp
diff --git a/ldap/servers/slapd/slapi-private.h b/ldap/servers/slapd/slapi-private.h
index 6c2781c..3ee1755 100644
--- a/ldap/servers/slapd/slapi-private.h
+++ b/ldap/servers/slapd/slapi-private.h
@@ -1252,6 +1252,12 @@ int slapi_add_internal_attr_syntax( const char *name, const char *oid, const cha
void pw_exp_init ( void );
int pw_copy_entry_ext(Slapi_Entry *src_e, Slapi_Entry *dest_e);
+/* op_shared.c */
+void modify_update_last_modified_attr(Slapi_PBlock *pb, Slapi_Mods *smods);
+
+/* add.c */
+void add_internal_modifiersname(Slapi_PBlock *pb, Slapi_Entry *e);
+
#ifdef __cplusplus
}
#endif
11 years, 5 months
ldap/servers
by Mark Reynolds
ldap/servers/plugins/dna/dna.c | 4 --
ldap/servers/slapd/add.c | 56 +++----------------------------------
ldap/servers/slapd/opshared.c | 8 +----
ldap/servers/slapd/proto-slap.h | 1
ldap/servers/slapd/slapi-private.h | 6 ---
5 files changed, 8 insertions(+), 67 deletions(-)
New commits:
commit 680cd143107be34fadd55cd0c08097b7cae7afff
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Fri Oct 19 14:56:08 2012 -0400
Revert "Ticket 495 - internalModifiersname not updated by DNA plugin"
-> need to free plugin_dn
This reverts commit 2bef7e7dad076549faa6af3f0d7e70294fe48a00.
diff --git a/ldap/servers/plugins/dna/dna.c b/ldap/servers/plugins/dna/dna.c
index 2b56967..34d67ab 100644
--- a/ldap/servers/plugins/dna/dna.c
+++ b/ldap/servers/plugins/dna/dna.c
@@ -2853,8 +2853,6 @@ _dna_pre_op_add(Slapi_PBlock *pb, Slapi_Entry *e)
/* no need to dup */
DNA_NEEDS_UPDATE);
}
- /* Update the internalModifiersname for this add op */
- add_internal_modifiersname(pb, e);
/* Make sure we don't generate for this
* type again by keeping a list of types
@@ -3108,8 +3106,6 @@ _dna_pre_op_modify(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Mods *smods)
/* no need to dup */
DNA_NEEDS_UPDATE);
}
- /* Update the internalModifersname for this mod op */
- modify_update_last_modified_attr(pb, smods);
/* Make sure we don't generate for this
* type again by keeping a list of types
diff --git a/ldap/servers/slapd/add.c b/ldap/servers/slapd/add.c
index c41c09f..d1d23b3 100644
--- a/ldap/servers/slapd/add.c
+++ b/ldap/servers/slapd/add.c
@@ -73,7 +73,7 @@
/* Forward declarations */
static int add_internal_pb (Slapi_PBlock *pb);
static void op_shared_add (Slapi_PBlock *pb);
-static int add_created_attrs(Slapi_PBlock *pb, Slapi_Entry *e);
+static int add_created_attrs(Operation *op, Slapi_Entry *e);
static int check_rdn_for_created_attrs(Slapi_Entry *e);
static void handle_fast_add(Slapi_PBlock *pb, Slapi_Entry *entry);
static int add_uniqueid (Slapi_Entry *e);
@@ -684,7 +684,7 @@ static void op_shared_add (Slapi_PBlock *pb)
/* can get lastmod only after backend is selected */
slapi_pblock_get(pb, SLAPI_BE_LASTMOD, &lastmod);
- if (lastmod && add_created_attrs(pb, e) != 0)
+ if (lastmod && add_created_attrs(operation, e) != 0)
{
send_ldap_result(pb, LDAP_UNWILLING_TO_PERFORM, NULL,
"cannot insert computed attributes", 0, NULL);
@@ -797,25 +797,20 @@ done:
}
static int
-add_created_attrs(Slapi_PBlock *pb, Slapi_Entry *e)
+add_created_attrs(Operation *op, Slapi_Entry *e)
{
char buf[20];
char *binddn = NULL;
- char *plugin_dn = NULL;
struct berval bv;
struct berval *bvals[2];
time_t curtime;
struct tm ltm;
- Operation *op;
- struct slapdplugin *plugin = NULL;
- struct slapi_componentid *cid = NULL;
slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
LDAPDebug(LDAP_DEBUG_TRACE, "add_created_attrs\n", 0, 0, 0);
bvals[0] = &bv;
bvals[1] = NULL;
- slapi_pblock_get(pb, SLAPI_OPERATION, &op);
if(slapdFrontendConfig->plugin_track){
/* plugin bindDN tracking is enabled, grab the dn from thread local storage */
@@ -823,21 +818,8 @@ add_created_attrs(Slapi_PBlock *pb, Slapi_Entry *e)
bv.bv_val = "";
bv.bv_len = strlen(bv.bv_val);
} else {
- slapi_pblock_get (pb, SLAPI_PLUGIN_IDENTITY, &cid);
- if (cid){
- plugin=(struct slapdplugin *) cid->sci_plugin;
- } else {
- slapi_pblock_get (pb, SLAPI_PLUGIN, &plugin);
- }
- if(plugin)
- plugin_dn = plugin_get_dn (plugin);
- if(plugin_dn){
- bv.bv_val = plugin_dn;
- bv.bv_len = strlen(bv.bv_val);
- } else {
- bv.bv_val = (char*)slapi_sdn_get_dn(&op->o_sdn);
- bv.bv_len = strlen(bv.bv_val);
- }
+ bv.bv_val = (char*)slapi_sdn_get_dn(&op->o_sdn);
+ bv.bv_len = strlen(bv.bv_val);
}
slapi_entry_attr_replace(e, "internalCreatorsName", bvals);
slapi_entry_attr_replace(e, "internalModifiersName", bvals);
@@ -1041,31 +1023,3 @@ check_oc_subentry(Slapi_Entry *e, struct berval **vals, char *normtype) {
}
return subentry;
}
-
-/*
- * Used by plugins that modify entries on add operations, otherwise the internalModifiersname
- * would be incorrect.
- */
-void
-add_internal_modifiersname(Slapi_PBlock *pb, Slapi_Entry *e)
-{
- slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
- struct slapi_componentid *cid = NULL;
- struct slapdplugin *plugin = NULL;
- char *plugin_dn = NULL;
-
- if(slapdFrontendConfig->plugin_track){
- /* plugin bindDN tracking is enabled, grab the bind dn from thread local storage */
- slapi_pblock_get (pb, SLAPI_PLUGIN_IDENTITY, &cid);
- if (cid){
- plugin=(struct slapdplugin *) cid->sci_plugin;
- } else {
- slapi_pblock_get (pb, SLAPI_PLUGIN, &plugin);
- }
- if(plugin)
- plugin_dn = plugin_get_dn (plugin);
- if(plugin_dn){
- slapi_entry_attr_set_charptr(e, "internalModifiersname", plugin_dn);
- }
- }
-}
diff --git a/ldap/servers/slapd/opshared.c b/ldap/servers/slapd/opshared.c
index 4a6ca44..019fe20 100644
--- a/ldap/servers/slapd/opshared.c
+++ b/ldap/servers/slapd/opshared.c
@@ -135,8 +135,7 @@ do_ps_service(Slapi_Entry *e, Slapi_Entry *eprev, ber_int_t chgtype, ber_int_t c
(ps_service_fn)(e, eprev, chgtype, chgnum);
}
-void
-modify_update_last_modified_attr(Slapi_PBlock *pb, Slapi_Mods *smods)
+void modify_update_last_modified_attr(Slapi_PBlock *pb, Slapi_Mods *smods)
{
char buf[20];
char *plugin_dn = NULL;
@@ -163,11 +162,8 @@ modify_update_last_modified_attr(Slapi_PBlock *pb, Slapi_Mods *smods)
bv.bv_len = strlen(bv.bv_val);
} else {
slapi_pblock_get (pb, SLAPI_PLUGIN_IDENTITY, &cid);
- if (cid){
+ if (cid)
plugin=(struct slapdplugin *) cid->sci_plugin;
- } else {
- slapi_pblock_get (pb, SLAPI_PLUGIN, &plugin);
- }
if(plugin)
plugin_dn = plugin_get_dn (plugin);
if(plugin_dn){
diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h
index 19c06a2..905b0f4 100644
--- a/ldap/servers/slapd/proto-slap.h
+++ b/ldap/servers/slapd/proto-slap.h
@@ -1290,6 +1290,7 @@ void set_config_params (Slapi_PBlock *pb);
/* set parameters common for all internal operations */
void set_common_params (Slapi_PBlock *pb);
void do_ps_service(Slapi_Entry *e, Slapi_Entry *eprev, ber_int_t chgtype, ber_int_t chgnum);
+void modify_update_last_modified_attr(Slapi_PBlock *pb, Slapi_Mods *smods);
/*
* debugdump.cpp
diff --git a/ldap/servers/slapd/slapi-private.h b/ldap/servers/slapd/slapi-private.h
index 3ee1755..6c2781c 100644
--- a/ldap/servers/slapd/slapi-private.h
+++ b/ldap/servers/slapd/slapi-private.h
@@ -1252,12 +1252,6 @@ int slapi_add_internal_attr_syntax( const char *name, const char *oid, const cha
void pw_exp_init ( void );
int pw_copy_entry_ext(Slapi_Entry *src_e, Slapi_Entry *dest_e);
-/* op_shared.c */
-void modify_update_last_modified_attr(Slapi_PBlock *pb, Slapi_Mods *smods);
-
-/* add.c */
-void add_internal_modifiersname(Slapi_PBlock *pb, Slapi_Entry *e);
-
#ifdef __cplusplus
}
#endif
11 years, 5 months
ldap/servers
by Mark Reynolds
ldap/servers/plugins/dna/dna.c | 4 ++
ldap/servers/slapd/add.c | 56 +++++++++++++++++++++++++++++++++----
ldap/servers/slapd/opshared.c | 8 +++--
ldap/servers/slapd/proto-slap.h | 1
ldap/servers/slapd/slapi-private.h | 6 +++
5 files changed, 67 insertions(+), 8 deletions(-)
New commits:
commit 2bef7e7dad076549faa6af3f0d7e70294fe48a00
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Fri Oct 19 10:22:21 2012 -0400
Ticket 495 - internalModifiersname not updated by DNA plugin
Bug Description: If you are using the "nsslapd-plugin-binddn-tracking", and the DNA plugin
modifiers the entry, the internalmodifiersname is not updated.
Fix Description: This is because the DNA plugin directly modifies the entry, and does not
use the internal modify functions that would trigger the last mod attributes
to be updated. So we have to call the last mod update funtciont directly from
the dna plugin.
There is also a slight change to the behavior now. The internalModifiersname &
internalCreatorsname will never be the bind dn, but instead it will be the plugin
that actually did the update. So if a entry was not touched by a DS plugin, then
the "database" plugin would be the internal modifier/creator:
cn=ldbm database,cn=plugins,cn=config
This would also allow us to detect if someone replaced the default backend.
https://fedorahosted.org/389/ticket/495
Reviewed by: nhosoi(Thanks!)
diff --git a/ldap/servers/plugins/dna/dna.c b/ldap/servers/plugins/dna/dna.c
index 34d67ab..2b56967 100644
--- a/ldap/servers/plugins/dna/dna.c
+++ b/ldap/servers/plugins/dna/dna.c
@@ -2853,6 +2853,8 @@ _dna_pre_op_add(Slapi_PBlock *pb, Slapi_Entry *e)
/* no need to dup */
DNA_NEEDS_UPDATE);
}
+ /* Update the internalModifiersname for this add op */
+ add_internal_modifiersname(pb, e);
/* Make sure we don't generate for this
* type again by keeping a list of types
@@ -3106,6 +3108,8 @@ _dna_pre_op_modify(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Mods *smods)
/* no need to dup */
DNA_NEEDS_UPDATE);
}
+ /* Update the internalModifersname for this mod op */
+ modify_update_last_modified_attr(pb, smods);
/* Make sure we don't generate for this
* type again by keeping a list of types
diff --git a/ldap/servers/slapd/add.c b/ldap/servers/slapd/add.c
index d1d23b3..c41c09f 100644
--- a/ldap/servers/slapd/add.c
+++ b/ldap/servers/slapd/add.c
@@ -73,7 +73,7 @@
/* Forward declarations */
static int add_internal_pb (Slapi_PBlock *pb);
static void op_shared_add (Slapi_PBlock *pb);
-static int add_created_attrs(Operation *op, Slapi_Entry *e);
+static int add_created_attrs(Slapi_PBlock *pb, Slapi_Entry *e);
static int check_rdn_for_created_attrs(Slapi_Entry *e);
static void handle_fast_add(Slapi_PBlock *pb, Slapi_Entry *entry);
static int add_uniqueid (Slapi_Entry *e);
@@ -684,7 +684,7 @@ static void op_shared_add (Slapi_PBlock *pb)
/* can get lastmod only after backend is selected */
slapi_pblock_get(pb, SLAPI_BE_LASTMOD, &lastmod);
- if (lastmod && add_created_attrs(operation, e) != 0)
+ if (lastmod && add_created_attrs(pb, e) != 0)
{
send_ldap_result(pb, LDAP_UNWILLING_TO_PERFORM, NULL,
"cannot insert computed attributes", 0, NULL);
@@ -797,20 +797,25 @@ done:
}
static int
-add_created_attrs(Operation *op, Slapi_Entry *e)
+add_created_attrs(Slapi_PBlock *pb, Slapi_Entry *e)
{
char buf[20];
char *binddn = NULL;
+ char *plugin_dn = NULL;
struct berval bv;
struct berval *bvals[2];
time_t curtime;
struct tm ltm;
+ Operation *op;
+ struct slapdplugin *plugin = NULL;
+ struct slapi_componentid *cid = NULL;
slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
LDAPDebug(LDAP_DEBUG_TRACE, "add_created_attrs\n", 0, 0, 0);
bvals[0] = &bv;
bvals[1] = NULL;
+ slapi_pblock_get(pb, SLAPI_OPERATION, &op);
if(slapdFrontendConfig->plugin_track){
/* plugin bindDN tracking is enabled, grab the dn from thread local storage */
@@ -818,8 +823,21 @@ add_created_attrs(Operation *op, Slapi_Entry *e)
bv.bv_val = "";
bv.bv_len = strlen(bv.bv_val);
} else {
- bv.bv_val = (char*)slapi_sdn_get_dn(&op->o_sdn);
- bv.bv_len = strlen(bv.bv_val);
+ slapi_pblock_get (pb, SLAPI_PLUGIN_IDENTITY, &cid);
+ if (cid){
+ plugin=(struct slapdplugin *) cid->sci_plugin;
+ } else {
+ slapi_pblock_get (pb, SLAPI_PLUGIN, &plugin);
+ }
+ if(plugin)
+ plugin_dn = plugin_get_dn (plugin);
+ if(plugin_dn){
+ bv.bv_val = plugin_dn;
+ bv.bv_len = strlen(bv.bv_val);
+ } else {
+ bv.bv_val = (char*)slapi_sdn_get_dn(&op->o_sdn);
+ bv.bv_len = strlen(bv.bv_val);
+ }
}
slapi_entry_attr_replace(e, "internalCreatorsName", bvals);
slapi_entry_attr_replace(e, "internalModifiersName", bvals);
@@ -1023,3 +1041,31 @@ check_oc_subentry(Slapi_Entry *e, struct berval **vals, char *normtype) {
}
return subentry;
}
+
+/*
+ * Used by plugins that modify entries on add operations, otherwise the internalModifiersname
+ * would be incorrect.
+ */
+void
+add_internal_modifiersname(Slapi_PBlock *pb, Slapi_Entry *e)
+{
+ slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+ struct slapi_componentid *cid = NULL;
+ struct slapdplugin *plugin = NULL;
+ char *plugin_dn = NULL;
+
+ if(slapdFrontendConfig->plugin_track){
+ /* plugin bindDN tracking is enabled, grab the bind dn from thread local storage */
+ slapi_pblock_get (pb, SLAPI_PLUGIN_IDENTITY, &cid);
+ if (cid){
+ plugin=(struct slapdplugin *) cid->sci_plugin;
+ } else {
+ slapi_pblock_get (pb, SLAPI_PLUGIN, &plugin);
+ }
+ if(plugin)
+ plugin_dn = plugin_get_dn (plugin);
+ if(plugin_dn){
+ slapi_entry_attr_set_charptr(e, "internalModifiersname", plugin_dn);
+ }
+ }
+}
diff --git a/ldap/servers/slapd/opshared.c b/ldap/servers/slapd/opshared.c
index 019fe20..4a6ca44 100644
--- a/ldap/servers/slapd/opshared.c
+++ b/ldap/servers/slapd/opshared.c
@@ -135,7 +135,8 @@ do_ps_service(Slapi_Entry *e, Slapi_Entry *eprev, ber_int_t chgtype, ber_int_t c
(ps_service_fn)(e, eprev, chgtype, chgnum);
}
-void modify_update_last_modified_attr(Slapi_PBlock *pb, Slapi_Mods *smods)
+void
+modify_update_last_modified_attr(Slapi_PBlock *pb, Slapi_Mods *smods)
{
char buf[20];
char *plugin_dn = NULL;
@@ -162,8 +163,11 @@ void modify_update_last_modified_attr(Slapi_PBlock *pb, Slapi_Mods *smods)
bv.bv_len = strlen(bv.bv_val);
} else {
slapi_pblock_get (pb, SLAPI_PLUGIN_IDENTITY, &cid);
- if (cid)
+ if (cid){
plugin=(struct slapdplugin *) cid->sci_plugin;
+ } else {
+ slapi_pblock_get (pb, SLAPI_PLUGIN, &plugin);
+ }
if(plugin)
plugin_dn = plugin_get_dn (plugin);
if(plugin_dn){
diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h
index 905b0f4..19c06a2 100644
--- a/ldap/servers/slapd/proto-slap.h
+++ b/ldap/servers/slapd/proto-slap.h
@@ -1290,7 +1290,6 @@ void set_config_params (Slapi_PBlock *pb);
/* set parameters common for all internal operations */
void set_common_params (Slapi_PBlock *pb);
void do_ps_service(Slapi_Entry *e, Slapi_Entry *eprev, ber_int_t chgtype, ber_int_t chgnum);
-void modify_update_last_modified_attr(Slapi_PBlock *pb, Slapi_Mods *smods);
/*
* debugdump.cpp
diff --git a/ldap/servers/slapd/slapi-private.h b/ldap/servers/slapd/slapi-private.h
index 6c2781c..3ee1755 100644
--- a/ldap/servers/slapd/slapi-private.h
+++ b/ldap/servers/slapd/slapi-private.h
@@ -1252,6 +1252,12 @@ int slapi_add_internal_attr_syntax( const char *name, const char *oid, const cha
void pw_exp_init ( void );
int pw_copy_entry_ext(Slapi_Entry *src_e, Slapi_Entry *dest_e);
+/* op_shared.c */
+void modify_update_last_modified_attr(Slapi_PBlock *pb, Slapi_Mods *smods);
+
+/* add.c */
+void add_internal_modifiersname(Slapi_PBlock *pb, Slapi_Entry *e);
+
#ifdef __cplusplus
}
#endif
11 years, 5 months
Branch '389-ds-base-1.2.10' - 2 commits - ldap/servers VERSION.sh
by Mark Reynolds
VERSION.sh | 2
ldap/servers/plugins/replication/repl5.h | 3
ldap/servers/plugins/replication/repl5_replica.c | 2
ldap/servers/plugins/replication/repl5_replica_config.c | 135 ++++++++++++++--
ldap/servers/plugins/replication/repl_extop.c | 33 ++-
5 files changed, 149 insertions(+), 26 deletions(-)
New commits:
commit 569c2d3d5b7612113073abc6a1ec24f660b4b95f
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Thu Oct 18 10:39:16 2012 -0400
bump version to 1.2.10.16
diff --git a/VERSION.sh b/VERSION.sh
index 0e62a09..f12b8e2 100644
--- a/VERSION.sh
+++ b/VERSION.sh
@@ -10,7 +10,7 @@ vendor="389 Project"
# PACKAGE_VERSION is constructed from these
VERSION_MAJOR=1
VERSION_MINOR=2
-VERSION_MAINT=10.15
+VERSION_MAINT=10.16
# if this is a PRERELEASE, set VERSION_PREREL
# otherwise, comment it out
# be sure to include the dot prefix in the prerel
commit 7a0e4c959bbd768475ed3711f51edf23462ab8f6
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Thu Oct 18 10:30:54 2012 -0400
Ticket 403 - CLEANALLRUV - minor fixes and add support for replica-force-cleaning
Description: Improved maxcsn checking of remote replicas. Added check for running
duplicate clean/abort tasks, added check to prevent multiple threads
from being created, and added a new option:
replica-force-cleaning: yes
- This skips the maxcsn checks
diff --git a/ldap/servers/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h
index 1637057..31231ac 100644
--- a/ldap/servers/plugins/replication/repl5.h
+++ b/ldap/servers/plugins/replication/repl5.h
@@ -616,8 +616,10 @@ CSN *replica_get_cleanruv_maxcsn(Replica *r, ReplicaId rid);
void ruv_get_cleaned_rids(RUV *ruv, ReplicaId *rids);
void add_aborted_rid(ReplicaId rid, Replica *r, char *repl_root);
int is_task_aborted(ReplicaId rid);
+int is_pre_cleaned_rid(ReplicaId rid);
void delete_aborted_rid(Replica *replica, ReplicaId rid, char *repl_root);
void set_cleaned_rid(ReplicaId rid);
+void set_aborted_rid(ReplicaId rid);
void cleanruv_log(Slapi_Task *task, char *task_type, char *fmt, ...);
#define CLEANRIDSIZ 4 /* maximum number for concurrent CLEANALLRUV tasks */
@@ -633,6 +635,7 @@ typedef struct _cleanruv_data
char *repl_root;
Slapi_DN *sdn;
char *certify;
+ char *force;
} cleanruv_data;
/* replutil.c */
diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c
index c956647..ec0b113 100644
--- a/ldap/servers/plugins/replication/repl5_replica.c
+++ b/ldap/servers/plugins/replication/repl5_replica.c
@@ -1863,6 +1863,7 @@ replica_check_for_tasks(Replica *r, Slapi_Entry *e)
csn_init_by_string(maxcsn, csnpart);
csn_as_string(maxcsn, PR_FALSE, csnstr);
add_cleaned_rid(rid, r, csnstr);
+ set_cleaned_rid(rid);
slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "CleanAllRUV Task: cleanAllRUV task found, "
"resuming the cleaning of rid(%d)...\n", rid);
@@ -1951,6 +1952,7 @@ done:
stop_ruv_cleaning();
maxcsn = replica_get_cleanruv_maxcsn(r, rid);
delete_cleaned_rid(r, rid, maxcsn);
+ set_aborted_rid(rid);
csn_free(&maxcsn);
slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "Abort CleanAllRUV Task: abort task found, "
diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
index 752b09b..fe34f4b 100644
--- a/ldap/servers/plugins/replication/repl5_replica_config.c
+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
@@ -64,6 +64,7 @@
int slapi_log_urp = SLAPI_LOG_REPL;
static ReplicaId cleaned_rids[CLEANRIDSIZ + 1] = {0};
+static ReplicaId pre_cleaned_rids[CLEANRIDSIZ + 1] = {0};
static ReplicaId aborted_rids[CLEANRIDSIZ + 1] = {0};
static Slapi_RWLock *rid_lock = NULL;
static Slapi_RWLock *abort_rid_lock = NULL;
@@ -84,7 +85,7 @@ static int replica_execute_task (Object *r, const char *task_name, char *returnt
static int replica_execute_cl2ldif_task (Object *r, char *returntext);
static int replica_execute_ldif2cl_task (Object *r, char *returntext);
static int replica_execute_cleanruv_task (Object *r, ReplicaId rid, char *returntext);
-static int replica_execute_cleanall_ruv_task (Object *r, ReplicaId rid, Slapi_Task *task, char *returntext);
+static int replica_execute_cleanall_ruv_task (Object *r, ReplicaId rid, Slapi_Task *task, const char *force_cleaning, char *returntext);
static void replica_cleanallruv_thread(void *arg);
static void replica_send_cleanruv_task(Repl_Agmt *agmt, ReplicaId rid, Slapi_Task *task);
static int check_agmts_are_alive(Replica *replica, ReplicaId rid, Slapi_Task *task);
@@ -96,6 +97,7 @@ static int replica_cleanallruv_replica_alive(Repl_Agmt *agmt);
static int replica_cleanallruv_check_ruv(Repl_Agmt *ra, char *rid_text, Slapi_Task *task);
static int get_cleanruv_task_count();
static int get_abort_cleanruv_task_count();
+static void preset_cleaned_rid(ReplicaId rid);
static int replica_cleanup_task (Object *r, const char *task_name, char *returntext, int apply_mods);
static int replica_task_done(Replica *replica);
static multimaster_mtnode_extension * _replica_config_get_mtnode_ext (const Slapi_Entry *e);
@@ -893,7 +895,7 @@ static int replica_execute_task (Object *r, const char *task_name, char *returnt
if (apply_mods)
{
Slapi_Task *empty_task = NULL;
- return replica_execute_cleanall_ruv_task(r, (ReplicaId)temprid, empty_task, returntext);
+ return replica_execute_cleanall_ruv_task(r, (ReplicaId)temprid, empty_task, "no", returntext);
}
else
return LDAP_SUCCESS;
@@ -1231,11 +1233,13 @@ replica_cleanall_ruv_task(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter,
Object *r;
const char *base_dn;
const char *rid_str;
+ const char *force_cleaning;
ReplicaId rid;
int rc = SLAPI_DSE_CALLBACK_OK;
/* allocate new task now */
task = slapi_new_task(slapi_entry_get_ndn(e));
+ task_dn = slapi_entry_get_sdn(e);
if(task == NULL){
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: Failed to create new task\n");
rc = SLAPI_DSE_CALLBACK_ERROR;
@@ -1255,8 +1259,21 @@ replica_cleanall_ruv_task(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter,
rc = SLAPI_DSE_CALLBACK_ERROR;
goto out;
}
+ if ((force_cleaning = fetch_attr(e, "replica-force-cleaning", 0)) != NULL){
+ if(strcasecmp(force_cleaning,"yes") != 0 && strcasecmp(force_cleaning,"no") != 0){
+ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Invalid value for replica-force-cleaning "
+ "(%s). Value must be \"yes\" or \"no\" for task - (%s)",
+ force_cleaning, slapi_sdn_get_dn(task_dn));
+ cleanruv_log(task, CLEANALLRUV_ID, "%s", returntext);
+ *returncode = LDAP_OPERATIONS_ERROR;
+ rc = SLAPI_DSE_CALLBACK_ERROR;
+ goto out;
+ }
+ } else {
+ force_cleaning = "no";
+ }
+
- task_dn = slapi_entry_get_sdn(e);
/*
* Check the rid
*/
@@ -1269,6 +1286,14 @@ replica_cleanall_ruv_task(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter,
rc = SLAPI_DSE_CALLBACK_ERROR;
goto out;
}
+ if(is_cleaned_rid(rid)){
+ /* we are already cleaning this rid */
+ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Replica id (%d) is already being cleaned", rid);
+ cleanruv_log(task, CLEANALLRUV_ID, "%s", returntext);
+ *returncode = LDAP_UNWILLING_TO_PERFORM;
+ rc = SLAPI_DSE_CALLBACK_ERROR;
+ goto out;
+ }
/*
* Get the replica object
*/
@@ -1282,7 +1307,7 @@ replica_cleanall_ruv_task(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter,
}
/* clean the RUV's */
- rc = replica_execute_cleanall_ruv_task (r, rid, task, returntext);
+ rc = replica_execute_cleanall_ruv_task (r, rid, task, force_cleaning, returntext);
out:
if(rc){
@@ -1305,7 +1330,7 @@ out:
*
*/
static int
-replica_execute_cleanall_ruv_task (Object *r, ReplicaId rid, Slapi_Task *task, char *returntext)
+replica_execute_cleanall_ruv_task (Object *r, ReplicaId rid, Slapi_Task *task, const char* force_cleaning, char *returntext)
{
PRThread *thread = NULL;
Slapi_Task *pre_task = NULL; /* this is supposed to be null for logging */
@@ -1374,7 +1399,7 @@ replica_execute_cleanall_ruv_task (Object *r, ReplicaId rid, Slapi_Task *task, c
/*
* Create payload
*/
- ridstr = slapi_ch_smprintf("%d:%s:%s", rid, slapi_sdn_get_dn(replica_get_root(replica)), csnstr);
+ ridstr = slapi_ch_smprintf("%d:%s:%s:%s", rid, slapi_sdn_get_dn(replica_get_root(replica)), csnstr, force_cleaning);
payload = create_ruv_payload(ridstr);
slapi_ch_free_string(&ridstr);
@@ -1400,12 +1425,14 @@ replica_execute_cleanall_ruv_task (Object *r, ReplicaId rid, Slapi_Task *task, c
data->maxcsn = maxcsn;
data->payload = payload;
data->sdn = NULL;
+ data->force = slapi_ch_strdup(force_cleaning);
thread = PR_CreateThread(PR_USER_THREAD, replica_cleanallruv_thread,
(void *)data, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
PR_UNJOINABLE_THREAD, SLAPD_DEFAULT_THREAD_STACKSIZE);
if (thread == NULL) {
rc = -1;
+ slapi_ch_free_string(&data->force);
goto fail;
} else {
goto done;
@@ -1501,6 +1528,7 @@ replica_cleanallruv_thread(void *arg)
}
rid_text = slapi_ch_smprintf("{replica %d ldap", data->rid);
csn_as_string(data->maxcsn, PR_FALSE, csnstr);
+ preset_cleaned_rid(data->rid); /* this prevents duplicate thread creation */
/*
* Add the cleanallruv task to the repl config - so we can handle restarts
@@ -1514,7 +1542,7 @@ replica_cleanallruv_thread(void *arg)
ruv_obj = replica_get_ruv(data->replica);
ruv = object_get_data (ruv_obj);
while(data->maxcsn && !is_task_aborted(data->rid) && !is_cleaned_rid(data->rid) && !slapi_is_shutting_down()){
- if(csn_get_replicaid(data->maxcsn) == 0 || ruv_covers_csn_cleanallruv(ruv,data->maxcsn)){
+ if(csn_get_replicaid(data->maxcsn) == 0 || ruv_covers_csn_cleanallruv(ruv,data->maxcsn) || strcasecmp(data->force,"yes") == 0){
/* We are caught up, now we can clean the ruv's */
break;
}
@@ -1525,6 +1553,8 @@ replica_cleanallruv_thread(void *arg)
object_release(ruv_obj);
/*
* Next, make sure all the replicas are up and running before sending off the clean ruv tasks
+ *
+ * Even if we are forcing the cleaning, the replicas still need to be up
*/
cleanruv_log(data->task, CLEANALLRUV_ID,"Waiting for all the replicas to be online...");
if(check_agmts_are_alive(data->replica, data->rid, data->task)){
@@ -1536,7 +1566,7 @@ replica_cleanallruv_thread(void *arg)
* Make sure all the replicas have seen the max csn
*/
cleanruv_log(data->task, CLEANALLRUV_ID,"Waiting for all the replicas to receive all the deleted replica updates...");
- if(check_agmts_are_caught_up(data->replica, data->rid, csnstr, data->task)){
+ if(strcasecmp(data->force,"no") == 0 && check_agmts_are_caught_up(data->replica, data->rid, csnstr, data->task)){
/* error, aborted or shutdown */
aborted = 1;
goto done;
@@ -1567,6 +1597,7 @@ replica_cleanallruv_thread(void *arg)
agmt_not_notified = 0;
} else {
agmt_not_notified = 1;
+ cleanruv_log(data->task, CLEANALLRUV_ID, "Failed to send task to replica (%s)",agmt_get_long_name(agmt));
break;
}
agmt_obj = agmtlist_get_next_agreement_for_replica (data->replica, agmt_obj);
@@ -1620,6 +1651,7 @@ replica_cleanallruv_thread(void *arg)
if(replica_cleanallruv_check_ruv(agmt, rid_text, data->task) == 0){
found_dirty_rid = 0;
} else {
+ cleanruv_log(data->task, CLEANALLRUV_ID,"Replica is not cleaned yet (%s)",agmt_get_long_name(agmt));
found_dirty_rid = 1;
break;
}
@@ -1679,6 +1711,7 @@ done:
object_release(data->repl_obj);
}
slapi_sdn_free(&data->sdn);
+ slapi_ch_free_string(&data->force);
slapi_ch_free_string(&rid_text);
csn_free(&data->maxcsn);
slapi_ch_free((void **)&data);
@@ -1715,6 +1748,7 @@ check_agmts_are_caught_up(Replica *replica, ReplicaId rid, char *maxcsn, Slapi_T
not_all_caughtup = 0;
} else {
not_all_caughtup = 1;
+ cleanruv_log(task, CLEANALLRUV_ID, "Replica not caught up (%s)",agmt_get_long_name(agmt));
break;
}
agmt_obj = agmtlist_get_next_agreement_for_replica (replica, agmt_obj);
@@ -1771,6 +1805,7 @@ check_agmts_are_alive(Replica *replica, ReplicaId rid, Slapi_Task *task)
not_all_alive = 0;
} else {
not_all_alive = 1;
+ cleanruv_log(task, CLEANALLRUV_ID, "Replica not online (%s)",agmt_get_long_name(agmt));
break;
}
agmt_obj = agmtlist_get_next_agreement_for_replica (replica, agmt_obj);
@@ -1914,6 +1949,23 @@ is_cleaned_rid(ReplicaId rid)
}
int
+is_pre_cleaned_rid(ReplicaId rid)
+{
+ int i;
+
+ slapi_rwlock_rdlock(rid_lock);
+ for(i = 0; i < CLEANRIDSIZ && pre_cleaned_rids[i] != 0; i++){
+ if(rid == pre_cleaned_rids[i]){
+ slapi_rwlock_unlock(rid_lock);
+ return 1;
+ }
+ }
+ slapi_rwlock_unlock(rid_lock);
+
+ return 0;
+}
+
+int
is_task_aborted(ReplicaId rid)
{
int i;
@@ -1947,11 +1999,44 @@ set_cleaned_rid(ReplicaId rid)
if(cleaned_rids[i] == 0){
cleaned_rids[i] = rid;
cleaned_rids[i + 1] = 0;
+ break;
}
}
slapi_rwlock_unlock(rid_lock);
}
+static void
+preset_cleaned_rid(ReplicaId rid)
+{
+ int i;
+
+ slapi_rwlock_wrlock(rid_lock);
+ for(i = 0; i < CLEANRIDSIZ; i++){
+ if(pre_cleaned_rids[i] == 0){
+ pre_cleaned_rids[i] = rid;
+ pre_cleaned_rids[i + 1] = 0;
+ break;
+ }
+ }
+ slapi_rwlock_unlock(rid_lock);
+}
+
+void
+set_aborted_rid(ReplicaId rid)
+{
+ int i;
+
+ slapi_rwlock_wrlock(abort_rid_lock);
+ for(i = 0; i < CLEANRIDSIZ; i++){
+ if(aborted_rids[i] == 0){
+ aborted_rids[i] = rid;
+ aborted_rids[i + 1] = 0;
+ break;
+ }
+ }
+ slapi_rwlock_unlock(abort_rid_lock);;
+}
+
/*
* Add the rid and maxcsn to the repl config (so we can resume after a server restart)
*/
@@ -2134,11 +2219,18 @@ delete_cleaned_rid(Replica *r, ReplicaId rid, CSN *maxcsn)
* Remove this rid, and optimize the array
*/
slapi_rwlock_wrlock(rid_lock);
+ /* do the cleaned rids */
for(i = 0; i < CLEANRIDSIZ && cleaned_rids[i] != rid; i++); /* found rid, stop */
for(; i < CLEANRIDSIZ; i++){
/* rewrite entire array */
cleaned_rids[i] = cleaned_rids[i + 1];
}
+ /* do the preset cleaned rids */
+ for(i = 0; i < CLEANRIDSIZ && pre_cleaned_rids[i] != rid; i++); /* found rid, stop */
+ for(; i < CLEANRIDSIZ; i++){
+ /* rewrite entire array */
+ pre_cleaned_rids[i] = pre_cleaned_rids[i + 1];
+ }
slapi_rwlock_unlock(rid_lock);
/*
* Prepare the mods for the config entry
@@ -2244,6 +2336,14 @@ replica_cleanall_ruv_abort(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter
rc = SLAPI_DSE_CALLBACK_ERROR;
goto out;
}
+ if(is_aborted_rid(rid)){
+ /* we are already cleaning this rid */
+ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Replica id (%d) is already being aborted", rid);
+ cleanruv_log(task, ABORT_CLEANALLRUV_ID, "%s", returntext);
+ *returncode = LDAP_UNWILLING_TO_PERFORM;
+ rc = SLAPI_DSE_CALLBACK_ERROR;
+ goto out;
+ }
/*
* Get the replica object
*/
@@ -2256,7 +2356,7 @@ replica_cleanall_ruv_abort(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter
goto out;
}
/*
- * Check verify value
+ * Check certify value
*/
if(certify_all){
if(strcasecmp(certify_all,"yes") && strcasecmp(certify_all,"no")){
@@ -2591,10 +2691,17 @@ replica_cleanallruv_check_maxcsn(Repl_Agmt *agmt, char *rid_text, char *maxcsn,
for(part_count = 1; ruv_part && part_count < 5; part_count++){
ruv_part = ldap_utf8strtok_r(iter, " ", &iter);
}
- if(part_count == 5 && ruv_part){
- /* we have the maxcsn */
- if(strcmp(ruv_part, maxcsn)){
+ if(part_count == 5 && ruv_part){/* we have the maxcsn */
+ CSN *max, *repl_max;
+
+ max = csn_new();
+ repl_max = csn_new();
+ csn_init_by_string(max, maxcsn);
+ csn_init_by_string(repl_max, ruv_part);
+ if(csn_compare (repl_max, max) < 0){
/* we are not caught up yet, free, and return */
+ cleanruv_log(task, CLEANALLRUV_ID,"Replica maxcsn (%s) not caught up deleted replica's maxcsn(%s)",
+ ruv_part, maxcsn);
ldap_value_free_len(vals);
ldap_memfree( attr );
ldap_msgfree( result );
@@ -2602,9 +2709,13 @@ replica_cleanallruv_check_maxcsn(Repl_Agmt *agmt, char *rid_text, char *maxcsn,
ber_free( ber, 0 );
}
conn_delete_internal_ext(conn);
+ csn_free(&max);
+ csn_free(&repl_max);
return -1;
} else {
/* ok this replica has all the updates from the deleted replica */
+ csn_free(&max);
+ csn_free(&repl_max);
rc = 0;
}
} else {
diff --git a/ldap/servers/plugins/replication/repl_extop.c b/ldap/servers/plugins/replication/repl_extop.c
index b2381b8..8026ff4 100644
--- a/ldap/servers/plugins/replication/repl_extop.c
+++ b/ldap/servers/plugins/replication/repl_extop.c
@@ -1519,6 +1519,7 @@ multimaster_extop_cleanruv(Slapi_PBlock *pb)
char *payload = NULL;
char *csnstr = NULL;
char *iter;
+ char *force = NULL;
int release_it = 0;
int rid = 0;
int rc = LDAP_OPERATIONS_ERROR;
@@ -1535,18 +1536,22 @@ multimaster_extop_cleanruv(Slapi_PBlock *pb)
* Decode the payload
*/
if(decode_cleanruv_payload(extop_payload, &payload)){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: failed to decode payload. Aborting ext op\n");
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV Task: failed to decode payload. Aborting ext op\n");
goto free_and_return;
}
rid = atoi(ldap_utf8strtok_r(payload, ":", &iter));
repl_root = ldap_utf8strtok_r(iter, ":", &iter);
csnstr = ldap_utf8strtok_r(iter, ":", &iter);
+ force = ldap_utf8strtok_r(iter, ":", &iter);
+ if(force == NULL){
+ force = "no";
+ }
maxcsn = csn_new();
csn_init_by_string(maxcsn, csnstr);
/*
* If we already cleaned this server, just return success
*/
- if(is_cleaned_rid(rid)){
+ if(is_cleaned_rid(rid) || is_pre_cleaned_rid(rid)){
csn_free(&maxcsn);
rc = LDAP_SUCCESS;
goto free_and_return;
@@ -1556,7 +1561,7 @@ multimaster_extop_cleanruv(Slapi_PBlock *pb)
* Get the node, so we can get the replica and its agreements
*/
if((mtnode_ext = replica_config_get_mtnode_by_dn(repl_root)) == NULL){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: failed to get replication node "
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV Task: failed to get replication node "
"from (%s), aborting operation\n", repl_root);
goto free_and_return;
}
@@ -1565,14 +1570,14 @@ multimaster_extop_cleanruv(Slapi_PBlock *pb)
object_acquire (mtnode_ext->replica);
release_it = 1;
} else {
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: replica is missing from (%s), "
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV Task: replica is missing from (%s), "
"aborting operation\n",repl_root);
goto free_and_return;
}
r = (Replica*)object_get_data (mtnode_ext->replica);
if(r == NULL){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: replica is NULL, aborting task\n");
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV Task: replica is NULL, aborting task\n");
goto free_and_return;
}
@@ -1582,10 +1587,10 @@ multimaster_extop_cleanruv(Slapi_PBlock *pb)
*
* This will also release mtnode_ext->replica
*/
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: launching cleanAllRUV thread...\n");
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV Task: launching cleanAllRUV thread...\n");
data = (cleanruv_data*)slapi_ch_calloc(1, sizeof(cleanruv_data));
if (data == NULL) {
- slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: failed to allocate "
+ slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV Task: failed to allocate "
"cleanruv_Data\n");
goto free_and_return;
}
@@ -1595,15 +1600,17 @@ multimaster_extop_cleanruv(Slapi_PBlock *pb)
data->task = NULL;
data->maxcsn = maxcsn;
data->payload = slapi_ch_bvdup(extop_payload);
+ data->force = slapi_ch_strdup(force);
thread = PR_CreateThread(PR_USER_THREAD, replica_cleanallruv_thread_ext,
(void *)data, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
PR_UNJOINABLE_THREAD, SLAPD_DEFAULT_THREAD_STACKSIZE);
if (thread == NULL) {
- slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: unable to create cleanAllRUV "
+ slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV Task: unable to create cleanAllRUV "
"monitoring thread. Aborting task.\n");
ber_bvfree(data->payload);
data->payload = NULL;
+ slapi_ch_free_string(&data->force);
slapi_ch_free((void **)&data);
} else {
release_it = 0; /* thread will release data->repl_obj == mtnode_ext->replica */
@@ -1625,18 +1632,18 @@ multimaster_extop_cleanruv(Slapi_PBlock *pb)
/* we've already been cleaned */
break;
}
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: checking if we're caught up...\n");
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV Task: checking if we're caught up...\n");
if(ruv_covers_csn_cleanallruv(ruv,maxcsn) || csn_get_replicaid(maxcsn) == 0){
/* We are caught up */
break;
} else {
char csnstr[CSN_STRSIZE];
csn_as_string(maxcsn, PR_FALSE, csnstr);
- slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: not ruv caught up maxcsn(%s)\n", csnstr);
+ slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV Task: ruv not caught up to maxcsn(%s)\n", csnstr);
}
DS_Sleep(PR_SecondsToInterval(5));
}
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: we're caught up...\n");
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV Task: we're caught up...\n");
/*
* Set cleaned rid in memory only - does not survive a server restart
*/
@@ -1652,8 +1659,8 @@ multimaster_extop_cleanruv(Slapi_PBlock *pb)
* This read-only replica has no easy way to tell when it's safe to release the rid.
* So we won't release it, not until a server restart.
*/
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: You must restart the server if you want to reuse rid(%d).\n", rid);
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: Successfully cleaned rid(%d).\n", rid);
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV Task: You must restart the server if you want to reuse rid(%d).\n", rid);
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV Task: Successfully cleaned rid(%d).\n", rid);
rc = LDAP_SUCCESS;
}
11 years, 5 months
Changes to 'refs/tags/389-ds-base-1.2.10.15'
by Richard Allen Megginson
Changes since 389-ds-base-1.2.6.a1:
Charles Lopes (1):
Bug #361: Bad DNs in ACIs can segfault ns-slapd
Endi S. Dewata (168):
Bug 545620 - Password cannot start with minus sign
Bug 538525 - Ability to create instance as non-root user
Bug 570542 - Root password cannot contain matching curly braces
Bug 470684 - Pam_passthru plugin doesn't verify account activation
Bug 573375 - MODRDN operation not logged
Bug 520151 - Error when modifying userPassword with proxy user
Bug 455489 - Address compiler warnings about strict-aliasing rules
Bug 566320 - RFE: add exception to removal of attributes in cn=config for aci
Bug 566043 - startpid file is only cleaned by initscript runs
Bug 584109 - Slapd crashes while parsing DNA configuration
Bug 542570 - Directory Server port number is not validated in the beginning.
Bug 145181 - Plugin target/bind subtrees only take 1 value.
Bug 614511 - fix coverify Defect Type: Null pointer dereferences issues 11846 - 11891
Bug 614511 - fix coverify Defect Type: Null pointer dereferences issues 11846 - 11891
Bug 614511 - fix coverify Defect Type: Null pointer dereferences issues 11846 - 11891
Bug 614511 - fix coverify Defect Type: Null pointer dereferences issues 11846 - 11891
Bug 614511 - fix coverify Defect Type: Null pointer dereferences issues 11846 - 11891
Bug 614511 - fix coverify Defect Type: Null pointer dereferences issues 11846 - 11891
Bug 614511 - fix coverify Defect Type: Null pointer dereferences issues 11846 - 11891
Bug 614511 - fix coverify Defect Type: Null pointer dereferences issues 11846 - 11891
Bug 614511 - fix coverify Defect Type: Null pointer dereferences issues 11846 - 11891
Bug 614511 - fix coverify Defect Type: Null pointer dereferences issues 11846 - 11891
Bug 614511 - fix coverify Defect Type: Null pointer dereferences issues 11846 - 11891
Bug 614511 - fix coverify Defect Type: Null pointer dereferences issues 11846 - 11891
Bug 614511 - fix coverify Defect Type: Null pointer dereferences issues 11846 - 11891
Bug 614511 - fix coverify Defect Type: Null pointer dereferences issues 11846 - 11891
Bug 614511 - fix coverify Defect Type: Null pointer dereferences issues 11846 - 11891
Bug 614511 - fix coverify Defect Type: Null pointer dereferences issues 11846 - 11891
Bug 614511 - fix coverify Defect Type: Null pointer dereferences issues 11846 - 11891
Bug 614511 - fix coverify Defect Type: Null pointer dereferences issues 11846 - 11891
Bug 614511 - fix coverify Defect Type: Null pointer dereferences issues 11846 - 11891
Bug 614511 - fix coverify Defect Type: Null pointer dereferences issues 11846 - 11891
Bug 614511 - fix coverify Defect Type: Null pointer dereferences issues 11846 - 11891
Bug 614511 - fix coverify Defect Type: Null pointer dereferences issues 11846 - 11891
Bug 619122 - fix coverify Defect Type: Resource leaks issues CID 11975 - 12053
Bug 619122 - fix coverify Defect Type: Resource leaks issues CID 11975 - 12053
Bug 619122 - fix coverify Defect Type: Resource leaks issues CID 11975 - 12053
Bug 619122 - fix coverify Defect Type: Resource leaks issues CID 11975 - 12053
Bug 619122 - fix coverify Defect Type: Resource leaks issues CID 11975 - 12053
Bug 619122 - fix coverify Defect Type: Resource leaks issues CID 11975 - 12053
Bug 619122 - fix coverify Defect Type: Resource leaks issues CID 11975 - 12053
Bug 619122 - fix coverify Defect Type: Resource leaks issues CID 11975 - 12053
Bug 619122 - fix coverify Defect Type: Resource leaks issues CID 11975 - 12053
Bug 619122 - fix coverify Defect Type: Resource leaks issues CID 11975 - 12053
Bug 619122 - fix coverify Defect Type: Resource leaks issues CID 11975 - 12053
Bug 619122 - fix coverify Defect Type: Resource leaks issues CID 11975 - 12053
Bug 619122 - fix coverify Defect Type: Resource leaks issues CID 11975 - 12053
Bug 619122 - fix coverify Defect Type: Resource leaks issues CID 11975 - 12053
Bug 619122 - fix coverify Defect Type: Resource leaks issues CID 11975 - 12053
Bug 619122 - fix coverify Defect Type: Resource leaks issues CID 11975 - 12053
Bug 619122 - fix coverify Defect Type: Resource leaks issues CID 11975 - 12053
Bug 619122 - fix coverify Defect Type: Resource leaks issues CID 11975 - 12053
Bug 619122 - fix coverify Defect Type: Resource leaks issues CID 11975 - 12053
Bug 619122 - fix coverify Defect Type: Resource leaks issues CID 11975 - 12053
Bug 619122 - fix coverify Defect Type: Resource leaks issues CID 11975 - 12053
Bug 619122 - fix coverify Defect Type: Resource leaks issues CID 11975 - 12053
Bug 619122 - fix coverify Defect Type: Resource leaks issues CID 11975 - 12053
Bug 619122 - fix coverify Defect Type: Resource leaks issues CID 11975 - 12053
Bug 619122 - fix coverify Defect Type: Resource leaks issues CID 11975 - 12053
Bug 619122 - fix coverify Defect Type: Resource leaks issues CID 11975 - 12053
Bug 619122 - fix coverify Defect Type: Resource leaks issues CID 11975 - 12053
Bug 619122 - fix coverify Defect Type: Resource leaks issues CID 11975 - 12053
Bug 619122 - fix coverify Defect Type: Resource leaks issues CID 11975 - 12053
Bug 619122 - fix coverify Defect Type: Resource leaks issues CID 11975 - 12053
Bug 619122 - fix coverify Defect Type: Resource leaks issues CID 11975 - 12053
Bug 619122 - fix coverify Defect Type: Resource leaks issues CID 11975 - 12053
Bug 619122 - fix coverify Defect Type: Resource leaks issues CID 11975 - 12053
Bug 619122 - fix coverify Defect Type: Resource leaks issues CID 11975 - 12053
Bug 619122 - fix coverify Defect Type: Resource leaks issues CID 11975 - 12053
Bug 617630 - fix coverify Defect Type: Resource leaks issues CID 12052 - 12093
Bug 617630 - fix coverify Defect Type: Resource leaks issues CID 12052 - 12093
Bug 617630 - fix coverify Defect Type: Resource leaks issues CID 12052 - 12093
Bug 617630 - fix coverify Defect Type: Resource leaks issues CID 12052 - 12093
Bug 617630 - fix coverify Defect Type: Resource leaks issues CID 12052 - 12093
Bug 617630 - fix coverify Defect Type: Resource leaks issues CID 12052 - 12093
Bug 617630 - fix coverify Defect Type: Resource leaks issues CID 12052 - 12093
Bug 617630 - fix coverify Defect Type: Resource leaks issues CID 12052 - 12093
Bug 617630 - fix coverify Defect Type: Resource leaks issues CID 12052 - 12093
Bug 617630 - fix coverify Defect Type: Resource leaks issues CID 12052 - 12093
Bug 617630 - fix coverify Defect Type: Resource leaks issues CID 12052 - 12093
Bug 617630 - fix coverify Defect Type: Resource leaks issues CID 12052 - 12093
Bug 617630 - fix coverify Defect Type: Resource leaks issues CID 12052 - 12093
Bug 617630 - fix coverify Defect Type: Resource leaks issues CID 12052 - 12093
Bug 617630 - fix coverify Defect Type: Resource leaks issues CID 12052 - 12093
Bug 617630 - fix coverify Defect Type: Resource leaks issues CID 12052 - 12093
Bug 617630 - fix coverify Defect Type: Resource leaks issues CID 12052 - 12093
Bug 617630 - fix coverify Defect Type: Resource leaks issues CID 12052 - 12093
Bug 617630 - fix coverify Defect Type: Resource leaks issues CID 12052 - 12093
Bug 617630 - fix coverify Defect Type: Resource leaks issues CID 12052 - 12093
Bug 617630 - fix coverify Defect Type: Resource leaks issues CID 12052 - 12093
Bug 617630 - fix coverify Defect Type: Resource leaks issues CID 12052 - 12093
Bug 613056 - fix coverify Defect Type: Null pointer dereferences issues 11892 - 11939
Bug 613056 - fix coverify Defect Type: Null pointer dereferences issues 11892 - 11939
Bug 613056 - fix coverify Defect Type: Null pointer dereferences issues 11892 - 11939
Bug 613056 - fix coverify Defect Type: Null pointer dereferences issues 11892 - 11939
Bug 613056 - fix coverify Defect Type: Null pointer dereferences issues 11892 - 11939
Bug 613056 - fix coverify Defect Type: Null pointer dereferences issues 11892 - 11939
Bug 613056 - fix coverify Defect Type: Null pointer dereferences issues 11892 - 11939
Bug 613056 - fix coverify Defect Type: Null pointer dereferences issues 11892 - 11939
Bug 613056 - fix coverify Defect Type: Null pointer dereferences issues 11892 - 11939
Bug 613056 - fix coverify Defect Type: Null pointer dereferences issues 11892 - 11939
Bug 613056 - fix coverify Defect Type: Null pointer dereferences issues 11892 - 11939
Bug 613056 - fix coverify Defect Type: Null pointer dereferences issues 11892 - 11939
Bug 613056 - fix coverify Defect Type: Null pointer dereferences issues 11892 - 11939
Bug 613056 - fix coverify Defect Type: Null pointer dereferences issues 11892 - 11939
Bug 613056 - fix coverify Defect Type: Null pointer dereferences issues 11892 - 11939
Bug 613056 - fix coverify Defect Type: Null pointer dereferences issues 11892 - 11939
Bug 613056 - fix coverify Defect Type: Null pointer dereferences issues 11892 - 11939
Bug 613056 - fix coverify Defect Type: Null pointer dereferences issues 11892 - 11939
Bug 613056 - fix coverify Defect Type: Null pointer dereferences issues 11892 - 11939
Bug 613056 - fix coverify Defect Type: Null pointer dereferences issues 11892 - 11939
Bug 613056 - fix coverify Defect Type: Null pointer dereferences issues 11892 - 11939
Bug 613056 - fix coverify Defect Type: Null pointer dereferences issues 11892 - 11939
Bug 613056 - fix coverify Defect Type: Null pointer dereferences issues 11892 - 11939
Bug 613056 - fix coverify Defect Type: Null pointer dereferences issues 11892 - 11939
Bug 613056 - fix coverify Defect Type: Null pointer dereferences issues 11892 - 11939
Bug 613056 - fix coverify Defect Type: Null pointer dereferences issues 11892 - 11939
Bug 616500 - fix coverify Defect Type: Resource leaks issues CID 12094 - 12136
Bug 616500 - fix coverify Defect Type: Resource leaks issues CID 12094 - 12136
Bug 616500 - fix coverify Defect Type: Resource leaks issues CID 12094 - 12136
Bug 616500 - fix coverify Defect Type: Resource leaks issues CID 12094 - 12136
Bug 616500 - fix coverify Defect Type: Resource leaks issues CID 12094 - 12136
Bug 616500 - fix coverify Defect Type: Resource leaks issues CID 12094 - 12136
Bug 616500 - fix coverify Defect Type: Resource leaks issues CID 12094 - 12136
Bug 616500 - fix coverify Defect Type: Resource leaks issues CID 12094 - 12136
Bug 616500 - fix coverify Defect Type: Resource leaks issues CID 12094 - 12136
Bug 616500 - fix coverify Defect Type: Resource leaks issues CID 12094 - 12136
Bug 616500 - fix coverify Defect Type: Resource leaks issues CID 12094 - 12136
Bug 616500 - fix coverify Defect Type: Resource leaks issues CID 12094 - 12136
Bug 616500 - fix coverify Defect Type: Resource leaks issues CID 12094 - 12136
Bug 616500 - fix coverify Defect Type: Resource leaks issues CID 12094 - 12136
Bug 616500 - fix coverify Defect Type: Resource leaks issues CID 12094 - 12136
Bug 616500 - fix coverify Defect Type: Resource leaks issues CID 12094 - 12136
Bug 616500 - fix coverify Defect Type: Resource leaks issues CID 12094 - 12136
Bug 610119 - fix coverify Defect Type: Null pointer dereferences issues 12167 - 12199
Bug 610119 - fix coverify Defect Type: Null pointer dereferences issues 12167 - 12199
Bug 610119 - fix coverify Defect Type: Null pointer dereferences issues 12167 - 12199
Bug 610119 - fix coverify Defect Type: Null pointer dereferences issues 12167 - 12199
Bug 610119 - fix coverify Defect Type: Null pointer dereferences issues 12167 - 12199
Bug 610119 - fix coverify Defect Type: Null pointer dereferences issues 12167 - 12199
Bug 610119 - fix coverify Defect Type: Null pointer dereferences issues 12167 - 12199
Bug 610119 - fix coverify Defect Type: Null pointer dereferences issues 12167 - 12199
Bug 610119 - fix coverify Defect Type: Null pointer dereferences issues 12167 - 12199
Bug 610119 - fix coverify Defect Type: Null pointer dereferences issues 12167 - 12199
Bug 610119 - fix coverify Defect Type: Null pointer dereferences issues 12167 - 12199
Bug 610119 - fix coverify Defect Type: Null pointer dereferences issues 12167 - 12199
Bug 610119 - fix coverify Defect Type: Null pointer dereferences issues 12167 - 12199
Bug 610119 - fix coverify Defect Type: Null pointer dereferences issues 12167 - 12199
Bug 610119 - fix coverify Defect Type: Null pointer dereferences issues 12167 - 12199
Bug 610119 - fix coverify Defect Type: Null pointer dereferences issues 12167 - 12199
Bug 611790 - fix coverify Defect Type: Null pointer dereferences issues 11940 - 12166
Bug 611790 - fix coverify Defect Type: Null pointer dereferences issues 11940 - 12166
Bug 611790 - fix coverify Defect Type: Null pointer dereferences issues 11940 - 12166
Bug 611790 - fix coverify Defect Type: Null pointer dereferences issues 11940 - 12166
Bug 611790 - fix coverify Defect Type: Null pointer dereferences issues 11940 - 12166
Bug 611790 - fix coverify Defect Type: Null pointer dereferences issues 11940 - 12166
Bug 611790 - fix coverify Defect Type: Null pointer dereferences issues 11940 - 12166
Bug 611790 - fix coverify Defect Type: Null pointer dereferences issues 11940 - 12166
Bug 611790 - fix coverify Defect Type: Null pointer dereferences issues 11940 - 12166
Bug 611790 - fix coverify Defect Type: Null pointer dereferences issues 11940 - 12166
Bug 611790 - fix coverify Defect Type: Null pointer dereferences issues 11940 - 12166
Bug 611790 - fix coverify Defect Type: Null pointer dereferences issues 11940 - 12166
Bug 611790 - fix coverify Defect Type: Null pointer dereferences issues 11940 - 12166
Bug 611790 - fix coverify Defect Type: Null pointer dereferences issues 11940 - 12166
Bug 628096 - spurious error message from /sbin/service when doing a stop on no instances
Bug 573889 - Migration does not remove deprecated schema
Bug 606545 - core schema should include numSubordinates
Bug 643979 - Strange byte sequence for attribute with no values (nsslapd-referral)
Endi Sukma Dewata (16):
Bug 630092 - Coverity #12117: Resource leaks issues
Bug 630092 - Coverity #15478: Resource leaks issues
Bug 630092 - Coverity #15479: Resource leaks issues
Bug 630092 - Coverity #15481: Resource leaks issues
Bug 630092 - Coverity #15482: Resource leaks issues
Bug 630092 - Coverity #15483: Resource leaks issues
Bug 630092 - Coverity #15484: Resource leaks issues
Bug 630092 - Coverity #15485: Resource leaks issues
Bug 630092 - Coverity #15487: Resource leaks issues
Bug 630092 - Coverity #15490: Resource leaks issues
Bug 630092 - Coverity #15497: Resource leaks issues
Bug 630092 - Coverity #11991: Resource leaks issues
Bug 630092 - Coverity #12000: Resource leaks issues
Bug 630092 - Coverity #12003: Resource leaks issues
Bug 630092 - Coverity #11985: Resource leaks issues
Bug 630092 - Coverity #11992,11993: Resource leaks issues
Mark Reynolds (31):
Ticket #71 - unable to delete managed entry config
Ticket #159 - Managed Entry Plugin runs against managed entries upon any update without validating
Ticket #177 - logconv.pl doesn't detect restarts
Merge branch 'ticket159'
Ticket #49 - better handling for server shutdown while long running tasks are active
Ticket #50 - server should not call a plugin after the plugin close function is calle
Updated for ticket#50
Ticket #55 - Limit of 1024 characters for nsMatchingRule
Ticket #140 - incorrect memset parameters
Revert "Ticket #140 - incorrect memset parameters"
Revert "Ticket #55 - Limit of 1024 characters for nsMatchingRule"
Ticket #38 - nisDomain schema is incorrect
Ticket #6 - protocol error from proxied auth operation
Ticket #55 - Limit of 1024 characters for nsMatchingRule
Ticket #39 - Account Policy Plugin does not work for simple binds when PAM Pass Through Auth plugin is enabled
Ticket 175 - logconv.pl improvements
Ticket 175 - minor fixes
Ticket #306 - void function cannot return value
Ticket #305 - Certain CMP operations hang or cause ns-slapd to crash
Ticket #337 - Improve CLEANRUV task
Ticket 368 - Make the cleanAllRUV task one step
Coverity Fix
Update the slapi-plugin documentation on new slapi functions, and added a slapi function for checking on shutdowns
Ticket 403 - CLEANALLRUV feature
Ticket 403 - cleanallruv coverity fixes
Ticket 403 - CLEANALLRUV revisions
Ticket 403 - fix CLEANALLRUV regression from last commit
CLEANALLRUV coverity fixes
Ticket 450 - CLEANALLRUV task gets stuck on winsync replication agreement
Ticket 467 - CLEANALLRUV abort task should be able to ignore down replicas
Ticket 477 - CLEANALLRUV if there are only winsync agmts task will hang
Nathan Kinder (189):
Bug 549554 - Trim single-valued attributes before sending to AD
Improve search for pcre header file
Bug 434735 - Allow SASL ANONYMOUS mech to work
Bug 570912 - Avoid selinux context conflict with httpd
Allow instance name to be parsed from start-slapd
Add managed entries plug-in
Bug 572355 - Label instance files and ports during upgrade.
Bug 578863 - Password modify extop needs to send referrals on replicas
Bug 584156 - Remove ldapi socket file during upgrade
Fix rsearch usage of name files for random filters
Bug 584497 - Allow DNA plugin to set same value on multiple attributes
Add replication session hooks
Correct function prototype for repl session hook
Bug 592389 - Set anonymous resource limits properly
Bug 601433 - Add man pages for start-dirsrv and related commands
Bug 604263 - Fix memory leak when password change is rejected
Bug 612242 - membership change on DS does not show on AD
Bug 613833 - Allow dirsrv_t to bind to rpc ports
Bug 594745 - Get rid of dirsrv_lib_t label
Bug 620927 - Allow multiple membership attributes in memberof plugin
Bug 612264 - ACI issue with (targetattr='userPassword')
Bug 630098 - fix coverity Defect Type: Code maintainability issues
Bug 630098 - fix coverity Defect Type: Code maintainability issues
Bug 630093 - (cov#15511) Don't use unintialized search_results in refint plugin
Bug 630093 - (cov#15518) Need to intialize fd in ldbm2ldif code
Bug 630096 - (cov#11778) check return value of ldap_parse_result
Bug 630096 - (cov#15446) check return value of ber_scanf()
Bug 630096 - (cov#15449,15450) Check return value of stat()
Bug 630096 - (cov#15448) Check return value of cache_replace()
Bug 630096 - (cov#15447) - Check return value of idl_append_extend()
Bug 630090 - (cov#11974) Remove unused ACL functions
Bug 630090 - (cov#15445) Fix illegal free in archive code
Bug 630094 - (cov#11818) Fix unreachable return in snmp subagent
Bug 630094 - (cov#15451) Get rid of unreachable free statements
Bug 630094 - (cov#15452) Remove NULL checking for op_string
Bug 630094 - (cov#15453) Eliminate NULL check for local_newentry
Bug 630094 - (cov#15454) Fix deadcode issue in mapping tree code
Bug 630094 - (cov#15455) Remove deadcode in attr_index_config()
Bug 630094 - (cov#15456) Remove NULL check for srdn in import code
Bug 630094 - (cov#15457) Remove deadcode in import code
Bug 630094 - (cov#15458) Fix deadcode issue in moddn code
Bug 630094 - (cov#15459) Remove NULL check for srdn in ldif2ldbm code
Bug 630094 - (cov#15520) Fix unreachable code issue if perfctrs code
Bug 630094 - (cov#15581) Add missing breaks in agt_mopen_stats()
Bug 690090 - (cov#11974) Remove additional unused ACL functions
Bug 630091 - (cov#15512) Fix usage of uninitialized bervals
Bug 630091 - (cov#15513) Fix usage of uninitialized bervals
Bug 630091 - (cov#15514) Initialize DBT in entryrdn_get_parent()
Bug 630091 - (cov#15515) Use of uninitialized array in index config code
Bug 630091 - (cov#15516,15517) Initialize pointers before attempting to free
Bug 630091 - (cov#15519) Initialize bervals in search_easter_egg()
Bug 630091 - (cov#15582) Free of uninitialized pointer in attr_index_config()
Bug 630097 - (cov#11933) Fix NULL dereference in schema code
Bug 630097 - (cov#11938) NULL dereference in mmldif
Bug 630097 - (cov#11946) NULL dereference in ResHashCreate()
Bug 630097 - (cov#11964) Remove dead code from libaccess
Bug 630097 - (cov#12143) NULL dereference in cos cache code
Bug 630097 - (cov#12148) NULL dereference in ruvInit()
Bug 630097 - (cov#12182,12183) NULL dereference in import code
Bug 630097 - (cov#15460) NULL deference in ACL URL code
Bug 630097 - (cov#15461) Remove unnecessary NULL check in DNA
Bug 630097 - (cov#15462) NULL dereference in mep_modrdn_post_op()
Bug 630097 - (cov#15463) Remove NULL check in referint plugin
Bug 630097 - (cov#15464) NULL dereference in repl code
Bug 630097 - (cov#15465) Null dereference in USN code
Bug 630097 - (cov#15473) NULL dereference in ResHashCreate()
Bug 630097 - (cov#15505) NULL dereference in memberOf code
Bug 630097 - (cov#15506) NULL dereference in dblayer code
Bug 630097 - (cov#15507,15508) NULL dereference in entryrdn code
Bug 630097 - (cov#15509) NULL dereference in idsktune
Bug 630097 - (cov#11938) NULL dereference in mmldif
Bug 630097 - (cov#15477) NULL dereference in ACL plug-in code
Bug 630091 - (cov#12209) Use of uninitialized pointer in libaccess
Bug 630092 - (cov#12116) Resource leak in ldclt code
Bug 630092 - (cov#12105) Resource leak in pwdscheme config code
Bug 630092 - (cov#12068) Resource leak in certmap code
Bug 630091 - (cov#11973) Array overrun in libaccess
Bug 522055 - Scope check for managed attribute fails
Bug 625335 - Self-write aci has permission to invalid attribute
Bug 631993 - Log authzid when proxy auth control is used
Cov #16300 - Unused variable in account policy plugin
Bug 544321 - remove-ds.pl should not throw error unlabelling port
Bug 555955 - Allow CoS values to be merged
Bug 643937 - Initialize replication version flags
Bug 305131 - Allow empty modify operation
Bug 619633 - Make attribute uniqueness obey requiredObjectClass
Bug 619623 - attr-unique-plugin ignores requiredObjectClass on modrdn operations
Bug 189985 - Improve attribute uniqueness error message
Bug 647932 - multiple memberOf configuration adding memberOf where there is no member
Bug 521088 - DNA should check ACLs before getting a value from the range
Bug 635009 - Add one-way AD sync capability
Bump VERSION.sh to 1.2.8.a1
Bug 648949 - Move selinux policy into base OS
Bug 648949 - Update configure
Roll back VERSION.sh for 1.2.7 release
Bug 625950 - hash nsslapd-rootpw changes in audit log
Bug 656392 - Remove calls to ber_err_print()
Bug 656515 - Allow Name and Optional UID syntax for grouping attributes
Bug 197886 - Avoid overflow of UUID generator
Bug 658312 - Allow mapped attribute types to be quoted
Bug 197886 - Initialize return value for UUID generation code
Bug 658309 - Process escaped characters in managed entry mappings
Bug 659456 - Incorrect usage of ber_printf() in winsync code
Bug 641944 - Don't normalize non-DN RDN values
Bug 658312 - Invalid free in Managed Entry plug-in
Bug 661792 - Valid managed entry config rejected
Bug 588791 - Allow anonymous rootDSE access only
Bug 606439 - Creating server instance with LDAPI takes too long
Bug 632670 - Chain-on-update logs managed-entries-plugin errors
Bug 621008 - parsing purge RUV from changelog at startup fails
Bug 663191 - Don't use $USER in DSCreate.pm
Bug 663597 - Memory leaks in normalization code
Bug 659131 - Incorrect RDN values added with multi-valued RDN
Bug 661102 - Rename of managed entries not handled correctly
Bug 193297 - Call pre-bind plug-ins for all SASL bind steps
Bug 201652 - LDAPv2 bind with expired password doesn't unbind correctly
Bug 470576 - Migration could do addition checks before commiting actions
Bug 481195 - Missing op type in log when password change required
Bug 509897 - Validate dnaScope to ensure it is a legal DN
Bug 505722 - Allow ntGroup to have mail attribute present
Bug 543633 - replication problems if supplier is killed under update load
Bug 671033 - range sharing between server breaks with SASL/GSSAPI auth
Bug 527912 - setup-ds.pl appears to hang when DNS is unreachable
Bug 252249 - Add pkg-config file for plug-in developers
Bug 670616 - Allow SSF to be set for local (ldapi) connections
Bug 668862 - init scripts return wrong error code
Bug 674430 - Improve error messages for attribute uniqueness
Bug 675853 - dirsrv crash segfault in need_new_pw()
Bug 678646 - Ignore tombstone operations in managed entry plug-in
Bug 671199 - Don't allow other to write to rundir
Bug 672468 - Don't use empty path elements in LD_LIBRARY_PATH
Bug 674852 - crash in ldap-agent when using OpenLDAP
Bug 681345 - setup-ds.pl should set SuiteSpotGroup automatically
Bug 680558 - Winsync plugin fails to restrain itself to the configured subtree
Bug 504803 - Allow maxlogsize to be set if logmaxdiskspace is -1
Bug 687974 - (cov#10715) Fix Coverity uninitialized variables issues
Bug 688341 - (cov#10709) Fix Coverity code maintainability issues
Bug 688341 - (cov#10708) Fix Coverity code maintainability issues
Bug 688341 - (cov#10706,10707) Fix Coverity code maintainability issues
Bug 688341 - (cov#10704,10705) Fix Coverity code maintainability issues
Bug 688341 - (cov#10703) Fix Coverity code maintainability issues
Bug 688341 - (cov#10702) Fix Coverity code maintainability issues
Bug 688341 - (cov#10709) Fix Coverity code maintainability issues
Bug 689537 - (cov#10699) Fix Coverity NULL pointer dereferences
Bug 689537 - (cov#10610) Fix Coverity NULL pointer dereferences
Bug 689537 - (cov#10608) Fix Coverity NULL pointer dereferences
Bug 689952 - (cov#10581) Incorrect bit check in replication connection code
Bug 690526 - (cov#10734) Double free in dse_add()
Bug 690649 - (cov#10731) Use of free'd pointer in indexing code
Bug 690882 - (cov#10571) Incorrect sizeof use in uuid code
Bug 690882 - (cov#10636,10637) Useless comparison in attrcrypt
Bug 690882 - (cov#10703) Incorrect sizeof use in vattr code
Bug 690882 - (cov#10572,10710) Incorrect sizeof use in uuid code
Bug 691574 - (cov#10579) Check return value of ber_scanf() in sort code
Bug 691574 - (cov#10577) Check return types when adding RDN CSNs
Bug 691574 - (cov#10573) check return value in GER code
Bug 691574 - (cov#10575) Check return value of ldap_get_option
Bug 691574 - (cov#10573) Fix syntax error
Bug 693868 - Add managed entry config during in-place upgrade
Add Auto Membership Plug-in
Bug 698428 - Make auto membership use Slapi_DN for DN comparisons
Bug 695779 - windows sync can lose old values when a new value is added
Bug 700557 - Linked attrs callbacks access free'd pointers after close
Bug 700557 - Leak at shutdown in DNA plug-in
Bug 703304 - Auto membership alternate config area should override default area
Bug 703304 - Auto membership alternate config area should override default area
Bug 703530 - Allow Managed Entry config to be relocated
Bug 697961 - memberOf needs to be triggered by internal operations
Bug 710377 - Import with chain-on-update crashes ns-slapd
Split automember regex rules into separate entries
Bug 713209 - Update sudo schema
Bug 691313 - Need TLS/SSL error messages in repl status and errors log
Bug 723937 - Slapi_Counter API broken on 32-bit F15
Bug 725743 - Make memberOf use PRMonitor for it's operation lock
Bug 729717 - Fatal error messages when syncing deletes from AD
Bug 728510 - Run dirsync after sending updates to AD
Bug 730387 - Add slapi_rwlock API and use POSIX rwlocks
Bug 611438 - Add Account Usability Control support
Bug 728592 - Allow ns-slapd to start with an invalid server cert
Bug 732541 - Ignore error 32 when adding automember config
Bug 722292 - Entries in DS are not updated properly when using WinSync API
Bug 722292 - (cov#11030) Leak of mapped_sdn in winsync rename code
Bug 735114 - renaming a managed entry does not update mepmanagedby
Bug 739172 - Allow separate fractional attrs for incremental and total protocols
Bug 743966 - Compiler warnings in account usability plugin
Bug 744946 - (cov#11046) NULL dereference in IDL code
Bug 752155 - Use restorecon after creating init script lock file
Ticket 284 - Remove unnecessary SNMP MIB files
ticket 304 - Fix kernel version checking in dsktune
Noriko Hosoi (312):
544089 - Referential Integrity Plugin does not take into account the attribute
557224 - subtree rename breaks the referential integrity plug-in
247413 - Incorrect error on multiple identical value add
559016 - Attempting to rename suffix returns inappropriate errors
555577 - Syntax validation fails for "ou=NetscapeRoot" tree
Undo - 555577 - Syntax validation fails for "ou=NetscapeRoot" tree
560827 - Admin Server templates: DistinguishName validation fails
548535 - memory leak in attrcrypt
563365 - Error handling problems in the backend functions
565664 - Incorrect parameter for CACHE_RETURN()
565987 - redhat-ds-base fails to build due to undefined struct
527848 - make sure db upgrade to 4.7 and later works correctly
539618 - Replication bulk import reports Invalid read/write
567370 - dncache: assertion failure in id2entry_delete
548115 - memory leak in schema reload
555970 - missing read lock in the combination of cos and nsview
539618 - Replication bulk import reports Invalid read/write
570667 - MMR: simultaneous total updates on the masters cause
Merge branch '547503'
Revert "Merge branch '547503'"
Bug 554573 - ACIs use bind DN from bind req rather than cert mapped DN from sasl/external
199923 - subtree search fails to find items under a db
570107 - The import of LDIFs with base-64 encoded DNs fails,
572649 - DS8.2 crashes on RHEL 4 (corresponding to bob, ber_2 test case)
573060 - DN normalizer: ESC HEX HEX is not normalized (
573896 - initializing subtree with invalid syntax crashes ns-slapd
515805 - Stop "initialize Database" crashes the server
548533 - memory leak in Repl_5_Inc_Protocol_new
Fixing a syntax error
Update to New DN Format
585905 - ACL with targattrfilters error crashes the server
574167 - An escaped space at the end of the RDN value is not
590931 - rhds81 import - hardcoded pages_limit for nsslapd-import-cache-autosize
591336 - Implementing upgrade DN format tool
593453 - Creating password policy with ns-newpolicy.pl on Replicated
593110 - backup-restore does not ALWAYS work
593899 - adding specific ACI causes very large mem allocate request
588867 - entryusn plugin fails on solaris
593899 - adding specific ACI causes very large mem allocate request
595893 - Base DN in SASL mapping is not normalized
511112 - Password history limited to 25 values
597375 - Deleting LDBM database causes backup/restore problem
574101 - MODRDN request never returns - possible deadlock
606920 - anonymous resource limit - nstimelimit -
605827 - In-place upgrade: upgrade dn format should not run in setup-ds-admin.pl
578296 - Attribute type entrydn needs to be added when subtree
609256 - Selinux: pwdhash fails if called via Admin Server CGI
609255 - fix coverity Defect Type: Memory - illegal accesses issues
609255 - fix coverity Defect Type: Memory - illegal accesses issues
609255 - fix coverity Defect Type: Memory - illegal accesses issues
609255 - fix coverity Defect Type: Memory - illegal accesses issues
609255 - fix coverity Defect Type: Memory - illegal accesses issues
609255 - fix coverity Defect Type: Memory - illegal accesses issues
609255 - fix coverity Defect Type: Memory - illegal accesses issues
609255 - fix coverity Defect Type: Memory - illegal accesses issues
609255 - fix coverity Defect Type: Memory - illegal accesses issues
609255 - fix coverity Defect Type: Memory - illegal accesses issues
609255 - fix coverity Defect Type: Memory - illegal accesses issues
609255 - fix coverity Defect Type: Memory - illegal accesses issues
609255 - fix coverity Defect Type: Memory - illegal accesses issues
609255 - fix coverity Defect Type: Memory - illegal accesses issues
609255 - fix coverity Defect Type: Memory - illegal accesses issues
609255 - fix coverity Defect Type: Memory - illegal accesses issues
616618 - 389 v1.2.5 accepts 2 identical entries with different DN formats
610281 - fix coverity Defect Type: Control flow issues
610281 - fix coverity Defect Type: Control flow issues
610281 - fix coverity Defect Type: Control flow issues
610281 - fix coverity Defect Type: Control flow issues
610281 - fix coverity Defect Type: Control flow issues
610281 - fix coverity Defect Type: Control flow issues
610281 - fix coverity Defect Type: Control flow issues
610281 - fix coverity Defect Type: Control flow issues
610281 - fix coverity Defect Type: Control flow issues
610281 - fix coverity Defect Type: Control flow issues
610281 - fix coverity Defect Type: Control flow issues
610281 - fix coverity Defect Type: Control flow issues
610281 - fix coverity Defect Type: Control flow issues
610281 - fix coverity Defect Type: Control flow issues
610281 - fix coverity Defect Type: Control flow issues
610281 - fix coverity Defect Type: Control flow issues
610281 - fix coverity Defect Type: Control flow issues
610281 - fix coverity Defect Type: Control flow issues
610281 - fix coverity Defect Type: Control flow issues
610281 - fix coverity Defect Type: Control flow issues
610281 - fix coverity Defect Type: Control flow issues
610281 - fix coverity Defect Type: Control flow issues
610281 - fix coverity Defect Type: Control flow issues
610281 - fix coverity Defect Type: Control flow issues
610281 - fix coverity Defect Type: Control flow issues
610281 - fix coverity Defect Type: Control flow issues
610281 - fix coverity Defect Type: Control flow issues
610281 - fix coverity Defect Type: Control flow issues
610281 - fix coverity Defect Type: Control flow issues
610281 - fix coverity Defect Type: Control flow issues
610281 - fix coverity Defect Type: Control flow issues
616608 - SIGBUS in RDN index reads on platforms with strict alignments
619595 - Upgrading sub suffix under non-normalized suffix disappears
513166 - Simple Paged result doesn't provide the server's estimate
621928 - Unable to enable replica (rdn problem?) on 1.2.6 rc6
Bug 194531 - db2bak is too noisy
Bug 622628 - fix coverity Defect Type: Integer handling issues
Bug 622628 - fix coverity Defect Type: Integer handling issues
Bug 622628 - fix coverity Defect Type: Integer handling issues
Bug 622903 - fix coverity Defect Type: Code maintainability issues
Bug 622903 - fix coverity Defect Type: Code maintainability issues
Bug 622903 - fix coverity Defect Type: Code maintainability issues
Bug 622903 - fix coverity Defect Type: Code maintainability issues
Bug 622903 - fix coverity Defect Type: Code maintainability issues
Bug 622903 - fix coverity Defect Type: Code maintainability issues
Bug 622903 - fix coverity Defect Type: Code maintainability issues
Bug 622903 - fix coverity Defect Type: Code maintainability issues
Bug 622903 - fix coverity Defect Type: Code maintainability issues
Bug 622903 - fix coverity Defect Type: Code maintainability issues
Bug 622903 - fix coverity Defect Type: Code maintainability issues
Bug 622903 - fix coverity Defect Type: Code maintainability issues
Bug 622903 - fix coverity Defect Type: Code maintainability issues
Bug 622903 - fix coverity Defect Type: Code maintainability issues
Bug 622903 - fix coverity Defect Type: Code maintainability issues
Bug 623118 - Simplepaged results going in infinite loop
Bug 614511 - fix coverity Defect Type: Null pointer dereferences issues 11846 - 11891
Bug 619122 - fix coverity Defect Type: Resource leaks issues CID 11975 - 12051
Bug 617630 - fix coverify Defect Type: Resource leaks issues CID 12052 - 12093
Bug 617630 - fix coverify Defect Type: Resource leaks issues CID 12052 - 12093
Bug 617630 - fix coverity Defect Type: Resource leaks issues CID 12052 - 12093
Bug 613056 - fix coverify Defect Type: Null pointer dereferences issues 11892 - 11939
Bug 616500 - fix coverity Defect Type: Resource leaks issues CID 12094 - 12136
Bug 616500 - fix coverity Defect Type: Resource leaks issues CID 12094 - 12136
Bug 616500 - fix coverity Defect Type: Resource leaks issues CID 12094 - 12136
Bug 614511 - fix coverify Defect Type: Null pointer dereferences issues 11846 - 11891
Bug 613056 - fix coverify Defect Type: Null pointer dereferences issues 11892 - 11939
Bug 613056 - fix coverify Defect Type: Null pointer dereferences issues 11892
Bug 616500 - fix coverity Defect Type: Resource leaks issues
Bug 623507 - fix coverity Defect Type: Incorrect expression issues
Bug 623507 - fix coverity Defect Type: Incorrect expression issues
Bug 613056 - fix coverify Defect Type: Null pointer dereferences
Bug 610119 - fix coverify Defect Type: Null pointer dereferences issues 12167 - 12199
Bug 610119 - fix coverify Defect Type: Null pointer dereferences issues 12167 - 12199
Bug 610119 - fix coverify Defect Type: Null pointer dereferences issues 12167 - 12199
Bug 610119 - fix coverify Defect Type: Null pointer dereferences issues 12167 - 12199
Bug 611790 - fix coverify Defect Type: Null pointer dereferences issues 11940 - 12166
Bug 611790 - fix coverify Defect Type: Null pointer dereferences issues 11940 - 12166
Bug 611790 - fix coverify Defect Type: Null pointer dereferences issues 11940 - 12166
Bug 611790 - fix coverify Defect Type: Null pointer dereferences issues 11940 - 12166
Bug 611790 - fix coverify Defect Type: Null pointer dereferences issues 11940 - 12166
Removed redundant code in agmt_new_from_entry
Bug 617630 - fix coverify Defect Type: Resource leaks issues CID 12052 - 12093
Bug 628300 - DN is not normalized in dn/entry cache when an entry is added, entrydn is not present in search results
Bug 531642 - EntryUSN: RFE: a configuration option to make entryusn "global"
Bug 627738 - The cn=monitor statistics entries for the dnentry cache do not change or change very rarely
DN normalizer should check the invalid type
Bug 627738 - The cn=monitor statistics entries for the dnentry cache
Bug 629710 - escape_string does not check '\<HEX><HEX>'
agmtlist_shutdown (repl5_agmtlist.c) had an illegal access defect.
Bug 633168 - Share backend dbEnv with the replication changelog
Bug 633168 - Share backend dbEnv with the replication changelog
Bug 631862 - crash - delete entries not in cache + referint
Bug 625014 - SubTree Renames: ModRDN operation fails and the server hangs if the entry is moved to "under" the same DN.
Bug 558099 - Enhancement request: Log more information about the search result being a paged one
Bug 635987 - Incorrect sub scope search result with
Bug 606920 - anonymous resource limit- nstimelimit -
Bug 635987 - Incorrect sub scope search result with ACL containing ldap:///self
Bug 639289 - Adding a new CN entry with UpperCase UTF-8 Character
Bug 640027 - Naming attribute with a special char sequence parsing bug
Bug 640854 - changelog db: _cl5WriteOperation: failed to
Bug 637852 - sasl_io_start_packet: failed - read only 3 bytes
Bug 586966 - Sample update script has syntax errors
Bug 586973 - Sample update ldif points to non-existent directory
Bug 602456 - Allow to add any cn=config attributes;
Bug 244229 - targetattr not verified against schema when setting an aci
Bug 643532 - Incorrect DNs sometimes returned on searches
Bug 592397 - Upgrade tool dn2rdn: it does not clean up
Bug 645061 - Upgrade: 06inetorgperson.ldif and 05rfc4524.ldif
Bug 629681 - Retro Changelog trimming does not behave as expected
Bug 644608 - RHDS 8.1->8.2 upgrade fails to properly migrate ACIs
Bug 644608 - RHDS 8.1->8.2 upgrade fails to properly migrate ACIs
Bug 644608 - RHDS 8.1->8.2 upgrade fails to properly migrate ACIs
Bug 638773 - permissions too loose on pid and lock files
Bug 491733 - dbtest crashes
Bug 329751 - "nested" filtered roles searches candidates more
Bug 567282 - server can not abandon searchRequest of "simple paged results"
Bug 572018 - Upgrading from 1.2.5 to 1.2.6.a2 deletes userRoot
Bug 651571 - When attrcrypt is on, entrydn is stored in the backend db
Bug 661918 - 389-ds MMR plugin's changelogdb path logic is incorrect
Bug 182507 - clear-password mod from replica is discarded before changelogged
Bug 602456 - Allow to add any cn=config attributes;
Bug 489379 - passwordExpirationTime in entry being added
Bug 663484 - Entry usn plugin fails to properly tag entries on initialization
Bug 664563 - GER: ger for non-present entry is not correct
Bug 653007 - db2ldif export of clear text passwords lacks storage scheme
Bug 667488 - Cannot recreate numsubordinates index with db2index
Bug 663752 - Cert renewal for attrcrypt and encchangelog
Bug 615100 - log rotationinfo always recreated at startup,
Bug 624442 - MMR: duplicate replica ID
Bug 669205 - db2bak: backed up changelog should include RUVs
Bug 616850 - ldapmodify failed to reject the replace operation
Bug 627993 - Inconsistent storage of password expiry times
Bug 627993 - Inconsistent storage of password expiry times
dn2rdn should respect the DB version info
Bug 646381 - Faulty password for nsmultiplexorcredentials does not give any error message in logs
Bug 624547 - attrcrypt should query the given slot/token for
Bug 668619 - slapd stops responding
Bug 151705 - Need to update Console Cipher Preferences with new ciphers
Bug 615052 - intrinsics and 64-bit atomics code fails to compile
Bug 616213 - insufficient stack size for HP-UX on PA-RISC
Bug 675265 - preventryusn gets added to entries on a failed delete
Bug 604881 - admin server log files have incorrect permissions/ownerships
Bug 676053 - export task followed by import task causes cache assertion
Bug 676053 - export task followed by import task causes cache assertion
Bug 676053 - export task followed by import task causes cache assertion
Bug 450016 - RFE- Console display values in KB/MB/GB
Cancelling commit aef19508c4f618285116d2068655183658f564d9
Bug 625424 - repl-monitor.pl doesn't work in hub node
Bug 679978 - modifying attr value crashes the server, which is supposed to
Bug 681015 - RFE: allow fine grained password policy duration attributes in days, hours, minutes, as well
Bug 668909 - Can't modify replication agreement in some cases
Bug 684996 - Exported tombstone cannot be imported correctly
Bug 681015 - RFE: allow fine grained password policy duration attributes in days, hours, minutes, as well
Bug 689866 - ns-newpwpolicy.pl needs to use the new DN format
Bug 690955 - Mrclone fails due to the replica generation id mismatch
Bug 696407 - If an entry with a mixed case RDN is turned to be
Bug 697027 - 1 - minor memory leaks found by Valgrind + TET
Bug 697027 - 2 - minor memory leaks found by Valgrind + TET
Bug 697027 - 3 - minor memory leaks found by Valgrind + TET
Bug 697027 - 4 - minor memory leaks found by Valgrind + TET
Bug 697027 - 5 - minor memory leaks found by Valgrind + TET
Bug 697027 - 6 - minor memory leaks found by Valgrind + TET
Bug 697027 - 7 - minor memory leaks found by Valgrind + TET
Bug 697027 - 8 - minor memory leaks found by Valgrind + TET
Bug 697027 - 9 - minor memory leaks found by Valgrind + TET
Bug 697027 - 10 - minor memory leaks found by Valgrind + TET
Bug 697027 - 11 - minor memory leaks found by Valgrind + TET
Bug 697027 - 12 - minor memory leaks found by Valgrind + TET
Bug 697027 - 13 - minor memory leaks found by Valgrind + TET
Bug 697027 - 14 - minor memory leaks found by Valgrind + TET
Bug 697027 - 15 - minor memory leaks found by Valgrind + TET
Bug 697027 - 16 - minor memory leaks found by Valgrind + TET
Bug 697027 - 3 - minor memory leaks found by Valgrind + TET
Bug 697027 - 3 - minor memory leaks found by Valgrind + TET
Bug 700215 - ldclt core dumps
Bug 668619 - slapd stops responding
Bug 709826 - Memory leak: when extra referrals configured
Bug 706179 - DS can not restart after create a new objectClass has entryusn attribute
Bug 663752 - Cert renewal for attrcrypt and encchangelog
Bug 663752 - Cert renewal for attrcrypt and encchangelog
Bug 711679 - unresponsive LDAP service when deleting vlv on replica
Bug 711679 - unresponsive LDAP service when deleting vlv on replica
Bug 718303 - Intensive updates on masters could break the consumer's cache
Merge branch '718303'
Bug 719069 - clean up compiler warnings in 389-ds-base 1.2.9
Bug 712855 - Directory Server 8.2 logs "Netscape Portable
Bug 663752 - Cert renewal for attrcrypt and encchangelog
Bug 732153 - subtree and user account lockout policies implemented?
Introducing an environment variable USE_VALGRIND to clean up the entry cache and dn cache on exit.
Bug 744945 - nsslapd-counters attribute value cannot be set to "off"
Keep unhashed password psuedo-attribute in the adding entry
Reduce the number of DN normalization
Bug 745259 - Incorrect entryUSN index under high load
Bug 750622 - Fix Coverity (11104) Resource leak:
Bug 750624 - Fix Coverity (11053) Explicit null dereferenced:
Bug 750625 - Fix Coverity (11066) Unused pointer value
Bug 750625 - Fix Coverity (11065) Uninitialized pointer read
Bug 750625 - Fix Coverity (11064) Dereference before null check
Bug 750625 - Fix Coverity (11061) Resource leak
Bug 750625 - Fix Coverity (11060) Dereference null return value
Bug 750625 - Fix Coverity (11058, 11059) Dereference null return value
Bug 750625 - Fix Coverity (11057) Dereference null return value
Bug 750625 - Fix Coverity (11055) Explicit null dereferenced
Bug 750625 - Fix Coverity (11054) Dereference after null check
Bug 750625 - Fix Coverity (11117) Uninitialized pointer read
Bug 750625 - Fix Coverity (11116) Uninitialized pointer read
Bug 750625 - Fix Coverity (11114, 11115) Uninitialized value use
Bug 750625 - Fix Coverity (11113) Uninitialized pointer read
Bug 750625 - Fix Coverity (11112) Uninitialized pointer read
Bug 750625 - Fix Coverity (11109, 11110, 11111) Uninitialized pointer read
Bug 750625 - Fix Coverity (11108) Sizeof not portable
Bug 750625 - Fix Coverity (11107) Dereference before null check
Bug 750625 - Fix Coverity (11096) Explicit null dereferenced
Bug 750625 - Fix Coverity (11095) Explicit null dereferenced
Bug 750625 - Fix Coverity (11094) Dereference after null check
Bug 750625 - Fix Coverity (11091) Unchecked return value
Bug 750625 - Fix Coverity (11055-2) Explicit null dereferenced
Bug 750625 - Fix Coverity (11062) Resource leak
Bug 750625 - Fix Coverity (11066-2) Unused pointer value
Bug 750625 - Fix Coverity (12195) Dereference after null check
Bug 750625 - Fix Coverity (12196) Dereference before null check
Bug 750625 - Fix Coverity (11066-3) Unused pointer value
Bug 745259 - Incorrect entryUSN index under high load in
Trac Ticket 2 - If node entries are tombstone'd,
Trac Ticket 2 - If node entries are tombstone'd,
Trac Ticket 26 - Please support setting
Trac Ticket 75 - Unconfigure plugin opperations are being called.
Trac Ticket 168 - minssf should not apply to rootdse
Trac Ticket #18 - Data inconsitency during replication
Trac Ticket #52 - FQDN set to nsslapd-listenhost
Trac Ticket 139 - eliminate the use of char *dn in favor of Slapi_DN *dn
Trac Ticket 35 - Log not clear enough on schema errors
Trac Ticket #274 - Reindexing entryrdn fails if
Trac Ticket #275 - Invalid read reported by valgrind
Trac Ticket 51 - memory leaks in 389-ds-base-1.2.8.2-1.el5?
Trac Ticket #26 - Please support setting defaultNamingContext in the rootdse.
Trac Ticket #298 - crash when replicating orphaned tombstone entry
Trac Ticket #290 - server hangs during shutdown if betxn pre/post op fails
Trac Ticket #359 - Database RUV could mismatch the one
Trac Ticket #338 - letters in object's cn get converted to
Trac Ticket #359 - Database RUV could mismatch the one
Ticket #390 - [abrt] 389-ds-base-1.2.10.6-1.fc16: slapi_attr_value_cmp: Process /usr/sbin/ns-slapd was killed by signal 11 (SIGSEGV)
Bug 829213 - unhashed#user#password visible after changing password
Ticket 365 - passwords in clear text in the audit log
Bug 829213 - unhashed#user#password visible after changing password
Bug 829213 - unhashed#user#password visible after changing password
Trac Ticket 396 - Account Usability Control Not Working [Bug 835238]
Trac Ticket #340 - Change on SLAPI_MODRDN_NEWSUPERIOR is not
Rich Megginson (337):
Net::LDAP password modify extop breaks; msgid in response is 0xFF
Clean up assert for entrydn
Bug 543080 - Bitwise plugin fails to return the exact matched entries for Bitwise search filter
Bug 537466 - nsslapd-distribution-plugin should not require plugin name to begin with "lib"
bump version to 1.2.6.a2
Do not use syntax plugins directly for filters, indexing
wrap new style matching rule plugins for use in old style indexing code
change extensible filter code to use new syntax function style mr funcs
change syntax plugins to register required matching rule plugins
crash looking up compat syntax; numeric string syntax using integer; make octet string ordering work correctly
fix memory leak in attr replace when replacement fails
fix dso linking issues found by fedora 13 linking
problems linking with -z defs
389 DS segfaults on libsyntax-plugin.so - part 1
389 DS segfaults on libsyntax-plugin.so - part 2
389 DS segfaults on libsyntax-plugin.so - part 3
Bug 460162 - FedoraDS "with-FHS" installs init.d StartupScript in wrong location on non-RHEL/Fedora OS
Bug 568196 - Install DS8.2 on Solaris fails
Bug 568196 - Install DS8.2 on Solaris fails - part 2
Bug 551198 - LDAPI: incorrect logging to access log
bump version to 1.2.6.a3
fix various memory leaks
Bug 551198 - LDAPI: incorrect logging to access log - part 2
Bug 554573 - ACIs use bind DN from bind req rather than cert mapped DN from sasl/external
cleanup build warnings
Bug 571514 - upgrade to 1.2.6 should upgrade 05rfc4523.ldif (cert schema)
Bug 570905 - postalAddress syntax should allow empty lines (should allow $$)
Add support for additional schema/matching rules included with 389
Bug 572677 - Memory leak in searches including GER control
Bug 571677 - Busy replica on consumers when directly deleting a replication conflict
Bug 576074 - search filters with parentheses fail
Bug 567429 - slapd didn't close connection and get into CLOSE_WAIT state
Bug 578167 - repl. of mod/replace deletes multi-valued attrs
Bug 561575 - setup-ds-admin fails to supply nsds5ReplicaName when configuring via ConfigFile
Bug 572162 - the string "|*" within a search filter on a non-indexed attribute returns all elements.
Bug 576644 - segfault while multimaster replication (paired node won't find deleted entries)
start of 1.2.6.a4
Bug 572018 - Upgrading from 1.2.5 to 1.2.6.a2 deletes userRoot
Fix too few args for format warning in acllas
Bug 586571 - DS Console shows escaped DNs
Bug 591685 - Server instances Fail to Start on Solaris due to Library Path and pcre
bump console version to 1.2.3
Repl Session API needs to check for NULL api before init
Bug 593392 - setup-ds-admin.pl -k creates world readable file
Bug 595874 - 99user.ldif getting overpopulated
bump version to 1.2.6.a5
bump version to 1.2.6.rc1
bump version to 1.2.6.rc2
bump version to 1.2.6.rc3
Bug 604453 - SASL Stress and Server crash: Program quits with the assertion failure in PR_Poll
Bug 604453 - SASL Stress and Server crash: Program quits with the assertion failure in PR_Poll
Bug 603942 - null deref in _ger_parse_control() for subjectdn
bump version to 1.2.6.rc4
Bug 609590 - fix coverity Defect Type: Memory - corruptions issues
Bug 609590 - fix coverity Defect Type: Memory - corruptions issues
Bug 609590 - fix coverity Defect Type: Memory - corruptions issues
Bug 609590 - fix coverity Defect Type: Memory - corruptions issues
Bug 609590 - fix coverity Defect Type: Memory - corruptions issues
Bug 609590 - fix coverity Defect Type: Memory - corruptions issues
Bug 609590 - fix coverity Defect Type: Memory - corruptions issues
Bug 609590 - fix coverity Defect Type: Memory - corruptions issues
Bug 609590 - fix coverity Defect Type: Memory - corruptions issues
Bug 602530 - coverity: op_shared_modify: compare pre, post and original entries before freeing them
Bug 602531 - coverity: op_shared_delete: compare preop entry and GLUE_PARENT_ENTRY before freeing them
Bug 609590 - fix coverity Defect Type: Memory - corruptions issues
Bug 610177 - fix coverity Defect Type: Uninitialized variables issues
Bug 610276 - fix coverity Defect Type: API usage errors issues
Bug 611850 - fix coverity Defect Type: Error handling issues
Bug 614242 - C99/ANSI C++ related compile errors on HP-UX
Bug 547503 - replication broken again, with 389 MMR replication and TCP errors
Bug 617013 - repl-monitor.pl use cpu upto 90%
fix build failures due to libtool problems
Bug 617629 - Missing aliases in new schema files
Bug 617862 - Replication: Unable to delete tombstone errors
bump version to 1.2.7.a1
Bug 610281 - fix coverity Defect Type: Control flow issues - daemon.c:write_function()
Bug 610281 - fix coverity Defect Type: Control flow issues - last repl init status
postalAddress syntax does not accept empty values
ger should support both "dn" and "distinguishedName"
openldap - ldap_url_parse_ext is not part of the public api
fix memleak in ldbm_config_read_instance_entries
Add -x option to ldap tools when using openldap
openldap - add support for missing controls, add ldif api, fix NSS usage
port client tools to use openldap API
use the mozldap versions of the proxy auth control create function
document slapi wrappers for openldap/mozldap functions that differ
fix some compiler warnings
use strcasecmp with ptype and type->bv_val
ber_printf 'o' cannot handle NULL bv_val
fix the url_parse logic when looking for a missing suffix DN
openldap ldapsearch uses -LLL to suppress # version: N
add ldaptool_opts for the non BUNDLE case in Makefile.am
openldap ldapsearch returns empty line at end of LDIF output
have to use LDAP_OPT_X_TLS_NEVER to defeat cert hostname checking
openldap_read_function needs to set EWOULDBLOCK if the buffer is empty
do not terminate unwrapped LDIF line with another newline
slapi_ldap_url_parse must handle multiple host:port in url
convert mozldap host list to openldap uri list
move the out pointer back if continuation lines were removed
check src < *out only; only check for \nspace if src < *out - 2
use slapi_ldap_url_parse in the acl code
do not un-null-terminate normalized DN until new url is constructed
implement slapi_ldap_explode_dn and slapi_ldap_explode_rdn
use slapi_pblock_set to set the ldap result code for the be postop plugins
pass the string copy to slapi_dn_normalize_original
bug 614511 - fix coverity null reference - revert macro aci $dn logic
fix compiler warnings - unused vars/funcs, invalid casts
use slapi_mods_init_passin/get_ldapmods_passout if modifying the smods
Have to explicitly set protocol version to 3
Only check modrdn ops for backend/suffix correctness if not the default backend
Bug 634561 - Server crushes when using Windows Sync Agreement
openldap ber_init will assert if the bv->bv_val is NULL
add the account policy plugin and related server code, schema, and config
fix pblock memory leak
do not register pre/post op plugins if disabled
add support for global inactivity limit
fix typos in Makefile.am, acctpolicy schema
bump version to 1.2.7.a2
remove extra format argument; use %lu for size_t printf format
Bug 644013 - uniqueness plugin segfault bug
bump version to 1.2.7.a3
bump to 1.2.7.a4
bump version to 1.2.7.a5
put replication config entries in separate file
bump version to 1.2.7.a6
bump version to 1.2.7.1
bump version to 1.2.7.2
bump version to 1.2.7.3
bump version to 1.2.7.4
Bug 515329 - Multiple mods in one operation can result in an inconsistent replica
bump version to 1.2.8.a1
Bug 642046 - Segfault when using SASL/GSSAPI multimaster replication, possible krb5_creds doublefree
Bug 624485 - setup dsktune check step should default to "yes" if no problems found
Bug 622907 - support piped passwords to perl-based maintenance commands
Bug 624485 - setup dsktune check step should default to "yes" if no problems found
Bug 576534 - Password displayed on console when entered in command-line utilities
Bug 667935 - DS pipe log script's logregex.py plugin is not redirecting the log output to the text file
bump version to 1.2.8.a2
Bug 668385 - DS pipe log script is executed as many times as the dirsrv service is restarted
Bug 676689 - crash while adding a new user to be synced to windows
Bug 675113 - ns-slapd core dump in windows_tot_run if oneway sync is used
Bug 677440 - clean up compiler warnings in 389-ds-base 1.2.8
Bug 677774 - DS fails to start after reboot
Bug 666076 - dirsrv crash (1.2.7.5) with multiple simple paged result searches
Bug 675320 - empty modify operation with repl on or lastmod off will crash server
bump version to 1.2.9.a1 - console version to 1.2.4
Bug 677705 - ds-logpipe.py script is failing to validate "-s" and "--serverpid" options with "-t".
Bug 676655 - winsync stops working after server restart
Bug 680555 - ns-slapd segfaults if I have more than 100 DBs
Bug 514190 - setup-ds-admin.pl --debug does not log to file
Bug 518890 - setup-ds-admin.pl - improve hostname validation
Bug 644784 - Memory leak in "testbind.c" plugin
Bug 683250 - slapd crashing when traffic replayed
Bug 690584 - #10691 ldbm_back_init() - fix coverity resource leak issues
Bug 690584 - #10690 #10689 attrcrypt_get_ssl_cert_name() - fix coverity resource leak issues
Bug 690584 - #10688 - dblayer_make_env - fix coverity resource leak issues
Bug 690584 - #10669 #10668 cl5ImportLDIF - fix coverity resource leak issues
Bug 690584 - #10658 linked_attrs_pre_op - fix coverity resource leak issues
Bug 690584 - #10655 acllas__handle_group_entry - fix coverity resource leak issues
Bug 690584 - #10654 #10653 str2entry_dupcheck - fix coverity resource leak issues
Bug 690584 - #10652 #10651 #10650 #10649 #10648 #10647 send_specific_attrs send_all_attrs - fix coverity resource leak issues
Bug 690584 - #10643 hash_rootpw - fix coverity resource leak issues
Bug 690584 - #10641 reslimit_bv2int - fix coverity resource leak issues
Bug 691422 - sdt_destroy - fix coverity control flow issues
Bug 691422 - ldbm_back_upgradedb - fix coverity control flow issues
Bug 691422 - csnplFree - fix coverity control flow issues
Bug 691422 - SetUnicodeStringFromUTF_8 - fix coverity control flow issues
Bug 691422 - cl5DeleteRUV - fix coverity control flow issues
Bug 691422 - acl_read_access_allowed_on_entry - fix coverity control flow issues
Bug 691422 - search_internal_callback_pb - fix coverity control flow issues
Bug 691422 - cl5WriteRUV - fix coverity control flow issues
Bug 691422 - windows_replay_update - fix coverity control flow issues
Bug 690584 - #10691 ldbm_back_init() - fix coverity resource leak issues
Bug 690584 - #10652 #10651 #10650 #10649 #10648 #10647 send_specific_attrs send_all_attrs - fix coverity resource leak issues
Bug 668385 - DS pipe log script is executed as many times as the dirsrv service is restarted
Bug 692937 - Replica install fails after step for "enable GSSAPI for replication"
Bug 692331 - Segfault on index update during full replication push on 1.2.7.5
Bug 693451 - cannot use localized matching rules
Bug 693455 - nsMatchingRule does not work with multiple values
Bug 693503 - matching rules do not inherit from superior attribute type
Bug 693466 - Unable to change schema online
Bug 692991 - rhds82 - windows_tot_run: failed to obtain data to send to the consumer; LDAP error - -1
Bug 693473 - rhds82 rfe - windows_tot_run to log Sizelimit exceeded instead of LDAP error - -1
Bug 693962 - Full replica push loses some entries with multi-valued RDNs
Bug 694336 - Group sync hangs Windows initial Sync
Bug 700145 - userpasswd not replicating
Bug 703990 - Support upgrade from Red Hat Directory Server
bump console version to 1.2.5
Bug 703990 - Support upgrade from Red Hat Directory Server
Bug 703990 - Support upgrade from Red Hat Directory Server
Bug 707015 - Cannot disable SSLv3 and use TLS only
bump version to 1.2.9.a2
Bug 707384 - only allow FIPS approved cipher suites in FIPS mode
Bug 711906 - ns-slapd segfaults using suffix referrals
Bug 706209 - LEGAL: RHEL6.1 License issue for 389-ds-base package
Bug 703703 - setup-ds-admin.pl asks for legal agreement to a non-existant file
Bug 711679 - unresponsive LDAP service when deleting vlv on replica
bump console version to 1.2.6
Bug 697694 - rhds82 - incr update state stop_fatal_error "requires administrator action", with extop_result: 9
Bug 716980 - winsync uses old AD entry if new one not found
add support for ldif files with changetype: add
writing Inf file shows SchemaFile = ARRAY(0xhexnum)
look for separate openldap ldif library
bump version to 1.2.9.a3
Bug 709468 - RSA Authentication Server timeouts when using simple paged results on RHDS 8.2.
Bug 720059 - RDN with % can cause crashes or missing entries
bump version to 1.2.9.0
Bug 725542 - Instance upgrade fails when upgrading 389-ds-base package
Bug 725953 - Winsync: DS entries fail to sync to AD, if the User's CN entry contains a comma
Bug 723937 - replication failing on RUV errors
bump version to 1.2.9.1
Bug 727511 - ldclt SSL search requests are failing with "illegal error number -1" error
bump version to 1.2.9.2
Bug 727511 - ldclt SSL search requests are failing with "illegal error numbe
bump version to 1.2.9.3
Bug 727511 - ldclt SSL search requests are failing with "illegal error number -1" error
bump version to 1.2.9.4
Bug 727511 - ldclt SSL search requests are failing with "illegal error number -1" error
bump version to 1.2.9.5
Bug 729378 - delete user subtree container in AD + modify password in DS == DS crash
Bug 723937 - replication failing on RUV errors
Bug 729369 - upgrade DB to upgrade from entrydn to entryrdn format is not working.
make sure the DBVERSION file ends in a newline
bump version to 1.2.10.a1
Bug 633803 - passwordisglobalpolicy attribute brakes TLS chaining
Bug 733103 - large targetattr list with syntax errors cause server to crash or hang
Bug 703990 - cross-platform - Support upgrade from Red Hat Directory Server
Bug 735121 - simple paged search + ip/dns based ACI hangs server
Bug 695736 - Providing native systemd file for upcoming F15 Feature Systemd
Bug 590826 - Reloading database from ldif causes changelog to emit "data no longer matches" errors
Bug 736712 - Modifying ruv entry deadlocks server
Add support for pre/post db transaction plugins
Make all backend operations transaction aware
Bug 741744 - MOD operations with chained delete/add get back error 53 on backend config
Bug 742324 - allow nsslapd-idlistscanlimit to be set dynamically and per-user
Bug 741744 - part2 - MOD operations with chained delete/add get back error 53 on backend config
Bug 740942 - allow resource limits to be set for paged searches independently of limits for other searches/operations
bump version to 1.2.10.a2
bump version to 1.2.10.a3
fix transaction support in ldbm_delete
bump version to 1.2.10.a4
set the ENTRY_POST_OP for modrdn betxnpostoperation plugins
pass the plugin config entry to the plugin init function
make memberof transaction aware and able to be a betxnpostoperation plugin
Bug 741744 - part3 - MOD operations with chained delete/add get back error 53
bump version to 1.2.10.a5
Change referential integrity to be a betxnpostoperation plugin
Use new PLUGIN_CONFIG_ENTRY feature to allow switching between txn and regular
Bug 748575 - rhds81 modrn operation and 100% cpu use in replication
Bug 748575 - part 2 - rhds81 modrdn operation and 100% cpu use in replication
Bug 751495 - 'setup-ds.pl -u' fails with undefined routine 'updateSystemD'
bump version to 1.2.10.a6
Bug 751645 - crash when simple paged fails to send entry to client
csn_as_string - use slapi_uN_to_hex instead of sprintf
uniqueid formatting - use slapi_u8_to_hex instead of sprintf
fix member variable name error in slapi_uniqueIDFormat
reduce calls to csn_as_string and slapi_log_error
csn_init_as_string should not use sscanf
use slapi_hexchar2int and slapi_str_to_u8 everywhere
Bug 755754 - Unable to start dirsrv service using systemd
Bug 755725 - 389 programs linked against openldap crash during shutdown
Ticket 1 - pre-normalize filter and pre-compile substring regex - and other optimizations
Ticket #162 - Infinite loop / spin inside strcmpi_fast, acl_read_access_allowed_on_attr, server DoS
bak2db gets stuck in infinite loop
Ticket #256 - debug build assertion in ACL_EvalDestroy()
bump version to 1.2.10.a7
Ticket #167 - Mixing transaction and non-transaction plugins can cause deadlock
fix mep sdn compiler warnings
add a hack to disable sasl hostname canonicalization - helps with testing when you don't want to set up correct host name resolution and/or cannot set the default system hostname
Ticket #12 - 389 DS DNA Plugin / Replication failing on GSSAPI
Ticket #257 - repl-monitor doesn't work if leftmost hostnames are the same
fix recent compiler warnings
Ticket #15 - Get rid of rwlock.h/rwlock.c and just use slapi_rwlock instead
fix compiler warnings
Remove redundant code - make a global into a static
Ticket #262 - pid file not removed with systemd
fix mozldap build issues
Ticket #264 - upgrade needs better check for "server is running"
Ticket #263 - add systemd include directive
bump version to 1.2.10.rc1
change version to 1.2.10.a8
Ticket #272 - add tombstonenumsubordinates to schema
bump version to 1.2.10.rc1
Ticket #161 - Review and address latest Coverity issues
Ticket #22 - RFE: Support sendmail LDAP routing schema
Ticket #29 - Samba3-schema is missing sambaTrustedDomainPassword
Ticket #273 - ruv tombstone searches don't work after reindex entryrdn
Ticket #273 - ruv tombstone searches don't work after reindex entryrdn
fix a couple of minor coverity issues
Ticket #87 - Manpages fixes
Ticket #13 - slapd process exits when put the database on read only mode while updates are coming to the server
Ticket #55 - Limit of 1024 characters for nsMatchingRule
Ticket #277 - cannot set repl referrals or state
Ticket #278 - Schema replication update failed: Invalid syntax
Ticket #277 - cannot set repl referrals or state
Ticket #279 - filter normalization does not use matching rules
Ticket #280 - extensible binary filters do not work
Ticket #281 - TLS not working with latest openldap
coverity 12488 Resource leak In attr_index_config(): Leak of memory or pointers to system resources
bump version to 1.2.10.rc2
bump version to 1.2.10.0
Ticket #294 - 389 DS Segfaults during replica install in FreeIPA
Ticket #281 - TLS not working with latest openldap
Trac Ticket #298 - crash when replicating orphaned tombstone entry
bump version to 1.2.10.2
handle null smods
memleak in mep_parse_config_entry
memleak in normalize_mods2bvals
bump version to 1.2.10.3
Ticket #305 - Certain CMP operations hang or cause ns-slapd to crash
bump version to 1.2.10.4
Bug 808770 - [abrt] 389-ds-base-1.2.10.4-2.fc16: index_range_read_ext: Process /usr/sbin/ns-slapd was killed by signal 11 (SIGSEGV)
Ticket #336 - [abrt] 389-ds-base-1.2.10.4-2.fc16: index_range_read_ext: Process /usr/sbin/ns-slapd was killed by signal 11 (SIGSEGV)
bump version to 1.2.10.5
Ticket #336 - [abrt] 389-ds-base-1.2.10.4-2.fc16: index_range_read_ext: Process /usr/sbin/ns-slapd was killed by signal 11 (SIGSEGV)
bump version to 1.2.10.6
Ticket #347 - IPA dirsvr seg-fault during system longevity test
Ticket #348 - crash in ldap_initialize with multiple threads
bump version to 1.2.10.7
Ticket #348 - crash in ldap_initialize with multiple threads
bump version to 1.2.10.8
Trac Ticket #359 - Database RUV could mismatch the one in changelog under the stress
Ticket #382 - DS Shuts down intermittently
bump version to 1.2.10.10
bump version to 1.2.10.11
Ticket 378 - unhashed#user#password visible after changing password
bump version to 1.2.10.12
Ticket #405 - referint modrdn not working if case is different
Ticket #406 - Impossible to rename entry (modrdn) with Attribute Uniqueness plugin enabled
bump version to 1.2.10.13
Ticket #410 - Referential integrity plug-in does not work when update interval is not zero
bump version to 1.2.10.14
Ticket #353 - coverity 12625-12629 - leaks, dead code, unchecked return
CLEANALLRUV - remove calls to agmt_get_enabled because this feature is not in 1.2.10
COVERITY FIXES in replica_execute_cleanall_ruv_task
Ticket #491 - multimaster_extop_cleanruv returns wrong error codes
bump version to 1.2.10.15
nturpin (1):
Ticket #3: acl cache overflown problem
root (2):
Bug 480787 - Autoconf parameter --with and --without
Ticket #337 - RFE - Improve CLEANRUV functionality
---
.gitignore | 1
Makefile.am | 262
Makefile.in | 5216 -
README | 11
VERSION.sh | 7
aclocal.m4 | 6996 --
compile | 21
config.guess | 302
config.h.in | 22
config.sub | 232
configure |41932 +++++-------
configure.ac | 176
depcomp | 172
dirsrv.pc.in | 7
include/base/dbtbase.h | 2
include/base/file.h | 3
include/base/lexer.h | 126
include/base/rwlock.h | 91
include/i18n.h | 115
include/ldaputil/ldaputil.h | 10
include/libaccess/aclerror.h | 1
include/libaccess/aclproto.h | 15
include/libaccess/aclstruct.h | 2
include/libaccess/dbtlibaccess.h | 3
include/public/nsacl/aclapi.h | 7
install-sh | 517
ldap/admin/src/base-initconfig.in | 44
ldap/admin/src/initconfig.in | 37
ldap/admin/src/logconv.pl | 639
ldap/admin/src/scripts/10cleanupldapi.pl | 23
ldap/admin/src/scripts/10fixrundir.pl | 11
ldap/admin/src/scripts/50acctusabilityplugin.ldif | 21
ldap/admin/src/scripts/50automemberplugin.ldif | 15
ldap/admin/src/scripts/50fixNsState.pl | 240
ldap/admin/src/scripts/50managedentriesplugin.ldif | 16
ldap/admin/src/scripts/50refintprecedence.ldif | 4
ldap/admin/src/scripts/50smd5pwdstorageplugin.ldif | 5
ldap/admin/src/scripts/60upgradeschemafiles.pl | 2
ldap/admin/src/scripts/70upgradefromldif.pl | 108
ldap/admin/src/scripts/80upgradednformat.pl | 206
ldap/admin/src/scripts/81changelog.pl | 34
ldap/admin/src/scripts/90subtreerename.pl | 21
ldap/admin/src/scripts/91subtreereindex.pl | 148
ldap/admin/src/scripts/DSCreate.pm.in | 323
ldap/admin/src/scripts/DSDialogs.pm | 4
ldap/admin/src/scripts/DSMigration.pm.in | 47
ldap/admin/src/scripts/DSUpdate.pm.in | 50
ldap/admin/src/scripts/DSUtil.pm.in | 247
ldap/admin/src/scripts/DialogManager.pm | 241
ldap/admin/src/scripts/DialogManager.pm.in | 241
ldap/admin/src/scripts/Inf.pm | 67
ldap/admin/src/scripts/Migration.pm.in | 20
ldap/admin/src/scripts/Setup.pm.in | 20
ldap/admin/src/scripts/SetupDialogs.pm.in | 31
ldap/admin/src/scripts/SetupLog.pm | 8
ldap/admin/src/scripts/ds-logpipe.py | 221
ldap/admin/src/scripts/exampleupdate.ldif | 2
ldap/admin/src/scripts/exampleupdate.sh | 10
ldap/admin/src/scripts/logregex.py | 16
ldap/admin/src/scripts/migrate-ds.pl.in | 13
ldap/admin/src/scripts/remove-ds.pl.in | 28
ldap/admin/src/scripts/repl-monitor.pl.in | 86
ldap/admin/src/scripts/restart-dirsrv.in | 25
ldap/admin/src/scripts/setup-ds.pl.in | 7
ldap/admin/src/scripts/setup-ds.res.in | 35
ldap/admin/src/scripts/start-dirsrv.in | 43
ldap/admin/src/scripts/stop-dirsrv.in | 27
ldap/admin/src/scripts/template-bak2db.in | 49
ldap/admin/src/scripts/template-bak2db.pl.in | 29
ldap/admin/src/scripts/template-cleanallruv.pl.in | 186
ldap/admin/src/scripts/template-db2bak.in | 53
ldap/admin/src/scripts/template-db2bak.pl.in | 29
ldap/admin/src/scripts/template-db2index.in | 14
ldap/admin/src/scripts/template-db2index.pl.in | 33
ldap/admin/src/scripts/template-db2ldif.in | 15
ldap/admin/src/scripts/template-db2ldif.pl.in | 29
ldap/admin/src/scripts/template-dbverify.in | 15
ldap/admin/src/scripts/template-dn2rdn.in | 25
ldap/admin/src/scripts/template-fixup-linkedattrs.pl.in | 29
ldap/admin/src/scripts/template-fixup-memberof.pl.in | 29
ldap/admin/src/scripts/template-ldif2db.in | 15
ldap/admin/src/scripts/template-ldif2db.pl.in | 29
ldap/admin/src/scripts/template-ldif2ldap.in | 19
ldap/admin/src/scripts/template-monitor.in | 19
ldap/admin/src/scripts/template-ns-accountstatus.pl.in | 33
ldap/admin/src/scripts/template-ns-activate.pl.in | 33
ldap/admin/src/scripts/template-ns-inactivate.pl.in | 33
ldap/admin/src/scripts/template-ns-newpwpolicy.pl.in | 47
ldap/admin/src/scripts/template-restart-slapd.in | 2
ldap/admin/src/scripts/template-restoreconfig.in | 15
ldap/admin/src/scripts/template-saveconfig.in | 15
ldap/admin/src/scripts/template-schema-reload.pl.in | 29
ldap/admin/src/scripts/template-start-slapd.in | 3
ldap/admin/src/scripts/template-stop-slapd.in | 2
ldap/admin/src/scripts/template-suffix2instance.in | 15
ldap/admin/src/scripts/template-syntax-validate.pl.in | 29
ldap/admin/src/scripts/template-upgradedb.in | 15
ldap/admin/src/scripts/template-upgradednformat.in | 63
ldap/admin/src/scripts/template-usn-tombstone-cleanup.pl.in | 29
ldap/admin/src/scripts/template-verify-db.pl.in | 19
ldap/admin/src/scripts/template-vlvindex.in | 15
ldap/admin/src/slapd.inf.in | 2
ldap/admin/src/template-initconfig.in | 18
ldap/docs/LICENSE.txt | 132
ldap/docs/README.txt | 11
ldap/include/ldaplog.h | 32
ldap/ldif/50replication-plugins.ldif | 26
ldap/ldif/template-baseacis.ldif.in | 2
ldap/ldif/template-bitwise.ldif.in | 6
ldap/ldif/template-dse.ldif.in | 96
ldap/ldif/template-suffix-db.ldif.in | 1
ldap/schema/00core.ldif | 72
ldap/schema/01core389.ldif | 24
ldap/schema/02common.ldif | 12
ldap/schema/05rfc4523.ldif | 14
ldap/schema/05rfc4524.ldif | 30
ldap/schema/06inetorgperson.ldif | 5
ldap/schema/10automember-plugin.ldif | 123
ldap/schema/10mep-plugin.ldif | 104
ldap/schema/30ns-common.ldif | 4
ldap/schema/50ns-directory.ldif | 4
ldap/schema/60acctpolicy.ldif | 47
ldap/schema/60nis.ldif | 2
ldap/schema/60qmail.ldif | 4
ldap/schema/60samba3.ldif | 34
ldap/schema/60sendmail.ldif | 54
ldap/schema/60sudo.ldif | 58
ldap/servers/plugins/acct_usability/acct_usability.c | 464
ldap/servers/plugins/acct_usability/acct_usability.h | 63
ldap/servers/plugins/acctpolicy/acct_config.c | 143
ldap/servers/plugins/acctpolicy/acct_init.c | 191
ldap/servers/plugins/acctpolicy/acct_plugin.c | 316
ldap/servers/plugins/acctpolicy/acct_util.c | 257
ldap/servers/plugins/acctpolicy/acctpolicy.h | 81
ldap/servers/plugins/acctpolicy/sampleconfig.ldif | 40
ldap/servers/plugins/acctpolicy/samplepolicy.ldif | 27
ldap/servers/plugins/acl/acl.c | 280
ldap/servers/plugins/acl/acl.h | 48
ldap/servers/plugins/acl/acl_ext.c | 152
ldap/servers/plugins/acl/aclanom.c | 13
ldap/servers/plugins/acl/acleffectiverights.c | 116
ldap/servers/plugins/acl/aclgroup.c | 21
ldap/servers/plugins/acl/aclinit.c | 2
ldap/servers/plugins/acl/acllas.c | 400
ldap/servers/plugins/acl/acllist.c | 123
ldap/servers/plugins/acl/aclparse.c | 615
ldap/servers/plugins/acl/aclplugin.c | 37
ldap/servers/plugins/acl/aclproxy.c | 232
ldap/servers/plugins/acl/aclutil.c | 110
ldap/servers/plugins/automember/automember.c | 1930
ldap/servers/plugins/automember/automember.h | 134
ldap/servers/plugins/bitwise/bitwise.c | 23
ldap/servers/plugins/chainingdb/cb.h | 8
ldap/servers/plugins/chainingdb/cb_add.c | 105
ldap/servers/plugins/chainingdb/cb_bind.c | 196
ldap/servers/plugins/chainingdb/cb_compare.c | 101
ldap/servers/plugins/chainingdb/cb_config.c | 37
ldap/servers/plugins/chainingdb/cb_conn_stateless.c | 102
ldap/servers/plugins/chainingdb/cb_controls.c | 36
ldap/servers/plugins/chainingdb/cb_delete.c | 125
ldap/servers/plugins/chainingdb/cb_init.c | 6
ldap/servers/plugins/chainingdb/cb_instance.c | 325
ldap/servers/plugins/chainingdb/cb_modify.c | 133
ldap/servers/plugins/chainingdb/cb_modrdn.c | 176
ldap/servers/plugins/chainingdb/cb_monitor.c | 6
ldap/servers/plugins/chainingdb/cb_schema.c | 4
ldap/servers/plugins/chainingdb/cb_search.c | 223
ldap/servers/plugins/chainingdb/cb_utils.c | 15
ldap/servers/plugins/collation/collate.c | 24
ldap/servers/plugins/collation/orfilter.c | 19
ldap/servers/plugins/cos/cos_cache.c | 769
ldap/servers/plugins/deref/deref.c | 20
ldap/servers/plugins/dna/dna.c | 908
ldap/servers/plugins/http/http_impl.c | 81
ldap/servers/plugins/linkedattrs/fixup_task.c | 154
ldap/servers/plugins/linkedattrs/linked_attrs.c | 284
ldap/servers/plugins/linkedattrs/linked_attrs.h | 6
ldap/servers/plugins/memberof/memberof.c | 841
ldap/servers/plugins/memberof/memberof.h | 8
ldap/servers/plugins/memberof/memberof_config.c | 242
ldap/servers/plugins/mep/mep.c | 2862
ldap/servers/plugins/mep/mep.h | 130
ldap/servers/plugins/pam_passthru/pam_passthru.h | 2
ldap/servers/plugins/pam_passthru/pam_ptconfig.c | 2
ldap/servers/plugins/pam_passthru/pam_ptimpl.c | 32
ldap/servers/plugins/pam_passthru/pam_ptpreop.c | 9
ldap/servers/plugins/passthru/passthru.h | 4
ldap/servers/plugins/passthru/ptbind.c | 6
ldap/servers/plugins/passthru/ptconfig.c | 43
ldap/servers/plugins/passthru/ptconn.c | 8
ldap/servers/plugins/passthru/ptpreop.c | 17
ldap/servers/plugins/pwdstorage/smd5_pwd.c | 9
ldap/servers/plugins/referint/referint.c | 765
ldap/servers/plugins/replication/cl4_api.c | 2
ldap/servers/plugins/replication/cl5.h | 1
ldap/servers/plugins/replication/cl5_api.c | 2839
ldap/servers/plugins/replication/cl5_api.h | 122
ldap/servers/plugins/replication/cl5_clcache.c | 55
ldap/servers/plugins/replication/cl5_clcache.h | 2
ldap/servers/plugins/replication/cl5_config.c | 247
ldap/servers/plugins/replication/cl5_init.c | 2
ldap/servers/plugins/replication/cl5_test.c | 2
ldap/servers/plugins/replication/cl_crypt.c | 203
ldap/servers/plugins/replication/cl_crypt.h | 53
ldap/servers/plugins/replication/csnpl.c | 74
ldap/servers/plugins/replication/legacy_consumer.c | 31
ldap/servers/plugins/replication/llist.c | 8
ldap/servers/plugins/replication/repl-session-plugin.h | 119
ldap/servers/plugins/replication/repl.h | 2
ldap/servers/plugins/replication/repl5.h | 126
ldap/servers/plugins/replication/repl5_agmt.c | 412
ldap/servers/plugins/replication/repl5_agmtlist.c | 110
ldap/servers/plugins/replication/repl5_connection.c | 194
ldap/servers/plugins/replication/repl5_inc_protocol.c | 113
ldap/servers/plugins/replication/repl5_init.c | 138
ldap/servers/plugins/replication/repl5_mtnode_ext.c | 13
ldap/servers/plugins/replication/repl5_plugins.c | 201
ldap/servers/plugins/replication/repl5_prot_private.h | 4
ldap/servers/plugins/replication/repl5_protocol.c | 107
ldap/servers/plugins/replication/repl5_protocol_util.c | 509
ldap/servers/plugins/replication/repl5_replica.c | 731
ldap/servers/plugins/replication/repl5_replica_config.c | 2257
ldap/servers/plugins/replication/repl5_replica_dnhash.c | 26
ldap/servers/plugins/replication/repl5_replica_hash.c | 30
ldap/servers/plugins/replication/repl5_ruv.c | 521
ldap/servers/plugins/replication/repl5_ruv.h | 20
ldap/servers/plugins/replication/repl5_tot_protocol.c | 32
ldap/servers/plugins/replication/repl5_total.c | 22
ldap/servers/plugins/replication/repl5_updatedn_list.c | 2
ldap/servers/plugins/replication/repl_bind.c | 6
ldap/servers/plugins/replication/repl_compare.c | 18
ldap/servers/plugins/replication/repl_connext.c | 2
ldap/servers/plugins/replication/repl_controls.c | 2
ldap/servers/plugins/replication/repl_extop.c | 673
ldap/servers/plugins/replication/repl_globals.c | 7
ldap/servers/plugins/replication/repl_init.c | 1
ldap/servers/plugins/replication/repl_objset.c | 9
ldap/servers/plugins/replication/repl_session_plugin.c | 188
ldap/servers/plugins/replication/repl_shared.h | 17
ldap/servers/plugins/replication/replutil.c | 107
ldap/servers/plugins/replication/test_repl_session_plugin.c | 335
ldap/servers/plugins/replication/urp.c | 222
ldap/servers/plugins/replication/urp.h | 11
ldap/servers/plugins/replication/urp_glue.c | 14
ldap/servers/plugins/replication/urp_tombstone.c | 21
ldap/servers/plugins/replication/windows_connection.c | 166
ldap/servers/plugins/replication/windows_inc_protocol.c | 55
ldap/servers/plugins/replication/windows_private.c | 128
ldap/servers/plugins/replication/windows_protocol_util.c | 677
ldap/servers/plugins/replication/windows_tot_protocol.c | 125
ldap/servers/plugins/replication/windowsrepl.h | 14
ldap/servers/plugins/replication/winsync-plugin.h | 2
ldap/servers/plugins/retrocl/retrocl.c | 3
ldap/servers/plugins/retrocl/retrocl.h | 2
ldap/servers/plugins/retrocl/retrocl_create.c | 13
ldap/servers/plugins/retrocl/retrocl_po.c | 23
ldap/servers/plugins/retrocl/retrocl_trim.c | 20
ldap/servers/plugins/rever/des.c | 72
ldap/servers/plugins/rever/rever.c | 8
ldap/servers/plugins/roles/roles_cache.c | 128
ldap/servers/plugins/schema_reload/schema_reload.c | 5
ldap/servers/plugins/shared/plugin-utils.h | 112
ldap/servers/plugins/shared/utils.c | 508
ldap/servers/plugins/statechange/statechange.c | 26
ldap/servers/plugins/syntaxes/bin.c | 142
ldap/servers/plugins/syntaxes/bitstring.c | 68
ldap/servers/plugins/syntaxes/ces.c | 172
ldap/servers/plugins/syntaxes/cis.c | 321
ldap/servers/plugins/syntaxes/deliverymethod.c | 32
ldap/servers/plugins/syntaxes/dn.c | 72
ldap/servers/plugins/syntaxes/facsimile.c | 32
ldap/servers/plugins/syntaxes/guide.c | 32
ldap/servers/plugins/syntaxes/int.c | 96
ldap/servers/plugins/syntaxes/nameoptuid.c | 72
ldap/servers/plugins/syntaxes/numericstring.c | 148
ldap/servers/plugins/syntaxes/sicis.c | 32
ldap/servers/plugins/syntaxes/string.c | 402
ldap/servers/plugins/syntaxes/syntax.h | 61
ldap/servers/plugins/syntaxes/syntax_common.c | 118
ldap/servers/plugins/syntaxes/tel.c | 94
ldap/servers/plugins/syntaxes/teletex.c | 32
ldap/servers/plugins/syntaxes/telex.c | 31
ldap/servers/plugins/syntaxes/validate.c | 17
ldap/servers/plugins/syntaxes/value.c | 120
ldap/servers/plugins/uiduniq/7bit.c | 52
ldap/servers/plugins/uiduniq/plugin-utils.h | 96
ldap/servers/plugins/uiduniq/uid.c | 353
ldap/servers/plugins/uiduniq/utils.c | 256
ldap/servers/plugins/usn/usn.c | 176
ldap/servers/plugins/usn/usn.h | 3
ldap/servers/plugins/usn/usn_cleanup.c | 31
ldap/servers/plugins/views/views.c | 27
ldap/servers/slapd/abandon.c | 7
ldap/servers/slapd/add.c | 186
ldap/servers/slapd/agtmmap.c | 56
ldap/servers/slapd/attr.c | 93
ldap/servers/slapd/attrlist.c | 7
ldap/servers/slapd/attrsyntax.c | 143
ldap/servers/slapd/auditlog.c | 86
ldap/servers/slapd/auth.c | 59
ldap/servers/slapd/ava.c | 2
ldap/servers/slapd/back-ldbm/ancestorid.c | 104
ldap/servers/slapd/back-ldbm/archive.c | 91
ldap/servers/slapd/back-ldbm/back-ldbm.h | 96
ldap/servers/slapd/back-ldbm/backentry.c | 2
ldap/servers/slapd/back-ldbm/cache.c | 83
ldap/servers/slapd/back-ldbm/dbhelp.c | 12
ldap/servers/slapd/back-ldbm/dblayer.c | 1614
ldap/servers/slapd/back-ldbm/dblayer.h | 14
ldap/servers/slapd/back-ldbm/dbtest.c | 349
ldap/servers/slapd/back-ldbm/dbversion.c | 52
ldap/servers/slapd/back-ldbm/dn2entry.c | 63
ldap/servers/slapd/back-ldbm/filterindex.c | 244
ldap/servers/slapd/back-ldbm/findentry.c | 147
ldap/servers/slapd/back-ldbm/id2entry.c | 175
ldap/servers/slapd/back-ldbm/idl.c | 35
ldap/servers/slapd/back-ldbm/idl_common.c | 7
ldap/servers/slapd/back-ldbm/idl_new.c | 111
ldap/servers/slapd/back-ldbm/idl_shim.c | 17
ldap/servers/slapd/back-ldbm/import-merge.c | 28
ldap/servers/slapd/back-ldbm/import-threads.c | 1366
ldap/servers/slapd/back-ldbm/import.c | 403
ldap/servers/slapd/back-ldbm/import.h | 32
ldap/servers/slapd/back-ldbm/index.c | 283
ldap/servers/slapd/back-ldbm/init.c | 89
ldap/servers/slapd/back-ldbm/instance.c | 174
ldap/servers/slapd/back-ldbm/ldbm_add.c | 245
ldap/servers/slapd/back-ldbm/ldbm_attr.c | 392
ldap/servers/slapd/back-ldbm/ldbm_attrcrypt.c | 986
ldap/servers/slapd/back-ldbm/ldbm_attrcrypt_config.c | 2
ldap/servers/slapd/back-ldbm/ldbm_bind.c | 4
ldap/servers/slapd/back-ldbm/ldbm_compare.c | 4
ldap/servers/slapd/back-ldbm/ldbm_config.c | 309
ldap/servers/slapd/back-ldbm/ldbm_config.h | 9
ldap/servers/slapd/back-ldbm/ldbm_delete.c | 364
ldap/servers/slapd/back-ldbm/ldbm_entryrdn.c | 896
ldap/servers/slapd/back-ldbm/ldbm_index_config.c | 668
ldap/servers/slapd/back-ldbm/ldbm_instance_config.c | 262
ldap/servers/slapd/back-ldbm/ldbm_modify.c | 145
ldap/servers/slapd/back-ldbm/ldbm_modrdn.c | 361
ldap/servers/slapd/back-ldbm/ldbm_search.c | 407
ldap/servers/slapd/back-ldbm/ldbm_usn.c | 74
ldap/servers/slapd/back-ldbm/ldif2ldbm.c | 792
ldap/servers/slapd/back-ldbm/matchrule.c | 50
ldap/servers/slapd/back-ldbm/misc.c | 298
ldap/servers/slapd/back-ldbm/monitor.c | 14
ldap/servers/slapd/back-ldbm/nextid.c | 17
ldap/servers/slapd/back-ldbm/parents.c | 141
ldap/servers/slapd/back-ldbm/perfctrs.c | 24
ldap/servers/slapd/back-ldbm/proto-back-ldbm.h | 52
ldap/servers/slapd/back-ldbm/sort.c | 38
ldap/servers/slapd/back-ldbm/start.c | 61
ldap/servers/slapd/back-ldbm/vlv.c | 383
ldap/servers/slapd/back-ldbm/vlv_srch.c | 17
ldap/servers/slapd/back-ldbm/vlv_srch.h | 3
ldap/servers/slapd/back-ldif/back-ldif.h | 2
ldap/servers/slapd/back-ldif/modrdn.c | 12
ldap/servers/slapd/backend.c | 72
ldap/servers/slapd/backend_manager.c | 18
ldap/servers/slapd/bind.c | 320
ldap/servers/slapd/bulk_import.c | 39
ldap/servers/slapd/charray.c | 27
ldap/servers/slapd/compare.c | 41
ldap/servers/slapd/computed.c | 36
ldap/servers/slapd/config.c | 2
ldap/servers/slapd/configdse.c | 63
ldap/servers/slapd/connection.c | 196
ldap/servers/slapd/conntable.c | 3
ldap/servers/slapd/control.c | 26
ldap/servers/slapd/csn.c | 77
ldap/servers/slapd/csngen.c | 54
ldap/servers/slapd/csnset.c | 4
ldap/servers/slapd/daemon.c | 173
ldap/servers/slapd/delete.c | 127
ldap/servers/slapd/dn.c | 1561
ldap/servers/slapd/dse.c | 222
ldap/servers/slapd/dynalib.c | 29
ldap/servers/slapd/entry.c | 961
ldap/servers/slapd/entrywsi.c | 137
ldap/servers/slapd/eventq.c | 4
ldap/servers/slapd/extendop.c | 35
ldap/servers/slapd/factory.c | 1
ldap/servers/slapd/fe.h | 5
ldap/servers/slapd/fedse.c | 40
ldap/servers/slapd/filter.c | 141
ldap/servers/slapd/filter.h | 1
ldap/servers/slapd/filtercmp.c | 26
ldap/servers/slapd/filterentry.c | 36
ldap/servers/slapd/generation.c | 1
ldap/servers/slapd/index_subsystem.c | 28
ldap/servers/slapd/intrinsics.h | 7
ldap/servers/slapd/ldaputil.c | 812
ldap/servers/slapd/lenstr.c | 6
ldap/servers/slapd/libglobs.c | 666
ldap/servers/slapd/libslapd.def | 1
ldap/servers/slapd/log.c | 104
ldap/servers/slapd/log.h | 20
ldap/servers/slapd/main.c | 288
ldap/servers/slapd/mapping_tree.c | 478
ldap/servers/slapd/match.c | 96
ldap/servers/slapd/modify.c | 491
ldap/servers/slapd/modrdn.c | 362
ldap/servers/slapd/modutil.c | 14
ldap/servers/slapd/operation.c | 27
ldap/servers/slapd/opshared.c | 296
ldap/servers/slapd/pagedresults.c | 130
ldap/servers/slapd/passwd_extop.c | 203
ldap/servers/slapd/pblock.c | 575
ldap/servers/slapd/plugin.c | 338
ldap/servers/slapd/plugin_acl.c | 50
ldap/servers/slapd/plugin_internal_op.c | 201
ldap/servers/slapd/plugin_mr.c | 474
ldap/servers/slapd/plugin_syntax.c | 442
ldap/servers/slapd/protect_db.c | 24
ldap/servers/slapd/protect_db.h | 7
ldap/servers/slapd/proto-slap.h | 74
ldap/servers/slapd/proxyauth.c | 246
ldap/servers/slapd/psearch.c | 77
ldap/servers/slapd/pw.c | 510
ldap/servers/slapd/pw.h | 5
ldap/servers/slapd/pw_mgmt.c | 164
ldap/servers/slapd/pw_retry.c | 99
ldap/servers/slapd/rdn.c | 141
ldap/servers/slapd/referral.c | 29
ldap/servers/slapd/regex.c | 3
ldap/servers/slapd/resourcelimit.c | 80
ldap/servers/slapd/result.c | 81
ldap/servers/slapd/rootdse.c | 12
ldap/servers/slapd/rwlock.c | 257
ldap/servers/slapd/rwlock.h | 65
ldap/servers/slapd/sasl_io.c | 167
ldap/servers/slapd/sasl_map.c | 57
ldap/servers/slapd/saslbind.c | 160
ldap/servers/slapd/schema.c | 194
ldap/servers/slapd/schemaparse.c | 13
ldap/servers/slapd/search.c | 89
ldap/servers/slapd/security_wrappers.c | 36
ldap/servers/slapd/slap.h | 196
ldap/servers/slapd/slapi-plugin-compat4.h | 6
ldap/servers/slapd/slapi-plugin.h | 1268
ldap/servers/slapd/slapi-private.h | 58
ldap/servers/slapd/slapi2nspr.c | 79
ldap/servers/slapd/slapi_counter.c | 24
ldap/servers/slapd/snmp_collator.c | 19
ldap/servers/slapd/ssl.c | 323
ldap/servers/slapd/str2filter.c | 5
ldap/servers/slapd/task.c | 184
ldap/servers/slapd/test-plugins/testbind.c | 1
ldap/servers/slapd/test-plugins/testpostop.c | 1
ldap/servers/slapd/time.c | 91
ldap/servers/slapd/tools/dbscan.c | 76
ldap/servers/slapd/tools/ldclt/data.c | 70
ldap/servers/slapd/tools/ldclt/ldapfct.c | 1149
ldap/servers/slapd/tools/ldclt/ldclt.c | 50
ldap/servers/slapd/tools/ldclt/ldclt.h | 3
ldap/servers/slapd/tools/ldclt/ldcltU.c | 24
ldap/servers/slapd/tools/ldclt/parser.c | 19
ldap/servers/slapd/tools/ldclt/scalab01.c | 190
ldap/servers/slapd/tools/ldclt/threadMain.c | 6
ldap/servers/slapd/tools/ldif.c | 4
ldap/servers/slapd/tools/mmldif.c | 9
ldap/servers/slapd/tools/pwenc.c | 2
ldap/servers/slapd/tools/rsearch/addthread.c | 51
ldap/servers/slapd/tools/rsearch/sdattable.c | 4
ldap/servers/slapd/tools/rsearch/searchthread.c | 94
ldap/servers/slapd/uniqueid.c | 99
ldap/servers/slapd/utf8compare.c | 6
ldap/servers/slapd/util.c | 357
ldap/servers/slapd/uuid.c | 22
ldap/servers/slapd/value.c | 53
ldap/servers/slapd/valueset.c | 75
ldap/servers/slapd/vattr.c | 115
ldap/servers/snmp/NETWORK-SERVICES-MIB.txt | 650
ldap/servers/snmp/RFC-1215.txt | 38
ldap/servers/snmp/RFC1155-SMI.txt | 119
ldap/servers/snmp/SNMPv2-CONF.txt | 322
ldap/servers/snmp/SNMPv2-SMI.txt | 344
ldap/servers/snmp/SNMPv2-TC.txt | 772
ldap/servers/snmp/ldap-agent.c | 26
ldap/servers/snmp/main.c | 11
ldap/servers/snmp/netscape-ldap.mib | 759
ldap/systools/idsktune.c | 100
lib/base/crit.cpp | 6
lib/base/ereport.cpp | 2
lib/base/file.cpp | 24
lib/base/lexer.cpp | 1015
lib/base/plist.cpp | 3
lib/base/rwlock.cpp | 168
lib/base/util.cpp | 13
lib/ldaputil/cert.c | 4
lib/ldaputil/certmap.c | 409
lib/ldaputil/dbconf.c | 1
lib/ldaputil/utest/Makefile | 149
lib/ldaputil/utest/auth.cpp | 611
lib/ldaputil/utest/authtest | 138
lib/ldaputil/utest/certmap.conf | 68
lib/ldaputil/utest/dblist.conf | 47
lib/ldaputil/utest/example.c | 153
lib/ldaputil/utest/plugin.c | 152
lib/ldaputil/utest/plugin.h | 57
lib/ldaputil/utest/stubs.c | 144
lib/ldaputil/utest/stubs.cpp | 139
lib/ldaputil/utest/test.ref | 480
lib/ldaputil/vtable.c | 2
lib/libaccess/acl.tab.cpp | 25
lib/libaccess/aclcache.cpp | 105
lib/libaccess/aclflush.cpp | 1
lib/libaccess/aclpriv.h | 1
lib/libaccess/acltext.y | 4
lib/libaccess/acltools.cpp | 1896
lib/libaccess/aclutil.cpp | 13
lib/libaccess/authdb.cpp | 112
lib/libaccess/lasdns.cpp | 23
lib/libaccess/lasgroup.cpp | 10
lib/libaccess/lasip.cpp | 20
lib/libaccess/nseframe.cpp | 1
lib/libaccess/oneeval.cpp | 19
lib/libaccess/permhash.h | 11
lib/libaccess/register.cpp | 50
lib/libaccess/usrcache.cpp | 14
lib/libaccess/utest/.purify | 19
lib/libaccess/utest/Makefile | 147
lib/libaccess/utest/acl.dat | 44
lib/libaccess/utest/aclfile0 | 87
lib/libaccess/utest/aclfile1 | 43
lib/libaccess/utest/aclfile10 | 45
lib/libaccess/utest/aclfile11 | 43
lib/libaccess/utest/aclfile12 | 43
lib/libaccess/utest/aclfile13 | 43
lib/libaccess/utest/aclfile14 | 43
lib/libaccess/utest/aclfile15 | 43
lib/libaccess/utest/aclfile16 | 43
lib/libaccess/utest/aclfile17 | 43
lib/libaccess/utest/aclfile18 | 51
lib/libaccess/utest/aclfile19 | 46
lib/libaccess/utest/aclfile2 | 43
lib/libaccess/utest/aclfile3 | 43
lib/libaccess/utest/aclfile4 | 43
lib/libaccess/utest/aclfile5 | 43
lib/libaccess/utest/aclfile6 | 55
lib/libaccess/utest/aclfile7 | 43
lib/libaccess/utest/aclfile8 | 43
lib/libaccess/utest/aclfile9 | 43
lib/libaccess/utest/aclgrp0 | 42
lib/libaccess/utest/aclgrp1 | 42
lib/libaccess/utest/aclgrp2 | 42
lib/libaccess/utest/aclgrp3 | 42
lib/libaccess/utest/aclgrp4 | 42
lib/libaccess/utest/acltest.cpp | 794
lib/libaccess/utest/onetest.cpp | 77
lib/libaccess/utest/shexp.cpp | 331
lib/libaccess/utest/shexp.h | 168
lib/libaccess/utest/test.ref | 217
lib/libaccess/utest/testmain.cpp | 89
lib/libaccess/utest/twotest.cpp | 87
lib/libaccess/utest/ustubs.cpp | 331
lib/libadmin/error.c | 2
lib/libadmin/template.c | 2
lib/libadmin/util.c | 48
lib/libsi18n/coreres.c | 141
lib/libsi18n/coreres.h | 52
lib/libsi18n/getlang.c | 330
lib/libsi18n/getstrmem.c | 160
lib/libsi18n/getstrmem.h | 1
lib/libsi18n/getstrprop.c | 85
lib/libsi18n/makstrdb.c | 21
lib/libsi18n/propset.c | 442
lib/libsi18n/propset.h | 80
lib/libsi18n/reshash.c | 21
ltmain.sh |13199 ++-
m4/db.m4 | 21
m4/fhs.m4 | 4
m4/icu.m4 | 25
m4/kerberos.m4 | 4
m4/mozldap.m4 | 38
m4/netsnmp.m4 | 15
m4/nspr.m4 | 17
m4/nss.m4 | 17
m4/openldap.m4 | 30
m4/pcre.m4 | 28
m4/sasl.m4 | 25
m4/selinux.m4 | 13
m4/svrcore.m4 | 41
man/man1/cl-dump.1 | 18
man/man1/dbgen.pl.1 | 4
man/man1/infadd.1 | 8
man/man1/migratecred.1 | 6
man/man1/mmldif.1 | 4
man/man1/pwdhash.1 | 4
man/man1/repl-monitor.1 | 16
man/man8/ns-slapd.8 | 10
man/man8/remove-ds.pl.8 | 6
man/man8/restart-dirsrv.8 | 50
man/man8/setup-ds.pl.8 | 4
man/man8/start-dirsrv.8 | 50
man/man8/stop-dirsrv.8 | 50
missing | 104
selinux/dirsrv.fc.in | 2
selinux/dirsrv.if | 41
selinux/dirsrv.te | 11
wrappers/cl-dump.in | 11
wrappers/dbscan.in | 10
wrappers/infadd.in | 12
wrappers/initscript.in | 244
wrappers/ldap-agent-initscript.in | 20
wrappers/ldap-agent.in | 12
wrappers/ldclt.in | 12
wrappers/ldif.in | 12
wrappers/migratecred.in | 14
wrappers/mmldif.in | 14
wrappers/pwdhash.in | 14
wrappers/repl-monitor.in | 11
wrappers/rsearch.in | 12
wrappers/systemd-snmp.service.in | 16
wrappers/systemd.group.in | 6
wrappers/systemd.template.service.in | 28
wrappers/systemd.template.sysconfig | 3
617 files changed, 83525 insertions(+), 68387 deletions(-)
---
11 years, 5 months
Branch '389-ds-base-1.2.10' - 19 commits - ldap/admin ldap/schema ldap/servers Makefile.am Makefile.in VERSION.sh
by Richard Allen Megginson
Makefile.am | 1
Makefile.in | 1
VERSION.sh | 2
ldap/admin/src/scripts/template-cleanallruv.pl.in | 186 +
ldap/schema/01core389.ldif | 7
ldap/servers/plugins/acl/acl.c | 77
ldap/servers/plugins/acl/acl.h | 5
ldap/servers/plugins/acl/aclgroup.c | 2
ldap/servers/plugins/acl/acllist.c | 48
ldap/servers/plugins/linkedattrs/fixup_task.c | 2
ldap/servers/plugins/linkedattrs/linked_attrs.h | 2
ldap/servers/plugins/memberof/memberof.c | 2
ldap/servers/plugins/memberof/memberof.h | 2
ldap/servers/plugins/replication/cl5_api.c | 138 -
ldap/servers/plugins/replication/cl5_api.h | 11
ldap/servers/plugins/replication/repl5.h | 61
ldap/servers/plugins/replication/repl5_agmt.c | 108
ldap/servers/plugins/replication/repl5_agmtlist.c | 4
ldap/servers/plugins/replication/repl5_connection.c | 39
ldap/servers/plugins/replication/repl5_inc_protocol.c | 21
ldap/servers/plugins/replication/repl5_init.c | 89
ldap/servers/plugins/replication/repl5_plugins.c | 8
ldap/servers/plugins/replication/repl5_replica.c | 439 ++-
ldap/servers/plugins/replication/repl5_replica_config.c | 1976 ++++++++++++++--
ldap/servers/plugins/replication/repl5_ruv.c | 108
ldap/servers/plugins/replication/repl5_ruv.h | 2
ldap/servers/plugins/replication/repl_extop.c | 382 +++
ldap/servers/plugins/replication/repl_globals.c | 5
ldap/servers/plugins/usn/usn_cleanup.c | 2
ldap/servers/slapd/dn.c | 2
ldap/servers/slapd/libglobs.c | 5
ldap/servers/slapd/log.c | 27
ldap/servers/slapd/plugin_acl.c | 35
ldap/servers/slapd/slapi-plugin.h | 10
ldap/servers/slapd/task.c | 56
35 files changed, 3493 insertions(+), 372 deletions(-)
New commits:
commit cdd0ee66e8965b4fd9e3f0ce1ca6344ed007da73
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Tue Oct 16 09:04:48 2012 -0600
bump version to 1.2.10.15
diff --git a/VERSION.sh b/VERSION.sh
index 3e3290e..0e62a09 100644
--- a/VERSION.sh
+++ b/VERSION.sh
@@ -10,7 +10,7 @@ vendor="389 Project"
# PACKAGE_VERSION is constructed from these
VERSION_MAJOR=1
VERSION_MINOR=2
-VERSION_MAINT=10.14
+VERSION_MAINT=10.15
# if this is a PRERELEASE, set VERSION_PREREL
# otherwise, comment it out
# be sure to include the dot prefix in the prerel
commit 77b673974892eaa1f026687f6cf683372cc45c8c
Author: Noriko Hosoi <nhosoi(a)totoro.usersys.redhat.com>
Date: Fri Sep 21 12:35:18 2012 -0700
Trac Ticket #340 - Change on SLAPI_MODRDN_NEWSUPERIOR is not
evaluated in acl
https://fedorahosted.org/389/ticket/340
Bug Description: When modrdn operation was executed, only newrdn
change was passed to the acl plugin. Also, the change was used
only for the acl search, but not for the acl target in the items
in the acl cache.
Fix Description: This patch also passes the newsuperior update
to the acl plugin. And the modrdn updates are applied to the
acl target in the acl cache.
(cherry picked from commit 5beb93d42efb807838c09c5fab898876876f8d09)
1.2.10 - cherry-picked from 7399cbd53d6289df592d3414a84972eacb4dc97d
- had to fix a couple of conflicts in the acl code
diff --git a/ldap/servers/plugins/acl/acl.c b/ldap/servers/plugins/acl/acl.c
index 5a7b446..e17a827 100644
--- a/ldap/servers/plugins/acl/acl.c
+++ b/ldap/servers/plugins/acl/acl.c
@@ -170,9 +170,9 @@ acl_access_allowed_modrdn(
* Test if have access to make the first rdn of dn in entry e.
*/
-static int check_rdn_access( Slapi_PBlock *pb, Slapi_Entry *e, const char *dn,
- int access) {
-
+static int
+check_rdn_access( Slapi_PBlock *pb, Slapi_Entry *e, const char *dn, int access)
+{
char **dns;
char **rdns;
int retCode = LDAP_INSUFFICIENT_ACCESS;
@@ -659,7 +659,8 @@ cleanup_and_ret:
}
-static void print_access_control_summary( char *source, int ret_val, char *clientDn,
+static void
+print_access_control_summary( char *source, int ret_val, char *clientDn,
struct acl_pblock *aclpb,
char *right,
char *attr,
@@ -1533,11 +1534,12 @@ acl_check_mods(
*
**************************************************************************/
extern void
-acl_modified (Slapi_PBlock *pb, int optype, char *n_dn, void *change)
+acl_modified (Slapi_PBlock *pb, int optype, Slapi_DN *e_sdn, void *change)
{
struct berval **bvalue;
char **value;
int rv=0; /* returned value */
+ const char* n_dn;
char* new_RDN;
char* parent_DN;
char* new_DN;
@@ -1547,10 +1549,12 @@ acl_modified (Slapi_PBlock *pb, int optype, char *n_dn, void *change)
Slapi_Attr *attr = NULL;
Slapi_Entry *e = NULL;
char ebuf [ BUFSIZ];
- Slapi_DN *e_sdn;
aclUserGroup *ugroup = NULL;
- e_sdn = slapi_sdn_new_normdn_byval ( n_dn );
+ if (NULL == e_sdn) {
+ return;
+ }
+ n_dn = slapi_sdn_get_dn(e_sdn);
/* Before we proceed, Let's first check if we are changing any groups.
** If we are, then we need to change the signature
*/
@@ -1778,45 +1782,64 @@ acl_modified (Slapi_PBlock *pb, int optype, char *n_dn, void *change)
}
break;
- }/* case op is modify*/
+ }/* case op is modify*/
- case SLAPI_OPERATION_MODRDN:
-
- new_RDN = (char*) change;
- slapi_log_error (SLAPI_LOG_ACL, plugin_name,
- "acl_modified (MODRDN %s => \"%s\"\n",
- ACL_ESCAPE_STRING_WITH_PUNCTUATION (n_dn, ebuf), new_RDN);
+ case SLAPI_OPERATION_MODRDN:
+ {
+ char **rdn_parent;
+ rdn_parent = (char **)change;
+ new_RDN = rdn_parent[0];
+ parent_DN = rdn_parent[1];
/* compute new_DN: */
- parent_DN = slapi_dn_parent (n_dn);
- if (parent_DN == NULL) {
- new_DN = new_RDN;
+ if (NULL == parent_DN) {
+ parent_DN = slapi_dn_parent(n_dn);
+ }
+ if (NULL == parent_DN) {
+ if (NULL == new_RDN) {
+ slapi_log_error (SLAPI_LOG_ACL, plugin_name,
+ "acl_modified (MODRDN %s => \"no change\"\n",
+ n_dn);
+ break;
+ } else {
+ new_DN = new_RDN;
+ }
} else {
- new_DN = slapi_create_dn_string("%s,%s", new_RDN, parent_DN);
+ if (NULL == new_RDN) {
+ Slapi_RDN *rdn= slapi_rdn_new();
+ slapi_sdn_get_rdn(e_sdn, rdn);
+ new_DN = slapi_create_dn_string("%s,%s", slapi_rdn_get_rdn(rdn),
+ parent_DN);
+ slapi_rdn_free(&rdn);
+ } else {
+ new_DN = slapi_create_dn_string("%s,%s", new_RDN, parent_DN);
+ }
}
+ slapi_log_error (SLAPI_LOG_ACL, plugin_name,
+ "acl_modified (MODRDN %s => \"%s\"\n", n_dn, new_RDN);
/* Change the acls */
- acllist_acicache_WRITE_LOCK();
+ acllist_acicache_WRITE_LOCK();
/* acllist_moddn_aci_needsLock expects normalized new_DN,
* which is no need to be case-ignored */
acllist_moddn_aci_needsLock ( e_sdn, new_DN );
acllist_acicache_WRITE_UNLOCK();
/* deallocat the parent_DN */
- if (parent_DN != NULL) {
- slapi_ch_free ( (void **) &new_DN );
- slapi_ch_free ( (void **) &parent_DN );
+ if (parent_DN != NULL) {
+ slapi_ch_free_string(&new_DN);
+ if (parent_DN != rdn_parent[1]) {
+ slapi_ch_free_string(&parent_DN);
+ }
}
break;
-
- default:
+ } /* case op is modrdn */
+ default:
/* print ERROR */
break;
} /*optype switch */
-
- slapi_sdn_free ( &e_sdn );
-
}
+
/***************************************************************************
*
* acl__scan_for_acis
diff --git a/ldap/servers/plugins/acl/acl.h b/ldap/servers/plugins/acl/acl.h
index 4fa3e3f..28c38e7 100644
--- a/ldap/servers/plugins/acl/acl.h
+++ b/ldap/servers/plugins/acl/acl.h
@@ -796,7 +796,8 @@ int acl_read_access_allowed_on_attr ( Slapi_PBlock *pb, Slapi_Entry *e, char
struct berval *val, int access);
void acl_set_acllist (Slapi_PBlock *pb, int scope, char *base);
void acl_gen_err_msg(int access, char *edn, char *attr, char **errbuf);
-void acl_modified ( Slapi_PBlock *pb, int optype, char *dn, void *change);
+void acl_modified (Slapi_PBlock *pb, int optype, Slapi_DN *e_sdn, void *change);
+
int acl_access_allowed_disjoint_resource( Slapi_PBlock *pb, Slapi_Entry *e,
char *attr, struct berval *val, int access );
int acl_access_allowed_main ( Slapi_PBlock *pb, Slapi_Entry *e, char **attrs,
@@ -866,7 +867,7 @@ void acllist_print_tree ( Avlnode *root, int *depth, char *start, char *side);
AciContainer *acllist_get_aciContainer_new ( );
void acllist_done_aciContainer ( AciContainer *);
-aclUserGroup* aclg_find_userGroup (char *n_dn);
+aclUserGroup* aclg_find_userGroup (const char *n_dn);
void aclg_regen_ugroup_signature( aclUserGroup *ugroup);
void aclg_markUgroupForRemoval ( aclUserGroup *u_group );
void aclg_reader_incr_ugroup_refcnt(aclUserGroup* u_group);
diff --git a/ldap/servers/plugins/acl/aclgroup.c b/ldap/servers/plugins/acl/aclgroup.c
index c694293..2231304 100644
--- a/ldap/servers/plugins/acl/aclgroup.c
+++ b/ldap/servers/plugins/acl/aclgroup.c
@@ -213,7 +213,7 @@ aclg_reset_userGroup ( struct acl_pblock *aclpb )
*/
aclUserGroup*
-aclg_find_userGroup(char *n_dn)
+aclg_find_userGroup(const char *n_dn)
{
aclUserGroup *u_group = NULL;
int i;
diff --git a/ldap/servers/plugins/acl/acllist.c b/ldap/servers/plugins/acl/acllist.c
index 9b5363a..e8198af 100644
--- a/ldap/servers/plugins/acl/acllist.c
+++ b/ldap/servers/plugins/acl/acllist.c
@@ -600,7 +600,6 @@ void
acllist_init_scan (Slapi_PBlock *pb, int scope, const char *base)
{
Acl_PBlock *aclpb;
- int i;
AciContainer *root;
char *basedn = NULL;
int index;
@@ -671,11 +670,6 @@ acllist_init_scan (Slapi_PBlock *pb, int scope, const char *base)
aclpb->aclpb_state &= ~ACLPB_SEARCH_BASED_ON_LIST ;
acllist_acicache_READ_UNLOCK();
-
- i = 0;
- while ( i < aclpb_max_selected_acls && aclpb->aclpb_base_handles_index[i] != -1 ) {
- i++;
- }
}
/*
@@ -893,34 +887,50 @@ acllist_acicache_WRITE_LOCK( )
int
acllist_moddn_aci_needsLock ( Slapi_DN *oldsdn, char *newdn )
{
-
-
AciContainer *aciListHead;
AciContainer *head;
+ aci_t *acip;
+ const char *oldndn;
/* first get the container */
aciListHead = acllist_get_aciContainer_new ( );
slapi_sdn_free(&aciListHead->acic_sdn);
- aciListHead->acic_sdn = oldsdn;
-
+ aciListHead->acic_sdn = oldsdn;
if ( NULL == (head = (AciContainer *) avl_find( acllistRoot, aciListHead,
- (IFP) __acllist_aciContainer_node_cmp ) ) ) {
+ (IFP) __acllist_aciContainer_node_cmp ) ) ) {
slapi_log_error ( SLAPI_PLUGIN_ACL, plugin_name,
- "Can't find the acl in the tree for moddn operation:olddn%s\n",
- slapi_sdn_get_ndn ( oldsdn ));
+ "Can't find the acl in the tree for moddn operation:olddn%s\n",
+ slapi_sdn_get_ndn ( oldsdn ));
aciListHead->acic_sdn = NULL;
__acllist_free_aciContainer ( &aciListHead );
- return 1;
+ return 1;
}
-
- /* Now set the new DN */
- slapi_sdn_done ( head->acic_sdn );
- slapi_sdn_set_normdn_byval ( head->acic_sdn, newdn );
-
+ /* Now set the new DN */
+ slapi_sdn_set_normdn_byval(head->acic_sdn, newdn);
+
+ /* If necessary, reset the target DNs, as well. */
+ oldndn = slapi_sdn_get_ndn(oldsdn);
+ for (acip = head->acic_list; acip; acip = acip->aci_next) {
+ const char *ndn = slapi_sdn_get_ndn(acip->aci_sdn);
+ char *p = PL_strstr(ndn, oldndn);
+ if (p) {
+ if (p == ndn) {
+ /* target dn is identical, replace it with new DN*/
+ slapi_sdn_set_normdn_byval(acip->aci_sdn, newdn);
+ } else {
+ /* target dn is a descendent of olddn, merge it with new DN*/
+ char *mynewdn;
+ *p = '\0';
+ mynewdn = slapi_ch_smprintf("%s%s", ndn, newdn);
+ slapi_sdn_set_normdn_passin(acip->aci_sdn, mynewdn);
+ }
+ }
+ }
+
aciListHead->acic_sdn = NULL;
__acllist_free_aciContainer ( &aciListHead );
diff --git a/ldap/servers/slapd/dn.c b/ldap/servers/slapd/dn.c
index 568871f..35c0700 100644
--- a/ldap/servers/slapd/dn.c
+++ b/ldap/servers/slapd/dn.c
@@ -2037,7 +2037,7 @@ slapi_sdn_set_normdn_byval(Slapi_DN *sdn, const char *normdn)
slapi_sdn_done(sdn);
sdn->flag = slapi_setbit_uchar(sdn->flag, FLAG_DN);
if(normdn == NULL) {
- sdn->dn = slapi_ch_strdup(normdn);
+ sdn->dn = NULL;
sdn->ndn_len = 0;
} else {
sdn->dn = slapi_ch_strdup(normdn);
diff --git a/ldap/servers/slapd/plugin_acl.c b/ldap/servers/slapd/plugin_acl.c
index 24dcc76..3bc3f21 100644
--- a/ldap/servers/slapd/plugin_acl.c
+++ b/ldap/servers/slapd/plugin_acl.c
@@ -134,11 +134,10 @@ int
plugin_call_acl_mods_update ( Slapi_PBlock *pb, int optype )
{
struct slapdplugin *p;
- char *dn;
int rc = 0;
- void *change = NULL;
- Slapi_Entry *te = NULL;
- Slapi_DN *sdn = NULL;
+ void *change = NULL;
+ Slapi_Entry *te = NULL;
+ Slapi_DN *sdn = NULL;
Operation *operation;
slapi_pblock_get (pb, SLAPI_OPERATION, &operation);
@@ -146,7 +145,7 @@ plugin_call_acl_mods_update ( Slapi_PBlock *pb, int optype )
(void)slapi_pblock_get( pb, SLAPI_TARGET_SDN, &sdn );
switch ( optype ) {
- case SLAPI_OPERATION_MODIFY:
+ case SLAPI_OPERATION_MODIFY:
(void)slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &change );
break;
case SLAPI_OPERATION_ADD:
@@ -157,9 +156,28 @@ plugin_call_acl_mods_update ( Slapi_PBlock *pb, int optype )
sdn = slapi_entry_get_sdn(te);
}
break;
- case SLAPI_OPERATION_MODRDN:
- (void)slapi_pblock_get( pb, SLAPI_MODRDN_NEWRDN, &change );
+ case SLAPI_OPERATION_MODRDN:
+ {
+ void *mychange[2];
+ char *newrdn = NULL;
+ Slapi_DN *psdn = NULL;
+ char *pdn = NULL;
+
+ /* newrdn: "change" is normalized but not case-ignored */
+ /* The acl plugin expects normalized newrdn, but no need to be case-
+ * ignored. */
+ (void)slapi_pblock_get( pb, SLAPI_MODRDN_NEWRDN, &newrdn );
+ (void)slapi_pblock_get( pb, SLAPI_MODRDN_NEWSUPERIOR_SDN, &psdn );
+ if (psdn) {
+ pdn = (char *)slapi_sdn_get_dn(psdn);
+ } else {
+ (void)slapi_pblock_get( pb, SLAPI_MODRDN_NEWSUPERIOR, &pdn );
+ }
+ mychange[0] = newrdn;
+ mychange[1] = pdn;
+ change = mychange;
break;
+ }
}
if (NULL == sdn) {
@@ -169,10 +187,9 @@ plugin_call_acl_mods_update ( Slapi_PBlock *pb, int optype )
}
/* call the global plugins first and then the backend specific */
- dn = (char*)slapi_sdn_get_ndn(sdn); /* jcm - Had to cast away const */
for ( p = get_plugin_list(PLUGIN_LIST_ACL); p != NULL; p = p->plg_next ) {
if (plugin_invoke_plugin_sdn(p, SLAPI_PLUGIN_ACL_MODS_UPDATE, pb, sdn)){
- rc = (*p->plg_acl_mods_update)(pb, optype, dn, change );
+ rc = (*p->plg_acl_mods_update)(pb, optype, sdn, change );
if ( rc != LDAP_SUCCESS ) break;
}
}
commit d1d6bfa9c616e552fd815fd80a84b66f0b8570dc
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Thu Oct 11 11:57:24 2012 -0600
Ticket #491 - multimaster_extop_cleanruv returns wrong error codes
https://fedorahosted.org/389/ticket/491
Reviewed by: ???
Branch: 389-ds-base-1.2.10
Fix Description: multimaster_extop_cleanruv must return with a code of
SLAPI_PLUGIN_EXTENDED_SENT_RESULT to tell the server that the result
has been sent - otherwise, in 1.2.10, the server will attempt to send
the result again. In 1.2.11 the result code has been changed to ignore
a subsequent attempt to send a result for the same operation, but the
function should still return the correct codes.
I also cleaned up the error codes and memory management a bit.
Platforms tested: RHEL6 x86_64
Flag Day: no
Doc impact: no
(cherry picked from commit 8e702a148b8a30c7b222a2f95260c6d53f884185)
(cherry picked from commit f19e9afa90a94198efd4b97f172d4443c7440f94)
diff --git a/ldap/servers/plugins/replication/repl_extop.c b/ldap/servers/plugins/replication/repl_extop.c
index a33dff3..b2381b8 100644
--- a/ldap/servers/plugins/replication/repl_extop.c
+++ b/ldap/servers/plugins/replication/repl_extop.c
@@ -1376,19 +1376,20 @@ free_and_return:
int
multimaster_extop_abort_cleanruv(Slapi_PBlock *pb)
{
- multimaster_mtnode_extension *mtnode_ext;
+ multimaster_mtnode_extension *mtnode_ext = NULL;
+ int release_it = 0;
PRThread *thread = NULL;
cleanruv_data *data;
Replica *r;
ReplicaId rid;
- CSN *maxcsn;
- struct berval *extop_payload;
+ CSN *maxcsn = NULL;
+ struct berval *extop_payload = NULL;
char *extop_oid;
char *repl_root;
char *payload = NULL;
char *certify_all;
char *iter;
- int rc = 0;
+ int rc = LDAP_SUCCESS;
slapi_pblock_get(pb, SLAPI_EXT_OP_REQ_OID, &extop_oid);
slapi_pblock_get(pb, SLAPI_EXT_OP_REQ_VALUE, &extop_payload);
@@ -1426,6 +1427,7 @@ multimaster_extop_abort_cleanruv(Slapi_PBlock *pb)
}
if (mtnode_ext->replica){
object_acquire (mtnode_ext->replica);
+ release_it = 1;
} else {
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "Abort cleanAllRUV task: replica is missing from (%s), "
"aborting operation\n",repl_root);
@@ -1449,6 +1451,7 @@ multimaster_extop_abort_cleanruv(Slapi_PBlock *pb)
goto out;
}
data->repl_obj = mtnode_ext->replica; /* released in replica_abort_task_thread() */
+ release_it = 0; /* thread owns it now */
data->replica = r;
data->task = NULL;
data->payload = slapi_ch_bvdup(extop_payload);
@@ -1470,17 +1473,20 @@ multimaster_extop_abort_cleanruv(Slapi_PBlock *pb)
(void *)data, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
PR_UNJOINABLE_THREAD, SLAPD_DEFAULT_THREAD_STACKSIZE);
if (thread == NULL) {
- if(mtnode_ext->replica){
- object_release(mtnode_ext->replica);
- }
slapi_log_error( SLAPI_LOG_REPL, repl_plugin_name, "Abort cleanAllRUV task: unable to create abort "
"thread. Aborting task.\n");
+ release_it = 1; /* have to release mtnode_ext->replica now */
slapi_ch_free_string(&data->repl_root);
slapi_ch_free_string(&data->certify);
+ ber_bvfree(data->payload);
+ slapi_ch_free((void **)&data);
rc = LDAP_OPERATIONS_ERROR;
}
out:
+ if (release_it && mtnode_ext && mtnode_ext->replica) {
+ object_release(mtnode_ext->replica);
+ }
slapi_ch_free_string(&payload);
return rc;
@@ -1500,7 +1506,7 @@ out:
int
multimaster_extop_cleanruv(Slapi_PBlock *pb)
{
- multimaster_mtnode_extension *mtnode_ext;
+ multimaster_mtnode_extension *mtnode_ext = NULL;
PRThread *thread = NULL;
Replica *r = NULL;
cleanruv_data *data = NULL;
@@ -1515,7 +1521,7 @@ multimaster_extop_cleanruv(Slapi_PBlock *pb)
char *iter;
int release_it = 0;
int rid = 0;
- int rc = 0;
+ int rc = LDAP_OPERATIONS_ERROR;
slapi_pblock_get(pb, SLAPI_EXT_OP_REQ_OID, &extop_oid);
slapi_pblock_get(pb, SLAPI_EXT_OP_REQ_VALUE, &extop_payload);
@@ -1523,7 +1529,6 @@ multimaster_extop_cleanruv(Slapi_PBlock *pb)
if (NULL == extop_oid || strcmp(extop_oid, REPL_CLEANRUV_OID) != 0 ||
NULL == extop_payload || NULL == extop_payload->bv_val){
/* something is wrong, error out */
- rc = -1;
goto free_and_return;
}
/*
@@ -1531,7 +1536,6 @@ multimaster_extop_cleanruv(Slapi_PBlock *pb)
*/
if(decode_cleanruv_payload(extop_payload, &payload)){
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: failed to decode payload. Aborting ext op\n");
- rc = -1;
goto free_and_return;
}
rid = atoi(ldap_utf8strtok_r(payload, ":", &iter));
@@ -1544,7 +1548,7 @@ multimaster_extop_cleanruv(Slapi_PBlock *pb)
*/
if(is_cleaned_rid(rid)){
csn_free(&maxcsn);
- rc = 1;
+ rc = LDAP_SUCCESS;
goto free_and_return;
}
@@ -1554,25 +1558,21 @@ multimaster_extop_cleanruv(Slapi_PBlock *pb)
if((mtnode_ext = replica_config_get_mtnode_by_dn(repl_root)) == NULL){
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: failed to get replication node "
"from (%s), aborting operation\n", repl_root);
- rc = -1;
goto free_and_return;
}
if (mtnode_ext->replica){
object_acquire (mtnode_ext->replica);
release_it = 1;
- }
- if (mtnode_ext->replica == NULL){
+ } else {
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: replica is missing from (%s), "
"aborting operation\n",repl_root);
- rc = LDAP_OPERATIONS_ERROR;
goto free_and_return;
}
r = (Replica*)object_get_data (mtnode_ext->replica);
if(r == NULL){
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: replica is NULL, aborting task\n");
- rc = -1;
goto free_and_return;
}
@@ -1587,7 +1587,6 @@ multimaster_extop_cleanruv(Slapi_PBlock *pb)
if (data == NULL) {
slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: failed to allocate "
"cleanruv_Data\n");
- rc = -1;
goto free_and_return;
}
data->repl_obj = mtnode_ext->replica;
@@ -1601,9 +1600,15 @@ multimaster_extop_cleanruv(Slapi_PBlock *pb)
(void *)data, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
PR_UNJOINABLE_THREAD, SLAPD_DEFAULT_THREAD_STACKSIZE);
if (thread == NULL) {
- rc = -1;
slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: unable to create cleanAllRUV "
"monitoring thread. Aborting task.\n");
+ ber_bvfree(data->payload);
+ data->payload = NULL;
+ slapi_ch_free((void **)&data);
+ } else {
+ release_it = 0; /* thread will release data->repl_obj == mtnode_ext->replica */
+ maxcsn = NULL; /* thread owns it now */
+ rc = LDAP_SUCCESS;
}
} else { /* this is a read-only consumer */
/*
@@ -1643,24 +1648,20 @@ multimaster_extop_cleanruv(Slapi_PBlock *pb)
/* free everything */
object_release(ruv_obj);
- csn_free(&maxcsn);
- if (mtnode_ext->replica && release_it)
- object_release (mtnode_ext->replica);
/*
* This read-only replica has no easy way to tell when it's safe to release the rid.
* So we won't release it, not until a server restart.
*/
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: You must restart the server if you want to reuse rid(%d).\n", rid);
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: Successfully cleaned rid(%d).\n", rid);
+ rc = LDAP_SUCCESS;
}
free_and_return:
- if(rc && release_it){
- if (mtnode_ext->replica)
- object_release (mtnode_ext->replica);
+ if(release_it && mtnode_ext && mtnode_ext->replica) {
+ object_release (mtnode_ext->replica);
}
- if(rc)
- csn_free(&maxcsn);
+ csn_free(&maxcsn);
slapi_ch_free_string(&payload);
/*
@@ -1684,6 +1685,10 @@ free_and_return:
{
ber_bvfree(resp_bval);
}
+ /* tell extendop code that we have already sent the result */
+ rc = SLAPI_PLUGIN_EXTENDED_SENT_RESULT;
+ } else {
+ rc = LDAP_OPERATIONS_ERROR;
}
return rc;
commit 7bbaf35f1d34eff567e53a9808f8e2c8dca6211d
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Thu Oct 11 11:09:48 2012 -0600
COVERITY FIXES in replica_execute_cleanall_ruv_task
check for null replica object and error if NULL
This is a backport of commit 5ff0a02468c530403b55a4a1d3555cf20a8db904
for just the replica_execute_cleanall_ruv_task replica object patch
diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
index 77a12fd..752b09b 100644
--- a/ldap/servers/plugins/replication/repl5_replica_config.c
+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
@@ -1329,7 +1329,12 @@ replica_execute_cleanall_ruv_task (Object *r, ReplicaId rid, Slapi_Task *task, c
/*
* Grab the replica
*/
- replica = (Replica*)object_get_data (r);
+ if(r){
+ replica = (Replica*)object_get_data (r);
+ } else {
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: replica is NULL, aborting task\n");
+ return -1;
+ }
/*
* Check if this is a consumer
*/
commit 1f356fa7d0a4122bea8b1eb6824e38cb551b87f3
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Wed Oct 10 09:19:05 2012 -0600
CLEANALLRUV - remove calls to agmt_get_enabled because this feature is not in 1.2.10
diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
index f4f3d41..77a12fd 100644
--- a/ldap/servers/plugins/replication/repl5_replica_config.c
+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
@@ -1553,7 +1553,7 @@ replica_cleanallruv_thread(void *arg)
}
while (agmt_obj){
agmt = (Repl_Agmt*)object_get_data (agmt_obj);
- if(!agmt_is_enabled(agmt) || get_agmt_agreement_type(agmt) == REPLICA_TYPE_WINDOWS){
+ if(get_agmt_agreement_type(agmt) == REPLICA_TYPE_WINDOWS){
agmt_obj = agmtlist_get_next_agreement_for_replica (data->replica, agmt_obj);
agmt_not_notified = 0;
continue;
@@ -1607,7 +1607,7 @@ replica_cleanallruv_thread(void *arg)
}
while (agmt_obj && !slapi_is_shutting_down()){
agmt = (Repl_Agmt*)object_get_data (agmt_obj);
- if(!agmt_is_enabled(agmt) || get_agmt_agreement_type(agmt) == REPLICA_TYPE_WINDOWS){
+ if(get_agmt_agreement_type(agmt) == REPLICA_TYPE_WINDOWS){
agmt_obj = agmtlist_get_next_agreement_for_replica (data->replica, agmt_obj);
found_dirty_rid = 0;
continue;
@@ -1701,7 +1701,7 @@ check_agmts_are_caught_up(Replica *replica, ReplicaId rid, char *maxcsn, Slapi_T
}
while (agmt_obj){
agmt = (Repl_Agmt*)object_get_data (agmt_obj);
- if(!agmt_is_enabled(agmt) || get_agmt_agreement_type(agmt) == REPLICA_TYPE_WINDOWS){
+ if(get_agmt_agreement_type(agmt) == REPLICA_TYPE_WINDOWS){
agmt_obj = agmtlist_get_next_agreement_for_replica (replica, agmt_obj);
not_all_caughtup = 0;
continue;
@@ -1757,7 +1757,7 @@ check_agmts_are_alive(Replica *replica, ReplicaId rid, Slapi_Task *task)
}
while (agmt_obj){
agmt = (Repl_Agmt*)object_get_data (agmt_obj);
- if(!agmt_is_enabled(agmt) || get_agmt_agreement_type(agmt) == REPLICA_TYPE_WINDOWS){
+ if(get_agmt_agreement_type(agmt) == REPLICA_TYPE_WINDOWS){
agmt_obj = agmtlist_get_next_agreement_for_replica (replica, agmt_obj);
not_all_alive = 0;
continue;
@@ -2168,7 +2168,7 @@ delete_cleaned_rid(Replica *r, ReplicaId rid, CSN *maxcsn)
agmt_obj = agmtlist_get_first_agreement_for_replica (r);
while (agmt_obj){
agmt = (Repl_Agmt*)object_get_data (agmt_obj);
- if(!agmt_is_enabled(agmt) || get_agmt_agreement_type(agmt) == REPLICA_TYPE_WINDOWS){
+ if(get_agmt_agreement_type(agmt) == REPLICA_TYPE_WINDOWS){
agmt_obj = agmtlist_get_next_agreement_for_replica (r, agmt_obj);
continue;
}
@@ -2369,7 +2369,7 @@ replica_abort_task_thread(void *arg)
}
while (agmt_obj){
agmt = (Repl_Agmt*)object_get_data (agmt_obj);
- if(!agmt_is_enabled(agmt) || get_agmt_agreement_type(agmt) == REPLICA_TYPE_WINDOWS){
+ if(get_agmt_agreement_type(agmt) == REPLICA_TYPE_WINDOWS){
agmt_obj = agmtlist_get_next_agreement_for_replica (data->replica, agmt_obj);
agmt_not_notified = 0;
continue;
commit 4bb14bda0d4cc35d438fc9c7f5638a23259472ac
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Mon Sep 24 13:22:09 2012 -0400
Ticket 477 - CLEANALLRUV if there are only winsync agmts task will hang
Bug Description: If there are only winsync agmts, the task will loop forever.
Fix Description: Need to clear a flag after skipping over invalid agmts. The same issue
would apply for agmts that were all disabled.
https://fedorahosted.org/389/ticket/477
Reviewed by: richm(Thanks!)
(cherry picked from commit 47c44d4e61723bb3013e614c1dafce5b37694e3c)
(cherry picked from commit 535511db8738e320c9305442c863b8a7ec11401f)
diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
index bcfe184..f4f3d41 100644
--- a/ldap/servers/plugins/replication/repl5_replica_config.c
+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
@@ -1555,6 +1555,7 @@ replica_cleanallruv_thread(void *arg)
agmt = (Repl_Agmt*)object_get_data (agmt_obj);
if(!agmt_is_enabled(agmt) || get_agmt_agreement_type(agmt) == REPLICA_TYPE_WINDOWS){
agmt_obj = agmtlist_get_next_agreement_for_replica (data->replica, agmt_obj);
+ agmt_not_notified = 0;
continue;
}
if(replica_cleanallruv_send_extop(agmt, data->rid, data->task, data->payload, 1) == 0){
@@ -1608,6 +1609,7 @@ replica_cleanallruv_thread(void *arg)
agmt = (Repl_Agmt*)object_get_data (agmt_obj);
if(!agmt_is_enabled(agmt) || get_agmt_agreement_type(agmt) == REPLICA_TYPE_WINDOWS){
agmt_obj = agmtlist_get_next_agreement_for_replica (data->replica, agmt_obj);
+ found_dirty_rid = 0;
continue;
}
if(replica_cleanallruv_check_ruv(agmt, rid_text, data->task) == 0){
@@ -1701,6 +1703,7 @@ check_agmts_are_caught_up(Replica *replica, ReplicaId rid, char *maxcsn, Slapi_T
agmt = (Repl_Agmt*)object_get_data (agmt_obj);
if(!agmt_is_enabled(agmt) || get_agmt_agreement_type(agmt) == REPLICA_TYPE_WINDOWS){
agmt_obj = agmtlist_get_next_agreement_for_replica (replica, agmt_obj);
+ not_all_caughtup = 0;
continue;
}
if(replica_cleanallruv_check_maxcsn(agmt, rid_text, maxcsn, task) == 0){
@@ -1756,6 +1759,7 @@ check_agmts_are_alive(Replica *replica, ReplicaId rid, Slapi_Task *task)
agmt = (Repl_Agmt*)object_get_data (agmt_obj);
if(!agmt_is_enabled(agmt) || get_agmt_agreement_type(agmt) == REPLICA_TYPE_WINDOWS){
agmt_obj = agmtlist_get_next_agreement_for_replica (replica, agmt_obj);
+ not_all_alive = 0;
continue;
}
if(replica_cleanallruv_replica_alive(agmt) == 0){
@@ -2367,6 +2371,7 @@ replica_abort_task_thread(void *arg)
agmt = (Repl_Agmt*)object_get_data (agmt_obj);
if(!agmt_is_enabled(agmt) || get_agmt_agreement_type(agmt) == REPLICA_TYPE_WINDOWS){
agmt_obj = agmtlist_get_next_agreement_for_replica (data->replica, agmt_obj);
+ agmt_not_notified = 0;
continue;
}
if(replica_cleanallruv_send_abort_extop(agmt, data->task, data->payload)){
commit 3022410899f02e9afa2d535d5b25e6141c70b210
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Fri Sep 21 12:49:09 2012 -0400
Ticket 467 - CLEANALLRUV abort task should be able to ignore down replicas
Bug Description: The abort task previously would wait for all the replicas to be online,
and receive the extended op task. This made it impossible to abort the
cleanallruv task, if you wanted to abort because a server was down.
Fix Description: Changed the default behavior to ignore down replicas, and added a new attribute
to the abort task entry: replica-certify-all: (yes,no). Default is "no". If
set to "yes", then it will wait until all the replicas have received the abort task.
Also fixed a crash caused by running the abort task agsint a server that does not have
replication setup. The crashed was caused by freeing uninitialized pointers.
https://fedorahosted.org/389/ticket/467
Reviewed by: richm(Thanks!)
(cherry picked from commit 822199e809b6100dfd908eb308eacf81956b3f34)
diff --git a/ldap/servers/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h
index 718018b..1637057 100644
--- a/ldap/servers/plugins/replication/repl5.h
+++ b/ldap/servers/plugins/replication/repl5.h
@@ -632,6 +632,7 @@ typedef struct _cleanruv_data
CSN *maxcsn;
char *repl_root;
Slapi_DN *sdn;
+ char *certify;
} cleanruv_data;
/* replutil.c */
diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c
index 8bb0744..c956647 100644
--- a/ldap/servers/plugins/replication/repl5_replica.c
+++ b/ldap/servers/plugins/replication/repl5_replica.c
@@ -1925,6 +1925,7 @@ done:
char *ridstr = NULL;
char *repl_root;
char *token = NULL;
+ char *certify = NULL;
ReplicaId rid;
int i;
@@ -1946,6 +1947,7 @@ done:
}
repl_root = ldap_utf8strtok_r(iter, ":", &iter);
+ certify = ldap_utf8strtok_r(iter, ":", &iter);
stop_ruv_cleaning();
maxcsn = replica_get_cleanruv_maxcsn(r, rid);
delete_cleaned_rid(r, rid, maxcsn);
@@ -1977,6 +1979,7 @@ done:
data->payload = payload;
data->repl_root = slapi_ch_strdup(repl_root);
data->sdn = slapi_sdn_dup(r->repl_root);
+ data->certify = slapi_ch_strdup(certify);
thread = PR_CreateThread(PR_USER_THREAD, replica_abort_task_thread,
(void *)data, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
@@ -1987,6 +1990,7 @@ done:
slapi_sdn_free(&data->sdn);
ber_bvfree(data->payload);
slapi_ch_free_string(&data->repl_root);
+ slapi_ch_free_string(&data->certify);
slapi_ch_free((void **)&data);
}
}
diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
index 8cad386..bcfe184 100644
--- a/ldap/servers/plugins/replication/repl5_replica_config.c
+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
@@ -1265,7 +1265,8 @@ replica_cleanall_ruv_task(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter,
PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Invalid replica id (%d) for task - (%s)",
rid, slapi_sdn_get_dn(task_dn));
cleanruv_log(task, CLEANALLRUV_ID, "%s", returntext);
- rc = LDAP_OPERATIONS_ERROR;
+ *returncode = LDAP_OPERATIONS_ERROR;
+ rc = SLAPI_DSE_CALLBACK_ERROR;
goto out;
}
/*
@@ -1273,7 +1274,9 @@ replica_cleanall_ruv_task(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter,
*/
dn = slapi_sdn_new_dn_byval(base_dn);
if((r = replica_get_replica_from_dn(dn)) == NULL){
- *returncode = LDAP_OPERATIONS_ERROR ;
+ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Could not find replica from dn(%s)",slapi_sdn_get_dn(dn));
+ cleanruv_log(task, CLEANALLRUV_ID, "%s", returntext);
+ *returncode = LDAP_OPERATIONS_ERROR;
rc = SLAPI_DSE_CALLBACK_ERROR;
goto out;
}
@@ -1284,9 +1287,7 @@ replica_cleanall_ruv_task(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter,
out:
if(rc){
cleanruv_log(task, CLEANALLRUV_ID, "Task failed...(%d)", rc);
- *returncode = rc;
slapi_task_finish(task, *returncode);
- rc = SLAPI_DSE_CALLBACK_ERROR;
} else {
rc = SLAPI_DSE_CALLBACK_OK;
}
@@ -2185,18 +2186,19 @@ replica_cleanall_ruv_abort(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter
Replica *replica;
ReplicaId rid;
cleanruv_data *data = NULL;
- Slapi_DN *sdn;
+ Slapi_DN *sdn = NULL;
Object *r;
- CSN *maxcsn;
+ CSN *maxcsn = NULL;
const char *base_dn;
const char *rid_str;
- char *ridstr;
+ const char *certify_all;
+ char *ridstr = NULL;
int rc = SLAPI_DSE_CALLBACK_OK;
if(get_abort_cleanruv_task_count() >= CLEANRIDSIZ){
/* we are already running the maximum number of tasks */
- cleanruv_log(task, ABORT_CLEANALLRUV_ID,
- "Exceeded maximum number of active ABORT CLEANALLRUV tasks(%d)",CLEANRIDSIZ);
+ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Exceeded maximum number of active ABORT CLEANALLRUV tasks(%d)",CLEANRIDSIZ);
+ cleanruv_log(task, ABORT_CLEANALLRUV_ID, "%s", returntext);
*returncode = LDAP_OPERATIONS_ERROR;
return SLAPI_DSE_CALLBACK_ERROR;
}
@@ -2207,17 +2209,20 @@ replica_cleanall_ruv_abort(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter
* Get our task settings
*/
if ((rid_str = fetch_attr(e, "replica-id", 0)) == NULL){
- cleanruv_log(task, ABORT_CLEANALLRUV_ID,"Missing required attr \"replica-id\"");
+ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Missing required attr \"replica-id\"");
+ cleanruv_log(task, ABORT_CLEANALLRUV_ID, "%s", returntext);
*returncode = LDAP_OBJECT_CLASS_VIOLATION;
rc = SLAPI_DSE_CALLBACK_ERROR;
goto out;
}
if ((base_dn = fetch_attr(e, "replica-base-dn", 0)) == NULL){
- cleanruv_log(task, ABORT_CLEANALLRUV_ID,"Missing required attr \"replica-base-dn\"");
+ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Missing required attr \"replica-base-dn\"");
+ cleanruv_log(task, ABORT_CLEANALLRUV_ID, "%s", returntext);
*returncode = LDAP_OBJECT_CLASS_VIOLATION;
rc = SLAPI_DSE_CALLBACK_ERROR;
goto out;
}
+ certify_all = fetch_attr(e, "replica-certify-all", 0);
/*
* Check the rid
*/
@@ -2235,15 +2240,31 @@ replica_cleanall_ruv_abort(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter
*/
sdn = slapi_sdn_new_dn_byval(base_dn);
if((r = replica_get_replica_from_dn(sdn)) == NULL){
- cleanruv_log(task, ABORT_CLEANALLRUV_ID,"Failed to find replica from dn(%s)", base_dn);
+ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Failed to find replica from dn(%s)", base_dn);
+ cleanruv_log(task, ABORT_CLEANALLRUV_ID, "%s", returntext);
*returncode = LDAP_OPERATIONS_ERROR;
rc = SLAPI_DSE_CALLBACK_ERROR;
goto out;
}
/*
+ * Check verify value
+ */
+ if(certify_all){
+ if(strcasecmp(certify_all,"yes") && strcasecmp(certify_all,"no")){
+ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Invalid value for \"replica-certify-all\", the value "
+ "must be \"yes\" or \"no\".");
+ cleanruv_log(task, ABORT_CLEANALLRUV_ID, "%s", returntext);
+ *returncode = LDAP_OPERATIONS_ERROR;
+ rc = SLAPI_DSE_CALLBACK_ERROR;
+ goto out;
+ }
+ } else {
+ certify_all = "no";
+ }
+ /*
* Create payload
*/
- ridstr = slapi_ch_smprintf("%d:%s", rid, base_dn);
+ ridstr = slapi_ch_smprintf("%d:%s:%s", rid, base_dn, certify_all);
payload = create_ruv_payload(ridstr);
if(payload == NULL){
@@ -2277,6 +2298,7 @@ replica_cleanall_ruv_abort(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter
data->rid = rid;
data->repl_root = slapi_ch_strdup(base_dn);
data->sdn = NULL;
+ data->certify = slapi_ch_strdup(certify_all);
thread = PR_CreateThread(PR_USER_THREAD, replica_abort_task_thread,
(void *)data, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
@@ -2289,7 +2311,6 @@ replica_cleanall_ruv_abort(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter
}
out:
-
csn_free(&maxcsn);
slapi_ch_free_string(&ridstr);
slapi_sdn_free(&sdn);
@@ -2324,7 +2345,7 @@ replica_abort_task_thread(void *arg)
* to timing issues, we need to wait to grab the replica obj until we get here.
*/
if((data->repl_obj = replica_get_replica_from_dn(data->sdn)) == NULL){
- cleanruv_log(data->task, ABORT_CLEANALLRUV_ID, "Failed to get replica from dn (%s).", slapi_sdn_get_dn(data->sdn));
+ cleanruv_log(data->task, ABORT_CLEANALLRUV_ID, "Failed to get replica object from dn (%s).", slapi_sdn_get_dn(data->sdn));
goto done;
}
if(data->replica == NULL && data->repl_obj){
@@ -2338,6 +2359,10 @@ replica_abort_task_thread(void *arg)
*/
while(agmt_not_notified && !slapi_is_shutting_down()){
agmt_obj = agmtlist_get_first_agreement_for_replica (data->replica);
+ if(agmt_obj == NULL){
+ agmt_not_notified = 0;
+ break;
+ }
while (agmt_obj){
agmt = (Repl_Agmt*)object_get_data (agmt_obj);
if(!agmt_is_enabled(agmt) || get_agmt_agreement_type(agmt) == REPLICA_TYPE_WINDOWS){
@@ -2345,8 +2370,14 @@ replica_abort_task_thread(void *arg)
continue;
}
if(replica_cleanallruv_send_abort_extop(agmt, data->task, data->payload)){
- agmt_not_notified = 1;
- break;
+ if(strcasecmp(data->certify,"yes") == 0){
+ /* we are verifying all the replicas receive the abort task */
+ agmt_not_notified = 1;
+ break;
+ } else {
+ /* we do not care if we could not reach a replica, just continue as if we did */
+ agmt_not_notified = 0;
+ }
} else {
/* success */
agmt_not_notified = 0;
@@ -2376,7 +2407,7 @@ replica_abort_task_thread(void *arg)
done:
if(agmt_not_notified){
/* failure */
- cleanruv_log(data->task, ABORT_CLEANALLRUV_ID,"Abort task failed, will resume the task at the next server startup.");
+ cleanruv_log(data->task, ABORT_CLEANALLRUV_ID,"Abort task failed, will resume the task at the next server startup.");
} else {
/*
* Clean up the config
@@ -2393,6 +2424,7 @@ done:
ber_bvfree(data->payload);
}
slapi_ch_free_string(&data->repl_root);
+ slapi_ch_free_string(&data->certify);
slapi_sdn_free(&data->sdn);
slapi_ch_free((void **)&data);
}
diff --git a/ldap/servers/plugins/replication/repl_extop.c b/ldap/servers/plugins/replication/repl_extop.c
index 334b86b..a33dff3 100644
--- a/ldap/servers/plugins/replication/repl_extop.c
+++ b/ldap/servers/plugins/replication/repl_extop.c
@@ -1386,6 +1386,7 @@ multimaster_extop_abort_cleanruv(Slapi_PBlock *pb)
char *extop_oid;
char *repl_root;
char *payload = NULL;
+ char *certify_all;
char *iter;
int rc = 0;
@@ -1406,6 +1407,7 @@ multimaster_extop_abort_cleanruv(Slapi_PBlock *pb)
}
rid = atoi(ldap_utf8strtok_r(payload, ":", &iter));
repl_root = ldap_utf8strtok_r(iter, ":", &iter);
+ certify_all = ldap_utf8strtok_r(iter, ":", &iter);
if(!is_cleaned_rid(rid) || is_task_aborted(rid)){
/* This replica has already been aborted, or was never cleaned, or already finished cleaning */
@@ -1452,6 +1454,7 @@ multimaster_extop_abort_cleanruv(Slapi_PBlock *pb)
data->payload = slapi_ch_bvdup(extop_payload);
data->rid = rid;
data->repl_root = slapi_ch_strdup(repl_root);
+ data->certify = slapi_ch_strdup(certify_all);
/*
* Stop the cleaning, and delete the rid
*/
@@ -1472,6 +1475,8 @@ multimaster_extop_abort_cleanruv(Slapi_PBlock *pb)
}
slapi_log_error( SLAPI_LOG_REPL, repl_plugin_name, "Abort cleanAllRUV task: unable to create abort "
"thread. Aborting task.\n");
+ slapi_ch_free_string(&data->repl_root);
+ slapi_ch_free_string(&data->certify);
rc = LDAP_OPERATIONS_ERROR;
}
commit 16fa0c0e613e069c298c5fdf839bf9ae696eb9ad
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Fri Sep 7 13:56:39 2012 -0400
Ticket 450 - CLEANALLRUV task gets stuck on winsync replication agreement
Bug Description: cleanallruv task was incorrectly processing winsync agmts, which
lead to errors and failures
Fix Description: Ignore winsync agmts during cleanallruv task processing.
https://fedorahosted.org/389/ticket/450
Reviewed by: richm (Thanks Rich!)
(cherry picked from commit 8fcc45973ca636009de817d72ee612fcaf1c9597)
diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
index d969f3c..8cad386 100644
--- a/ldap/servers/plugins/replication/repl5_replica_config.c
+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
@@ -1552,7 +1552,7 @@ replica_cleanallruv_thread(void *arg)
}
while (agmt_obj){
agmt = (Repl_Agmt*)object_get_data (agmt_obj);
- if(!agmt_is_enabled(agmt)){ /* skip disabled replicas */
+ if(!agmt_is_enabled(agmt) || get_agmt_agreement_type(agmt) == REPLICA_TYPE_WINDOWS){
agmt_obj = agmtlist_get_next_agreement_for_replica (data->replica, agmt_obj);
continue;
}
@@ -1605,7 +1605,7 @@ replica_cleanallruv_thread(void *arg)
}
while (agmt_obj && !slapi_is_shutting_down()){
agmt = (Repl_Agmt*)object_get_data (agmt_obj);
- if(!agmt_is_enabled(agmt)){ /* skip disabled replicas */
+ if(!agmt_is_enabled(agmt) || get_agmt_agreement_type(agmt) == REPLICA_TYPE_WINDOWS){
agmt_obj = agmtlist_get_next_agreement_for_replica (data->replica, agmt_obj);
continue;
}
@@ -1698,7 +1698,7 @@ check_agmts_are_caught_up(Replica *replica, ReplicaId rid, char *maxcsn, Slapi_T
}
while (agmt_obj){
agmt = (Repl_Agmt*)object_get_data (agmt_obj);
- if(!agmt_is_enabled(agmt)){ /* skip disabled replicas */
+ if(!agmt_is_enabled(agmt) || get_agmt_agreement_type(agmt) == REPLICA_TYPE_WINDOWS){
agmt_obj = agmtlist_get_next_agreement_for_replica (replica, agmt_obj);
continue;
}
@@ -1753,7 +1753,7 @@ check_agmts_are_alive(Replica *replica, ReplicaId rid, Slapi_Task *task)
}
while (agmt_obj){
agmt = (Repl_Agmt*)object_get_data (agmt_obj);
- if(!agmt_is_enabled(agmt)){ /* skip disabled replicas */
+ if(!agmt_is_enabled(agmt) || get_agmt_agreement_type(agmt) == REPLICA_TYPE_WINDOWS){
agmt_obj = agmtlist_get_next_agreement_for_replica (replica, agmt_obj);
continue;
}
@@ -2163,7 +2163,7 @@ delete_cleaned_rid(Replica *r, ReplicaId rid, CSN *maxcsn)
agmt_obj = agmtlist_get_first_agreement_for_replica (r);
while (agmt_obj){
agmt = (Repl_Agmt*)object_get_data (agmt_obj);
- if(!agmt_is_enabled(agmt)){
+ if(!agmt_is_enabled(agmt) || get_agmt_agreement_type(agmt) == REPLICA_TYPE_WINDOWS){
agmt_obj = agmtlist_get_next_agreement_for_replica (r, agmt_obj);
continue;
}
@@ -2340,7 +2340,7 @@ replica_abort_task_thread(void *arg)
agmt_obj = agmtlist_get_first_agreement_for_replica (data->replica);
while (agmt_obj){
agmt = (Repl_Agmt*)object_get_data (agmt_obj);
- if(!agmt_is_enabled(agmt)){ /* skip disabled replicas */
+ if(!agmt_is_enabled(agmt) || get_agmt_agreement_type(agmt) == REPLICA_TYPE_WINDOWS){
agmt_obj = agmtlist_get_next_agreement_for_replica (data->replica, agmt_obj);
continue;
}
commit 8545947b812a160e49a3578bdb1aebd35189e335
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Tue Aug 21 12:18:21 2012 -0400
CLEANALLRUV coverity fixes
There was code that allowed for a static buffer overflow(CLEANRIDSIZ) in a few places,
but there are previous checks that make this impossible to over run.
A small potential memory leak was also fixed.
Reviewed by: Noriko(Thanks!)
(cherry picked from commit 37e0121445b69405a7d11f9990eb91dc3d3a0d7c)
(cherry picked from commit 2734a710d4283f6584768a3f15b583d4952e42cb)
diff --git a/ldap/servers/plugins/replication/repl5_agmt.c b/ldap/servers/plugins/replication/repl5_agmt.c
index ee94353..c63524b 100644
--- a/ldap/servers/plugins/replication/repl5_agmt.c
+++ b/ldap/servers/plugins/replication/repl5_agmt.c
@@ -396,7 +396,7 @@ agmt_new_from_entry(Slapi_Entry *e)
for (i = 0; i < CLEANRIDSIZ && clean_vals[i]; i++){
ra->cleanruv_notified[i] = atoi(clean_vals[i]);
}
- if(i <= CLEANRIDSIZ)
+ if(i < CLEANRIDSIZ)
ra->cleanruv_notified[i + 1] = 0;
slapi_ch_array_free(clean_vals);
} else {
@@ -2533,7 +2533,7 @@ agmt_set_cleanruv_notified_from_entry(Repl_Agmt *ra, Slapi_Entry *e){
for (i = 0; i < CLEANRIDSIZ && attr_vals[i]; i++){
ra->cleanruv_notified[i] = atoi(attr_vals[i]);
}
- if( i <= CLEANRIDSIZ )
+ if( i < CLEANRIDSIZ )
ra->cleanruv_notified[i + 1] = 0;
slapi_ch_array_free(attr_vals);
} else {
diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c
index c512faf..8bb0744 100644
--- a/ldap/servers/plugins/replication/repl5_replica.c
+++ b/ldap/servers/plugins/replication/repl5_replica.c
@@ -1967,6 +1967,7 @@ done:
if(payload == NULL){
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "Abort CleanAllRUV Task: failed to create extended "
"op payload\n");
+ slapi_ch_free((void **)&data);
} else {
/* setup the data */
data->repl_obj = NULL;
@@ -3829,10 +3830,10 @@ replica_add_cleanruv_data(Replica *r, char *val)
PR_Lock(r->repl_lock);
for (i = 0; i < CLEANRIDSIZ && r->repl_cleanruv_data[i] != NULL; i++); /* goto the end of the list */
- if( i < CLEANRIDSIZ)
+ if( i < CLEANRIDSIZ){
r->repl_cleanruv_data[i] = slapi_ch_strdup(val); /* append to list */
- if(i <= CLEANRIDSIZ)
- r->repl_cleanruv_data[i + 1] = NULL;
+ r->repl_cleanruv_data[i + 1] = 0;
+ }
PR_Unlock(r->repl_lock);
}
commit 9e85def2dc45fdb02d1c4a185138715726a8cd1f
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Mon Aug 20 12:17:51 2012 -0400
Ticket 403 - fix CLEANALLRUV regression from last commit
Bug Description: The last commit for CLEANALLRUV caused a regression that could
hang the process when comparing maxcsn's.
Fix Description: Needed to write a new ruv_compare_csn function to handle the
unique scenarios presented by CLEANALLRUV.
Also improved settings verfication, and error handling.
https://fedorahosted.org/389/ticket/403
Reviewed by: ?
(cherry picked from commit 0968b3f5d5551dc75e00c9d6e9528cc062f451fa)
diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
index ef69d75..d969f3c 100644
--- a/ldap/servers/plugins/replication/repl5_replica_config.c
+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
@@ -1464,19 +1464,32 @@ replica_cleanallruv_thread(void *arg)
if(data->replica == NULL && data->repl_obj == NULL){
/*
* This thread was initiated at startup because the process did not finish. Due
- * to timing issues, we need to wait to grab the replica obj until we get here.
+ * to startup timing issues, we need to wait before grabbing the replica obj, as
+ * the backends might not be online yet.
*/
+ PR_Lock( notify_lock );
+ PR_WaitCondVar( notify_cvar, PR_SecondsToInterval(5) );
+ PR_Unlock( notify_lock );
data->repl_obj = replica_get_replica_from_dn(data->sdn);
+ if(data->repl_obj == NULL){
+ cleanruv_log(data->task, CLEANALLRUV_ID, "Unable to retrieve repl object from dn(%s).", data->sdn);
+ aborted = 1;
+ goto done;
+ }
data->replica = (Replica*)object_get_data(data->repl_obj);
free_obj = 1;
- }
- if(data->replica == NULL && data->repl_obj){
+ } else if(data->replica == NULL && data->repl_obj){
data->replica = (Replica*)object_get_data(data->repl_obj);
- }
- if( data->repl_obj == NULL){
+ } else if( data->repl_obj == NULL && data->replica){
data->repl_obj = object_new(data->replica, NULL);
free_obj = 1;
}
+ /* verify we have set our repl objects */
+ if(data->repl_obj == NULL || data->replica == NULL){
+ cleanruv_log(data->task, CLEANALLRUV_ID, "Unable to set the replica objects.");
+ aborted = 1;
+ goto done;
+ }
if(data->task){
slapi_task_begin(data->task, 1);
}
@@ -1495,11 +1508,13 @@ replica_cleanallruv_thread(void *arg)
ruv_obj = replica_get_ruv(data->replica);
ruv = object_get_data (ruv_obj);
while(data->maxcsn && !is_task_aborted(data->rid) && !is_cleaned_rid(data->rid) && !slapi_is_shutting_down()){
- if(csn_get_replicaid(data->maxcsn) == 0 || ruv_covers_csn_strict(ruv,data->maxcsn)){
+ if(csn_get_replicaid(data->maxcsn) == 0 || ruv_covers_csn_cleanallruv(ruv,data->maxcsn)){
/* We are caught up, now we can clean the ruv's */
break;
}
- DS_Sleep(PR_SecondsToInterval(5));
+ PR_Lock( notify_lock );
+ PR_WaitCondVar( notify_cvar, PR_SecondsToInterval(5) );
+ PR_Unlock( notify_lock );
}
object_release(ruv_obj);
/*
@@ -1966,7 +1981,7 @@ add_cleaned_rid(ReplicaId rid, Replica *r, char *maxcsn)
repl_get_plugin_identity (PLUGIN_MULTIMASTER_REPLICATION), 0);
slapi_modify_internal_pb (pb);
slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
- if (rc != LDAP_SUCCESS){
+ if (rc != LDAP_SUCCESS && rc != LDAP_TYPE_OR_VALUE_EXISTS){
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "CleanAllRUV Task: failed to update replica "
"config (%d), rid (%d)\n", rc, rid);
}
diff --git a/ldap/servers/plugins/replication/repl5_ruv.c b/ldap/servers/plugins/replication/repl5_ruv.c
index b962951..dd32ef2 100644
--- a/ldap/servers/plugins/replication/repl5_ruv.c
+++ b/ldap/servers/plugins/replication/repl5_ruv.c
@@ -920,6 +920,35 @@ ruv_covers_csn_strict(const RUV *ruv, const CSN *csn)
return rc;
}
+/*
+ * Used by the cleanallruv task
+ *
+ * We want to return TRUE if replica is NULL,
+ * and we want to use "csn_compare() <="
+ */
+PRBool
+ruv_covers_csn_cleanallruv(const RUV *ruv, const CSN *csn)
+{
+ RUVElement *replica;
+ ReplicaId rid;
+ PRBool return_value;
+
+ if (ruv == NULL || csn == NULL){
+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "ruv_covers_csn_cleanallruv: NULL argument\n");
+ return_value = PR_FALSE;
+ } else {
+ rid = csn_get_replicaid(csn);
+ replica = ruvGetReplica (ruv, rid);
+ if (replica == NULL){
+ /* already cleaned */
+ return_value = PR_TRUE;
+ } else {
+ return_value = (csn_compare (csn, replica->csn) <= 0);
+ }
+ }
+
+ return return_value;
+}
/*
* The function gets min{maxcsns of all ruv elements} if get_the_max=0,
diff --git a/ldap/servers/plugins/replication/repl5_ruv.h b/ldap/servers/plugins/replication/repl5_ruv.h
index f2d96f3..944f5ed 100644
--- a/ldap/servers/plugins/replication/repl5_ruv.h
+++ b/ldap/servers/plugins/replication/repl5_ruv.h
@@ -115,6 +115,7 @@ void ruv_set_replica_generation (RUV *ruv, const char *generation);
PRBool ruv_covers_ruv(const RUV *covering_ruv, const RUV *covered_ruv);
PRBool ruv_covers_csn(const RUV *ruv, const CSN *csn);
PRBool ruv_covers_csn_strict(const RUV *ruv, const CSN *csn);
+PRBool ruv_covers_csn_cleanallruv(const RUV *ruv, const CSN *csn);
int ruv_get_min_csn(const RUV *ruv, CSN **csn);
int ruv_get_max_csn(const RUV *ruv, CSN **csn);
int ruv_get_rid_max_csn(const RUV *ruv, CSN **csn, ReplicaId rid);
diff --git a/ldap/servers/plugins/replication/repl_extop.c b/ldap/servers/plugins/replication/repl_extop.c
index ecf1f93..334b86b 100644
--- a/ldap/servers/plugins/replication/repl_extop.c
+++ b/ldap/servers/plugins/replication/repl_extop.c
@@ -1541,8 +1541,6 @@ multimaster_extop_cleanruv(Slapi_PBlock *pb)
csn_free(&maxcsn);
rc = 1;
goto free_and_return;
- } else {
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: cleaning rid (%d)...\n", rid);
}
/*
@@ -1618,7 +1616,7 @@ multimaster_extop_cleanruv(Slapi_PBlock *pb)
break;
}
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: checking if we're caught up...\n");
- if(ruv_covers_csn_strict(ruv,maxcsn) || csn_get_replicaid(maxcsn) == 0){
+ if(ruv_covers_csn_cleanallruv(ruv,maxcsn) || csn_get_replicaid(maxcsn) == 0){
/* We are caught up */
break;
} else {
commit cacd4bc52d576d655da43a78d0dccb90f475a3e4
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Wed Aug 15 10:54:00 2012 -0400
Ticket 403 - CLEANALLRUV revisions
Addressed two issues:
[1] Need to handle case where rid was already cleaned
[2] Needed to improve closing sequence when repl agmts are not present
Reviewed by richm and noriko(Thanks!)
https://fedorahosted.org/389/ticket/403
(cherry picked from commit c40902c872fab29922d8dca8f32dc18dabc7d936)
diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
index 0ddec25..ef69d75 100644
--- a/ldap/servers/plugins/replication/repl5_replica_config.c
+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
@@ -1454,6 +1454,7 @@ replica_cleanallruv_thread(void *arg)
int found_dirty_rid = 1;
int agmt_not_notified = 1;
int interval = 10;
+ int aborted = 0;
int free_obj = 0;
int rc = 0;
@@ -1494,7 +1495,7 @@ replica_cleanallruv_thread(void *arg)
ruv_obj = replica_get_ruv(data->replica);
ruv = object_get_data (ruv_obj);
while(data->maxcsn && !is_task_aborted(data->rid) && !is_cleaned_rid(data->rid) && !slapi_is_shutting_down()){
- if(csn_get_replicaid(data->maxcsn) == 0 || ruv_covers_csn(ruv,data->maxcsn)){
+ if(csn_get_replicaid(data->maxcsn) == 0 || ruv_covers_csn_strict(ruv,data->maxcsn)){
/* We are caught up, now we can clean the ruv's */
break;
}
@@ -1507,6 +1508,7 @@ replica_cleanallruv_thread(void *arg)
cleanruv_log(data->task, CLEANALLRUV_ID,"Waiting for all the replicas to be online...");
if(check_agmts_are_alive(data->replica, data->rid, data->task)){
/* error, aborted or shutdown */
+ aborted = 1;
goto done;
}
/*
@@ -1515,6 +1517,7 @@ replica_cleanallruv_thread(void *arg)
cleanruv_log(data->task, CLEANALLRUV_ID,"Waiting for all the replicas to receive all the deleted replica updates...");
if(check_agmts_are_caught_up(data->replica, data->rid, csnstr, data->task)){
/* error, aborted or shutdown */
+ aborted = 1;
goto done;
}
/*
@@ -1548,6 +1551,7 @@ replica_cleanallruv_thread(void *arg)
}
if(is_task_aborted(data->rid)){
+ aborted = 1;
goto done;
}
if(agmt_not_notified == 0){
@@ -1600,6 +1604,7 @@ replica_cleanallruv_thread(void *arg)
}
/* If the task is abort or everyone is cleaned, break out */
if(is_task_aborted(data->rid)){
+ aborted = 1;
goto done;
}
if(found_dirty_rid == 0){
@@ -1625,7 +1630,7 @@ done:
/*
* If the replicas are cleaned, release the rid, and trim the changelog
*/
- if(!found_dirty_rid){
+ if(!aborted){
trigger_cl_trimming(data->rid);
delete_cleaned_rid(data->replica, data->rid, data->maxcsn);
cleanruv_log(data->task, CLEANALLRUV_ID, "Successfully cleaned rid(%d).", data->rid);
diff --git a/ldap/servers/plugins/replication/repl_extop.c b/ldap/servers/plugins/replication/repl_extop.c
index db94ba7..ecf1f93 100644
--- a/ldap/servers/plugins/replication/repl_extop.c
+++ b/ldap/servers/plugins/replication/repl_extop.c
@@ -1618,7 +1618,7 @@ multimaster_extop_cleanruv(Slapi_PBlock *pb)
break;
}
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: checking if we're caught up...\n");
- if(ruv_covers_csn(ruv,maxcsn) || csn_get_replicaid(maxcsn) == 0){
+ if(ruv_covers_csn_strict(ruv,maxcsn) || csn_get_replicaid(maxcsn) == 0){
/* We are caught up */
break;
} else {
commit e2571130f23402fb1820f2a9895172ce87ab2b3a
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Fri Aug 3 11:28:43 2012 -0400
Ticket 403 - cleanallruv coverity fixes
Fixed coverity issues
Reviewed by: richm(Thanks Rich!)
(cherry picked from commit 75e5d3d1dba984f0219512d908d1a624096c7acc)
1.2.10 cherry-picked from d68b40c3b5638f5160ff12584bb535dac6cb6628
- removed replica enabled, strip attrs code
diff --git a/ldap/servers/plugins/replication/repl5_agmt.c b/ldap/servers/plugins/replication/repl5_agmt.c
index 6e4e2d7..ee94353 100644
--- a/ldap/servers/plugins/replication/repl5_agmt.c
+++ b/ldap/servers/plugins/replication/repl5_agmt.c
@@ -396,7 +396,8 @@ agmt_new_from_entry(Slapi_Entry *e)
for (i = 0; i < CLEANRIDSIZ && clean_vals[i]; i++){
ra->cleanruv_notified[i] = atoi(clean_vals[i]);
}
- ra->cleanruv_notified[i + 1] = 0;
+ if(i <= CLEANRIDSIZ)
+ ra->cleanruv_notified[i + 1] = 0;
slapi_ch_array_free(clean_vals);
} else {
ra->cleanruv_notified[0] = 0;
@@ -2532,7 +2533,9 @@ agmt_set_cleanruv_notified_from_entry(Repl_Agmt *ra, Slapi_Entry *e){
for (i = 0; i < CLEANRIDSIZ && attr_vals[i]; i++){
ra->cleanruv_notified[i] = atoi(attr_vals[i]);
}
- ra->cleanruv_notified[i + 1] = 0;
+ if( i <= CLEANRIDSIZ )
+ ra->cleanruv_notified[i + 1] = 0;
+ slapi_ch_array_free(attr_vals);
} else {
ra->cleanruv_notified[0] = 0;
}
diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c
index 135f3a2..c512faf 100644
--- a/ldap/servers/plugins/replication/repl5_replica.c
+++ b/ldap/servers/plugins/replication/repl5_replica.c
@@ -1838,7 +1838,7 @@ replica_check_for_tasks(Replica *r, Slapi_Entry *e)
ReplicaId rid;
int i;
- for(i = 0; clean_vals[i]; i++){
+ for(i = 0; i < CLEANRIDSIZ && clean_vals[i]; i++){
cleanruv_data *data = NULL;
/*
@@ -1876,7 +1876,8 @@ replica_check_for_tasks(Replica *r, Slapi_Entry *e)
if(payload == NULL){
slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "CleanAllRUV Task: Startup: Failed to "
"create extended op payload, aborting task");
- return;
+ csn_free(&maxcsn);
+ goto done;
}
/*
* Setup the data struct, and fire off the thread.
@@ -1899,12 +1900,20 @@ replica_check_for_tasks(Replica *r, Slapi_Entry *e)
(void *)data, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
PR_UNJOINABLE_THREAD, SLAPD_DEFAULT_THREAD_STACKSIZE);
if (thread == NULL) {
+ /* log an error and free everything */
slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV: unable to create cleanAllRUV "
"thread for rid(%d)\n", (int)data->rid);
+ csn_free(&maxcsn);
+ slapi_sdn_free(&data->sdn);
+ ber_bvfree(data->payload);
+ slapi_ch_free((void **)&data);
}
}
}
r->repl_cleanruv_data[i] = NULL;
+
+done:
+ slapi_ch_array_free(clean_vals);
}
if ((clean_vals = slapi_entry_attr_get_charray(e, type_replicaAbortCleanRUV)) != NULL)
@@ -1928,12 +1937,12 @@ replica_check_for_tasks(Replica *r, Slapi_Entry *e)
if(rid <= 0 || rid >= READ_ONLY_REPLICA_ID){
slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "Abort CleanAllRUV Task: invalid replica id(%d) "
"aborting task.\n", rid);
- goto done;
+ goto done2;
}
} else {
slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "Abort CleanAllRUV Task: unable to parse cleanallruv "
"data (%s), aborting task.\n",clean_vals[i]);
- goto done;
+ goto done2;
}
repl_root = ldap_utf8strtok_r(iter, ":", &iter);
@@ -1974,14 +1983,18 @@ replica_check_for_tasks(Replica *r, Slapi_Entry *e)
if (thread == NULL) {
slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "Abort CleanAllRUV Task: unable to create abort cleanAllRUV "
"thread for rid(%d)\n", (int)data->rid);
+ slapi_sdn_free(&data->sdn);
+ ber_bvfree(data->payload);
+ slapi_ch_free_string(&data->repl_root);
+ slapi_ch_free((void **)&data);
}
}
}
}
- }
-done:
- slapi_ch_array_free(clean_vals);
+done2:
+ slapi_ch_array_free(clean_vals);
+ }
}
/* This function updates the entry to contain information generated
@@ -3816,8 +3829,10 @@ replica_add_cleanruv_data(Replica *r, char *val)
PR_Lock(r->repl_lock);
for (i = 0; i < CLEANRIDSIZ && r->repl_cleanruv_data[i] != NULL; i++); /* goto the end of the list */
- r->repl_cleanruv_data[i] = slapi_ch_strdup(val); /* append to list */
- r->repl_cleanruv_data[i + 1] = NULL;
+ if( i < CLEANRIDSIZ)
+ r->repl_cleanruv_data[i] = slapi_ch_strdup(val); /* append to list */
+ if(i <= CLEANRIDSIZ)
+ r->repl_cleanruv_data[i + 1] = NULL;
PR_Unlock(r->repl_lock);
}
diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
index 8ae9add..0ddec25 100644
--- a/ldap/servers/plugins/replication/repl5_replica_config.c
+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
@@ -1322,21 +1322,13 @@ replica_execute_cleanall_ruv_task (Object *r, ReplicaId rid, Slapi_Task *task, c
/* we are already running the maximum number of tasks */
cleanruv_log(pre_task, CLEANALLRUV_ID,
"Exceeded maximum number of active CLEANALLRUV tasks(%d)",CLEANRIDSIZ);
- returntext = PR_smprintf("Exceeded maximum number of active CLEANALLRUV tasks(%d), "
- "you must wait for one to finish.", CLEANRIDSIZ);
return LDAP_UNWILLING_TO_PERFORM;
}
/*
* Grab the replica
*/
- if(r){
- replica = (Replica*)object_get_data (r);
- } else {
- cleanruv_log(pre_task, CLEANALLRUV_ID, "Replica is NULL, aborting task");
- rc = -1;
- goto fail;
- }
+ replica = (Replica*)object_get_data (r);
/*
* Check if this is a consumer
*/
@@ -1422,7 +1414,8 @@ fail:
ber_bvfree(payload);
}
csn_free(&maxcsn);
- object_release (r);
+ if(task) /* only the task acquires the r obj */
+ object_release (r);
done:
@@ -1479,7 +1472,7 @@ replica_cleanallruv_thread(void *arg)
if(data->replica == NULL && data->repl_obj){
data->replica = (Replica*)object_get_data(data->repl_obj);
}
- if( data->replica && data->repl_obj == NULL){
+ if( data->repl_obj == NULL){
data->repl_obj = object_new(data->replica, NULL);
free_obj = 1;
}
@@ -1822,7 +1815,7 @@ replica_send_cleanruv_task(Repl_Agmt *agmt, ReplicaId rid, Slapi_Task *task)
Repl_Connection *conn;
ConnResult crc = 0;
LDAP *ld;
- Slapi_DN *dn;
+ Slapi_DN *sdn;
struct berval *vals[2];
struct berval val;
LDAPMod *mods[2];
@@ -1845,7 +1838,7 @@ replica_send_cleanruv_task(Repl_Agmt *agmt, ReplicaId rid, Slapi_Task *task)
return;
}
val.bv_len = PR_snprintf(data, sizeof(data), "CLEANRUV%d", rid);
- dn = agmt_get_replarea(agmt);
+ sdn = agmt_get_replarea(agmt);
mod.mod_op = LDAP_MOD_ADD|LDAP_MOD_BVALUES;
mod.mod_type = "nsds5task";
mod.mod_bvalues = vals;
@@ -1854,7 +1847,7 @@ replica_send_cleanruv_task(Repl_Agmt *agmt, ReplicaId rid, Slapi_Task *task)
val.bv_val = data;
mods[0] = &mod;
mods[1] = NULL;
- repl_dn = PR_smprintf("cn=replica,cn=\"%s\",cn=mapping tree,cn=config", slapi_sdn_get_dn(dn));
+ repl_dn = slapi_create_dn_string("cn=replica,cn=%s,cn=mapping tree,cn=config", slapi_sdn_get_dn(sdn));
/*
* Add task to remote replica
*/
@@ -1866,6 +1859,7 @@ replica_send_cleanruv_task(Repl_Agmt *agmt, ReplicaId rid, Slapi_Task *task)
agmt_get_long_name(agmt), agmt_get_hostname(agmt), rc);
}
slapi_ch_free_string(&repl_dn);
+ slapi_sdn_free(&sdn);
conn_delete_internal_ext(conn);
}
@@ -1943,6 +1937,9 @@ add_cleaned_rid(ReplicaId rid, Replica *r, char *maxcsn)
char *dn;
int rc;
+ if(r == NULL || maxcsn == NULL){
+ return;
+ }
/*
* Write the rid & maxcsn to the config entry
*/
@@ -2071,13 +2068,12 @@ delete_aborted_rid(Replica *r, ReplicaId rid, char *repl_root){
slapi_modify_internal_set_pb(pb, dn, mods, NULL, NULL, repl_get_plugin_identity (PLUGIN_MULTIMASTER_REPLICATION), 0);
slapi_modify_internal_pb (pb);
- slapi_pblock_destroy (pb);
slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
if (rc != LDAP_SUCCESS){
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "Abort CleanAllRUV Task: failed to remove replica "
"config (%d), rid (%d)\n", rc, rid);
}
-
+ slapi_pblock_destroy (pb);
slapi_ch_free_string(&dn);
slapi_ch_free_string(&data);
}
@@ -2169,7 +2165,7 @@ replica_cleanall_ruv_abort(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter
Replica *replica;
ReplicaId rid;
cleanruv_data *data = NULL;
- const Slapi_DN *dn;
+ Slapi_DN *sdn;
Object *r;
CSN *maxcsn;
const char *base_dn;
@@ -2181,8 +2177,6 @@ replica_cleanall_ruv_abort(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter
/* we are already running the maximum number of tasks */
cleanruv_log(task, ABORT_CLEANALLRUV_ID,
"Exceeded maximum number of active ABORT CLEANALLRUV tasks(%d)",CLEANRIDSIZ);
- returntext = PR_smprintf("Exceeded maximum number of active ABORT CLEANALLRUV tasks(%d), "
- "you must wait for one to finish.", CLEANRIDSIZ);
*returncode = LDAP_OPERATIONS_ERROR;
return SLAPI_DSE_CALLBACK_ERROR;
}
@@ -2219,8 +2213,8 @@ replica_cleanall_ruv_abort(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter
/*
* Get the replica object
*/
- dn = slapi_sdn_new_dn_byval(base_dn);
- if((r = replica_get_replica_from_dn(dn)) == NULL){
+ sdn = slapi_sdn_new_dn_byval(base_dn);
+ if((r = replica_get_replica_from_dn(sdn)) == NULL){
cleanruv_log(task, ABORT_CLEANALLRUV_ID,"Failed to find replica from dn(%s)", base_dn);
*returncode = LDAP_OPERATIONS_ERROR;
rc = SLAPI_DSE_CALLBACK_ERROR;
@@ -2278,6 +2272,7 @@ out:
csn_free(&maxcsn);
slapi_ch_free_string(&ridstr);
+ slapi_sdn_free(&sdn);
if(rc != SLAPI_DSE_CALLBACK_OK){
cleanruv_log(task, ABORT_CLEANALLRUV_ID, "Abort Task failed (%d)", rc);
@@ -2480,7 +2475,7 @@ replica_cleanallruv_check_maxcsn(Repl_Agmt *agmt, char *rid_text, char *maxcsn,
{
Repl_Connection *conn = NULL;
LDAP *ld;
- Slapi_DN *dn = agmt_get_replarea(agmt);
+ Slapi_DN *sdn;
struct berval **vals;
LDAPMessage *result = NULL, *entry = NULL;
BerElement *ber;
@@ -2504,10 +2499,11 @@ replica_cleanallruv_check_maxcsn(Repl_Agmt *agmt, char *rid_text, char *maxcsn,
conn_delete_internal_ext(conn);
return -1;
}
- rc = ldap_search_ext_s(ld, slapi_sdn_get_dn(dn), LDAP_SCOPE_SUBTREE,
+ sdn = agmt_get_replarea(agmt);
+ rc = ldap_search_ext_s(ld, slapi_sdn_get_dn(sdn), LDAP_SCOPE_SUBTREE,
"(&(nsuniqueid=ffffffff-ffffffff-ffffffff-ffffffff)(objectclass=nstombstone))",
attrs, 0, NULL, NULL, NULL, 0, &result);
- slapi_sdn_free(&dn);
+ slapi_sdn_free(&sdn);
if(rc != LDAP_SUCCESS){
cleanruv_log(task, CLEANALLRUV_ID,"Failed to contact "
"agmt (%s) error (%d), will retry later.", agmt_get_long_name(agmt), rc);
@@ -2533,7 +2529,7 @@ replica_cleanallruv_check_maxcsn(Repl_Agmt *agmt, char *rid_text, char *maxcsn,
for(part_count = 1; ruv_part && part_count < 5; part_count++){
ruv_part = ldap_utf8strtok_r(iter, " ", &iter);
}
- if(part_count == 5){
+ if(part_count == 5 && ruv_part){
/* we have the maxcsn */
if(strcmp(ruv_part, maxcsn)){
/* we are not caught up yet, free, and return */
@@ -2621,7 +2617,7 @@ replica_cleanallruv_check_ruv(Repl_Agmt *ra, char *rid_text, Slapi_Task *task)
struct berval **vals = NULL;
LDAPMessage *result = NULL, *entry = NULL;
LDAP *ld = NULL;
- Slapi_DN *dn = agmt_get_replarea(ra);
+ Slapi_DN *sdn;
char *attrs[2];
char *attr = NULL;
int rc = 0, i;
@@ -2640,10 +2636,11 @@ replica_cleanallruv_check_ruv(Repl_Agmt *ra, char *rid_text, Slapi_Task *task)
goto done;
}
- rc = ldap_search_ext_s(ld, slapi_sdn_get_dn(dn), LDAP_SCOPE_SUBTREE,
+ sdn = agmt_get_replarea(ra);
+ rc = ldap_search_ext_s(ld, slapi_sdn_get_dn(sdn), LDAP_SCOPE_SUBTREE,
"(&(nsuniqueid=ffffffff-ffffffff-ffffffff-ffffffff)(objectclass=nstombstone))",
attrs, 0, NULL, NULL, NULL, 0, &result);
- slapi_sdn_free(&dn);
+ slapi_sdn_free(&sdn);
if(rc != LDAP_SUCCESS){
cleanruv_log(task, CLEANALLRUV_ID,"Failed to contact "
"agmt (%s) error (%d), will retry later.", agmt_get_long_name(ra), rc);
diff --git a/ldap/servers/plugins/replication/repl_extop.c b/ldap/servers/plugins/replication/repl_extop.c
index 88bb9e3..db94ba7 100644
--- a/ldap/servers/plugins/replication/repl_extop.c
+++ b/ldap/servers/plugins/replication/repl_extop.c
@@ -1499,7 +1499,7 @@ multimaster_extop_cleanruv(Slapi_PBlock *pb)
PRThread *thread = NULL;
Replica *r = NULL;
cleanruv_data *data = NULL;
- CSN *maxcsn;
+ CSN *maxcsn = NULL;
struct berval *extop_payload;
struct berval *resp_bval = NULL;
BerElement *resp_bere = NULL;
@@ -1656,6 +1656,8 @@ free_and_return:
if (mtnode_ext->replica)
object_release (mtnode_ext->replica);
}
+ if(rc)
+ csn_free(&maxcsn);
slapi_ch_free_string(&payload);
/*
commit da92c0d4da1997e74f2b169fc531f18dd6cbefb3
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Wed Aug 1 16:12:01 2012 -0400
Ticket 403 - CLEANALLRUV feature
This is a rewrite of the first version of CLEANALLRUV. The task is now an official slapi task, but the
older/original method still works as well. You can run multiple tasks(4) at the same time. The task can handle
situations where a replica is down, or "older"replicas are in the topology. I've also added an "abort"
task to cancel a particular cleanallruv task, as the task can potentially run for a long time while
waiting for a server to come online or be cleaned.
https://fedorahosted.org/389/ticket/403
Reviewed by: richm & noriko (Thanks!)
(cherry picked from commit 657efc69487cc1b04d82642dddd47f93b7a37cf1)
1.2.10 branch cherry-picked from 74b25ce9c7bf2fc05e401896238f6039c3aefb03
- many conflicts
- took only the cleanruv changes, skipped the rest
diff --git a/Makefile.am b/Makefile.am
index bb761e3..e67f9fa 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -371,6 +371,7 @@ task_SCRIPTS = ldap/admin/src/scripts/template-bak2db \
ldap/admin/src/scripts/template-db2ldif.pl \
ldap/admin/src/scripts/template-fixup-linkedattrs.pl \
ldap/admin/src/scripts/template-fixup-memberof.pl \
+ ldap/admin/src/scripts/template-cleanallruv.pl \
ldap/admin/src/scripts/template-ldif2db.pl \
ldap/admin/src/scripts/template-ns-accountstatus.pl \
ldap/admin/src/scripts/template-ns-activate.pl \
diff --git a/Makefile.in b/Makefile.in
index 88ab46f..efa370b 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1575,6 +1575,7 @@ task_SCRIPTS = ldap/admin/src/scripts/template-bak2db \
ldap/admin/src/scripts/template-db2ldif.pl \
ldap/admin/src/scripts/template-fixup-linkedattrs.pl \
ldap/admin/src/scripts/template-fixup-memberof.pl \
+ ldap/admin/src/scripts/template-cleanallruv.pl \
ldap/admin/src/scripts/template-ldif2db.pl \
ldap/admin/src/scripts/template-ns-accountstatus.pl \
ldap/admin/src/scripts/template-ns-activate.pl \
diff --git a/ldap/admin/src/scripts/template-cleanallruv.pl.in b/ldap/admin/src/scripts/template-cleanallruv.pl.in
new file mode 100644
index 0000000..be95a6d
--- /dev/null
+++ b/ldap/admin/src/scripts/template-cleanallruv.pl.in
@@ -0,0 +1,186 @@
+#{{PERL-EXEC}}
+#
+# BEGIN COPYRIGHT BLOCK
+# This Program is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free Software
+# Foundation; version 2 of the License.
+#
+# This Program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
+# Place, Suite 330, Boston, MA 02111-1307 USA.
+#
+# In addition, as a special exception, Red Hat, Inc. gives You the additional
+# right to link the code of this Program with code not covered under the GNU
+# General Public License ("Non-GPL Code") and to distribute linked combinations
+# including the two, subject to the limitations in this paragraph. Non-GPL Code
+# permitted under this exception must only link to the code of this Program
+# through those well defined interfaces identified in the file named EXCEPTION
+# found in the source code files (the "Approved Interfaces"). The files of
+# Non-GPL Code may instantiate templates or use macros or inline functions from
+# the Approved Interfaces without causing the resulting work to be covered by
+# the GNU General Public License. Only Red Hat, Inc. may make changes or
+# additions to the list of Approved Interfaces. You must obey the GNU General
+# Public License in all respects for all of the Program code and other code used
+# in conjunction with the Program except the Non-GPL Code covered by this
+# exception. If you modify this file, you may extend this exception to your
+# version of the file, but you are not obligated to do so. If you do not wish to
+# provide this exception without modification, you must delete this exception
+# statement from your version and license this file solely under the GPL without
+# exception.
+#
+#
+# Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
+# Copyright (C) 2012 Red Hat, Inc.
+# All rights reserved.
+# END COPYRIGHT BLOCK
+#
+
+sub usage {
+ print(STDERR "Usage: $0 [-v] -D rootdn { -w password | -w - | -j filename } \n");
+ print(STDERR " [-b basedn | -r rid | -A]\n");
+ print(STDERR " Opts: -D rootdn - Directory Manager\n");
+ print(STDERR " : -w password - Directory Manager's password\n");
+ print(STDERR " : -w - - Prompt for Directory Manager's password\n");
+ print(STDERR " : -j filename - Read Directory Manager's password from file\n");
+ print(STDERR " : -b basedn - DN of the replica root you want to clean\n");
+ print(STDERR " : -r rid - The replica id that you want to clean\n");
+ print(STDERR " : -A - Abort an existing cleanallruv task(must use with -b and -r args\n");
+ print(STDERR " : -v - verbose\n");
+}
+
+$rootdn = "";
+$passwd = "";
+$passwdfile = "";
+$basedn = "";
+$rid = "";
+$abort = "";
+$verbose = 0;
+
+$prefix = "{{DS-ROOT}}";
+
+$ENV{'PATH'} = "$prefix@ldaptool_bindir@:$prefix/usr/bin:@ldaptool_bindir@:/usr/bin";
+
+libpath_add("$prefix@nss_libdir@");
+libpath_add("$prefix/usr/lib");
+libpath_add("@nss_libdir@");
+libpath_add("/usr/lib");
+
+$ENV{'SHLIB_PATH'} = "$ENV{'LD_LIBRARY_PATH'}";
+
+$i = 0;
+while ($i <= $#ARGV)
+{
+ if ("$ARGV[$i]" eq "-b")
+ {
+ # Base DN
+ $i++; $basedn = $ARGV[$i];
+ }
+ elsif ("$ARGV[$i]" eq "-r")
+ {
+ # rid
+ $i++; $rid = $ARGV[$i];
+ }
+ elsif ("$ARGV[$i]" eq "-A")
+ {
+ # abort
+ $abort = "yes";
+ }
+ elsif ("$ARGV[$i]" eq "-D")
+ {
+ # Directory Manager
+ $i++; $rootdn = $ARGV[$i];
+ }
+ elsif ("$ARGV[$i]" eq "-w")
+ {
+ # Directory Manager's password
+ $i++; $passwd = $ARGV[$i];
+ }
+ elsif ("$ARGV[$i]" eq "-j")
+ {
+ # Read Directory Manager's password from a file
+ $i++; $passwdfile = $ARGV[$i];
+ }
+ elsif ("$ARGV[$i]" eq "-v")
+ {
+ # verbose
+ $verbose = 1;
+ }
+ else
+ {
+ &usage; exit(1);
+ }
+ $i++;
+}
+
+if ($passwdfile ne ""){
+# Open file and get the password
+ unless (open (RPASS, $passwdfile)) {
+ die "Error, cannot open password file $passwdfile\n";
+ }
+ $passwd = <RPASS>;
+ chomp($passwd);
+ close(RPASS);
+} elsif ($passwd eq "-"){
+# Read the password from terminal
+ print "Bind Password: ";
+ # Disable console echo
+ system("@sttyexec@ -echo") if -t STDIN;
+ # read the answer
+ $passwd = <STDIN>;
+ # Enable console echo
+ system("@sttyexec@ echo") if -t STDIN;
+ print "\n";
+ chop($passwd); # trim trailing newline
+}
+
+if ( $rootdn eq "" || $passwd eq "" || $basedn eq "" || $rid eq "")
+{
+ &usage;
+ exit(1);
+}
+
+$vstr = "";
+if ($verbose != 0)
+{
+ $vstr = "-v";
+}
+
+# Use a timestamp as part of the task entry name
+($s, $m, $h, $dy, $mn, $yr, $wdy, $ydy, $r) = localtime(time);
+$mn++; $yr += 1900;
+
+if($abort eq ""){
+ # Build the task entry to add
+ $taskname = "cleanallruv_${yr}_${mn}_${dy}_${h}_${m}_${s}";
+ $dn = "dn: cn=$taskname, cn=cleanallruv, cn=tasks, cn=config\n";
+} else {
+ $taskname = "abort_cleanallruv_${yr}_${mn}_${dy}_${h}_${m}_${s}";
+ $dn = "dn: cn=$taskname, cn=abort cleanallruv, cn=tasks, cn=config\n";
+}
+$misc = "changetype: add\nobjectclass: top\nobjectclass: extensibleObject\n";
+$cn = "cn: $taskname\n";
+$basedn = "replica-base-dn: $basedn\n";
+$rid = "replica-id: $rid\n";
+
+
+$entry = "${dn}${misc}${cn}${basedn}${rid}";
+open(FOO, "| ldapmodify @ldaptool_opts@ $vstr -h {{SERVER-NAME}} -p {{SERVER-PORT}} -D \"$rootdn\" -w \"$passwd\" -a" );
+print(FOO "$entry");
+close(FOO);
+
+sub libpath_add {
+ my $libpath = shift;
+
+ if ($libpath) {
+ if ($ENV{'LD_LIBRARY_PATH'}) {
+ $ENV{'LD_LIBRARY_PATH'} = "$ENV{'LD_LIBRARY_PATH'}:$libpath";
+ } else {
+ $ENV{'LD_LIBRARY_PATH'} = "$libpath";
+ }
+ }
+}
+
diff --git a/ldap/schema/01core389.ldif b/ldap/schema/01core389.ldif
index cf30ab0..2a99c1a 100644
--- a/ldap/schema/01core389.ldif
+++ b/ldap/schema/01core389.ldif
@@ -137,6 +137,9 @@ attributeTypes: ( 2.16.840.1.113730.3.1.2111 NAME 'tombstoneNumSubordinates'
NO-USER-MODIFICATION
USAGE directoryOperation
X-ORIGIN '389 directory server' )
+attributeTypes: ( 2.16.840.1.113730.3.1.2135 NAME 'nsds5ReplicaCleanRUV' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
+attributeTypes: ( 2.16.840.1.113730.3.1.2136 NAME 'nsds5ReplicaCleanRUVNotified' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 X-ORIGIN 'Netscape Directory Server' )
+attributeTypes: ( 2.16.840.1.113730.3.1.2137 NAME 'nsds5ReplicaAbortCleanRUV' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
#
# objectclasses
#
@@ -146,9 +149,9 @@ objectClasses: ( 2.16.840.1.113730.3.2.44 NAME 'nsIndex' DESC 'Netscape defined
objectClasses: ( 2.16.840.1.113730.3.2.109 NAME 'nsBackendInstance' DESC 'Netscape defined objectclass' SUP top MUST ( CN ) X-ORIGIN 'Netscape Directory Server' )
objectClasses: ( 2.16.840.1.113730.3.2.110 NAME 'nsMappingTree' DESC 'Netscape defined objectclass' SUP top MUST ( CN ) X-ORIGIN 'Netscape Directory Server' )
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.108 NAME 'nsDS5Replica' DESC 'Netscape defined objectclass' SUP top MUST ( nsDS5ReplicaRoot $ nsDS5ReplicaId ) MAY (cn $ nsds5ReplicaCleanRUV $ nsds5ReplicaAbortCleanRUV $ 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 ( nsds5ReplicaCleanRUVNotified $ 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.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 b10ac9d..f7960db 100644
--- a/ldap/servers/plugins/replication/cl5_api.c
+++ b/ldap/servers/plugins/replication/cl5_api.c
@@ -337,15 +337,15 @@ static int _cl5CheckMissingCSN (const CSN *minCsn, const RUV *supplierRUV, CL5DB
static int _cl5TrimInit ();
static void _cl5TrimCleanup ();
static int _cl5TrimMain (void *param);
-static void _cl5DoTrimming ();
-static void _cl5TrimFile (Object *obj, long *numToTrim);
+static void _cl5DoTrimming (ReplicaId rid);
+static void _cl5TrimFile (Object *obj, long *numToTrim, ReplicaId cleaned_rid);
static PRBool _cl5CanTrim (time_t time, long *numToTrim);
static int _cl5ReadRUV (const char *replGen, Object *obj, PRBool purge);
static int _cl5WriteRUV (CL5DBFile *file, PRBool purge);
static int _cl5ConstructRUV (const char *replGen, Object *obj, PRBool purge);
static int _cl5UpdateRUV (Object *obj, CSN *csn, PRBool newReplica, PRBool purge);
static int _cl5GetRUV2Purge2 (Object *fileObj, RUV **ruv);
-void trigger_cl_trimming_thread();
+void trigger_cl_trimming_thread(void *rid);
/* bakup/recovery, import/export */
static int _cl5LDIF2Operation (char *ldifEntry, slapi_operation_parameters *op,
@@ -691,12 +691,12 @@ int cl5DeleteDBSync (Object *replica)
}
/* Name: cl5GetUpperBoundRUV
- Description: retrieves vector for that represnts the upper bound of the changes for a replica.
+ Description: retrieves vector for that represents the upper bound of the changes for a replica.
Parameters: r - replica for which the purge vector is requested
ruv - contains a copy of the purge ruv if function is successful;
- unchanged otherwise. It is responsobility pf the caller to free
+ unchanged otherwise. It is responsibility of the caller to free
the ruv when it is no longer is in use
- Return: CL5_SUCCESS if function is successfull
+ Return: CL5_SUCCESS if function is successful
CL5_BAD_STATE if the changelog is not initialized;
CL5_BAD_DATA - if NULL id is supplied
CL5_NOTFOUND, if changelog file for replica is not found
@@ -1674,6 +1674,16 @@ cl5GetNextOperationToReplay (CL5ReplayIterator *iterator, CL5Entry *entry)
return CL5_DB_ERROR;
}
+ if(is_cleaned_rid(csn_get_replicaid(csn))){
+ /*
+ * This operation is from a deleted replica. During the cleanallruv task the
+ * replicas are cleaned first before this instance is. This can cause the
+ * server to basically do a full update over and over. So we have to watch for
+ * this, and not send these operations out.
+ */
+ return CL5_IGNORE_OP;
+ }
+
/* there is an entry we should return */
/* Callers of this function should cl5_operation_parameters_done(op) */
if ( 0 != cl5DBData2Entry ( data, datalen, entry ) )
@@ -3375,7 +3385,7 @@ static int _cl5TrimMain (void *param)
{
/* time to trim */
timePrev = timeNow;
- _cl5DoTrimming ();
+ _cl5DoTrimming (0 /* there's no cleaned rid */);
}
if (NULL == s_cl5Desc.clLock)
{
@@ -3409,7 +3419,7 @@ static int _cl5TrimMain (void *param)
*/
-static void _cl5DoTrimming ()
+static void _cl5DoTrimming (ReplicaId rid)
{
Object *obj;
long numToTrim;
@@ -3422,7 +3432,7 @@ static void _cl5DoTrimming ()
obj = objset_first_obj (s_cl5Desc.dbFiles);
while (obj && _cl5CanTrim ((time_t)0, &numToTrim))
{
- _cl5TrimFile (obj, &numToTrim);
+ _cl5TrimFile (obj, &numToTrim, rid);
obj = objset_next_obj (s_cl5Desc.dbFiles, obj);
}
@@ -3439,12 +3449,13 @@ static void _cl5DoTrimming ()
*/
#define CL5_TRIM_MAX_PER_TRANSACTION 10
-static void _cl5TrimFile (Object *obj, long *numToTrim)
+static void _cl5TrimFile (Object *obj, long *numToTrim, ReplicaId cleaned_rid)
{
DB_TXN *txnid;
RUV *ruv = NULL;
CL5Entry entry;
slapi_operation_parameters op = {0};
+ ReplicaId csn_rid;
void *it;
int finished = 0, totalTrimmed = 0, count;
PRBool abort;
@@ -3468,7 +3479,6 @@ static void _cl5TrimFile (Object *obj, long *numToTrim)
count = 0;
txnid = NULL;
abort = PR_FALSE;
- ReplicaId rid;
/* DB txn lock accessed pages until the end of the transaction. */
@@ -3489,14 +3499,13 @@ static void _cl5TrimFile (Object *obj, long *numToTrim)
* This change can be trimmed if it exceeds purge
* parameters and has been seen by all consumers.
*/
- rid = csn_get_replicaid (op.csn);
+ csn_rid = csn_get_replicaid (op.csn);
if ( (*numToTrim > 0 || _cl5CanTrim (entry.time, numToTrim)) &&
ruv_covers_csn_strict (ruv, op.csn) )
{
rc = _cl5CurrentDeleteEntry (it);
- if ( rc == CL5_SUCCESS && !is_released_rid(rid))
+ if ( rc == CL5_SUCCESS && cleaned_rid != csn_rid)
{
- /* update purge vector, unless this is a released rid */
rc = _cl5UpdateRUV (obj, op.csn, PR_FALSE, PR_TRUE);
}
if ( rc == CL5_SUCCESS)
@@ -3522,8 +3531,7 @@ static void _cl5TrimFile (Object *obj, long *numToTrim)
* the trim forever.
*/
CSN *maxcsn = NULL;
- rid = csn_get_replicaid (op.csn);
- ruv_get_largest_csn_for_replica (ruv, rid, &maxcsn);
+ ruv_get_largest_csn_for_replica (ruv, csn_rid, &maxcsn);
if ( csn_compare (op.csn, maxcsn) != 0 )
{
/* op.csn is not anchor CSN */
@@ -3887,20 +3895,18 @@ static int _cl5UpdateRUV (Object *obj, CSN *csn, PRBool newReplica, PRBool purge
/* update vector only if this replica is not yet part of RUV */
if (purge && newReplica)
{
- if (ruv_contains_replica (file->purgeRUV, rid))
+ if (ruv_contains_replica (file->purgeRUV, rid)){
return CL5_SUCCESS;
- else if(!is_cleaned_rid(rid))
- {
+ } else {
/* if the replica is not part of the purgeRUV yet, add it unless it's from a cleaned rid */
ruv_add_replica (file->purgeRUV, rid, multimaster_get_local_purl());
}
}
else
{
- if (purge)
+ if (purge){
rc = ruv_set_csns(file->purgeRUV, csn, NULL);
- else if(!is_cleaned_rid(rid)){
- /* don't update maxRuv if rid is cleaned */
+ } else {
rc = ruv_set_csns(file->maxRUV, csn, NULL);
}
}
@@ -4507,17 +4513,9 @@ static int _cl5WriteOperationTxn(const char *replName, const char *replGen,
CL5Entry entry;
CL5DBFile *file = NULL;
Object *file_obj = NULL;
- ReplicaId rid = csn_get_replicaid (op->csn);
DB_TXN *txnid = NULL;
DB_TXN *parent_txnid = (DB_TXN *)txn;
- /*
- * If the op csn contains the cleaned rid, don't write it
- */
- if(is_cleaned_rid(rid)){
- return CL5_SUCCESS;
- }
-
rc = _cl5GetDBFileByReplicaName (replName, replGen, &file_obj);
if (rc == CL5_NOTFOUND)
{
@@ -5076,7 +5074,7 @@ static int _cl5PositionCursorForReplay (ReplicaId consumerRID, const RUV *consum
* legacy consumer. In this case the supplier
* and the consumer may have the same RID.
*/
- if (rid == consumerRID && rid != MAX_REPLICA_ID)
+ if ((rid == consumerRID && rid != MAX_REPLICA_ID) || (is_cleaned_rid(rid)) )
continue;
startCSN = csns[i];
@@ -6543,13 +6541,12 @@ cl5CleanRUV(ReplicaId rid){
}
}
-void trigger_cl_trimming(){
+void trigger_cl_trimming(ReplicaId rid){
PRThread *trim_tid = NULL;
- ReplicaId rid = get_released_rid();
slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name_cl, "trigger_cl_trimming: rid (%d)\n",(int)rid);
trim_tid = PR_CreateThread(PR_USER_THREAD, (VFP)(void*)trigger_cl_trimming_thread,
- NULL, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
+ (void *)&rid, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
PR_UNJOINABLE_THREAD, DEFAULT_THREAD_STACKSIZE);
if (NULL == trim_tid){
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
@@ -6562,7 +6559,9 @@ void trigger_cl_trimming(){
}
void
-trigger_cl_trimming_thread(){
+trigger_cl_trimming_thread(void *arg){
+ ReplicaId rid = *(ReplicaId *)arg;
+
/* make sure we have a change log, and we aren't closing it */
if(s_cl5Desc.dbState == CL5_STATE_CLOSED || s_cl5Desc.dbState == CL5_STATE_CLOSING){
return;
@@ -6572,6 +6571,6 @@ trigger_cl_trimming_thread(){
"trigger_cl_trimming: failed to increment thread count "
"NSPR error - %d\n", PR_GetError ());
}
- _cl5DoTrimming();
+ _cl5DoTrimming(rid);
_cl5RemoveThread();
}
diff --git a/ldap/servers/plugins/replication/cl5_api.h b/ldap/servers/plugins/replication/cl5_api.h
index b9c3dd8..9b285ca 100644
--- a/ldap/servers/plugins/replication/cl5_api.h
+++ b/ldap/servers/plugins/replication/cl5_api.h
@@ -145,9 +145,10 @@ enum
CL5_CSN_ERROR, /* CSN API failed */
CL5_RUV_ERROR, /* RUV API failed */
CL5_OBJSET_ERROR, /* namedobjset api failed */
- CL5_PURGED_DATA, /* requested data has been purged */
- CL5_MISSING_DATA, /* data should be in the changelog, but is missing */
- CL5_UNKNOWN_ERROR /* unclassified error */
+ CL5_PURGED_DATA, /* requested data has been purged */
+ CL5_MISSING_DATA, /* data should be in the changelog, but is missing */
+ CL5_UNKNOWN_ERROR, /* unclassified error */
+ CL5_IGNORE_OP /* ignore this updated - used by CLEANALLRUV task */
};
/***** Module APIs *****/
@@ -489,6 +490,6 @@ int cl5WriteRUV();
int cl5DeleteRUV();
void cl5CleanRUV(ReplicaId rid);
void cl5NotifyCleanup(int rid);
-void trigger_cl_trimming();
+void trigger_cl_trimming(ReplicaId rid);
#endif
diff --git a/ldap/servers/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h
index 6caa332..718018b 100644
--- a/ldap/servers/plugins/replication/repl5.h
+++ b/ldap/servers/plugins/replication/repl5.h
@@ -94,10 +94,11 @@
* new set of start and response extops. */
#define REPL_START_NSDS90_REPLICATION_REQUEST_OID "2.16.840.1.113730.3.5.12"
#define REPL_NSDS90_REPLICATION_RESPONSE_OID "2.16.840.1.113730.3.5.13"
-/* cleanruv/releaseruv extended ops */
+/* cleanallruv extended ops */
#define REPL_CLEANRUV_OID "2.16.840.1.113730.3.6.5"
-#define REPL_RELEASERUV_OID "2.16.840.1.113730.3.6.6"
-
+#define REPL_ABORT_CLEANRUV_OID "2.16.840.1.113730.3.6.6"
+#define CLEANRUV_NOTIFIED 0
+#define CLEANRUV_RELEASED 1
/* DS 5.0 replication protocol error codes */
#define NSDS50_REPL_REPLICA_READY 0x00 /* Replica ready, go ahead */
@@ -155,6 +156,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_nsds5ReplicaCleanRUVnotified;
/* Attribute names for windows replication agreements */
extern const char *type_nsds7WindowsReplicaArea;
@@ -183,6 +185,8 @@ extern const char *type_replicaPurgeDelay;
extern const char *type_replicaChangeCount;
extern const char *type_replicaTombstonePurgeInterval;
extern const char *type_replicaLegacyConsumer;
+extern const char *type_replicaCleanRUV;
+extern const char *type_replicaAbortCleanRUV;
extern const char *type_ruvElementUpdatetime;
/* multimaster plugin points */
@@ -222,7 +226,7 @@ char* get_repl_session_id (Slapi_PBlock *pb, char *id, CSN **opcsn);
int multimaster_extop_StartNSDS50ReplicationRequest(Slapi_PBlock *pb);
int multimaster_extop_EndNSDS50ReplicationRequest(Slapi_PBlock *pb);
int multimaster_extop_cleanruv(Slapi_PBlock *pb);
-int multimaster_extop_releaseruv(Slapi_PBlock *pb);
+int multimaster_extop_abort_cleanruv(Slapi_PBlock *pb);
int extop_noop(Slapi_PBlock *pb);
struct berval *NSDS50StartReplicationRequest_new(const char *protocol_oid,
const char *repl_root, char **extra_referrals, CSN *csn);
@@ -353,6 +357,9 @@ 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);
+void agmt_set_cleanruv_notified_from_entry(Repl_Agmt *ra, Slapi_Entry *e);
+int agmt_set_cleanruv_data(Repl_Agmt *ra, ReplicaId rid, int op);
+int agmt_is_cleanruv_notified(Repl_Agmt *ra, ReplicaId rid);
typedef struct replica Replica;
@@ -363,7 +370,6 @@ void agmtlist_notify_all(Slapi_PBlock *pb);
Object* agmtlist_get_first_agreement_for_replica (Replica *r);
Object* agmtlist_get_next_agreement_for_replica (Replica *r, Object *prev);
-
/* In repl5_backoff.c */
typedef struct backoff_timer Backoff_Timer;
#define BACKOFF_FIXED 1
@@ -437,6 +443,7 @@ ConnResult conn_read_result_ex(Repl_Connection *conn, char **retoidp, struct ber
LDAP * conn_get_ldap(Repl_Connection *conn);
void conn_lock(Repl_Connection *conn);
void conn_unlock(Repl_Connection *conn);
+void conn_delete_internal_ext(Repl_Connection *conn);
/* In repl5_protocol.c */
typedef struct repl_protocol Repl_Protocol;
@@ -548,6 +555,9 @@ void replica_set_tombstone_reap_interval (Replica *r, long interval);
void replica_update_ruv_consumer (Replica *r, RUV *supplier_ruv);
void replica_set_ruv_dirty (Replica *r);
void replica_write_ruv (Replica *r);
+char *replica_get_dn(Replica *r);
+void replica_check_for_tasks(Replica*r, Slapi_Entry *e);
+
/* The functions below handles the state flag */
/* Current internal state flags */
/* The replica can be busy and not other flag,
@@ -588,22 +598,40 @@ int replica_config_init();
void replica_config_destroy ();
int get_replica_type(Replica *r);
int replica_execute_cleanruv_task_ext(Object *r, ReplicaId rid);
-void set_cleaned_rid(ReplicaId rid);
-void delete_cleaned_rid();
+void add_cleaned_rid(ReplicaId rid, Replica *r, char *maxcsn);
int is_cleaned_rid(ReplicaId rid);
-int get_released_rid();
-void set_released_rid(int rid);
-int is_released_rid(int rid);
-int is_already_released_rid();
-void delete_released_rid();
-void replica_cleanallruv_monitor_thread(void *arg);
+int replica_cleanall_ruv_abort(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter,
+ int *returncode, char *returntext, void *arg);
+void replica_cleanallruv_thread_ext(void *arg);
+void stop_ruv_cleaning();
+int task_aborted();
+void replica_abort_task_thread(void *arg);
+void delete_cleaned_rid(Replica *r, ReplicaId rid, CSN *maxcsn);
+int process_repl_agmts(Replica *replica, int *agmt_info, char *oid, Slapi_Task *task, struct berval *payload, int op);
+int decode_cleanruv_payload(struct berval *extop_value, char **payload);
+struct berval *create_ruv_payload(char *value);
+void replica_add_cleanruv_data(Replica *r, char *val);
+void replica_remove_cleanruv_data(Replica *r, char *val);
+CSN *replica_get_cleanruv_maxcsn(Replica *r, ReplicaId rid);
+void ruv_get_cleaned_rids(RUV *ruv, ReplicaId *rids);
+void add_aborted_rid(ReplicaId rid, Replica *r, char *repl_root);
+int is_task_aborted(ReplicaId rid);
+void delete_aborted_rid(Replica *replica, ReplicaId rid, char *repl_root);
+void set_cleaned_rid(ReplicaId rid);
+void cleanruv_log(Slapi_Task *task, char *task_type, char *fmt, ...);
-#define ALREADY_RELEASED -1
+#define CLEANRIDSIZ 4 /* maximum number for concurrent CLEANALLRUV tasks */
typedef struct _cleanruv_data
{
Object *repl_obj;
+ Replica *replica;
ReplicaId rid;
+ Slapi_Task *task;
+ struct berval *payload;
+ CSN *maxcsn;
+ char *repl_root;
+ Slapi_DN *sdn;
} cleanruv_data;
/* replutil.c */
diff --git a/ldap/servers/plugins/replication/repl5_agmt.c b/ldap/servers/plugins/replication/repl5_agmt.c
index 8714021..6e4e2d7 100644
--- a/ldap/servers/plugins/replication/repl5_agmt.c
+++ b/ldap/servers/plugins/replication/repl5_agmt.c
@@ -138,6 +138,7 @@ typedef struct repl5agmt {
for sync agreements or for replication session plug-in
private data for normal replication agreements */
int agreement_type;
+ int cleanruv_notified[CLEANRIDSIZ + 1]; /* specifies if the replica has been notified of a CLEANALLRUV task */
} repl5agmt;
/* Forward declarations */
@@ -228,6 +229,7 @@ agmt_new_from_entry(Slapi_Entry *e)
Repl_Agmt *ra;
char *tmpstr;
Slapi_Attr *sattr;
+ char **clean_vals = NULL;
char **denied_attrs = NULL;
char *auto_initialize = NULL;
@@ -387,6 +389,19 @@ agmt_new_from_entry(Slapi_Entry *e)
ra->last_init_start_time = 0UL;
ra->last_init_status[0] = '\0';
+ /* cleanruv notification */
+ clean_vals = slapi_entry_attr_get_charray(e, type_nsds5ReplicaCleanRUVnotified);
+ if(clean_vals){
+ int i;
+ for (i = 0; i < CLEANRIDSIZ && clean_vals[i]; i++){
+ ra->cleanruv_notified[i] = atoi(clean_vals[i]);
+ }
+ ra->cleanruv_notified[i + 1] = 0;
+ slapi_ch_array_free(clean_vals);
+ } else {
+ ra->cleanruv_notified[0] = 0;
+ }
+
/* Fractional attributes */
slapi_entry_attr_find(e, type_nsds5ReplicatedAttributeList, &sattr);
@@ -2442,3 +2457,84 @@ agmt_has_protocol(Repl_Agmt *agmt)
}
return 0;
}
+
+int
+agmt_is_cleanruv_notified(Repl_Agmt *ra, ReplicaId rid){
+ int notified = 0;
+ int i;
+
+ PR_Lock(ra->lock);
+ for(i = 0; i < CLEANRIDSIZ && ra->cleanruv_notified[i]; i++){
+ if(ra->cleanruv_notified[i] == rid){
+ notified = 1;
+ break;
+ }
+ }
+ PR_Unlock(ra->lock);
+
+ return notified;
+}
+
+/*
+ * This will trigger agmt_set_cleanruv_notified_from_entry() to be called,
+ * which will update the in memory agmt.
+ *
+ * op can be: CLEANRUV_NOTIFIED or CLEANRUV_RELEASED
+ */
+int
+agmt_set_cleanruv_data(Repl_Agmt *ra, ReplicaId rid, int op){
+ Slapi_PBlock *pb;
+ LDAPMod *mods[2];
+ LDAPMod mod;
+ struct berval *vals[2];
+ struct berval val;
+ char data[6];
+ int rc = 0;
+
+ if(ra == NULL){
+ return -1;
+ }
+
+ if(op == CLEANRUV_NOTIFIED){
+ /* add the cleanruv data */
+ mod.mod_op = LDAP_MOD_ADD|LDAP_MOD_BVALUES;
+ } else {
+ /* remove the cleanruv data */
+ mod.mod_op = LDAP_MOD_DELETE|LDAP_MOD_BVALUES;
+ }
+
+ pb = slapi_pblock_new();
+ val.bv_len = PR_snprintf(data, sizeof(data), "%d", (int)rid);
+ mod.mod_type = (char *)type_nsds5ReplicaCleanRUVnotified;
+ mod.mod_bvalues = vals;
+ vals [0] = &val;
+ vals [1] = NULL;
+ val.bv_val = data;
+ mods[0] = &mod;
+ mods[1] = NULL;
+
+ slapi_modify_internal_set_pb_ext (pb, ra->dn, mods, NULL, NULL,
+ repl_get_plugin_identity (PLUGIN_MULTIMASTER_REPLICATION), 0);
+ slapi_modify_internal_pb (pb);
+ slapi_pblock_destroy(pb);
+
+ return rc;
+}
+
+void
+agmt_set_cleanruv_notified_from_entry(Repl_Agmt *ra, Slapi_Entry *e){
+ char **attr_vals = NULL;
+ int i;
+
+ PR_Lock(ra->lock);
+ attr_vals = slapi_entry_attr_get_charray(e, type_nsds5ReplicaCleanRUVnotified);
+ if(attr_vals){
+ for (i = 0; i < CLEANRIDSIZ && attr_vals[i]; i++){
+ ra->cleanruv_notified[i] = atoi(attr_vals[i]);
+ }
+ ra->cleanruv_notified[i + 1] = 0;
+ } else {
+ ra->cleanruv_notified[0] = 0;
+ }
+ PR_Unlock(ra->lock);
+}
diff --git a/ldap/servers/plugins/replication/repl5_agmtlist.c b/ldap/servers/plugins/replication/repl5_agmtlist.c
index 8a98c21..6b5dab4 100644
--- a/ldap/servers/plugins/replication/repl5_agmtlist.c
+++ b/ldap/servers/plugins/replication/repl5_agmtlist.c
@@ -488,6 +488,10 @@ 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_nsds5ReplicaCleanRUVnotified))
+ {
+ agmt_set_cleanruv_notified_from_entry(agmt, e);
+ }
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_connection.c b/ldap/servers/plugins/replication/repl5_connection.c
index 5fdc601..51a2bc5 100644
--- a/ldap/servers/plugins/replication/repl5_connection.c
+++ b/ldap/servers/plugins/replication/repl5_connection.c
@@ -140,7 +140,7 @@ static void repl5_debug_timeout_callback(time_t when, void *arg);
static void close_connection_internal(Repl_Connection *conn);
/*
- * Create a new conenction object. Returns a pointer to the object, or
+ * Create a new connection object. Returns a pointer to the object, or
* NULL if an error occurs.
*/
Repl_Connection *
@@ -217,6 +217,17 @@ conn_delete_internal(Repl_Connection *conn)
}
/*
+ * Used by CLEANALLRUV - free it all!
+ */
+void
+conn_delete_internal_ext(Repl_Connection *conn)
+{
+ conn_delete_internal(conn);
+ PR_DestroyLock(conn->lock);
+ slapi_ch_free((void **)&conn);
+}
+
+/*
* Destroy a connection. It is an error to use the connection object
* after conn_delete() has been called.
*/
diff --git a/ldap/servers/plugins/replication/repl5_inc_protocol.c b/ldap/servers/plugins/replication/repl5_inc_protocol.c
index c9ad6fc..eb361e6 100644
--- a/ldap/servers/plugins/replication/repl5_inc_protocol.c
+++ b/ldap/servers/plugins/replication/repl5_inc_protocol.c
@@ -463,7 +463,7 @@ repl5_inc_waitfor_async_results(result_data *rd)
int done = 0;
int loops = 0;
/* Keep pulling results off the LDAP connection until we catch up to the last message id stored in the rd */
- while (!done)
+ while (!done && !slapi_is_shutting_down())
{
/* Lock the structure to force memory barrier */
PR_Lock(rd->lock);
@@ -1571,10 +1571,10 @@ repl5_inc_update_from_op_result(Private_Repl_Protocol *prp, ConnResult replay_cr
agmt_inc_last_update_changecount (prp->agmt, replica_id, 1 /*skipped*/);
}
slapi_log_error(*finished ? SLAPI_LOG_FATAL : slapi_log_urp, repl_plugin_name,
- "%s: Consumer failed to replay change (uniqueid %s, CSN %s): %s. %s.\n",
+ "%s: Consumer failed to replay change (uniqueid %s, CSN %s): %s (%d). %s.\n",
agmt_get_long_name(prp->agmt),
uniqueid, csn_str,
- ldap_err2string(connection_error),
+ ldap_err2string(connection_error), connection_error,
*finished ? "Will retry later" : "Skipping");
}
else if (CONN_NOT_CONNECTED == replay_crc)
@@ -1585,10 +1585,11 @@ repl5_inc_update_from_op_result(Private_Repl_Protocol *prp, ConnResult replay_cr
*finished = 1;
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
"%s: Consumer failed to replay change (uniqueid %s, CSN %s): "
- "%s. Will retry later.\n",
+ "%s(%d). Will retry later.\n",
agmt_get_long_name(prp->agmt),
uniqueid, csn_str,
- connection_error ? ldap_err2string(connection_error) : "Connection lost");
+ connection_error ? ldap_err2string(connection_error) : "Connection lost",
+ connection_error);
}
else if (CONN_TIMEOUT == replay_crc)
{
@@ -1631,7 +1632,7 @@ repl5_inc_update_from_op_result(Private_Repl_Protocol *prp, ConnResult replay_cr
* has already been acquired, (2) that the consumer's update vector has
* been checked and (3) that it's ok to send incremental updates.
* Returns:
- * UPDATE_NO_MORE_UPDATES - all updates were sent succussfully
+ * UPDATE_NO_MORE_UPDATES - all updates were sent successfully
* UPDATE_TRANSIENT_ERROR - some non-permanent error occurred. Try again later.
* UPDATE_FATAL_ERROR - some bad, permanent error occurred.
* UPDATE_SCHEDULE_WINDOW_CLOSED - the schedule window closed on us.
@@ -1701,7 +1702,7 @@ send_updates(Private_Repl_Protocol *prp, RUV *remote_update_vector, PRUint32 *nu
agmt_get_long_name(prp->agmt));
return_value = UPDATE_FATAL_ERROR;
break;
- case CL5_SYSTEM_ERROR: /* NSPR error occurred: use PR_GetError for furhter info */
+ case CL5_SYSTEM_ERROR: /* NSPR error occurred: use PR_GetError for further info */
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
"%s: An NSPR error (%d) occurred\n",
agmt_get_long_name(prp->agmt), PR_GetError());
@@ -1740,7 +1741,7 @@ send_updates(Private_Repl_Protocol *prp, RUV *remote_update_vector, PRUint32 *nu
break;
case CL5_UNKNOWN_ERROR: /* unclassified error */
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
- "%s: An unknown error was ecountered\n",
+ "%s: An unknown error was encountered\n",
agmt_get_long_name(prp->agmt));
return_value = UPDATE_TRANSIENT_ERROR;
break;
@@ -1926,6 +1927,8 @@ send_updates(Private_Repl_Protocol *prp, RUV *remote_update_vector, PRUint32 *nu
agmt_get_long_name(prp->agmt));
return_value = UPDATE_FATAL_ERROR;
break;
+ case CL5_IGNORE_OP:
+ break;
default:
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
"%s: Unknown error code (%d) returned from cl5GetNextOperationToReplay\n",
@@ -1957,7 +1960,7 @@ send_updates(Private_Repl_Protocol *prp, RUV *remote_update_vector, PRUint32 *nu
/* Terminate the results reading thread */
if (!prp->repl50consumer)
{
- /* We need to ensure that we wait until all the responses have been recived from our operations */
+ /* We need to ensure that we wait until all the responses have been received from our operations */
if (return_value != UPDATE_CONNECTION_LOST) {
/* if connection was lost/closed, there will be nothing to read */
repl5_inc_waitfor_async_results(rd);
diff --git a/ldap/servers/plugins/replication/repl5_init.c b/ldap/servers/plugins/replication/repl5_init.c
index a878b19..7a80c6f 100644
--- a/ldap/servers/plugins/replication/repl5_init.c
+++ b/ldap/servers/plugins/replication/repl5_init.c
@@ -126,12 +126,12 @@ static char *cleanruv_name_list[] = {
NSDS_REPL_NAME_PREFIX " Cleanruv",
NULL
};
-static char *releaseruv_oid_list[] = {
- REPL_RELEASERUV_OID,
+static char *cleanruv_abort_oid_list[] = {
+ REPL_ABORT_CLEANRUV_OID,
NULL
};
-static char *releaseruv_name_list[] = {
- NSDS_REPL_NAME_PREFIX " Releaseruv",
+static char *cleanruv_abort_name_list[] = {
+ NSDS_REPL_NAME_PREFIX " Cleanruv Abort",
NULL
};
@@ -474,7 +474,7 @@ multimaster_cleanruv_extop_init( Slapi_PBlock *pb )
}
int
-multimaster_releaseruv_extop_init( Slapi_PBlock *pb )
+multimaster_cleanruv_abort_extop_init( Slapi_PBlock *pb )
{
int rc= 0; /* OK */
void *identity = NULL;
@@ -485,11 +485,11 @@ multimaster_releaseruv_extop_init( Slapi_PBlock *pb )
if (slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION, SLAPI_PLUGIN_VERSION_01 ) != 0 ||
slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION, (void *)&multimasterextopdesc ) != 0 ||
- slapi_pblock_set( pb, SLAPI_PLUGIN_EXT_OP_OIDLIST, (void *)releaseruv_oid_list ) != 0 ||
- slapi_pblock_set( pb, SLAPI_PLUGIN_EXT_OP_NAMELIST, (void *)releaseruv_name_list ) != 0 ||
- slapi_pblock_set( pb, SLAPI_PLUGIN_EXT_OP_FN, (void *)multimaster_extop_releaseruv ))
+ slapi_pblock_set( pb, SLAPI_PLUGIN_EXT_OP_OIDLIST, (void *)cleanruv_abort_oid_list ) != 0 ||
+ slapi_pblock_set( pb, SLAPI_PLUGIN_EXT_OP_NAMELIST, (void *)cleanruv_abort_name_list ) != 0 ||
+ slapi_pblock_set( pb, SLAPI_PLUGIN_EXT_OP_FN, (void *)multimaster_extop_abort_cleanruv ))
{
- slapi_log_error( SLAPI_LOG_PLUGIN, repl_plugin_name, "multimaster_releaseruv_extop_init failed\n" );
+ slapi_log_error( SLAPI_LOG_PLUGIN, repl_plugin_name, "multimaster_cleanruv_abort_extop_init failed\n" );
rc= -1;
}
@@ -605,24 +605,22 @@ multimaster_stop( Slapi_PBlock *pb )
int rc= 0; /* OK */
if (!multimaster_stopped_flag)
- {
- if (!is_ldif_dump)
- {
- agmtlist_shutdown(); /* Shut down replication agreements */
- }
-
+ {
+ if (!is_ldif_dump)
+ {
+ /* Shut down replication agreements */
+ agmtlist_shutdown();
+ }
+ /* if we are cleaning a ruv, stop */
+ stop_ruv_cleaning();
/* unregister backend state change notification */
slapi_unregister_backend_state_change((void *)multimaster_be_state_change);
-
- changelog5_cleanup(); /* Shut down the changelog */
- multimaster_mtnode_extension_destroy(); /* Destroy mapping tree node exts */
+ changelog5_cleanup(); /* Shut down the changelog */
+ multimaster_mtnode_extension_destroy(); /* Destroy mapping tree node exts */
replica_destroy_name_hash(); /* destroy the hash and its remaining content */
replica_config_destroy (); /* Destroy replica config info */
- multimaster_stopped_flag = 1;
- /* JCMREPL - Wait for all our threads to stop */
- /* JCMREPL - Shut down the replication plugin */
- /* JCMREPL - Mark all the replication plugin interfaces at not enabled. */
- }
+ multimaster_stopped_flag = 1;
+ }
return rc;
}
@@ -680,7 +678,7 @@ int replication_multimaster_plugin_init(Slapi_PBlock *pb)
rc= slapi_register_plugin("extendedop", 1 /* Enabled */, "multimaster_total_extop_init", multimaster_total_extop_init, "Multimaster replication total update extended operation plugin", NULL, identity);
rc= slapi_register_plugin("extendedop", 1 /* Enabled */, "multimaster_response_extop_init", multimaster_response_extop_init, "Multimaster replication extended response plugin", NULL, identity);
rc= slapi_register_plugin("extendedop", 1 /* Enabled */, "multimaster_cleanruv_extop_init", multimaster_cleanruv_extop_init, "Multimaster replication cleanruv extended operation plugin", NULL, identity);
- rc= slapi_register_plugin("extendedop", 1 /* Enabled */, "multimaster_releaseruv_extop_init", multimaster_releaseruv_extop_init, "Multimaster replication releaserid extended response plugin", NULL, identity);
+ rc= slapi_register_plugin("extendedop", 1 /* Enabled */, "multimaster_cleanruv_abort_extop_init", multimaster_cleanruv_abort_extop_init, "Multimaster replication cleanruv abort extended operation plugin", NULL, identity);
if (0 == rc)
{
multimaster_initialised = 1;
diff --git a/ldap/servers/plugins/replication/repl5_plugins.c b/ldap/servers/plugins/replication/repl5_plugins.c
index dfbb80e..9da7329 100644
--- a/ldap/servers/plugins/replication/repl5_plugins.c
+++ b/ldap/servers/plugins/replication/repl5_plugins.c
@@ -1005,15 +1005,6 @@ write_changelog_and_ruv (Slapi_PBlock *pb)
r = (Replica*)object_get_data (repl_obj);
PR_ASSERT (r);
- /*
- * In case we had to run cleanruv, we don't want to continue to write
- * updates to the changelog/database ruv from that replica(rid).
- */
- if( is_cleaned_rid(replica_get_rid(r))){
- /* this RID has been cleaned, just goto done */
- goto done;
- }
-
if (replica_is_flag_set (r, REPLICA_LOG_CHANGES) &&
(cl5GetState () == CL5_STATE_OPEN))
{
@@ -1068,6 +1059,12 @@ write_changelog_and_ruv (Slapi_PBlock *pb)
op_params->target_address.uniqueid = slapi_ch_strdup (uniqueid);
}
+ if( is_cleaned_rid(csn_get_replicaid(op_params->csn))){
+ /* this RID has been cleaned */
+ object_release (repl_obj);
+ return 0;
+ }
+
/* we might have stripped all the mods - in that case we do not
log the operation */
if (op_params->operation_type != SLAPI_OPERATION_MODIFY ||
@@ -1120,7 +1117,6 @@ write_changelog_and_ruv (Slapi_PBlock *pb)
update_ruv_component(r, opcsn, pb);
}
-done:
object_release (repl_obj);
return return_value;
}
@@ -1323,7 +1319,7 @@ process_operation (Slapi_PBlock *pb, const CSN *csn)
ruv = (RUV*)object_get_data (ruv_obj);
PR_ASSERT (ruv);
- rc = ruv_add_csn_inprogress (ruv, csn);
+ rc = ruv_add_csn_inprogress (ruv, csn);
object_release (ruv_obj);
object_release (r_obj);
diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c
index 293e55a..135f3a2 100644
--- a/ldap/servers/plugins/replication/repl5_replica.c
+++ b/ldap/servers/plugins/replication/repl5_replica.c
@@ -61,20 +61,20 @@
*/
struct replica {
Slapi_DN *repl_root; /* top of the replicated area */
- char *repl_name; /* unique replica name */
- PRBool new_name; /* new name was generated - need to be saved */
+ char *repl_name; /* unique replica name */
+ PRBool new_name; /* new name was generated - need to be saved */
ReplicaUpdateDNList updatedn_list; /* list of dns with which a supplier should bind
to update this replica */
ReplicaType repl_type; /* is this replica read-only ? */
- PRBool legacy_consumer; /* if true, this replica is supplied by 4.0 consumer */
- char* legacy_purl; /* partial url of the legacy supplier */
+ PRBool legacy_consumer; /* if true, this replica is supplied by 4.0 consumer */
+ char* legacy_purl; /* partial url of the legacy supplier */
ReplicaId repl_rid; /* replicaID */
Object *repl_ruv; /* replica update vector */
PRBool repl_ruv_dirty; /* Dirty flag for ruv */
CSNPL *min_csn_pl; /* Pending list for minimal CSN */
void *csn_pl_reg_id; /* registration assignment for csn callbacks */
unsigned long repl_state_flags; /* state flags */
- PRUint32 repl_flags; /* persistent, externally visible flags */
+ PRUint32 repl_flags; /* persistent, externally visible flags */
PRLock *repl_lock; /* protects entire structure */
Slapi_Eq_Context repl_eqcxt_rs; /* context to cancel event that saves ruv */
Slapi_Eq_Context repl_eqcxt_tr; /* context to cancel event that reaps tombstones */
@@ -85,9 +85,10 @@ struct replica {
PRBool tombstone_reap_active; /* TRUE when the tombstone reaper is running */
long tombstone_reap_interval; /* Time in seconds between tombstone reaping */
Slapi_ValueSet *repl_referral; /* A list of administrator provided referral URLs */
- PRBool state_update_inprogress; /* replica state is being updated */
- PRLock *agmt_lock; /* protects agreement creation, start and stop */
+ PRBool state_update_inprogress; /* replica state is being updated */
+ PRLock *agmt_lock; /* protects agreement creation, start and stop */
char *locking_purl; /* supplier who has exclusive access */
+ char *repl_cleanruv_data[CLEANRIDSIZ + 1];
};
@@ -123,6 +124,7 @@ static int replica_log_ruv_elements_nolock (const Replica *r);
static void replica_replace_ruv_tombstone(Replica *r);
static void start_agreements_for_replica (Replica *r, PRBool start);
static void _delete_tombstone(const char *tombstone_dn, const char *uniqueid, int ext_op_flags);
+static void replica_strip_cleaned_rids(Replica *r);
/* Allocates new replica and reads its state and state of its component from
* various parts of the DIT.
@@ -273,6 +275,8 @@ replica_new_from_entry (Slapi_Entry *e, char *errortext, PRBool is_add_operation
escape_string(slapi_sdn_get_dn(r->repl_root),ebuf));
}
+ replica_check_for_tasks(r, e);
+
done:
if (rc != 0 && r)
{
@@ -309,6 +313,7 @@ replica_destroy(void **arg)
{
Replica *r;
void *repl_name;
+ int i;
if (arg == NULL)
return;
@@ -395,6 +400,10 @@ replica_destroy(void **arg)
csnplFree(&r->min_csn_pl);;
}
+ for(i = 0;r->repl_cleanruv_data[i] != NULL; i++){
+ slapi_ch_free_string(&r->repl_cleanruv_data[i]);
+ }
+
slapi_ch_free((void **)arg);
}
@@ -1308,7 +1317,7 @@ replica_reload_ruv (Replica *r)
}
/* check if there is a changelog and whether this replica logs changes */
- if (cl5GetState () == CL5_STATE_OPEN && r->repl_flags & REPLICA_LOG_CHANGES)
+ if (cl5GetState () == CL5_STATE_OPEN && (r->repl_flags & REPLICA_LOG_CHANGES))
{
/* Compare new ruv to the changelog's upper bound ruv. We could only keep
@@ -1432,7 +1441,7 @@ int replica_check_for_data_reload (Replica *r, void *arg)
PR_ASSERT (r);
/* check that we have a changelog and if this replica logs changes */
- if (cl5GetState () == CL5_STATE_OPEN && r->repl_flags & REPLICA_LOG_CHANGES)
+ if (cl5GetState () == CL5_STATE_OPEN && (r->repl_flags & REPLICA_LOG_CHANGES))
{
/* Compare new ruv to the purge ruv. If the new contains csns which
are smaller than those in purge ruv, we need to remove old and
@@ -1567,6 +1576,12 @@ _replica_get_config_entry (const Slapi_DN *root)
return e;
}
+char *
+replica_get_dn(Replica *r)
+{
+ return _replica_get_config_dn (r->repl_root);
+}
+
static int
_replica_check_validity (const Replica *r)
{
@@ -1798,6 +1813,177 @@ _replica_init_from_config (Replica *r, Slapi_Entry *e, char *errortext)
return (_replica_check_validity (r));
}
+void
+replica_check_for_tasks(Replica *r, Slapi_Entry *e)
+{
+ char **clean_vals;
+
+ if(e == NULL){
+ return;
+ }
+ /*
+ * check if we are in the middle of a CLEANALLRUV task,
+ * if so set the cleaned rid, and fire off the thread
+ */
+ if ((clean_vals = slapi_entry_attr_get_charray(e, type_replicaCleanRUV)) != NULL)
+ {
+ PRThread *thread = NULL;
+ struct berval *payload = NULL;
+ CSN *maxcsn = NULL;
+ char *csnpart;
+ char *iter;
+ char csnstr[CSN_STRSIZE];
+ char *ridstr;
+ char *token = NULL;
+ ReplicaId rid;
+ int i;
+
+ for(i = 0; clean_vals[i]; i++){
+ cleanruv_data *data = NULL;
+
+ /*
+ * Set the cleanruv data, and add the cleaned rid
+ */
+ r->repl_cleanruv_data[i] = slapi_ch_strdup(clean_vals[i]);
+ token = ldap_utf8strtok_r(clean_vals[i], ":", &iter);
+ if(token){
+ rid = atoi(token);
+ if(rid <= 0 || rid >= READ_ONLY_REPLICA_ID){
+ slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "CleanAllRUV Task: invalid replica id(%d) "
+ "aborting task.\n", rid);
+ goto done;
+ }
+ } else {
+ slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "CleanAllRUV Task: unable to parse cleanallruv "
+ "data (%s), aborting task.\n",clean_vals[i]);
+ goto done;
+ }
+ csnpart = ldap_utf8strtok_r(iter, ":", &iter);
+ maxcsn = csn_new();
+ csn_init_by_string(maxcsn, csnpart);
+ csn_as_string(maxcsn, PR_FALSE, csnstr);
+ add_cleaned_rid(rid, r, csnstr);
+
+ slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "CleanAllRUV Task: cleanAllRUV task found, "
+ "resuming the cleaning of rid(%d)...\n", rid);
+ /*
+ * Create payload
+ */
+ ridstr = slapi_ch_smprintf("%d:%s:%s", rid, slapi_sdn_get_dn(replica_get_root(r)), csnstr);
+ payload = create_ruv_payload(ridstr);
+ slapi_ch_free_string(&ridstr);
+
+ if(payload == NULL){
+ slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "CleanAllRUV Task: Startup: Failed to "
+ "create extended op payload, aborting task");
+ return;
+ }
+ /*
+ * Setup the data struct, and fire off the thread.
+ */
+ data = (cleanruv_data*)slapi_ch_calloc(1, sizeof(cleanruv_data));
+ if (data == NULL) {
+ slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV: failed to allocate cleanruv_data.\n");
+ csn_free(&maxcsn);
+ } else {
+ /* setup our data */
+ data->repl_obj = NULL;
+ data->replica = NULL;
+ data->rid = rid;
+ data->task = NULL;
+ data->maxcsn = maxcsn;
+ data->sdn = slapi_sdn_dup(r->repl_root);
+ data->payload = payload;
+
+ thread = PR_CreateThread(PR_USER_THREAD, replica_cleanallruv_thread_ext,
+ (void *)data, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
+ PR_UNJOINABLE_THREAD, SLAPD_DEFAULT_THREAD_STACKSIZE);
+ if (thread == NULL) {
+ slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV: unable to create cleanAllRUV "
+ "thread for rid(%d)\n", (int)data->rid);
+ }
+ }
+ }
+ r->repl_cleanruv_data[i] = NULL;
+ }
+
+ if ((clean_vals = slapi_entry_attr_get_charray(e, type_replicaAbortCleanRUV)) != NULL)
+ {
+ PRThread *thread = NULL;
+ struct berval *payload;
+ CSN *maxcsn = NULL;
+ char *iter;
+ char *ridstr = NULL;
+ char *repl_root;
+ char *token = NULL;
+ ReplicaId rid;
+ int i;
+
+ for(i = 0; clean_vals[i]; i++){
+ cleanruv_data *data = NULL;
+
+ token = ldap_utf8strtok_r(clean_vals[i], ":", &iter);
+ if(token){
+ rid = atoi(token);
+ if(rid <= 0 || rid >= READ_ONLY_REPLICA_ID){
+ slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "Abort CleanAllRUV Task: invalid replica id(%d) "
+ "aborting task.\n", rid);
+ goto done;
+ }
+ } else {
+ slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "Abort CleanAllRUV Task: unable to parse cleanallruv "
+ "data (%s), aborting task.\n",clean_vals[i]);
+ goto done;
+ }
+
+ repl_root = ldap_utf8strtok_r(iter, ":", &iter);
+ stop_ruv_cleaning();
+ maxcsn = replica_get_cleanruv_maxcsn(r, rid);
+ delete_cleaned_rid(r, rid, maxcsn);
+ csn_free(&maxcsn);
+
+ slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "Abort CleanAllRUV Task: abort task found, "
+ "resuming abort of rid(%d).\n", rid);
+ /*
+ * Setup the data struct, and fire off the abort thread.
+ */
+ data = (cleanruv_data*)slapi_ch_calloc(1, sizeof(cleanruv_data));
+ if (data == NULL) {
+ slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "Abort CleanAllRUV Task: failed to allocate cleanruv_data.\n");
+ } else {
+ ridstr = slapi_ch_smprintf("%d:%s", rid, repl_root);
+ payload = create_ruv_payload(ridstr);
+ slapi_ch_free_string(&ridstr);
+
+ if(payload == NULL){
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "Abort CleanAllRUV Task: failed to create extended "
+ "op payload\n");
+ } else {
+ /* setup the data */
+ data->repl_obj = NULL;
+ data->replica = NULL;
+ data->rid = rid;
+ data->task = NULL;
+ data->payload = payload;
+ data->repl_root = slapi_ch_strdup(repl_root);
+ data->sdn = slapi_sdn_dup(r->repl_root);
+
+ thread = PR_CreateThread(PR_USER_THREAD, replica_abort_task_thread,
+ (void *)data, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
+ PR_UNJOINABLE_THREAD, SLAPD_DEFAULT_THREAD_STACKSIZE);
+ if (thread == NULL) {
+ slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "Abort CleanAllRUV Task: unable to create abort cleanAllRUV "
+ "thread for rid(%d)\n", (int)data->rid);
+ }
+ }
+ }
+ }
+ }
+
+done:
+ slapi_ch_array_free(clean_vals);
+}
+
/* This function updates the entry to contain information generated
during replica initialization.
Returns 0 if successful and -1 otherwise */
@@ -2804,9 +2990,9 @@ static const char *root_glue =
static int
replica_create_ruv_tombstone(Replica *r)
{
- int return_value = LDAP_LOCAL_ERROR;
- char *root_entry_str;
- Slapi_Entry *e = NULL;
+ int return_value = LDAP_LOCAL_ERROR;
+ char *root_entry_str;
+ Slapi_Entry *e = NULL;
const char *purl = NULL;
RUV *ruv;
struct berval **bvals = NULL;
@@ -2814,17 +3000,16 @@ replica_create_ruv_tombstone(Replica *r)
int rc;
char ebuf[BUFSIZ];
- PR_ASSERT(NULL != r && NULL != r->repl_root);
- root_entry_str = slapi_ch_smprintf(root_glue, slapi_sdn_get_ndn(r->repl_root),
- RUV_STORAGE_ENTRY_UNIQUEID);
+ PR_ASSERT(NULL != r && NULL != r->repl_root);
+
+ root_entry_str = slapi_ch_smprintf(root_glue, slapi_sdn_get_ndn(r->repl_root), RUV_STORAGE_ENTRY_UNIQUEID);
- e = slapi_str2entry(root_entry_str, SLAPI_STR2ENTRY_TOMBSTONE_CHECK);
+ e = slapi_str2entry(root_entry_str, SLAPI_STR2ENTRY_TOMBSTONE_CHECK);
if (e == NULL)
goto done;
/* Add ruv */
- if (r->repl_ruv == NULL)
- {
+ if (r->repl_ruv == NULL){
CSNGen *gen;
CSN *csn;
char csnstr [CSN_STRSIZE];
@@ -2833,15 +3018,16 @@ replica_create_ruv_tombstone(Replica *r)
gen = (CSNGen *)object_get_data(r->repl_csngen);
PR_ASSERT (gen);
- if (csngen_new_csn(gen, &csn, PR_FALSE /* notify */) == CSN_SUCCESS)
- {
- (void)csn_as_string(csn, PR_FALSE, csnstr);
- csn_free(&csn);
+ if (csngen_new_csn(gen, &csn, PR_FALSE /* notify */) == CSN_SUCCESS){
+ (void)csn_as_string(csn, PR_FALSE, csnstr);
+ csn_free(&csn);
- /* if this is an updateable replica - add its own
- element to the RUV so that referrals work correctly */
- if (r->repl_type == REPLICA_TYPE_UPDATABLE)
- purl = multimaster_get_local_purl();
+ /*
+ * if this is an updateable replica - add its own
+ * element to the RUV so that referrals work correctly
+ */
+ if (r->repl_type == REPLICA_TYPE_UPDATABLE)
+ purl = multimaster_get_local_purl();
if (ruv_init_new(csnstr, r->repl_rid, purl, &ruv) == RUV_SUCCESS)
{
@@ -2865,10 +3051,8 @@ replica_create_ruv_tombstone(Replica *r)
escape_string(slapi_sdn_get_dn(r->repl_root),ebuf));
csn_free(&csn);
goto done;
- }
- }
- else /* failed to write the entry because DB was not initialized - retry */
- {
+ }
+ } else { /* failed to write the entry because DB was not initialized - retry */
ruv = (RUV*) object_get_data (r->repl_ruv);
PR_ASSERT (ruv);
}
@@ -2876,30 +3060,22 @@ replica_create_ruv_tombstone(Replica *r)
PR_ASSERT (r->repl_ruv);
rc = ruv_to_bervals(ruv, &bvals);
- if (rc != RUV_SUCCESS)
- {
+ if (rc != RUV_SUCCESS){
goto done;
}
/* ONREPL this is depricated function but there is currently no better API to use */
rc = slapi_entry_add_values(e, type_ruvElement, bvals);
- if (rc != 0)
- {
+ if (rc != 0){
goto done;
}
-
- pb = slapi_pblock_new();
- slapi_add_entry_internal_set_pb(
- pb,
- e,
- NULL /* controls */,
- repl_get_plugin_identity(PLUGIN_MULTIMASTER_REPLICATION),
- OP_FLAG_TOMBSTONE_ENTRY | OP_FLAG_REPLICATED | OP_FLAG_REPL_FIXUP |
- OP_FLAG_REPL_RUV);
- slapi_add_internal_pb(pb);
- e = NULL; /* add consumes e, upon success or failure */
- slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &return_value);
+ pb = slapi_pblock_new();
+ slapi_add_entry_internal_set_pb(pb, e, NULL /* controls */, repl_get_plugin_identity(PLUGIN_MULTIMASTER_REPLICATION),
+ OP_FLAG_TOMBSTONE_ENTRY | OP_FLAG_REPLICATED | OP_FLAG_REPL_FIXUP | OP_FLAG_REPL_RUV);
+ slapi_add_internal_pb(pb);
+ e = NULL; /* add consumes e, upon success or failure */
+ slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &return_value);
if (return_value == LDAP_SUCCESS)
r->repl_ruv_dirty = PR_FALSE;
@@ -2912,30 +3088,30 @@ done:
if (pb)
slapi_pblock_destroy(pb);
- slapi_ch_free((void **) &root_entry_str);
+ slapi_ch_free_string(&root_entry_str);
- return return_value;
+ return return_value;
}
static void
assign_csn_callback(const CSN *csn, void *data)
{
- Replica *r = (Replica *)data;
+ Replica *r = (Replica *)data;
Object *ruv_obj;
RUV *ruv;
- PR_ASSERT(NULL != csn);
- PR_ASSERT(NULL != r);
+ PR_ASSERT(NULL != csn);
+ PR_ASSERT(NULL != r);
ruv_obj = replica_get_ruv (r);
PR_ASSERT (ruv_obj);
ruv = (RUV*)object_get_data (ruv_obj);
PR_ASSERT (ruv);
- PR_Lock(r->repl_lock);
+ PR_Lock(r->repl_lock);
- r->repl_csn_assigned = PR_TRUE;
+ r->repl_csn_assigned = PR_TRUE;
if (NULL != r->min_csn_pl)
{
@@ -2956,7 +3132,7 @@ assign_csn_callback(const CSN *csn, void *data)
ruv_add_csn_inprogress (ruv, csn);
- PR_Unlock(r->repl_lock);
+ PR_Unlock(r->repl_lock);
object_release (ruv_obj);
}
@@ -3193,19 +3369,41 @@ replica_set_tombstone_reap_interval (Replica *r, long interval)
PR_Unlock(r->repl_lock);
}
+static void
+replica_strip_cleaned_rids(Replica *r)
+{
+ Object *RUVObj;
+ RUV *ruv = NULL;
+ ReplicaId rid[32] = {0};
+ int i = 0;
+
+ RUVObj = replica_get_ruv(r);
+ ruv = (RUV*)object_get_data (RUVObj);
+
+ ruv_get_cleaned_rids(ruv, rid);
+ while(rid[i] != 0){
+ ruv_delete_replica(ruv, rid[i]);
+ replica_set_ruv_dirty(r);
+ replica_write_ruv(r);
+ i++;
+ }
+ object_release(RUVObj);
+}
+
/* Update the tombstone entry to reflect the content of the ruv */
static void
replica_replace_ruv_tombstone(Replica *r)
{
Slapi_PBlock *pb = NULL;
- char *dn;
- int rc;
-
Slapi_Mod smod;
Slapi_Mod smod_last_modified;
LDAPMod *mods [3];
+ char *dn;
+ int rc;
- PR_ASSERT(NULL != r && NULL != r->repl_root);
+ PR_ASSERT(NULL != r && NULL != r->repl_root);
+
+ replica_strip_cleaned_rids(r);
PR_Lock(r->repl_lock);
@@ -3214,14 +3412,14 @@ replica_replace_ruv_tombstone(Replica *r)
ruv_last_modified_to_smod ((RUV*)object_get_data(r->repl_ruv), &smod_last_modified);
dn = _replica_get_config_dn (r->repl_root);
- if (NULL == dn) {
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
- "replica_replace_ruv_tombstone: "
- "failed to get the config dn for %s\n",
- slapi_sdn_get_dn (r->repl_root));
- PR_Unlock(r->repl_lock);
- goto bail;
- }
+ if (NULL == dn) {
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
+ "replica_replace_ruv_tombstone: "
+ "failed to get the config dn for %s\n",
+ slapi_sdn_get_dn (r->repl_root));
+ PR_Unlock(r->repl_lock);
+ goto bail;
+ }
mods[0] = (LDAPMod*)slapi_mod_get_ldapmod_byref(&smod);
mods[1] = (LDAPMod*)slapi_mod_get_ldapmod_byref(&smod_last_modified);
@@ -3245,12 +3443,12 @@ replica_replace_ruv_tombstone(Replica *r)
if (rc != LDAP_SUCCESS)
{
- if ((rc != LDAP_NO_SUCH_OBJECT) || !replica_is_state_flag_set(r, REPLICA_IN_USE))
- {
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "replica_replace_ruv_tombstone: "
- "failed to update replication update vector for replica %s: LDAP "
- "error - %d\n", (char*)slapi_sdn_get_dn (r->repl_root), rc);
- }
+ if ((rc != LDAP_NO_SUCH_OBJECT) || !replica_is_state_flag_set(r, REPLICA_IN_USE))
+ {
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "replica_replace_ruv_tombstone: "
+ "failed to update replication update vector for replica %s: LDAP "
+ "error - %d\n", (char*)slapi_sdn_get_dn (r->repl_root), rc);
+ }
}
slapi_ch_free ((void**)&dn);
@@ -3266,14 +3464,18 @@ replica_update_ruv_consumer(Replica *r, RUV *supplier_ruv)
ReplicaId supplier_id = 0;
char *supplier_purl = NULL;
- if ( ruv_get_first_id_and_purl(supplier_ruv, &supplier_id, &supplier_purl) == RUV_SUCCESS )
+ if ( ruv_get_first_id_and_purl(supplier_ruv, &supplier_id, &supplier_purl) == RUV_SUCCESS)
{
RUV *local_ruv = NULL;
PR_Lock(r->repl_lock);
local_ruv = (RUV*)object_get_data (r->repl_ruv);
- PR_ASSERT (local_ruv);
+
+ if(is_cleaned_rid(supplier_id) || local_ruv == NULL){
+ PR_Unlock(r->repl_lock);
+ return;
+ }
if ( ruv_local_contains_supplier(local_ruv, supplier_id) == 0 )
{
@@ -3605,3 +3807,67 @@ replica_get_attr ( Slapi_PBlock *pb, const char* type, void *value )
return rc;
}
+
+void
+replica_add_cleanruv_data(Replica *r, char *val)
+{
+ int i;
+
+ PR_Lock(r->repl_lock);
+
+ for (i = 0; i < CLEANRIDSIZ && r->repl_cleanruv_data[i] != NULL; i++); /* goto the end of the list */
+ r->repl_cleanruv_data[i] = slapi_ch_strdup(val); /* append to list */
+ r->repl_cleanruv_data[i + 1] = NULL;
+
+ PR_Unlock(r->repl_lock);
+}
+
+void
+replica_remove_cleanruv_data(Replica *r, char *val)
+{
+ int i;
+
+ PR_Lock(r->repl_lock);
+
+ for(i = 0; i < CLEANRIDSIZ && r->repl_cleanruv_data[i] && strcmp(r->repl_cleanruv_data[i], val) != 0; i++);
+ if( i < CLEANRIDSIZ ){
+ slapi_ch_free_string(&r->repl_cleanruv_data[i]);
+ for(; i < CLEANRIDSIZ; i++){
+ /* rewrite entire array */
+ r->repl_cleanruv_data[i] = r->repl_cleanruv_data[i + 1];
+ }
+ }
+
+ PR_Unlock(r->repl_lock);
+}
+
+CSN *
+replica_get_cleanruv_maxcsn(Replica *r, ReplicaId rid)
+{
+ CSN *newcsn;
+ char *csnstr;
+ char *token;
+ char *iter;
+ int repl_rid = 0;
+ int i;
+
+ PR_Lock(r->repl_lock);
+
+ for(i = 0; i < CLEANRIDSIZ && r->repl_cleanruv_data[i]; i++){
+ token = ldap_utf8strtok_r(r->repl_cleanruv_data[i], ":", &iter);
+ if(token){
+ repl_rid = atoi(token);
+ }
+ csnstr = ldap_utf8strtok_r(iter, ":", &iter);
+ if(repl_rid == rid){
+ newcsn = csn_new();
+ csn_init_by_string(newcsn, csnstr);
+ PR_Unlock(r->repl_lock);
+ return newcsn;
+ }
+ }
+
+ PR_Unlock(r->repl_lock);
+
+ return NULL;
+}
diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
index d16dc28..8ae9add 100644
--- a/ldap/servers/plugins/replication/repl5_replica_config.c
+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
@@ -2,15 +2,15 @@
* This Program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; version 2 of the License.
- *
+ *
* This Program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License along with
* this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA.
- *
+ *
* In addition, as a special exception, Red Hat, Inc. gives You the additional
* right to link the code of this Program with code not covered under the GNU
* General Public License ("Non-GPL Code") and to distribute linked combinations
@@ -28,9 +28,9 @@
* version of the file, but you are not obligated to do so. If you do not wish to
* provide this exception without modification, you must delete this exception
* statement from your version and license this file solely under the GPL without
- * exception.
- *
- *
+ * exception.
+ *
+ *
* Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
* Copyright (C) 2005 Red Hat, Inc.
* All rights reserved.
@@ -58,13 +58,17 @@
#define CLEANRUVLEN 8
#define CLEANALLRUV "CLEANALLRUV"
#define CLEANALLRUVLEN 11
-#define RELEASERUV "RELEASERUV"
-#define RELEASERUVLEN 10
#define REPLICA_RDN "cn=replica"
+#define CLEANALLRUV_ID "CleanAllRUV Task"
+#define ABORT_CLEANALLRUV_ID "Abort CleanAllRUV Task"
int slapi_log_urp = SLAPI_LOG_REPL;
-static ReplicaId cleaned_rid = 0;
-static int released_rid = 0;
+static ReplicaId cleaned_rids[CLEANRIDSIZ + 1] = {0};
+static ReplicaId aborted_rids[CLEANRIDSIZ + 1] = {0};
+static Slapi_RWLock *rid_lock = NULL;
+static Slapi_RWLock *abort_rid_lock = NULL;
+static PRLock *notify_lock = NULL;
+static PRCondVar *notify_cvar = NULL;
/* Forward Declartions */
static int replica_config_add (Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry* entryAfter, int *returncode, char *returntext, void *arg);
@@ -72,7 +76,7 @@ static int replica_config_modify (Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry*
static int replica_config_post_modify (Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry* entryAfter, int *returncode, char *returntext, void *arg);
static int replica_config_delete (Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry* entryAfter, int *returncode, char *returntext, void *arg);
static int replica_config_search (Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry* entryAfter, int *returncode, char *returntext, void *arg);
-
+static int replica_cleanall_ruv_task(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter, int *returncode, char *returntext, void *arg);
static int replica_config_change_type_and_id (Replica *r, const char *new_type, const char *new_id, char *returntext, int apply_mods);
static int replica_config_change_updatedn (Replica *r, const LDAPMod *mod, char *returntext, int apply_mods);
static int replica_config_change_flags (Replica *r, const char *new_flags, char *returntext, int apply_mods);
@@ -80,9 +84,18 @@ static int replica_execute_task (Object *r, const char *task_name, char *returnt
static int replica_execute_cl2ldif_task (Object *r, char *returntext);
static int replica_execute_ldif2cl_task (Object *r, char *returntext);
static int replica_execute_cleanruv_task (Object *r, ReplicaId rid, char *returntext);
-static int replica_execute_cleanall_ruv_task (Object *r, ReplicaId rid, char *returntext);
-static int replica_execute_release_ruv_task(Object *r, ReplicaId rid);
-static struct berval *create_ruv_payload(char *value);
+static int replica_execute_cleanall_ruv_task (Object *r, ReplicaId rid, Slapi_Task *task, char *returntext);
+static void replica_cleanallruv_thread(void *arg);
+static void replica_send_cleanruv_task(Repl_Agmt *agmt, ReplicaId rid, Slapi_Task *task);
+static int check_agmts_are_alive(Replica *replica, ReplicaId rid, Slapi_Task *task);
+static int check_agmts_are_caught_up(Replica *replica, ReplicaId rid, char *maxcsn, Slapi_Task *task);
+static int replica_cleanallruv_send_extop(Repl_Agmt *ra, ReplicaId rid, Slapi_Task *task, struct berval *payload, int check_result);
+static int replica_cleanallruv_send_abort_extop(Repl_Agmt *ra, Slapi_Task *task, struct berval *payload);
+static int replica_cleanallruv_check_maxcsn(Repl_Agmt *agmt, char *rid_text, char *maxcsn, Slapi_Task *task);
+static int replica_cleanallruv_replica_alive(Repl_Agmt *agmt);
+static int replica_cleanallruv_check_ruv(Repl_Agmt *ra, char *rid_text, Slapi_Task *task);
+static int get_cleanruv_task_count();
+static int get_abort_cleanruv_task_count();
static int replica_cleanup_task (Object *r, const char *task_name, char *returntext, int apply_mods);
static int replica_task_done(Replica *replica);
static multimaster_mtnode_extension * _replica_config_get_mtnode_ext (const Slapi_Entry *e);
@@ -105,29 +118,59 @@ int
replica_config_init()
{
s_configLock = PR_NewLock ();
+
if (s_configLock == NULL)
{
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "replica_config_init: "
- "failed to cretate configuration lock; NSPR error - %d\n",
+ "failed to create configuration lock; NSPR error - %d\n",
PR_GetError ());
return -1;
}
+ rid_lock = slapi_new_rwlock();
+ if(rid_lock == NULL)
+ {
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "replica_config_init: "
+ "failed to create rid_lock; NSPR error - %d\n", PR_GetError ());
+ return -1;
+ }
+ abort_rid_lock = slapi_new_rwlock();
+ if(abort_rid_lock == NULL)
+ {
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "replica_config_init: "
+ "failed to create abort_rid_lock; NSPR error - %d\n", PR_GetError ());
+ return -1;
+ }
+ if ( ( notify_lock = PR_NewLock()) == NULL ) {
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "replica_config_init: "
+ "failed to create notify lock; NSPR error - %d\n", PR_GetError ());
+ return -1;
+ }
+ if ( ( notify_cvar = PR_NewCondVar( notify_lock )) == NULL ) {
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "replica_config_init: "
+ "failed to create notify cond var; NSPR error - %d\n", PR_GetError ());
+ return -1;
+ }
/* config DSE must be initialized before we get here */
slapi_config_register_callback(SLAPI_OPERATION_ADD, DSE_FLAG_PREOP, CONFIG_BASE, LDAP_SCOPE_SUBTREE,
- CONFIG_FILTER, replica_config_add, NULL);
+ CONFIG_FILTER, replica_config_add, NULL);
slapi_config_register_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_PREOP, CONFIG_BASE, LDAP_SCOPE_SUBTREE,
CONFIG_FILTER, replica_config_modify,NULL);
slapi_config_register_callback(SLAPI_OPERATION_MODRDN, DSE_FLAG_PREOP, CONFIG_BASE, LDAP_SCOPE_SUBTREE,
CONFIG_FILTER, dont_allow_that, NULL);
slapi_config_register_callback(SLAPI_OPERATION_DELETE, DSE_FLAG_PREOP, CONFIG_BASE, LDAP_SCOPE_SUBTREE,
- CONFIG_FILTER, replica_config_delete,NULL);
+ CONFIG_FILTER, replica_config_delete,NULL);
slapi_config_register_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP, CONFIG_BASE, LDAP_SCOPE_SUBTREE,
- CONFIG_FILTER, replica_config_search,NULL);
- slapi_config_register_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_POSTOP,
+ CONFIG_FILTER, replica_config_search,NULL);
+ slapi_config_register_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_POSTOP,
CONFIG_BASE, LDAP_SCOPE_SUBTREE,
CONFIG_FILTER, replica_config_post_modify,
NULL);
+
+ /* register the CLEANALLRUV & ABORT task */
+ slapi_task_register_handler("cleanallruv", replica_cleanall_ruv_task);
+ slapi_task_register_handler("abort cleanallruv", replica_cleanall_ruv_abort);
+
return 0;
}
@@ -142,7 +185,7 @@ replica_config_destroy ()
/* config DSE must be initialized before we get here */
slapi_config_remove_callback(SLAPI_OPERATION_ADD, DSE_FLAG_PREOP, CONFIG_BASE, LDAP_SCOPE_SUBTREE,
- CONFIG_FILTER, replica_config_add);
+ CONFIG_FILTER, replica_config_add);
slapi_config_remove_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_PREOP, CONFIG_BASE, LDAP_SCOPE_SUBTREE,
CONFIG_FILTER, replica_config_modify);
slapi_config_remove_callback(SLAPI_OPERATION_MODRDN, DSE_FLAG_PREOP, CONFIG_BASE, LDAP_SCOPE_SUBTREE,
@@ -151,26 +194,26 @@ replica_config_destroy ()
CONFIG_FILTER, replica_config_delete);
slapi_config_remove_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP, CONFIG_BASE, LDAP_SCOPE_SUBTREE,
CONFIG_FILTER, replica_config_search);
- slapi_config_remove_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_PREOP,
+ slapi_config_remove_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_PREOP,
CONFIG_BASE, LDAP_SCOPE_SUBTREE,
CONFIG_FILTER, replica_config_post_modify);
}
-static int
-replica_config_add (Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry* entryAfter,
+static int
+replica_config_add (Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry* entryAfter,
int *returncode, char *errorbuf, void *arg)
{
Replica *r = NULL;
- multimaster_mtnode_extension *mtnode_ext;
+ multimaster_mtnode_extension *mtnode_ext;
char *replica_root = (char*)slapi_entry_attr_get_charptr (e, attr_replicaRoot);
char buf [SLAPI_DSE_RETURNTEXT_SIZE];
char *errortext = errorbuf ? errorbuf : buf;
-
+
if (errorbuf)
{
errorbuf[0] = '\0';
- }
-
+ }
+
*returncode = LDAP_SUCCESS;
PR_Lock (s_configLock);
@@ -185,16 +228,16 @@ replica_config_add (Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry* entryAfter,
{
PR_snprintf (errortext, SLAPI_DSE_RETURNTEXT_SIZE, "replica already configured for %s", replica_root);
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "replica_config_add: %s\n", errortext);
- *returncode = LDAP_UNWILLING_TO_PERFORM;
- goto done;
+ *returncode = LDAP_UNWILLING_TO_PERFORM;
+ goto done;
}
/* create replica object */
r = replica_new_from_entry (e, errortext, PR_TRUE /* is a newly added entry */);
if (r == NULL)
{
- *returncode = LDAP_OPERATIONS_ERROR;
- goto done;
+ *returncode = LDAP_OPERATIONS_ERROR;
+ goto done;
}
/* Set the mapping tree node state, and the referrals from the RUV */
@@ -220,24 +263,24 @@ done:
if (*returncode != LDAP_SUCCESS)
{
- if (mtnode_ext->replica)
+ if (mtnode_ext->replica)
object_release (mtnode_ext->replica);
return SLAPI_DSE_CALLBACK_ERROR;
}
- else
+ else
return SLAPI_DSE_CALLBACK_OK;
}
-static int
-replica_config_modify (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* e,
+static int
+replica_config_modify (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* e,
int *returncode, char *returntext, void *arg)
{
int rc= 0;
LDAPMod **mods;
int i, apply_mods;
- multimaster_mtnode_extension *mtnode_ext;
+ multimaster_mtnode_extension *mtnode_ext;
Replica *r = NULL;
- char *replica_root = NULL;
+ char *replica_root = NULL;
char buf [SLAPI_DSE_RETURNTEXT_SIZE];
char *errortext = returntext ? returntext : buf;
char *config_attr, *config_attr_value;
@@ -252,7 +295,7 @@ replica_config_modify (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry*
/* just let internal operations originated from replication plugin to go through */
slapi_pblock_get (pb, SLAPI_OPERATION, &op);
- slapi_pblock_get (pb, SLAPI_PLUGIN_IDENTITY, &identity);
+ slapi_pblock_get (pb, SLAPI_PLUGIN_IDENTITY, &identity);
if (operation_is_flag_set(op, OP_FLAG_INTERNAL) &&
(identity == repl_get_plugin_identity (PLUGIN_MULTIMASTER_REPLICATION)))
@@ -264,7 +307,7 @@ replica_config_modify (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry*
replica_root = (char*)slapi_entry_attr_get_charptr (e, attr_replicaRoot);
PR_Lock (s_configLock);
-
+
mtnode_ext = _replica_config_get_mtnode_ext (e);
PR_ASSERT (mtnode_ext);
@@ -276,7 +319,7 @@ replica_config_modify (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry*
PR_snprintf (errortext, SLAPI_DSE_RETURNTEXT_SIZE, "replica does not exist for %s", replica_root);
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "replica_config_modify: %s\n",
errortext);
- *returncode = LDAP_OPERATIONS_ERROR;
+ *returncode = LDAP_OPERATIONS_ERROR;
goto done;
}
@@ -287,7 +330,7 @@ replica_config_modify (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry*
for (apply_mods = 0; apply_mods <= 1; apply_mods++)
{
/* we only allow the replica ID and type to be modified together e.g.
- if converting a read only replica to a master or vice versa -
+ if converting a read only replica to a master or vice versa -
we will need to change both the replica ID and the type at the same
time - we must disallow changing the replica ID if the type is not
being changed and vice versa
@@ -304,7 +347,7 @@ replica_config_modify (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry*
break;
config_attr = (char *) mods[i]->mod_type;
- PR_ASSERT (config_attr);
+ PR_ASSERT (config_attr);
/* disallow modifications or removal of replica root,
replica name and replica state attributes */
@@ -313,14 +356,14 @@ replica_config_modify (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry*
strcasecmp (config_attr, attr_state) == 0)
{
*returncode = LDAP_UNWILLING_TO_PERFORM;
- PR_snprintf (errortext, SLAPI_DSE_RETURNTEXT_SIZE, "modification of %s attribute is not allowed",
- config_attr);
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "replica_config_modify: %s\n",
+ PR_snprintf (errortext, SLAPI_DSE_RETURNTEXT_SIZE, "modification of %s attribute is not allowed",
+ config_attr);
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "replica_config_modify: %s\n",
errortext);
}
/* this is a request to delete an attribute */
- else if (mods[i]->mod_op & LDAP_MOD_DELETE || mods[i]->mod_bvalues == NULL
- || mods[i]->mod_bvalues[0]->bv_val == NULL)
+ else if ((mods[i]->mod_op & LDAP_MOD_DELETE) || mods[i]->mod_bvalues == NULL
+ || mods[i]->mod_bvalues[0]->bv_val == NULL)
{
/* currently, you can only remove referral,
legacy consumer or bind dn attribute */
@@ -345,10 +388,9 @@ replica_config_modify (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry*
else
{
*returncode = LDAP_UNWILLING_TO_PERFORM;
- PR_snprintf (errortext, SLAPI_DSE_RETURNTEXT_SIZE, "deletion of %s attribute is not allowed", config_attr);
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "replica_config_modify: %s\n",
- errortext);
- }
+ PR_snprintf (errortext, SLAPI_DSE_RETURNTEXT_SIZE, "deletion of %s attribute is not allowed", config_attr);
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "replica_config_modify: %s\n", errortext);
+ }
}
else /* modify an attribute */
{
@@ -356,8 +398,7 @@ replica_config_modify (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry*
if (strcasecmp (config_attr, attr_replicaBindDn) == 0)
{
- *returncode = replica_config_change_updatedn (r, mods[i],
- errortext, apply_mods);
+ *returncode = replica_config_change_updatedn (r, mods[i], errortext, apply_mods);
}
else if (strcasecmp (config_attr, attr_replicaType) == 0)
{
@@ -367,16 +408,14 @@ replica_config_modify (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry*
{
new_repl_id = slapi_ch_strdup(config_attr_value);
}
- else if (strcasecmp (config_attr, attr_flags) == 0)
+ else if (strcasecmp (config_attr, attr_flags) == 0)
{
- *returncode = replica_config_change_flags (r, config_attr_value,
- errortext, apply_mods);
+ *returncode = replica_config_change_flags (r, config_attr_value, errortext, apply_mods);
}
- else if (strcasecmp (config_attr, TASK_ATTR) == 0)
+ else if (strcasecmp (config_attr, TASK_ATTR) == 0)
{
- *returncode = replica_execute_task (mtnode_ext->replica, config_attr_value,
- errortext, apply_mods);
- }
+ *returncode = replica_execute_task (mtnode_ext->replica, config_attr_value, errortext, apply_mods);
+ }
else if (strcasecmp (config_attr, attr_replicaReferral) == 0)
{
if (apply_mods)
@@ -391,14 +430,14 @@ replica_config_modify (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry*
if (!replica_is_legacy_consumer (r)) {
consumer5_set_mapping_tree_state_for_replica(r, NULL);
}
- }
+ }
}
else if (strcasecmp (config_attr, type_replicaPurgeDelay) == 0)
{
- if (apply_mods && config_attr_value && config_attr_value[0])
+ if (apply_mods && config_attr_value && config_attr_value[0])
{
PRUint32 delay;
- if (isdigit (config_attr_value[0]))
+ if (isdigit (config_attr_value[0]))
{
delay = (unsigned int)atoi(config_attr_value);
replica_set_purge_delay(r, delay);
@@ -409,7 +448,7 @@ replica_config_modify (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry*
}
else if (strcasecmp (config_attr, type_replicaTombstonePurgeInterval) == 0)
{
- if (apply_mods && config_attr_value && config_attr_value[0])
+ if (apply_mods && config_attr_value && config_attr_value[0])
{
long interval;
interval = atol (config_attr_value);
@@ -439,17 +478,14 @@ replica_config_modify (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry*
*returncode = LDAP_UNWILLING_TO_PERFORM;
PR_snprintf (errortext, SLAPI_DSE_RETURNTEXT_SIZE,
"modification of attribute %s is not allowed in replica entry", config_attr);
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "replica_config_modify: %s\n",
- errortext);
- }
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "replica_config_modify: %s\n", errortext);
+ }
}
}
if (new_repl_id || new_repl_type)
{
- *returncode = replica_config_change_type_and_id(r, new_repl_type,
- new_repl_id, errortext,
- apply_mods);
+ *returncode = replica_config_change_type_and_id(r, new_repl_type, new_repl_id, errortext, apply_mods);
slapi_ch_free_string(&new_repl_id);
slapi_ch_free_string(&new_repl_type);
}
@@ -458,9 +494,9 @@ replica_config_modify (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry*
done:
if (mtnode_ext->replica)
object_release (mtnode_ext->replica);
-
+
/* slapi_ch_free accepts NULL pointer */
- slapi_ch_free ((void**)&replica_root);
+ slapi_ch_free_string(&replica_root);
PR_Unlock (s_configLock);
@@ -474,9 +510,9 @@ done:
}
}
-static int
+static int
replica_config_post_modify(Slapi_PBlock *pb,
- Slapi_Entry* entryBefore,
+ Slapi_Entry* entryBefore,
Slapi_Entry* e,
int *returncode,
char *returntext,
@@ -485,9 +521,9 @@ replica_config_post_modify(Slapi_PBlock *pb,
int rc= 0;
LDAPMod **mods;
int i, apply_mods;
- multimaster_mtnode_extension *mtnode_ext;
+ multimaster_mtnode_extension *mtnode_ext;
Replica *r = NULL;
- char *replica_root = NULL;
+ char *replica_root = NULL;
char buf [SLAPI_DSE_RETURNTEXT_SIZE];
char *errortext = returntext ? returntext : buf;
char *config_attr, *config_attr_value;
@@ -503,7 +539,7 @@ replica_config_post_modify(Slapi_PBlock *pb,
/* just let internal operations originated from replication plugin to go through */
slapi_pblock_get (pb, SLAPI_OPERATION, &op);
- slapi_pblock_get (pb, SLAPI_PLUGIN_IDENTITY, &identity);
+ slapi_pblock_get (pb, SLAPI_PLUGIN_IDENTITY, &identity);
if (operation_is_flag_set(op, OP_FLAG_INTERNAL) &&
(identity == repl_get_plugin_identity (PLUGIN_MULTIMASTER_REPLICATION)))
@@ -515,7 +551,7 @@ replica_config_post_modify(Slapi_PBlock *pb,
replica_root = (char*)slapi_entry_attr_get_charptr (e, attr_replicaRoot);
PR_Lock (s_configLock);
-
+
mtnode_ext = _replica_config_get_mtnode_ext (e);
PR_ASSERT (mtnode_ext);
@@ -529,7 +565,7 @@ replica_config_post_modify(Slapi_PBlock *pb,
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
"replica_config_post_modify: %s\n",
errortext);
- *returncode = LDAP_OPERATIONS_ERROR;
+ *returncode = LDAP_OPERATIONS_ERROR;
goto done;
}
@@ -540,7 +576,7 @@ replica_config_post_modify(Slapi_PBlock *pb,
for (apply_mods = 0; apply_mods <= 1; apply_mods++)
{
/* we only allow the replica ID and type to be modified together e.g.
- if converting a read only replica to a master or vice versa -
+ if converting a read only replica to a master or vice versa -
we will need to change both the replica ID and the type at the same
time - we must disallow changing the replica ID if the type is not
being changed and vice versa
@@ -554,7 +590,7 @@ replica_config_post_modify(Slapi_PBlock *pb,
break;
config_attr = (char *) mods[i]->mod_type;
- PR_ASSERT (config_attr);
+ PR_ASSERT (config_attr);
/* disallow modifications or removal of replica root,
replica name and replica state attributes */
@@ -564,16 +600,16 @@ replica_config_post_modify(Slapi_PBlock *pb,
{
*returncode = LDAP_UNWILLING_TO_PERFORM;
PR_snprintf (errortext, SLAPI_DSE_RETURNTEXT_SIZE,
- "modification of %s attribute is not allowed",
- config_attr);
+ "modification of %s attribute is not allowed",
+ config_attr);
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
- "replica_config_post_modify: %s\n",
+ "replica_config_post_modify: %s\n",
errortext);
}
/* this is a request to delete an attribute */
- else if (mods[i]->mod_op & LDAP_MOD_DELETE ||
+ else if ((mods[i]->mod_op & LDAP_MOD_DELETE) ||
mods[i]->mod_bvalues == NULL ||
- mods[i]->mod_bvalues[0]->bv_val == NULL)
+ mods[i]->mod_bvalues[0]->bv_val == NULL)
{
;
}
@@ -581,7 +617,7 @@ replica_config_post_modify(Slapi_PBlock *pb,
{
config_attr_value = (char *) mods[i]->mod_bvalues[0]->bv_val;
- if (strcasecmp (config_attr, TASK_ATTR) == 0)
+ if (strcasecmp (config_attr, TASK_ATTR) == 0)
{
flag_need_cleanup = 1;
}
@@ -605,7 +641,7 @@ done:
if (mtnode_ext->replica)
object_release (mtnode_ext->replica);
-
+
if (*returncode != LDAP_SUCCESS)
{
return SLAPI_DSE_CALLBACK_ERROR;
@@ -616,8 +652,8 @@ done:
}
}
-static int
-replica_config_delete (Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry* entryAfter,
+static int
+replica_config_delete (Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry* entryAfter,
int *returncode, char *returntext, void *arg)
{
multimaster_mtnode_extension *mtnode_ext;
@@ -652,26 +688,26 @@ replica_config_delete (Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry* entryAfter
return SLAPI_DSE_CALLBACK_OK;
}
-static int
-replica_config_search (Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry* entryAfter, int *returncode,
+static int
+replica_config_search (Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry* entryAfter, int *returncode,
char *returntext, void *arg)
{
- multimaster_mtnode_extension *mtnode_ext;
+ multimaster_mtnode_extension *mtnode_ext;
int changeCount = 0;
PRBool reapActive = PR_FALSE;
char val [64];
/* add attribute that contains number of entries in the changelog for this replica */
-
+
PR_Lock (s_configLock);
-
+
mtnode_ext = _replica_config_get_mtnode_ext (e);
PR_ASSERT (mtnode_ext);
-
+
if (mtnode_ext->replica) {
Replica *replica;
object_acquire (mtnode_ext->replica);
- if (cl5GetState () == CL5_STATE_OPEN) {
+ if (cl5GetState () == CL5_STATE_OPEN) {
changeCount = cl5GetOperationCount (mtnode_ext->replica);
}
replica = (Replica*)object_get_data (mtnode_ext->replica);
@@ -690,9 +726,9 @@ replica_config_search (Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry* entryAfter
return SLAPI_DSE_CALLBACK_OK;
}
-static int
+static int
replica_config_change_type_and_id (Replica *r, const char *new_type,
- const char *new_id, char *returntext,
+ const char *new_id, char *returntext,
int apply_mods)
{
int type;
@@ -772,8 +808,8 @@ replica_config_change_type_and_id (Replica *r, const char *new_type,
return LDAP_SUCCESS;
}
-static int
-replica_config_change_updatedn (Replica *r, const LDAPMod *mod, char *returntext,
+static int
+replica_config_change_updatedn (Replica *r, const LDAPMod *mod, char *returntext,
int apply_mods)
{
PR_ASSERT (r);
@@ -792,7 +828,7 @@ replica_config_change_updatedn (Replica *r, const LDAPMod *mod, char *returntext
return LDAP_SUCCESS;
}
-static int replica_config_change_flags (Replica *r, const char *new_flags,
+static int replica_config_change_flags (Replica *r, const char *new_flags,
char *returntext, int apply_mods)
{
PR_ASSERT (r);
@@ -809,10 +845,10 @@ static int replica_config_change_flags (Replica *r, const char *new_flags,
return LDAP_SUCCESS;
}
-static int replica_execute_task (Object *r, const char *task_name, char *returntext,
+static int replica_execute_task (Object *r, const char *task_name, char *returntext,
int apply_mods)
{
-
+
if (strcasecmp (task_name, CL2LDIF_TASK) == 0)
{
if (apply_mods)
@@ -850,13 +886,14 @@ static int replica_execute_task (Object *r, const char *task_name, char *returnt
{
int temprid = atoi(&(task_name[CLEANALLRUVLEN]));
if (temprid <= 0 || temprid >= READ_ONLY_REPLICA_ID){
- PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Invalid replica id (%d) for task - (%s)", temprid, task_name);
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "replica_execute_task: %s\n", returntext);
- return LDAP_OPERATIONS_ERROR;
+ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Invalid replica id (%d) for task - (%s)", temprid, task_name);
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "replica_execute_task: %s\n", returntext);
+ return LDAP_OPERATIONS_ERROR;
}
if (apply_mods)
{
- return replica_execute_cleanall_ruv_task(r, (ReplicaId)temprid, returntext);
+ Slapi_Task *empty_task = NULL;
+ return replica_execute_cleanall_ruv_task(r, (ReplicaId)temprid, empty_task, returntext);
}
else
return LDAP_SUCCESS;
@@ -864,22 +901,22 @@ static int replica_execute_task (Object *r, const char *task_name, char *returnt
else
{
PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "unsupported replica task - %s", task_name);
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
- "replica_execute_task: %s\n", returntext);
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
+ "replica_execute_task: %s\n", returntext);
return LDAP_OPERATIONS_ERROR;
}
-
+
}
-static int
-replica_cleanup_task (Object *r, const char *task_name, char *returntext,
+static int
+replica_cleanup_task (Object *r, const char *task_name, char *returntext,
int apply_mods)
{
int rc = LDAP_SUCCESS;
if (apply_mods) {
Replica *replica = (Replica*)object_get_data (r);
if (NULL == replica) {
- rc = LDAP_OPERATIONS_ERROR;
+ rc = LDAP_OPERATIONS_ERROR;
} else {
rc = replica_task_done(replica);
}
@@ -915,19 +952,19 @@ replica_task_done(Replica *replica)
mod.mod_type = (char *)TASK_ATTR;
mod.mod_bvalues = NULL;
- slapi_modify_internal_set_pb_ext(pb, replica_sdn, mods, NULL/* controls */,
- NULL/* uniqueid */,
+ slapi_modify_internal_set_pb_ext(pb, replica_sdn, mods, NULL/* controls */,
+ NULL/* uniqueid */,
repl_get_plugin_identity (PLUGIN_MULTIMASTER_REPLICATION),
0/* flags */);
slapi_modify_internal_pb (pb);
slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
if ((rc != LDAP_SUCCESS) && (rc != LDAP_NO_SUCH_ATTRIBUTE)) {
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
"replica_task_done: "
"failed to remove (%s) attribute from (%s) entry; "
"LDAP error - %d\n",
- TASK_ATTR, replica_dn, rc);
+ TASK_ATTR, replica_dn, rc);
}
slapi_pblock_destroy (pb);
@@ -947,9 +984,9 @@ static int replica_execute_cl2ldif_task (Object *r, char *returntext)
if (cl5GetState () != CL5_STATE_OPEN)
{
PR_snprintf (returntext, SLAPI_DSE_RETURNTEXT_SIZE, "changelog is not open");
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
- "replica_execute_cl2ldif_task: %s\n", returntext);
- rc = LDAP_OPERATIONS_ERROR;
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
+ "replica_execute_cl2ldif_task: %s\n", returntext);
+ rc = LDAP_OPERATIONS_ERROR;
goto bail;
}
@@ -960,25 +997,25 @@ static int replica_execute_cl2ldif_task (Object *r, char *returntext)
<replica name>.ldif */
clDir = cl5GetDir ();
if (NULL == clDir) {
- rc = LDAP_OPERATIONS_ERROR;
+ rc = LDAP_OPERATIONS_ERROR;
goto bail;
}
replica = (Replica*)object_get_data (r);
if (NULL == replica) {
- rc = LDAP_OPERATIONS_ERROR;
+ rc = LDAP_OPERATIONS_ERROR;
goto bail;
}
PR_snprintf (fName, MAXPATHLEN, "%s/%s.ldif", clDir, replica_get_name (replica));
slapi_ch_free_string (&clDir);
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
"Beginning changelog export of replica \"%s\"\n",
replica_get_name(replica));
rc = cl5ExportLDIF (fName, rlist);
if (rc == CL5_SUCCESS) {
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
"Finished changelog export of replica \"%s\"\n",
replica_get_name(replica));
rc = LDAP_SUCCESS;
@@ -986,9 +1023,9 @@ static int replica_execute_cl2ldif_task (Object *r, char *returntext)
PR_snprintf (returntext, SLAPI_DSE_RETURNTEXT_SIZE,
"Failed changelog export replica %s; "
"changelog error - %d", replica_get_name(replica), rc);
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
"replica_execute_cl2ldif_task: %s\n", returntext);
- rc = LDAP_OPERATIONS_ERROR;
+ rc = LDAP_OPERATIONS_ERROR;
}
bail:
return rc;
@@ -1006,8 +1043,8 @@ static int replica_execute_ldif2cl_task (Object *r, char *returntext)
if (cl5GetState () != CL5_STATE_OPEN)
{
PR_snprintf (returntext, SLAPI_DSE_RETURNTEXT_SIZE, "changelog is not open");
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
- "replica_execute_ldif2cl_task: %s\n", returntext);
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
+ "replica_execute_ldif2cl_task: %s\n", returntext);
rc = LDAP_OPERATIONS_ERROR;
goto bail;
}
@@ -1019,13 +1056,13 @@ static int replica_execute_ldif2cl_task (Object *r, char *returntext)
<replica name>.ldif */
clDir = cl5GetDir ();
if (NULL == clDir) {
- rc = LDAP_OPERATIONS_ERROR;
+ rc = LDAP_OPERATIONS_ERROR;
goto bail;
}
replica = (Replica*)object_get_data (r);
if (NULL == replica) {
- rc = LDAP_OPERATIONS_ERROR;
+ rc = LDAP_OPERATIONS_ERROR;
goto bail;
}
@@ -1037,19 +1074,19 @@ static int replica_execute_ldif2cl_task (Object *r, char *returntext)
PR_snprintf (returntext, SLAPI_DSE_RETURNTEXT_SIZE,
"failed to close changelog to import changelog data; "
"changelog error - %d", rc);
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
"replica_execute_ldif2cl_task: %s\n", returntext);
rc = LDAP_OPERATIONS_ERROR;
goto bail;
}
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
"Beginning changelog import of replica \"%s\"\n",
replica_get_name(replica));
imprc = cl5ImportLDIF (clDir, fName, rlist);
slapi_ch_free_string (&clDir);
if (CL5_SUCCESS == imprc)
{
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
"Finished changelog import of replica \"%s\"\n",
replica_get_name(replica));
}
@@ -1058,7 +1095,7 @@ static int replica_execute_ldif2cl_task (Object *r, char *returntext)
PR_snprintf (returntext, SLAPI_DSE_RETURNTEXT_SIZE,
"Failed changelog import replica %s; "
"changelog error - %d", replica_get_name(replica), rc);
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
"replica_execute_ldif2cl_task: %s\n", returntext);
imprc = LDAP_OPERATIONS_ERROR;
}
@@ -1071,10 +1108,10 @@ static int replica_execute_ldif2cl_task (Object *r, char *returntext)
}
else
{
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
"replica_execute_ldif2cl_task: failed to start changelog at %s\n",
config.dir?config.dir:"null config dir");
- rc = LDAP_OPERATIONS_ERROR;
+ rc = LDAP_OPERATIONS_ERROR;
}
bail:
changelog5_config_done(&config);
@@ -1082,7 +1119,7 @@ bail:
return imprc?imprc:rc;
}
-static multimaster_mtnode_extension *
+static multimaster_mtnode_extension *
_replica_config_get_mtnode_ext (const Slapi_Entry *e)
{
const char *replica_root;
@@ -1115,9 +1152,9 @@ _replica_config_get_mtnode_ext (const Slapi_Entry *e)
else
{
/* check if replica object already exists for the specified subtree */
- ext = (multimaster_mtnode_extension *)repl_con_get_ext (REPL_CON_EXT_MTNODE, mtnode);
+ ext = (multimaster_mtnode_extension *)repl_con_get_ext (REPL_CON_EXT_MTNODE, mtnode);
}
-
+
slapi_sdn_free (&sdn);
return ext;
@@ -1126,26 +1163,24 @@ _replica_config_get_mtnode_ext (const Slapi_Entry *e)
int
replica_execute_cleanruv_task_ext(Object *r, ReplicaId rid)
{
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "cleanruv_extop: calling clean_ruv_ext\n");
- return replica_execute_cleanruv_task(r, rid, NULL);
+ return replica_execute_cleanruv_task(r, rid, NULL);
}
static int
replica_execute_cleanruv_task (Object *r, ReplicaId rid, char *returntext /* not used */)
{
- int rc = 0;
Object *RUVObj;
RUV *local_ruv = NULL;
Replica *replica = (Replica*)object_get_data (r);
-
+ int rc = 0;
PR_ASSERT (replica);
slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "cleanruv_task: cleaning rid (%d)...\n",(int)rid);
RUVObj = replica_get_ruv(replica);
PR_ASSERT(RUVObj);
local_ruv = (RUV*)object_get_data (RUVObj);
- /* Need to check that :
- * - rid is not the local one
+ /* Need to check that :
+ * - rid is not the local one
* - rid is not the last one
*/
if ((replica_get_rid(replica) == rid) ||
@@ -1159,12 +1194,11 @@ replica_execute_cleanruv_task (Object *r, ReplicaId rid, char *returntext /* not
/* Update Mapping Tree to reflect RUV changes */
consumer5_set_mapping_tree_state_for_replica(replica, NULL);
-
+
/*
- * Clean the changelog RUV's, and set the rids
+ * Clean the changelog RUV's
*/
cl5CleanRUV(rid);
- delete_released_rid();
if (rc != RUV_SUCCESS){
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanruv_task: task failed(%d)\n",rc);
@@ -1174,484 +1208,1566 @@ replica_execute_cleanruv_task (Object *r, ReplicaId rid, char *returntext /* not
return LDAP_SUCCESS;
}
-static int
-replica_execute_cleanall_ruv_task (Object *r, ReplicaId rid, char *returntext)
+const char *
+fetch_attr(Slapi_Entry *e, const char *attrname, const char *default_val)
{
- PRThread *thread = NULL;
- Repl_Connection *conn;
- Replica *replica = (Replica*)object_get_data (r);
- Object *agmt_obj;
- Repl_Agmt *agmt;
- ConnResult crc;
- cleanruv_data *data = NULL;
- const Slapi_DN *dn = NULL;
- struct berval *payload = NULL;
- char *ridstr = NULL;
- int send_msgid = 0;
- int agmt_count = 0;
- int rc = 0;
+ Slapi_Attr *attr;
+ Slapi_Value *val = NULL;
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: cleaning rid (%d)...\n",(int)rid);
- set_cleaned_rid(rid);
- /*
- * Create payload
- */
- ridstr = slapi_ch_smprintf("%d:%s", rid, slapi_sdn_get_dn(replica_get_root(replica)));
- payload = create_ruv_payload(ridstr);
- if(payload == NULL){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: failed to create ext op payload, aborting task\n");
- goto done;
- }
+ if (slapi_entry_attr_find(e, attrname, &attr) != 0)
+ return default_val;
- agmt_obj = agmtlist_get_first_agreement_for_replica (replica);
- while (agmt_obj)
- {
- agmt = (Repl_Agmt*)object_get_data (agmt_obj);
- dn = agmt_get_dn_byref(agmt);
- conn = (Repl_Connection *)agmt_get_connection(agmt);
- if(conn == NULL){
- /* no connection for this agreement, and move on */
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: the replica (%s), is "
- "missing the connection. This replica will not be cleaned.\n", slapi_sdn_get_dn(dn));
- agmt_obj = agmtlist_get_next_agreement_for_replica (replica, agmt_obj);
- continue;
- }
- crc = conn_connect(conn);
- if (CONN_OPERATION_FAILED == crc ){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: failed to connect "
- "to repl agreement connection (%s), error %d\n",slapi_sdn_get_dn(dn), ACQUIRE_TRANSIENT_ERROR);
- } else if (CONN_SSL_NOT_ENABLED == crc){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: failed to acquire "
- "repl agmt connection (%s), errror %d\n",slapi_sdn_get_dn(dn), ACQUIRE_FATAL_ERROR);
- } else {
- conn_cancel_linger(conn);
- crc = conn_send_extended_operation(conn, REPL_CLEANRUV_OID, payload, NULL, &send_msgid);
- if (CONN_OPERATION_SUCCESS != crc){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: failed to send "
- "cleanruv extended op to repl agmt (%s), error %d\n", slapi_sdn_get_dn(dn), crc);
- } else {
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: successfully sent "
- "cleanruv extended op to (%s)\n",slapi_sdn_get_dn(dn));
- agmt_count++;
- }
- conn_start_linger(conn);
- }
- if(crc){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: replica (%s) has not "
- "been cleaned. You will need to rerun the CLEANALLRUV task on this replica.\n", slapi_sdn_get_dn(dn));
- rc = crc;
- }
- agmt_obj = agmtlist_get_next_agreement_for_replica (replica, agmt_obj);
- }
+ slapi_attr_first_value(attr, &val);
+ return slapi_value_get_string(val);
+}
-done:
+static int
+replica_cleanall_ruv_task(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter,
+ int *returncode, char *returntext, void *arg)
+{
+ Slapi_Task *task = NULL;
+ const Slapi_DN *task_dn;
+ Slapi_DN *dn = NULL;
+ Object *r;
+ const char *base_dn;
+ const char *rid_str;
+ ReplicaId rid;
+ int rc = SLAPI_DSE_CALLBACK_OK;
+
+ /* allocate new task now */
+ task = slapi_new_task(slapi_entry_get_ndn(e));
+ if(task == NULL){
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: Failed to create new task\n");
+ rc = SLAPI_DSE_CALLBACK_ERROR;
+ goto out;
+ }
+
+ /*
+ * Get our task settings
+ */
+ if ((base_dn = fetch_attr(e, "replica-base-dn", 0)) == NULL){
+ *returncode = LDAP_OBJECT_CLASS_VIOLATION;
+ rc = SLAPI_DSE_CALLBACK_ERROR;
+ goto out;
+ }
+ if ((rid_str = fetch_attr(e, "replica-id", 0)) == NULL){
+ *returncode = LDAP_OBJECT_CLASS_VIOLATION;
+ rc = SLAPI_DSE_CALLBACK_ERROR;
+ goto out;
+ }
- if(payload)
- ber_bvfree(payload);
+ task_dn = slapi_entry_get_sdn(e);
+ /*
+ * Check the rid
+ */
+ rid = atoi(rid_str);
+ if (rid <= 0 || rid >= READ_ONLY_REPLICA_ID){
+ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Invalid replica id (%d) for task - (%s)",
+ rid, slapi_sdn_get_dn(task_dn));
+ cleanruv_log(task, CLEANALLRUV_ID, "%s", returntext);
+ rc = LDAP_OPERATIONS_ERROR;
+ goto out;
+ }
+ /*
+ * Get the replica object
+ */
+ dn = slapi_sdn_new_dn_byval(base_dn);
+ if((r = replica_get_replica_from_dn(dn)) == NULL){
+ *returncode = LDAP_OPERATIONS_ERROR ;
+ rc = SLAPI_DSE_CALLBACK_ERROR;
+ goto out;
+ }
- slapi_ch_free_string(&ridstr);
+ /* clean the RUV's */
+ rc = replica_execute_cleanall_ruv_task (r, rid, task, returntext);
- /*
- * Now run the cleanruv task
- */
- replica_execute_cleanruv_task (r, rid, returntext);
-
- if(rc == 0 && agmt_count > 0){ /* success, but we need to check our replicas */
- /*
- * Launch the cleanruv monitoring thread. Once all the replicas are cleaned it will release the rid
- */
- data = (cleanruv_data*)slapi_ch_calloc(1, sizeof(cleanruv_data));
- if (data == NULL) {
- slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: failed to allocate "
- "cleanruv_data. Aborting task.\n");
- return -1;
- }
- data->repl_obj = r;
- data->rid = rid;
-
- thread = PR_CreateThread(PR_USER_THREAD, replica_cleanallruv_monitor_thread,
- (void *)data, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
- PR_UNJOINABLE_THREAD, SLAPD_DEFAULT_THREAD_STACKSIZE);
- if (thread == NULL) {
- slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: unable to create cleanAllRUV "
- "monitoring thread. Aborting task.\n");
- }
- } else if(rc == 0){ /* success */
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: Successfully Finished.\n");
- } else {
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: Task failed (%d)\n",rc);
- }
+out:
+ if(rc){
+ cleanruv_log(task, CLEANALLRUV_ID, "Task failed...(%d)", rc);
+ *returncode = rc;
+ slapi_task_finish(task, *returncode);
+ rc = SLAPI_DSE_CALLBACK_ERROR;
+ } else {
+ rc = SLAPI_DSE_CALLBACK_OK;
+ }
+ slapi_sdn_free(&dn);
- return rc;
+ return rc;
}
/*
- * After all the cleanAllRUV extended ops have been sent, we need to monitoring those replicas'
- * RUVs. Once the rid is cleaned, then we need to release it, and push this "release"
- * to the other replicas
+ * CLEANALLRUV task
+ *
+ * [1] Get the maxcsn from the RUV of the rid we want to clean
+ * [2] Create the payload for the "cleanallruv" extended ops
+ * [3] Create "monitor" thread to do the real work.
+ *
*/
-void
-replica_cleanallruv_monitor_thread(void *arg)
+static int
+replica_execute_cleanall_ruv_task (Object *r, ReplicaId rid, Slapi_Task *task, char *returntext)
{
- Object *agmt_obj;
- LDAP *ld;
- Repl_Connection *conn;
- Repl_Agmt *agmt;
- Replica *replica;;
- cleanruv_data *data = arg;
- LDAPMessage *result, *entry;
- BerElement *ber;
- time_t start_time;
- struct berval **vals;
- char *rid_text;
- char *attrs[2];
- char *attr;
- int replicas_cleaned = 0;
- int found = 0;
- int crc;
- int rc = 0;
- int i;
+ PRThread *thread = NULL;
+ Slapi_Task *pre_task = NULL; /* this is supposed to be null for logging */
+ Replica *replica;
+ Object *ruv_obj;
+ cleanruv_data *data = NULL;
+ CSN *maxcsn = NULL;
+ const RUV *ruv;
+ struct berval *payload = NULL;
+ char *ridstr = NULL;
+ char csnstr[CSN_STRSIZE];
+ int rc = 0;
+
+ if(get_cleanruv_task_count() >= CLEANRIDSIZ){
+ /* we are already running the maximum number of tasks */
+ cleanruv_log(pre_task, CLEANALLRUV_ID,
+ "Exceeded maximum number of active CLEANALLRUV tasks(%d)",CLEANRIDSIZ);
+ returntext = PR_smprintf("Exceeded maximum number of active CLEANALLRUV tasks(%d), "
+ "you must wait for one to finish.", CLEANRIDSIZ);
+ return LDAP_UNWILLING_TO_PERFORM;
+ }
- /*
- * Initialize our settings
- */
- attrs[0] = "nsds50ruv";
- attrs[1] = NULL;
- rid_text = slapi_ch_smprintf("{replica %d ldap", data->rid);
- replica = (Replica*)object_get_data (data->repl_obj);
- start_time = current_time();
+ /*
+ * Grab the replica
+ */
+ if(r){
+ replica = (Replica*)object_get_data (r);
+ } else {
+ cleanruv_log(pre_task, CLEANALLRUV_ID, "Replica is NULL, aborting task");
+ rc = -1;
+ goto fail;
+ }
+ /*
+ * Check if this is a consumer
+ */
+ if(replica_get_type(replica) == REPLICA_TYPE_READONLY){
+ /* this is a consumer, send error */
+ cleanruv_log(pre_task, CLEANALLRUV_ID, "Failed to clean rid (%d), task can not be run on a consumer",rid);
+ if(task){
+ rc = -1;
+ slapi_task_finish(task, rc);
+ }
+ return -1;
+ }
+ /*
+ * Grab the max csn of the deleted replica
+ */
+ ruv_obj = replica_get_ruv(replica);
+ ruv = object_get_data (ruv_obj);
+ if(ruv_get_rid_max_csn(ruv, &maxcsn, rid) == RUV_BAD_DATA){
+ /* no maxcsn, can not proceed */
+ cleanruv_log(pre_task, CLEANALLRUV_ID, "Could not find maxcsn for rid (%d)", rid);
+ rc = -1;
+ object_release(ruv_obj);
+ goto fail;
+ } else {
+ object_release(ruv_obj);
+ if(maxcsn == NULL || csn_get_replicaid(maxcsn) == 0){
+ /*
+ * This is for consistency with extop csn creation, where
+ * we want the csn string to be "0000000000000000000" not ""
+ */
+ csn_free(&maxcsn);
+ maxcsn = csn_new();
+ csn_init_by_string(maxcsn, "");
+ }
+ csn_as_string(maxcsn, PR_FALSE, csnstr);
+ }
+ /*
+ * Create payload
+ */
+ ridstr = slapi_ch_smprintf("%d:%s:%s", rid, slapi_sdn_get_dn(replica_get_root(replica)), csnstr);
+ payload = create_ruv_payload(ridstr);
+ slapi_ch_free_string(&ridstr);
+
+ if(payload == NULL){
+ cleanruv_log(pre_task, CLEANALLRUV_ID, "Failed to create extended op payload, aborting task");
+ rc = -1;
+ goto fail;
+ }
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: Waiting for all the replicas to get cleaned...\n");
+ /*
+ * Launch the cleanallruv thread. Once all the replicas are cleaned it will release the rid
+ */
+ data = (cleanruv_data*)slapi_ch_calloc(1, sizeof(cleanruv_data));
+ if (data == NULL) {
+ cleanruv_log(pre_task, CLEANALLRUV_ID, "Failed to allocate cleanruv_data. Aborting task.");
+ rc = -1;
+ goto fail;
+ }
+ data->repl_obj = r;
+ data->replica = replica;
+ data->rid = rid;
+ data->task = task;
+ data->maxcsn = maxcsn;
+ data->payload = payload;
+ data->sdn = NULL;
+
+ thread = PR_CreateThread(PR_USER_THREAD, replica_cleanallruv_thread,
+ (void *)data, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
+ PR_UNJOINABLE_THREAD, SLAPD_DEFAULT_THREAD_STACKSIZE);
+ if (thread == NULL) {
+ rc = -1;
+ goto fail;
+ } else {
+ goto done;
+ }
- while(!slapi_is_shutting_down())
- {
- DS_Sleep(PR_SecondsToInterval(10));
- found = 0;
- agmt_obj = agmtlist_get_first_agreement_for_replica (replica);
- 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;
- }
- /*
- * Get the replication connection
- */
- conn = (Repl_Connection *)agmt_get_connection(agmt);
- crc = conn_connect(conn);
- if (CONN_OPERATION_FAILED == crc ){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: monitor thread failed to connect "
- "to repl agreement connection (%s), error %d\n","", ACQUIRE_TRANSIENT_ERROR);
- continue;
- } else if (CONN_SSL_NOT_ENABLED == crc){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: monitor thread failed to acquire "
- "repl agmt connection (%s), error %d\n","", ACQUIRE_FATAL_ERROR);
- continue;
- }
- /*
- * Get the LDAP connection handle from the conn
- */
- ld = conn_get_ldap(conn);
- if(ld == NULL){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: monitor thread failed to get LDAP "
- "handle from the replication agmt (%s). Moving on to the next agmt.\n",agmt_get_long_name(agmt));
- continue;
- }
- /*
- * Search this replica for its tombstone/ruv entry
- */
- conn_cancel_linger(conn);
- conn_lock(conn);
- rc = ldap_search_ext_s(ld, slapi_sdn_get_dn(agmt_get_replarea(agmt)), LDAP_SCOPE_SUBTREE,
- "(&(nsuniqueid=ffffffff-ffffffff-ffffffff-ffffffff)(objectclass=nstombstone))",
- attrs, 0, NULL, NULL, NULL, 0, &result);
- if(rc != LDAP_SUCCESS){
- /*
- * Couldn't contact ldap server, what should we do?
- *
- * Skip it and move on! It's the admin's job to make sure all the replicas are up and running
- */
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: monitor thread failed to contact "
- "agmt (%s), moving on to the next agmt.\n", agmt_get_long_name(agmt));
- conn_unlock(conn);
- conn_start_linger(conn);
- continue;
- }
- /*
- * There is only one entry. Check its "nsds50ruv" for our cleaned rid
- */
- entry = ldap_first_entry( ld, result );
- if ( entry != NULL ) {
- for ( attr = ldap_first_attribute( ld, entry, &ber ); attr != NULL; attr = ldap_next_attribute( ld, entry, ber ) ){
- /* make sure the attribute is nsds50ruv */
- if(strcasecmp(attr,"nsds50ruv") != 0){
- continue;
- }
- if ((vals = ldap_get_values_len( ld, entry, attr)) != NULL ) {
- for ( i = 0; vals[i] && vals[i]->bv_val; i++ ) {
- /* look for this replica */
- if(strstr(rid_text, vals[i]->bv_val)){
- /* rid has not been cleaned yet, start over */
- found = 1;
- break;
- }
- }
- ldap_value_free_len(vals);
- }
- ldap_memfree( attr );
- }
- if ( ber != NULL ) {
- ber_free( ber, 0 );
- }
- }
- ldap_msgfree( result );
- /*
- * Unlock the connection, and start the linger timer
- */
- conn_unlock(conn);
- conn_start_linger(conn);
-
- if(found){
- /*
- * If we've been trying to clean these replicas for over an hour, just quit
- */
- if( (current_time() - start_time) > 3600){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: timed out checking if replicas have "
- "been cleaned. The rid has not been released, you need to rerun the task.\n");
- goto done;
- }
- /*
- * a rid has not been cleaned yet, go back to sleep and check them again
- */
- break;
- }
+fail:
+ cleanruv_log(pre_task, CLEANALLRUV_ID, "Failed to clean rid (%d)",rid);
+ if(task){
+ slapi_task_finish(task, rc);
+ }
+ if(payload){
+ ber_bvfree(payload);
+ }
+ csn_free(&maxcsn);
+ object_release (r);
- agmt_obj = agmtlist_get_next_agreement_for_replica (replica, agmt_obj);
- }
- if(!found){
- /*
- * The replicas have been cleaned! Next, release the rid
- */
- replicas_cleaned = 1;
- break;
- }
- } /* while */
+done:
- /*
- * If the replicas are cleaned, release the rid
- */
- if(replicas_cleaned){
- rc = replica_execute_release_ruv_task(data->repl_obj, data->rid);
- if(rc == 0){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: Successfully Finished. All active "
- "replicas have been cleaned.\n");
- } else {
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: Failed: Replica ID was not released (%d) "
- "You will need to rerun the task.\n", rc);
- }
- } else {
- /*
- * Shutdown
- */
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: slapd shutting down, you will need to rerun the task.\n");
- }
+ return rc;
+}
-done:
- slapi_ch_free((void **)&rid_text);
- slapi_ch_free((void **)&data);
+void
+replica_cleanallruv_thread_ext(void *arg)
+{
+ replica_cleanallruv_thread(arg);
}
/*
- * This function releases the cleaned rid so that it can be reused.
- * We send this operation to all the known active replicas.
+ * CLEANALLRUV Thread
+ *
+ * [1] Wait for the maxcsn to be covered
+ * [2] Make sure all the replicas are alive
+ * [3] Set the cleaned rid
+ * [4] Send the cleanAllRUV extop to all the replicas
+ * [5] Manually send the CLEANRUV task to replicas that do not support CLEANALLRUV
+ * [6] Wait for all the replicas to be cleaned.
+ * [7] Trigger cl trimming, release the rid, and remove all the "cleanallruv" attributes
+ * from the config.
*/
-static int
-replica_execute_release_ruv_task(Object *r, ReplicaId rid)
+static void
+replica_cleanallruv_thread(void *arg)
{
- Repl_Connection *conn;
- Replica *replica = (Replica*)object_get_data (r);
- Object *agmt_obj;
- Repl_Agmt *agmt;
- ConnResult crc;
- const Slapi_DN *dn = NULL;
- struct berval *payload = NULL;
- char *ridstr = NULL;
- int send_msgid = 0;
- int rc = 0;
+ Object *ruv_obj = NULL;
+ Object *agmt_obj = NULL;
+ Repl_Agmt *agmt = NULL;
+ RUV *ruv = NULL;
+ cleanruv_data *data = arg;
+ char csnstr[CSN_STRSIZE];
+ char *returntext = NULL;
+ char *rid_text = NULL;
+ int found_dirty_rid = 1;
+ int agmt_not_notified = 1;
+ int interval = 10;
+ int free_obj = 0;
+ int rc = 0;
+
+ /*
+ * Initialize our settings
+ */
+ if(data->replica == NULL && data->repl_obj == NULL){
+ /*
+ * This thread was initiated at startup because the process did not finish. Due
+ * to timing issues, we need to wait to grab the replica obj until we get here.
+ */
+ data->repl_obj = replica_get_replica_from_dn(data->sdn);
+ data->replica = (Replica*)object_get_data(data->repl_obj);
+ free_obj = 1;
+ }
+ if(data->replica == NULL && data->repl_obj){
+ data->replica = (Replica*)object_get_data(data->repl_obj);
+ }
+ if( data->replica && data->repl_obj == NULL){
+ data->repl_obj = object_new(data->replica, NULL);
+ free_obj = 1;
+ }
+ if(data->task){
+ slapi_task_begin(data->task, 1);
+ }
+ rid_text = slapi_ch_smprintf("{replica %d ldap", data->rid);
+ csn_as_string(data->maxcsn, PR_FALSE, csnstr);
+
+ /*
+ * Add the cleanallruv task to the repl config - so we can handle restarts
+ */
+ cleanruv_log(data->task, CLEANALLRUV_ID, "Cleaning rid (%d)...", data->rid);
+ add_cleaned_rid(data->rid, data->replica, csnstr); /* marks config that we started cleaning a rid */
+ /*
+ * First, wait for the maxcsn to be covered
+ */
+ cleanruv_log(data->task, CLEANALLRUV_ID, "Waiting to process all the updates from the deleted replica...");
+ ruv_obj = replica_get_ruv(data->replica);
+ ruv = object_get_data (ruv_obj);
+ while(data->maxcsn && !is_task_aborted(data->rid) && !is_cleaned_rid(data->rid) && !slapi_is_shutting_down()){
+ if(csn_get_replicaid(data->maxcsn) == 0 || ruv_covers_csn(ruv,data->maxcsn)){
+ /* We are caught up, now we can clean the ruv's */
+ break;
+ }
+ DS_Sleep(PR_SecondsToInterval(5));
+ }
+ object_release(ruv_obj);
+ /*
+ * Next, make sure all the replicas are up and running before sending off the clean ruv tasks
+ */
+ cleanruv_log(data->task, CLEANALLRUV_ID,"Waiting for all the replicas to be online...");
+ if(check_agmts_are_alive(data->replica, data->rid, data->task)){
+ /* error, aborted or shutdown */
+ goto done;
+ }
+ /*
+ * Make sure all the replicas have seen the max csn
+ */
+ cleanruv_log(data->task, CLEANALLRUV_ID,"Waiting for all the replicas to receive all the deleted replica updates...");
+ if(check_agmts_are_caught_up(data->replica, data->rid, csnstr, data->task)){
+ /* error, aborted or shutdown */
+ goto done;
+ }
+ /*
+ * Set the rid as notified - this blocks the changelog from sending out updates
+ * during this process, as well as prevents the db ruv from getting polluted.
+ */
+ set_cleaned_rid(data->rid);
+ /*
+ * Now send the cleanruv extended op to all the agreements
+ */
+ cleanruv_log(data->task, CLEANALLRUV_ID, "Sending cleanAllRUV task to all the replicas...");
+ while(agmt_not_notified && !is_task_aborted(data->rid) && !slapi_is_shutting_down()){
+ agmt_obj = agmtlist_get_first_agreement_for_replica (data->replica);
+ if(agmt_obj == NULL){
+ /* no agmts, just clean this replica */
+ break;
+ }
+ while (agmt_obj){
+ agmt = (Repl_Agmt*)object_get_data (agmt_obj);
+ if(!agmt_is_enabled(agmt)){ /* skip disabled replicas */
+ agmt_obj = agmtlist_get_next_agreement_for_replica (data->replica, agmt_obj);
+ continue;
+ }
+ if(replica_cleanallruv_send_extop(agmt, data->rid, data->task, data->payload, 1) == 0){
+ agmt_not_notified = 0;
+ } else {
+ agmt_not_notified = 1;
+ break;
+ }
+ agmt_obj = agmtlist_get_next_agreement_for_replica (data->replica, agmt_obj);
+ }
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: releasing rid (%d)...\n", rid);
+ if(is_task_aborted(data->rid)){
+ goto done;
+ }
+ if(agmt_not_notified == 0){
+ break;
+ }
+ /*
+ * need to sleep between passes
+ */
+ cleanruv_log(data->task, CLEANALLRUV_ID, "Not all replicas have received the "
+ "cleanallruv extended op, retrying in %d seconds",interval);
+ PR_Lock( notify_lock );
+ PR_WaitCondVar( notify_cvar, PR_SecondsToInterval(interval) );
+ PR_Unlock( notify_lock );
+
+ if(interval < 14400){ /* 4 hour max */
+ interval = interval * 2;
+ } else {
+ interval = 14400;
+ }
+ }
+ /*
+ * Run the CLEANRUV task
+ */
+ cleanruv_log(data->task, CLEANALLRUV_ID,"Cleaning local ruv's...");
+ replica_execute_cleanruv_task (data->repl_obj, data->rid, returntext);
+ /*
+ * Wait for all the replicas to be cleaned
+ */
+ cleanruv_log(data->task, CLEANALLRUV_ID,"Waiting for all the replicas to be cleaned...");
+
+ interval = 10;
+ while(found_dirty_rid && !is_task_aborted(data->rid) && !slapi_is_shutting_down()){
+ agmt_obj = agmtlist_get_first_agreement_for_replica (data->replica);
+ if(agmt_obj == NULL){
+ break;
+ }
+ while (agmt_obj && !slapi_is_shutting_down()){
+ agmt = (Repl_Agmt*)object_get_data (agmt_obj);
+ if(!agmt_is_enabled(agmt)){ /* skip disabled replicas */
+ agmt_obj = agmtlist_get_next_agreement_for_replica (data->replica, agmt_obj);
+ continue;
+ }
+ if(replica_cleanallruv_check_ruv(agmt, rid_text, data->task) == 0){
+ found_dirty_rid = 0;
+ } else {
+ found_dirty_rid = 1;
+ break;
+ }
+ agmt_obj = agmtlist_get_next_agreement_for_replica (data->replica, agmt_obj);
+ }
+ /* If the task is abort or everyone is cleaned, break out */
+ if(is_task_aborted(data->rid)){
+ goto done;
+ }
+ if(found_dirty_rid == 0){
+ break;
+ }
+ /*
+ * need to sleep between passes
+ */
+ cleanruv_log(data->task, CLEANALLRUV_ID, "Replicas have not been cleaned yet, "
+ "retrying in %d seconds", interval);
+ PR_Lock( notify_lock );
+ PR_WaitCondVar( notify_cvar, PR_SecondsToInterval(interval) );
+ PR_Unlock( notify_lock );
+
+ if(interval < 14400){ /* 4 hour max */
+ interval = interval * 2;
+ } else {
+ interval = 14400;
+ }
+ } /* while */
- /*
- * Set the released rid, and trigger cl trimmming
- */
- set_released_rid((int)rid);
- trigger_cl_trimming();
- /*
- * Create payload
- */
- ridstr = slapi_ch_smprintf("%d:%s", rid, slapi_sdn_get_dn(replica_get_root(replica)));
- payload = create_ruv_payload(ridstr);
- if(payload == NULL){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "releaseRUV_task: failed to create ext op payload, aborting op\n");
- rc = -1;
- goto done;
- }
+done:
+ /*
+ * If the replicas are cleaned, release the rid, and trim the changelog
+ */
+ if(!found_dirty_rid){
+ trigger_cl_trimming(data->rid);
+ delete_cleaned_rid(data->replica, data->rid, data->maxcsn);
+ cleanruv_log(data->task, CLEANALLRUV_ID, "Successfully cleaned rid(%d).", data->rid);
+ slapi_task_finish(data->task, rc);
+ } else {
+ /*
+ * Shutdown or abort
+ */
+ if(!is_task_aborted(data->rid)){
+ cleanruv_log(data->task, CLEANALLRUV_ID,"Server shutting down. Process will resume at server startup");
+ } else {
+ cleanruv_log(data->task, CLEANALLRUV_ID,"Task aborted for rid(%d).",data->rid);
+ }
+ if(data->task){
+ slapi_task_finish(data->task, rc);
+ }
+ }
- agmt_obj = agmtlist_get_first_agreement_for_replica (replica);
- while (agmt_obj)
- {
- agmt = (Repl_Agmt*)object_get_data (agmt_obj);
- dn = agmt_get_dn_byref(agmt);
- conn = (Repl_Connection *)agmt_get_connection(agmt);
- if(conn == NULL){
- /* no connection for this agreement, log error, and move on */
- agmt_obj = agmtlist_get_next_agreement_for_replica (replica, agmt_obj);
- continue;
- }
- crc = conn_connect(conn);
- if (CONN_OPERATION_FAILED == crc ){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "releaseRUV_task: failed to connect "
- "to repl agmt (%s), error %d\n",slapi_sdn_get_dn(dn), ACQUIRE_TRANSIENT_ERROR);
- rc = LDAP_OPERATIONS_ERROR;
- } else if (CONN_SSL_NOT_ENABLED == crc){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "releaseRUV_task: failed to acquire "
- "repl agmt (%s), error %d\n",slapi_sdn_get_dn(dn), ACQUIRE_FATAL_ERROR);
- rc = LDAP_OPERATIONS_ERROR;
- } else {
- conn_cancel_linger(conn);
- crc = conn_send_extended_operation(conn, REPL_RELEASERUV_OID, payload, NULL, &send_msgid);
- if (CONN_OPERATION_SUCCESS != crc){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: failed to send "
- "releaseRUV extended op to repl agmt (%s), error %d\n", slapi_sdn_get_dn(dn), crc);
- rc = LDAP_OPERATIONS_ERROR;
- } else {
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: successfully sent "
- "releaseRUV extended op to (%s)\n",slapi_sdn_get_dn(dn));
- }
- conn_start_linger(conn);
- }
- if(crc){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: replica (%s) has not "
- "been released. You will need to rerun the task\n",
- slapi_sdn_get_dn(dn));
- rc = crc;
- }
- agmt_obj = agmtlist_get_next_agreement_for_replica (replica, agmt_obj);
- }
+ if(data->payload){
+ ber_bvfree(data->payload);
+ }
+ if(data->repl_obj && free_obj){
+ object_release(data->repl_obj);
+ }
+ slapi_sdn_free(&data->sdn);
+ slapi_ch_free_string(&rid_text);
+ csn_free(&data->maxcsn);
+ slapi_ch_free((void **)&data);
+}
-done:
- /*
- * reset the released/clean rid
- */
- if(rc == 0){
- set_released_rid(ALREADY_RELEASED);
- delete_cleaned_rid();
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: Successfully released rid (%d)\n", rid);
- } else {
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: Failed to release rid (%d), error (%d)\n", rid, rc);
- }
+/*
+ * Waits for all the repl agmts to be have have the maxcsn. Returns error only on abort or shutdown
+ */
+static int
+check_agmts_are_caught_up(Replica *replica, ReplicaId rid, char *maxcsn, Slapi_Task *task)
+{
+ Object *agmt_obj;
+ Repl_Agmt *agmt;
+ char *rid_text;
+ int not_all_caughtup = 1;
+ int interval = 10;
+
+ rid_text = slapi_ch_smprintf("{replica %d ldap", rid);
+
+ while(not_all_caughtup && !is_task_aborted(rid) && !slapi_is_shutting_down()){
+ agmt_obj = agmtlist_get_first_agreement_for_replica (replica);
+ if(agmt_obj == NULL){
+ not_all_caughtup = 0;
+ break;
+ }
+ while (agmt_obj){
+ agmt = (Repl_Agmt*)object_get_data (agmt_obj);
+ if(!agmt_is_enabled(agmt)){ /* skip disabled replicas */
+ agmt_obj = agmtlist_get_next_agreement_for_replica (replica, agmt_obj);
+ continue;
+ }
+ if(replica_cleanallruv_check_maxcsn(agmt, rid_text, maxcsn, task) == 0){
+ not_all_caughtup = 0;
+ } else {
+ not_all_caughtup = 1;
+ break;
+ }
+ agmt_obj = agmtlist_get_next_agreement_for_replica (replica, agmt_obj);
+ } /* agmt while */
+
+ if(not_all_caughtup == 0 || is_task_aborted(rid) ){
+ break;
+ }
+ cleanruv_log(task, CLEANALLRUV_ID, "Not all replicas caught up, retrying in %d seconds",interval);
+ PR_Lock( notify_lock );
+ PR_WaitCondVar( notify_cvar, PR_SecondsToInterval(interval) );
+ PR_Unlock( notify_lock );
- if(payload)
- ber_bvfree(payload);
+ if(interval < 14400){ /* 4 hour max */
+ interval = interval * 2;
+ } else {
+ interval = 14400;
+ }
+ }
+ slapi_ch_free_string(&rid_text);
- slapi_ch_free_string(&ridstr);
+ if(is_task_aborted(rid)){
+ return -1;
+ }
- return rc;
+ return not_all_caughtup;
}
-static struct berval *
-create_ruv_payload(char *value){
- struct berval *req_data = NULL;
- BerElement *tmp_bere = NULL;
+/*
+ * Waits for all the repl agmts to be online. Returns error only on abort or shutdown
+ */
+static int
+check_agmts_are_alive(Replica *replica, ReplicaId rid, Slapi_Task *task)
+{
+ Object *agmt_obj;
+ Repl_Agmt *agmt;
+ int not_all_alive = 1;
+ int interval = 10;
+
+ while(not_all_alive && is_task_aborted(rid) == 0 && !slapi_is_shutting_down()){
+ agmt_obj = agmtlist_get_first_agreement_for_replica (replica);
+ if(agmt_obj == NULL){
+ not_all_alive = 0;
+ break;
+ }
+ while (agmt_obj){
+ agmt = (Repl_Agmt*)object_get_data (agmt_obj);
+ if(!agmt_is_enabled(agmt)){ /* skip disabled replicas */
+ agmt_obj = agmtlist_get_next_agreement_for_replica (replica, agmt_obj);
+ continue;
+ }
+ if(replica_cleanallruv_replica_alive(agmt) == 0){
+ not_all_alive = 0;
+ } else {
+ not_all_alive = 1;
+ break;
+ }
+ agmt_obj = agmtlist_get_next_agreement_for_replica (replica, agmt_obj);
+ }
- if ((tmp_bere = der_alloc()) == NULL){
- goto error;
- }
- if (ber_printf(tmp_bere, "{s", value) == -1){
- goto error;
- }
+ if(not_all_alive == 0 || is_task_aborted(rid)){
+ break;
+ }
+ cleanruv_log(task, CLEANALLRUV_ID, "Not all replicas online, retrying in %d seconds...",interval);
+ PR_Lock( notify_lock );
+ PR_WaitCondVar( notify_cvar, PR_SecondsToInterval(interval) );
+ PR_Unlock( notify_lock );
- if (ber_printf(tmp_bere, "}") == -1){
- goto error;
- }
+ if(interval < 14400){ /* 4 hour max */
+ interval = interval * 2;
+ } else {
+ interval = 14400;
+ }
+ }
+ if(is_task_aborted(rid)){
+ return -1;
+ }
- if (ber_flatten(tmp_bere, &req_data) == -1){
- goto error;
- }
+ return not_all_alive;
+}
- goto done;
+/*
+ * Create the CLEANALLRUV extended op payload
+ */
+struct berval *
+create_ruv_payload(char *value)
+{
+ struct berval *req_data = NULL;
+ BerElement *tmp_bere = NULL;
+
+ if ((tmp_bere = der_alloc()) == NULL){
+ goto error;
+ }
+ if (ber_printf(tmp_bere, "{s", value) == -1){
+ goto error;
+ }
+ if (ber_printf(tmp_bere, "}") == -1){
+ goto error;
+ }
+ if (ber_flatten(tmp_bere, &req_data) == -1){
+ goto error;
+ }
+ goto done;
error:
- if (NULL != req_data){
- ber_bvfree(req_data);
- req_data = NULL;
- }
+ if (NULL != req_data){
+ ber_bvfree(req_data);
+ req_data = NULL;
+ }
done:
- if (NULL != tmp_bere){
- ber_free(tmp_bere, 1);
- tmp_bere = NULL;
- }
+ if (NULL != tmp_bere){
+ ber_free(tmp_bere, 1);
+ tmp_bere = NULL;
+ }
+
+ return req_data;
+}
- return req_data;
+/*
+ * Manually add the CLEANRUV task to replicas that do not support
+ * the CLEANALLRUV task.
+ */
+static void
+replica_send_cleanruv_task(Repl_Agmt *agmt, ReplicaId rid, Slapi_Task *task)
+{
+ Repl_Connection *conn;
+ ConnResult crc = 0;
+ LDAP *ld;
+ Slapi_DN *dn;
+ struct berval *vals[2];
+ struct berval val;
+ LDAPMod *mods[2];
+ LDAPMod mod;
+ char *repl_dn = NULL;
+ char data[15];
+ int rc;
+
+ if((conn = conn_new(agmt)) == NULL){
+ return;
+ }
+ crc = conn_connect(conn);
+ if (CONN_OPERATION_SUCCESS != crc){
+ conn_delete_internal_ext(conn);
+ return;
+ }
+ ld = conn_get_ldap(conn);
+ if(ld == NULL){
+ conn_delete_internal_ext(conn);
+ return;
+ }
+ val.bv_len = PR_snprintf(data, sizeof(data), "CLEANRUV%d", rid);
+ dn = agmt_get_replarea(agmt);
+ mod.mod_op = LDAP_MOD_ADD|LDAP_MOD_BVALUES;
+ mod.mod_type = "nsds5task";
+ mod.mod_bvalues = vals;
+ vals [0] = &val;
+ vals [1] = NULL;
+ val.bv_val = data;
+ mods[0] = &mod;
+ mods[1] = NULL;
+ repl_dn = PR_smprintf("cn=replica,cn=\"%s\",cn=mapping tree,cn=config", slapi_sdn_get_dn(dn));
+ /*
+ * Add task to remote replica
+ */
+ rc = ldap_modify_ext_s( ld, repl_dn, mods, NULL, NULL);
+
+ if(rc != LDAP_SUCCESS){
+ cleanruv_log(task, CLEANALLRUV_ID, "Failed to add CLEANRUV task replica "
+ "(%s). You will need to manually run the CLEANRUV task on this replica (%s) error (%d)",
+ agmt_get_long_name(agmt), agmt_get_hostname(agmt), rc);
+ }
+ slapi_ch_free_string(&repl_dn);
+ conn_delete_internal_ext(conn);
}
+/*
+ * Check if the rid is in our list of "cleaned" rids
+ */
int
is_cleaned_rid(ReplicaId rid)
{
- if(rid == cleaned_rid){
- return 1;
- } else {
- return 0;
- }
+ int i;
+
+ slapi_rwlock_rdlock(rid_lock);
+ for(i = 0; i < CLEANRIDSIZ && cleaned_rids[i] != 0; i++){
+ if(rid == cleaned_rids[i]){
+ slapi_rwlock_unlock(rid_lock);
+ return 1;
+ }
+ }
+ slapi_rwlock_unlock(rid_lock);
+
+ return 0;
}
+int
+is_task_aborted(ReplicaId rid)
+{
+ int i;
+
+ if(rid == 0){
+ return 0;
+ }
+ slapi_rwlock_rdlock(abort_rid_lock);
+ for(i = 0; i < CLEANRIDSIZ && aborted_rids[i] != 0; i++){
+ if(rid == aborted_rids[i]){
+ slapi_rwlock_unlock(abort_rid_lock);
+ return 1;
+ }
+ }
+ slapi_rwlock_unlock(abort_rid_lock);
+ return 0;
+}
+
+/*
+ * Just add the rid to the in memory, as we don't want it to survive after a restart,
+ * This prevent the changelog from sending updates from this rid, and the local ruv
+ * will not be updated either.
+ */
void
-set_cleaned_rid( ReplicaId rid )
+set_cleaned_rid(ReplicaId rid)
{
- cleaned_rid = rid;
+ int i;
+
+ slapi_rwlock_wrlock(rid_lock);
+ for(i = 0; i < CLEANRIDSIZ; i++){
+ if(cleaned_rids[i] == 0){
+ cleaned_rids[i] = rid;
+ cleaned_rids[i + 1] = 0;
+ }
+ }
+ slapi_rwlock_unlock(rid_lock);
}
+/*
+ * Add the rid and maxcsn to the repl config (so we can resume after a server restart)
+ */
void
-delete_cleaned_rid()
+add_cleaned_rid(ReplicaId rid, Replica *r, char *maxcsn)
{
- cleaned_rid = 0;
+ Slapi_PBlock *pb;
+ struct berval *vals[2];
+ struct berval val;
+ LDAPMod *mods[2];
+ LDAPMod mod;
+ char data[CSN_STRSIZE + 10];
+ char *dn;
+ int rc;
+
+ /*
+ * Write the rid & maxcsn to the config entry
+ */
+ val.bv_len = PR_snprintf(data, sizeof(data),"%d:%s", rid, maxcsn);
+ dn = replica_get_dn(r);
+ pb = slapi_pblock_new();
+ mod.mod_op = LDAP_MOD_ADD|LDAP_MOD_BVALUES;
+ mod.mod_type = (char *)type_replicaCleanRUV;
+ mod.mod_bvalues = vals;
+ vals [0] = &val;
+ vals [1] = NULL;
+ val.bv_val = data;
+ mods[0] = &mod;
+ mods[1] = NULL;
+
+ replica_add_cleanruv_data(r, val.bv_val);
+
+ slapi_modify_internal_set_pb (pb, dn, mods, NULL, NULL,
+ repl_get_plugin_identity (PLUGIN_MULTIMASTER_REPLICATION), 0);
+ slapi_modify_internal_pb (pb);
+ slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
+ if (rc != LDAP_SUCCESS){
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "CleanAllRUV Task: failed to update replica "
+ "config (%d), rid (%d)\n", rc, rid);
+ }
+ slapi_ch_free_string(&dn);
+ slapi_pblock_destroy(pb);
}
-int
-get_released_rid()
+/*
+ * Add aborted rid and repl root to config in case of a server restart
+ */
+void
+add_aborted_rid(ReplicaId rid, Replica *r, char *repl_root)
{
- return released_rid;
+ Slapi_PBlock *pb;
+ struct berval *vals[2];
+ struct berval val;
+ LDAPMod *mods[2];
+ LDAPMod mod;
+ char *data;
+ char *dn;
+ int rc;
+ int i;
+
+ slapi_rwlock_wrlock(abort_rid_lock);
+ for(i = 0; i < CLEANRIDSIZ; i++){
+ if(aborted_rids[i] == 0){
+ aborted_rids[i] = rid;
+ aborted_rids[i + 1] = 0;
+ break;
+ }
+ }
+ slapi_rwlock_unlock(abort_rid_lock);
+ /*
+ * Write the rid to the config entry
+ */
+ dn = replica_get_dn(r);
+ pb = slapi_pblock_new();
+ data = PR_smprintf("%d:%s", rid, repl_root);
+ mod.mod_op = LDAP_MOD_ADD|LDAP_MOD_BVALUES;
+ mod.mod_type = (char *)type_replicaAbortCleanRUV;
+ mod.mod_bvalues = vals;
+ vals [0] = &val;
+ vals [1] = NULL;
+ val.bv_val = data;
+ val.bv_len = strlen (data);
+ mods[0] = &mod;
+ mods[1] = NULL;
+
+ slapi_modify_internal_set_pb (pb, dn, mods, NULL, NULL,
+ repl_get_plugin_identity (PLUGIN_MULTIMASTER_REPLICATION), 0);
+ slapi_modify_internal_pb (pb);
+ slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
+ if (rc != LDAP_SUCCESS){
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "Abort CleanAllRUV Task: failed to update "
+ "replica config (%d), rid (%d)\n", rc, rid);
+ }
+
+ slapi_ch_free_string(&dn);
+ slapi_ch_free_string(&data);
+ slapi_pblock_destroy(pb);
}
-int
-is_released_rid(int rid)
+void
+delete_aborted_rid(Replica *r, ReplicaId rid, char *repl_root){
+ Slapi_PBlock *pb;
+ LDAPMod *mods[2];
+ LDAPMod mod;
+ struct berval *vals[2];
+ struct berval val;
+ char *data;
+ char *dn;
+ int rc;
+ int i;
+
+ if(r == NULL)
+ return;
+
+ /*
+ * Remove this rid, and optimize the array
+ */
+ slapi_rwlock_wrlock(abort_rid_lock);
+ for(i = 0; i < CLEANRIDSIZ && aborted_rids[i] != rid; i++); /* found rid, stop */
+ for(; i < CLEANRIDSIZ; i++){
+ /* rewrite entire array */
+ aborted_rids[i] = aborted_rids[i + 1];
+ }
+ slapi_rwlock_unlock(abort_rid_lock);
+ /*
+ * Prepare the mods for the config entry
+ */
+ dn = replica_get_dn(r);
+ pb = slapi_pblock_new();
+ data = PR_smprintf("%d:%s", (int)rid, repl_root);
+
+ mod.mod_op = LDAP_MOD_DELETE|LDAP_MOD_BVALUES;
+ mod.mod_type = (char *)type_replicaAbortCleanRUV;
+ mod.mod_bvalues = vals;
+ vals [0] = &val;
+ vals [1] = NULL;
+ val.bv_val = data;
+ val.bv_len = strlen (data);
+ mods[0] = &mod;
+ mods[1] = NULL;
+
+ slapi_modify_internal_set_pb(pb, dn, mods, NULL, NULL, repl_get_plugin_identity (PLUGIN_MULTIMASTER_REPLICATION), 0);
+ slapi_modify_internal_pb (pb);
+ slapi_pblock_destroy (pb);
+ slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
+ if (rc != LDAP_SUCCESS){
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "Abort CleanAllRUV Task: failed to remove replica "
+ "config (%d), rid (%d)\n", rc, rid);
+ }
+
+ slapi_ch_free_string(&dn);
+ slapi_ch_free_string(&data);
+}
+
+/*
+ * Remove the rid from our list, and the config
+ */
+void
+delete_cleaned_rid(Replica *r, ReplicaId rid, CSN *maxcsn)
{
- if(rid == released_rid){
- return 1;
- } else {
- return 0;
- }
+ Slapi_PBlock *pb;
+ Object *agmt_obj;
+ Repl_Agmt *agmt;
+ LDAPMod *mods[2];
+ LDAPMod mod;
+ struct berval *vals[2];
+ struct berval val;
+ char *dn;
+ char data[CSN_STRSIZE + 10];
+ char csnstr[CSN_STRSIZE];
+ int rc;
+ int i;
+
+ if(r == NULL || maxcsn == NULL)
+ return;
+
+ /*
+ * Remove this rid, and optimize the array
+ */
+ slapi_rwlock_wrlock(rid_lock);
+ for(i = 0; i < CLEANRIDSIZ && cleaned_rids[i] != rid; i++); /* found rid, stop */
+ for(; i < CLEANRIDSIZ; i++){
+ /* rewrite entire array */
+ cleaned_rids[i] = cleaned_rids[i + 1];
+ }
+ slapi_rwlock_unlock(rid_lock);
+ /*
+ * Prepare the mods for the config entry
+ */
+ csn_as_string(maxcsn, PR_FALSE, csnstr);
+ val.bv_len = PR_snprintf(data, sizeof(data), "%d:%s", (int)rid, csnstr);
+ dn = replica_get_dn(r);
+ pb = slapi_pblock_new();
+ mod.mod_op = LDAP_MOD_DELETE|LDAP_MOD_BVALUES;
+ mod.mod_type = (char *)type_replicaCleanRUV;
+ mod.mod_bvalues = vals;
+ vals [0] = &val;
+ vals [1] = NULL;
+ val.bv_val = data;
+ mods[0] = &mod;
+ mods[1] = NULL;
+
+ replica_remove_cleanruv_data(r, data);
+
+ slapi_modify_internal_set_pb(pb, dn, mods, NULL, NULL, repl_get_plugin_identity (PLUGIN_MULTIMASTER_REPLICATION), 0);
+ slapi_modify_internal_pb (pb);
+ slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
+ if (rc != LDAP_SUCCESS){
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "CleanAllRUV Task: failed to remove replica config "
+ "(%d), rid (%d)\n", rc, rid);
+ }
+ slapi_pblock_destroy (pb);
+ slapi_ch_free_string(&dn);
+ /*
+ * Now release the cleaned rid from the repl agmts
+ */
+ agmt_obj = agmtlist_get_first_agreement_for_replica (r);
+ 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;
+ }
+ agmt_set_cleanruv_data(agmt, rid, CLEANRUV_RELEASED);
+ agmt_obj = agmtlist_get_next_agreement_for_replica (r, agmt_obj);
+ }
}
+/*
+ * Abort the CLEANALLRUV task
+ */
int
-is_already_released_rid()
+replica_cleanall_ruv_abort(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter,
+ int *returncode, char *returntext, void *arg)
{
- if(released_rid == ALREADY_RELEASED){
- return 1;
- } else {
- return 0;
- }
+ PRThread *thread = NULL;
+ struct berval *payload = NULL;
+ Slapi_Task *task = NULL;
+ Replica *replica;
+ ReplicaId rid;
+ cleanruv_data *data = NULL;
+ const Slapi_DN *dn;
+ Object *r;
+ CSN *maxcsn;
+ const char *base_dn;
+ const char *rid_str;
+ char *ridstr;
+ int rc = SLAPI_DSE_CALLBACK_OK;
+
+ if(get_abort_cleanruv_task_count() >= CLEANRIDSIZ){
+ /* we are already running the maximum number of tasks */
+ cleanruv_log(task, ABORT_CLEANALLRUV_ID,
+ "Exceeded maximum number of active ABORT CLEANALLRUV tasks(%d)",CLEANRIDSIZ);
+ returntext = PR_smprintf("Exceeded maximum number of active ABORT CLEANALLRUV tasks(%d), "
+ "you must wait for one to finish.", CLEANRIDSIZ);
+ *returncode = LDAP_OPERATIONS_ERROR;
+ return SLAPI_DSE_CALLBACK_ERROR;
+ }
+
+ /* allocate new task now */
+ task = slapi_new_task(slapi_entry_get_ndn(e));
+ /*
+ * Get our task settings
+ */
+ if ((rid_str = fetch_attr(e, "replica-id", 0)) == NULL){
+ cleanruv_log(task, ABORT_CLEANALLRUV_ID,"Missing required attr \"replica-id\"");
+ *returncode = LDAP_OBJECT_CLASS_VIOLATION;
+ rc = SLAPI_DSE_CALLBACK_ERROR;
+ goto out;
+ }
+ if ((base_dn = fetch_attr(e, "replica-base-dn", 0)) == NULL){
+ cleanruv_log(task, ABORT_CLEANALLRUV_ID,"Missing required attr \"replica-base-dn\"");
+ *returncode = LDAP_OBJECT_CLASS_VIOLATION;
+ rc = SLAPI_DSE_CALLBACK_ERROR;
+ goto out;
+ }
+ /*
+ * Check the rid
+ */
+ rid = atoi(rid_str);
+ if (rid <= 0 || rid >= READ_ONLY_REPLICA_ID){
+ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Invalid replica id (%d) for task - (%s)",
+ rid, slapi_sdn_get_dn(slapi_entry_get_sdn(e)));
+ cleanruv_log(task, ABORT_CLEANALLRUV_ID,"%s", returntext);
+ *returncode = LDAP_OPERATIONS_ERROR;
+ rc = SLAPI_DSE_CALLBACK_ERROR;
+ goto out;
+ }
+ /*
+ * Get the replica object
+ */
+ dn = slapi_sdn_new_dn_byval(base_dn);
+ if((r = replica_get_replica_from_dn(dn)) == NULL){
+ cleanruv_log(task, ABORT_CLEANALLRUV_ID,"Failed to find replica from dn(%s)", base_dn);
+ *returncode = LDAP_OPERATIONS_ERROR;
+ rc = SLAPI_DSE_CALLBACK_ERROR;
+ goto out;
+ }
+ /*
+ * Create payload
+ */
+ ridstr = slapi_ch_smprintf("%d:%s", rid, base_dn);
+ payload = create_ruv_payload(ridstr);
+
+ if(payload == NULL){
+ cleanruv_log(task, ABORT_CLEANALLRUV_ID, "Failed to create extended op payload, aborting task");
+ *returncode = LDAP_OPERATIONS_ERROR;
+ rc = SLAPI_DSE_CALLBACK_ERROR;
+ goto out;
+ }
+ /*
+ * Stop the cleaning, and delete the rid
+ */
+ replica = (Replica*)object_get_data (r);
+ maxcsn = replica_get_cleanruv_maxcsn(replica, rid);
+ delete_cleaned_rid(replica, rid, maxcsn);
+ add_aborted_rid(rid, replica, (char *)base_dn);
+ stop_ruv_cleaning();
+ /*
+ * Prepare the abort struct and fire off the thread
+ */
+ data = (cleanruv_data*)slapi_ch_calloc(1, sizeof(cleanruv_data));
+ if (data == NULL) {
+ cleanruv_log(task, ABORT_CLEANALLRUV_ID,"Failed to allocate abort_cleanruv_data. Aborting task.");
+ *returncode = LDAP_OPERATIONS_ERROR;
+ rc = SLAPI_DSE_CALLBACK_ERROR;
+ goto out;
+ }
+ data->repl_obj = r; /* released in replica_abort_task_thread() */
+ data->replica = replica;
+ data->task = task;
+ data->payload = payload;
+ data->rid = rid;
+ data->repl_root = slapi_ch_strdup(base_dn);
+ data->sdn = NULL;
+
+ thread = PR_CreateThread(PR_USER_THREAD, replica_abort_task_thread,
+ (void *)data, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
+ PR_UNJOINABLE_THREAD, SLAPD_DEFAULT_THREAD_STACKSIZE);
+ if (thread == NULL) {
+ object_release(r);
+ cleanruv_log(task, ABORT_CLEANALLRUV_ID,"Unable to create abort thread. Aborting task.");
+ *returncode = LDAP_OPERATIONS_ERROR;
+ rc = SLAPI_DSE_CALLBACK_ERROR;
+ }
+
+out:
+
+ csn_free(&maxcsn);
+ slapi_ch_free_string(&ridstr);
+
+ if(rc != SLAPI_DSE_CALLBACK_OK){
+ cleanruv_log(task, ABORT_CLEANALLRUV_ID, "Abort Task failed (%d)", rc);
+ slapi_task_finish(task, rc);
+ }
+
+ return rc;
+}
+
+/*
+ * Abort CLEANALLRUV task thread
+ */
+void
+replica_abort_task_thread(void *arg)
+{
+ cleanruv_data *data = (cleanruv_data *)arg;
+ Repl_Agmt *agmt;
+ Object *agmt_obj;
+ int agmt_not_notified = 1;
+ int interval = 10;
+ int release_it = 0;
+
+ /*
+ * Need to build the replica from the dn
+ */
+ if(data->replica == NULL && data->repl_obj == NULL){
+ /*
+ * This thread was initiated at startup because the process did not finish. Due
+ * to timing issues, we need to wait to grab the replica obj until we get here.
+ */
+ if((data->repl_obj = replica_get_replica_from_dn(data->sdn)) == NULL){
+ cleanruv_log(data->task, ABORT_CLEANALLRUV_ID, "Failed to get replica from dn (%s).", slapi_sdn_get_dn(data->sdn));
+ goto done;
+ }
+ if(data->replica == NULL && data->repl_obj){
+ data->replica = (Replica*)object_get_data(data->repl_obj);
+ }
+ release_it = 1;
+ }
+
+ /*
+ * Now send the cleanruv extended op to all the agreements
+ */
+ while(agmt_not_notified && !slapi_is_shutting_down()){
+ agmt_obj = agmtlist_get_first_agreement_for_replica (data->replica);
+ while (agmt_obj){
+ agmt = (Repl_Agmt*)object_get_data (agmt_obj);
+ if(!agmt_is_enabled(agmt)){ /* skip disabled replicas */
+ agmt_obj = agmtlist_get_next_agreement_for_replica (data->replica, agmt_obj);
+ continue;
+ }
+ if(replica_cleanallruv_send_abort_extop(agmt, data->task, data->payload)){
+ agmt_not_notified = 1;
+ break;
+ } else {
+ /* success */
+ agmt_not_notified = 0;
+ }
+ agmt_obj = agmtlist_get_next_agreement_for_replica (data->replica, agmt_obj);
+ } /* while loop for agmts */
+
+ if(agmt_not_notified == 0){
+ /* everybody has been contacted */
+ break;
+ }
+ /*
+ * need to sleep between passes
+ */
+ cleanruv_log(data->task, ABORT_CLEANALLRUV_ID,"Retrying in %d seconds",interval);
+ PR_Lock( notify_lock );
+ PR_WaitCondVar( notify_cvar, PR_SecondsToInterval(interval) );
+ PR_Unlock( notify_lock );
+
+ if(interval < 14400){ /* 4 hour max */
+ interval = interval * 2;
+ } else {
+ interval = 14400;
+ }
+ } /* while */
+
+done:
+ if(agmt_not_notified){
+ /* failure */
+ cleanruv_log(data->task, ABORT_CLEANALLRUV_ID,"Abort task failed, will resume the task at the next server startup.");
+ } else {
+ /*
+ * Clean up the config
+ */
+ delete_aborted_rid(data->replica, data->rid, data->repl_root);
+ cleanruv_log(data->task, ABORT_CLEANALLRUV_ID, "Successfully aborted cleanAllRUV task for rid(%d)", data->rid);
+ }
+ if(data->task){
+ slapi_task_finish(data->task, agmt_not_notified);
+ }
+ if(data->repl_obj && release_it)
+ object_release(data->repl_obj);
+ if(data->payload){
+ ber_bvfree(data->payload);
+ }
+ slapi_ch_free_string(&data->repl_root);
+ slapi_sdn_free(&data->sdn);
+ slapi_ch_free((void **)&data);
+}
+
+static int
+replica_cleanallruv_send_abort_extop(Repl_Agmt *ra, Slapi_Task *task, struct berval *payload)
+{
+ Repl_Connection *conn = NULL;
+ ConnResult crc = 0;
+ int msgid = 0;
+ int rc = 0;
+
+ if((conn = conn_new(ra)) == NULL){
+ return -1;
+ }
+ if(conn_connect(conn) == CONN_OPERATION_SUCCESS){
+ crc = conn_send_extended_operation(conn, REPL_ABORT_CLEANRUV_OID, payload, NULL, &msgid);
+ /*
+ * success or failure, just return the error code
+ */
+ rc = crc;
+ if(rc){
+ cleanruv_log(task, ABORT_CLEANALLRUV_ID, "Failed to send extop to replica(%s).", agmt_get_long_name(ra));
+ }
+ } else {
+ cleanruv_log(task, ABORT_CLEANALLRUV_ID, "Failed to connect to replica(%s).", agmt_get_long_name(ra));
+ rc = -1;
+ }
+ conn_delete_internal_ext(conn);
+
+ return rc;
+}
+
+
+static int
+replica_cleanallruv_send_extop(Repl_Agmt *ra, ReplicaId rid, Slapi_Task *task, struct berval *payload, int check_result)
+{
+ Repl_Connection *conn = NULL;
+ ConnResult crc = 0;
+ int msgid = 0;
+ int rc = 0;
+
+ if((conn = conn_new(ra)) == NULL){
+ return -1;
+ }
+ if(conn_connect(conn) == CONN_OPERATION_SUCCESS){
+ crc = conn_send_extended_operation(conn, REPL_CLEANRUV_OID, payload, NULL, &msgid);
+ if(crc == CONN_OPERATION_SUCCESS && check_result){
+ struct berval *retsdata = NULL;
+ char *retoid = NULL;
+
+ crc = conn_read_result_ex(conn, &retoid, &retsdata, NULL, msgid, NULL, 1);
+ if (CONN_OPERATION_SUCCESS == crc ){
+ struct berval **ruv_bervals = NULL;
+ struct berval *data = NULL;
+ char *data_guid = NULL;
+
+ decode_repl_ext_response(retsdata, &rc, &ruv_bervals, &data_guid, &data);
+ /* just free everything, we only wanted "rc" */
+ slapi_ch_free_string(&data_guid);
+ if(data)
+ ber_bvfree(data);
+ if (ruv_bervals)
+ ber_bvecfree(ruv_bervals);
+
+ if(rc == 0 ){ /* rc == 1 is success */
+ cleanruv_log(task, CLEANALLRUV_ID,"Replica %s does not support the CLEANALLRUV task. Sending replica CLEANRUV task...",
+ slapi_sdn_get_dn(agmt_get_dn_byref(ra)));
+ /*
+ * Ok, this replica doesn't know about CLEANALLRUV, so just manually
+ * add the CLEANRUV task to the replica.
+ */
+ replica_send_cleanruv_task(ra, rid, task);
+ } else {
+ /* extop was accepted */
+ rc = 0;
+ }
+ if (NULL != retoid)
+ ldap_memfree(retoid);
+ if (NULL != retsdata)
+ ber_bvfree(retsdata);
+ }
+ agmt_set_cleanruv_data(ra, rid, CLEANRUV_NOTIFIED);
+ } else {
+ /*
+ * success or failure, just return the error code
+ */
+ rc = crc;
+ }
+ } else {
+ rc =-1;
+ }
+ conn_delete_internal_ext(conn);
+
+ return rc;
+}
+
+static int
+replica_cleanallruv_check_maxcsn(Repl_Agmt *agmt, char *rid_text, char *maxcsn, Slapi_Task *task)
+{
+ Repl_Connection *conn = NULL;
+ LDAP *ld;
+ Slapi_DN *dn = agmt_get_replarea(agmt);
+ struct berval **vals;
+ LDAPMessage *result = NULL, *entry = NULL;
+ BerElement *ber;
+ char *attrs[2];
+ char *attr = NULL;
+ char *iter = NULL;
+ char *ruv_part = NULL;
+ int found_rid = 0;
+ int part_count = 0;
+ int rc = 0, i;
+
+ if((conn = conn_new(agmt)) == NULL){
+ return -1;
+ }
+
+ if(conn_connect(conn) == CONN_OPERATION_SUCCESS){
+ attrs[0] = "nsds50ruv";
+ attrs[1] = NULL;
+ ld = conn_get_ldap(conn);
+ if(ld == NULL){
+ conn_delete_internal_ext(conn);
+ return -1;
+ }
+ rc = ldap_search_ext_s(ld, slapi_sdn_get_dn(dn), LDAP_SCOPE_SUBTREE,
+ "(&(nsuniqueid=ffffffff-ffffffff-ffffffff-ffffffff)(objectclass=nstombstone))",
+ attrs, 0, NULL, NULL, NULL, 0, &result);
+ slapi_sdn_free(&dn);
+ if(rc != LDAP_SUCCESS){
+ cleanruv_log(task, CLEANALLRUV_ID,"Failed to contact "
+ "agmt (%s) error (%d), will retry later.", agmt_get_long_name(agmt), rc);
+ conn_delete_internal_ext(conn);
+ return -1;
+ }
+ entry = ldap_first_entry( ld, result );
+ if ( entry != NULL ) {
+ for ( attr = ldap_first_attribute( ld, entry, &ber ); attr != NULL; attr = ldap_next_attribute( ld, entry, ber ) ){
+ /* make sure the attribute is nsds50ruv */
+ if(strcasecmp(attr,"nsds50ruv") != 0){
+ ldap_memfree( attr );
+ continue;
+ }
+ found_rid = 0;
+ if ((vals = ldap_get_values_len( ld, entry, attr)) != NULL ) {
+ for ( i = 0; vals[i] && vals[i]->bv_val; i++ ) {
+ /* look for this replica */
+ if(strstr(vals[i]->bv_val, rid_text)){
+ found_rid = 1;
+ /* get the max csn compare it to our known max csn */
+ ruv_part = ldap_utf8strtok_r(vals[i]->bv_val, " ", &iter);
+ for(part_count = 1; ruv_part && part_count < 5; part_count++){
+ ruv_part = ldap_utf8strtok_r(iter, " ", &iter);
+ }
+ if(part_count == 5){
+ /* we have the maxcsn */
+ if(strcmp(ruv_part, maxcsn)){
+ /* we are not caught up yet, free, and return */
+ ldap_value_free_len(vals);
+ ldap_memfree( attr );
+ ldap_msgfree( result );
+ if(ber){
+ ber_free( ber, 0 );
+ }
+ conn_delete_internal_ext(conn);
+ return -1;
+ } else {
+ /* ok this replica has all the updates from the deleted replica */
+ rc = 0;
+ }
+ } else {
+ /* there is no maxcsn for this rid - treat it as caught up */
+ rc = 0;
+ }
+ }
+ }
+ if(!found_rid){
+ /* must have been cleaned already */
+ rc = 0;
+ }
+ ldap_value_free_len(vals);
+ }
+ ldap_memfree( attr );
+ }
+ if ( ber != NULL ) {
+ ber_free( ber, 0 );
+ }
+ }
+ if(result)
+ ldap_msgfree( result );
+ } else {
+ rc = -1;
+ }
+ conn_delete_internal_ext(conn);
+
+ return rc;
+}
+
+static int
+replica_cleanallruv_replica_alive(Repl_Agmt *agmt)
+{
+ Repl_Connection *conn = NULL;
+ LDAP *ld = NULL;
+ LDAPMessage *result = NULL;
+ int rc = 0;
+
+ if((conn = conn_new(agmt)) == NULL){
+ return -1;
+ }
+ if(conn_connect(conn) == CONN_OPERATION_SUCCESS){
+ ld = conn_get_ldap(conn);
+ if(ld == NULL){
+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "cleanAllRUV_task: failed to get LDAP "
+ "handle from the replication agmt (%s). Moving on to the next agmt.\n",agmt_get_long_name(agmt));
+ conn_delete_internal_ext(conn);
+ return -1;
+ }
+ if(ldap_search_ext_s(ld, "", LDAP_SCOPE_BASE, "objectclass=top",
+ NULL, 0, NULL, NULL, NULL, 0, &result) == LDAP_SUCCESS)
+ {
+ rc = 0;
+ } else {
+ rc = -1;
+ }
+ if(result)
+ ldap_msgfree( result );
+ } else {
+ rc = -1;
+ }
+ conn_delete_internal_ext(conn);
+
+ return rc;
+}
+
+static int
+replica_cleanallruv_check_ruv(Repl_Agmt *ra, char *rid_text, Slapi_Task *task)
+{
+ Repl_Connection *conn = NULL;
+ BerElement *ber = NULL;
+ struct berval **vals = NULL;
+ LDAPMessage *result = NULL, *entry = NULL;
+ LDAP *ld = NULL;
+ Slapi_DN *dn = agmt_get_replarea(ra);
+ char *attrs[2];
+ char *attr = NULL;
+ int rc = 0, i;
+
+ if((conn = conn_new(ra)) == NULL){
+ return -1;
+ }
+ if(conn_connect(conn) == CONN_OPERATION_SUCCESS){
+ attrs[0] = "nsds50ruv";
+ attrs[1] = NULL;
+ ld = conn_get_ldap(conn);
+ if(ld == NULL){
+ cleanruv_log(task, CLEANALLRUV_ID,"Failed to get LDAP handle from "
+ "the replication agmt (%s). Moving on to the next agmt.",agmt_get_long_name(ra));
+ rc = -1;
+ goto done;
+ }
+
+ rc = ldap_search_ext_s(ld, slapi_sdn_get_dn(dn), LDAP_SCOPE_SUBTREE,
+ "(&(nsuniqueid=ffffffff-ffffffff-ffffffff-ffffffff)(objectclass=nstombstone))",
+ attrs, 0, NULL, NULL, NULL, 0, &result);
+ slapi_sdn_free(&dn);
+ if(rc != LDAP_SUCCESS){
+ cleanruv_log(task, CLEANALLRUV_ID,"Failed to contact "
+ "agmt (%s) error (%d), will retry later.", agmt_get_long_name(ra), rc);
+ rc = -1;
+ goto done;
+ }
+ entry = ldap_first_entry( ld, result );
+ if ( entry != NULL ) {
+ for ( attr = ldap_first_attribute( ld, entry, &ber ); attr != NULL; attr = ldap_next_attribute( ld, entry, ber ) ){
+ /* make sure the attribute is nsds50ruv */
+ if(strcasecmp(attr,"nsds50ruv") != 0){
+ ldap_memfree( attr );
+ continue;
+ }
+ if ((vals = ldap_get_values_len( ld, entry, attr)) != NULL ) {
+ for ( i = 0; vals[i] && vals[i]->bv_val; i++ ) {
+ /* look for this replica */
+ if(strstr(vals[i]->bv_val, rid_text)){
+ /* rid has not been cleaned yet, free and return */
+ rc = -1;
+ ldap_value_free_len(vals);
+ ldap_memfree( attr );
+ if ( ber != NULL ) {
+ ber_free( ber, 0 );
+ ber = NULL;
+ }
+ goto done;
+ } else {
+ rc = 0;
+ }
+ }
+ ldap_value_free_len(vals);
+ }
+ ldap_memfree( attr );
+ } /* for loop */
+ if ( ber != NULL ) {
+ ber_free( ber, 0 );
+ }
+ }
+done:
+ if(result)
+ ldap_msgfree( result );
+ } else {
+ return -1;
+ }
+ conn_delete_internal_ext(conn);
+
+ return rc;
}
+static int
+get_cleanruv_task_count()
+{
+ int i, count = 0;
+
+ slapi_rwlock_wrlock(rid_lock);
+ for(i = 0; i < CLEANRIDSIZ; i++){
+ if(cleaned_rids[i] != 0){
+ count++;
+ }
+ }
+ slapi_rwlock_unlock(rid_lock);
+
+ return count;
+}
+
+static int
+get_abort_cleanruv_task_count()
+{
+ int i, count = 0;
+
+ slapi_rwlock_wrlock(rid_lock);
+ for(i = 0; i < CLEANRIDSIZ; i++){
+ if(aborted_rids[i] != 0){
+ count++;
+ }
+ }
+ slapi_rwlock_unlock(rid_lock);
+
+ return count;
+}
+
+/*
+ * Notify sleeping CLEANALLRUV threads to stop
+ */
void
-set_released_rid( int rid )
+stop_ruv_cleaning()
{
- released_rid = rid;
+ if(notify_lock){
+ PR_Lock( notify_lock );
+ PR_NotifyCondVar( notify_cvar );
+ PR_Unlock( notify_lock );
+ }
}
+/*
+ * Write our logging to the task and error log
+ */
void
-delete_released_rid()
+cleanruv_log(Slapi_Task *task, char *task_type, char *fmt, ...)
{
- released_rid = 0;
+ va_list ap1;
+ va_list ap2;
+ va_list ap3;
+ va_list ap4;
+ char *errlog_fmt;
+
+ va_start(ap1, fmt);
+ va_start(ap2, fmt);
+ va_start(ap3, fmt);
+ va_start(ap4, fmt);
+
+ if(task){
+ slapi_task_log_notice_ext(task, fmt, ap1);
+ slapi_task_log_status_ext(task, fmt, ap2);
+ slapi_task_inc_progress(task);
+ }
+ errlog_fmt = PR_smprintf("%s: %s\n",task_type, fmt);
+ slapi_log_error_ext(SLAPI_LOG_FATAL, repl_plugin_name, errlog_fmt, ap3, ap4);
+ slapi_ch_free_string(&errlog_fmt);
+
+ va_end(ap1);
+ va_end(ap2);
+ va_end(ap3);
+ va_end(ap4);
}
+
diff --git a/ldap/servers/plugins/replication/repl5_ruv.c b/ldap/servers/plugins/replication/repl5_ruv.c
index 501cedc..b962951 100644
--- a/ldap/servers/plugins/replication/repl5_ruv.c
+++ b/ldap/servers/plugins/replication/repl5_ruv.c
@@ -487,9 +487,9 @@ ruv_replace_replica_purl (RUV *ruv, ReplicaId rid, const char *replica_purl)
replica = ruvGetReplica (ruv, rid);
if (replica != NULL)
{
- if (strcmp(replica->replica_purl, replica_purl)) { /* purl updated */
+ if (replica->replica_purl == NULL || strcmp(replica->replica_purl, replica_purl)) { /* purl updated */
/* Replace replica_purl in RUV since supplier has been updated. */
- slapi_ch_free((void **)&(replica->replica_purl));
+ slapi_ch_free_string(&replica->replica_purl);
replica->replica_purl = slapi_ch_strdup(replica_purl);
/* Also, reset csn and min_csn. */
replica->csn = replica->min_csn = NULL;
@@ -863,10 +863,6 @@ ruv_covers_csn_internal(const RUV *ruv, const CSN *csn, PRBool strict)
{
rid = csn_get_replicaid(csn);
replica = ruvGetReplica (ruv, rid);
- if((is_released_rid(rid)) || (replica == NULL && is_already_released_rid()) ){
- /* this is a released rid, so return true */
- return PR_TRUE;
- }
if (replica == NULL)
{
/*
@@ -930,7 +926,7 @@ ruv_covers_csn_strict(const RUV *ruv, const CSN *csn)
* or max{maxcsns of all ruv elements} if get_the_max != 0.
*/
static int
-ruv_get_min_or_max_csn(const RUV *ruv, CSN **csn, int get_the_max)
+ruv_get_min_or_max_csn(const RUV *ruv, CSN **csn, int get_the_max, ReplicaId rid)
{
int return_value;
@@ -960,12 +956,18 @@ ruv_get_min_or_max_csn(const RUV *ruv, CSN **csn, int get_the_max)
{
continue;
}
-
- if (found == NULL ||
- (!get_the_max && csn_compare(found, replica->csn)>0) ||
- ( get_the_max && csn_compare(found, replica->csn)<0))
- {
- found = replica->csn;
+ if(rid){ /* we are only interested in this rid's maxcsn */
+ if(replica->rid == rid){
+ found = replica->csn;
+ break;
+ }
+ } else {
+ if (found == NULL ||
+ (!get_the_max && csn_compare(found, replica->csn)>0) ||
+ ( get_the_max && csn_compare(found, replica->csn)<0))
+ {
+ found = replica->csn;
+ }
}
}
if (found == NULL)
@@ -983,15 +985,20 @@ ruv_get_min_or_max_csn(const RUV *ruv, CSN **csn, int get_the_max)
}
int
+ruv_get_rid_max_csn(const RUV *ruv, CSN **csn, ReplicaId rid){
+ return ruv_get_min_or_max_csn(ruv, csn, 1 /* get the max */, rid);
+}
+
+int
ruv_get_max_csn(const RUV *ruv, CSN **csn)
{
- return ruv_get_min_or_max_csn(ruv, csn, 1 /* get the max */);
+ return ruv_get_min_or_max_csn(ruv, csn, 1 /* get the max */, 0 /* rid */);
}
int
ruv_get_min_csn(const RUV *ruv, CSN **csn)
{
- return ruv_get_min_or_max_csn(ruv, csn, 0 /* get the min */);
+ return ruv_get_min_or_max_csn(ruv, csn, 0 /* get the min */, 0 /* rid */);
}
int
@@ -1097,6 +1104,22 @@ ruv_to_bervals(const RUV *ruv, struct berval ***bvals)
return return_value;
}
+void
+ruv_get_cleaned_rids(RUV *ruv, ReplicaId *rids)
+{
+ RUVElement *replica;
+ int cookie;
+ int i = 0;
+
+ for (replica = dl_get_first (ruv->elements, &cookie); replica;
+ replica = dl_get_next (ruv->elements, &cookie))
+ {
+ if(is_cleaned_rid(replica->rid)){
+ rids[i++] = replica->rid;
+ }
+ }
+}
+
int
ruv_to_smod(const RUV *ruv, Slapi_Mod *smod)
{
@@ -1428,15 +1451,14 @@ int ruv_add_csn_inprogress (RUV *ruv, const CSN *csn)
slapi_rwlock_wrlock (ruv->lock);
if(is_cleaned_rid(rid)){
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "ruv_add_csn_inprogress: invalid replica ID"
- "(%d), aborting update\n", rid);
/* return success because we want to consume the update, but not perform it */
+ rc = RUV_COVERS_CSN;
goto done;
}
replica = ruvGetReplica (ruv, rid);
if (replica == NULL)
{
- replica = ruvAddReplicaNoCSN (ruv, csn_get_replicaid (csn), NULL/*purl*/);
+ replica = ruvAddReplicaNoCSN (ruv, rid, NULL/*purl*/);
if (replica == NULL)
{
if (slapi_is_loglevel_set(SLAPI_LOG_REPL)) {
diff --git a/ldap/servers/plugins/replication/repl5_ruv.h b/ldap/servers/plugins/replication/repl5_ruv.h
index d329dc3..f2d96f3 100644
--- a/ldap/servers/plugins/replication/repl5_ruv.h
+++ b/ldap/servers/plugins/replication/repl5_ruv.h
@@ -117,6 +117,7 @@ PRBool ruv_covers_csn(const RUV *ruv, const CSN *csn);
PRBool ruv_covers_csn_strict(const RUV *ruv, const CSN *csn);
int ruv_get_min_csn(const RUV *ruv, CSN **csn);
int ruv_get_max_csn(const RUV *ruv, CSN **csn);
+int ruv_get_rid_max_csn(const RUV *ruv, CSN **csn, ReplicaId rid);
int ruv_enumerate_elements (const RUV *ruv, FNEnumRUV fn, void *arg);
int ruv_to_smod(const RUV *ruv, Slapi_Mod *smod);
int ruv_last_modified_to_smod(const RUV *ruv, Slapi_Mod *smod);
diff --git a/ldap/servers/plugins/replication/repl_extop.c b/ldap/servers/plugins/replication/repl_extop.c
index 63e2bb9..88bb9e3 100644
--- a/ldap/servers/plugins/replication/repl_extop.c
+++ b/ldap/servers/plugins/replication/repl_extop.c
@@ -1338,7 +1338,7 @@ replica_config_get_mtnode_by_dn(const char *dn)
/*
* Decode the ber element passed to us by the cleanAllRUV task
*/
-static int
+int
decode_cleanruv_payload(struct berval *extop_value, char **payload)
{
BerElement *tmp_bere = NULL;
@@ -1373,305 +1373,313 @@ free_and_return:
return rc;
}
-/*
- * Process the REPL_CLEANRUV_OID extended operation.
- *
- * The payload consists of the replica ID, and the repl root dn. Since this is
- * basically a replication operation, it could of originated here and bounced
- * back from another master. So check the rid against the "cleaned_rid". If
- * it's a match, then we were already here, and we can just return success.
- *
- * Otherwise, we the set the cleaned_rid from the payload, fire off extended ops
- * to all the replica agreements on this replica. Then perform the actual
- * cleanruv_task on this replica.
- */
int
-multimaster_extop_cleanruv(Slapi_PBlock *pb){
+multimaster_extop_abort_cleanruv(Slapi_PBlock *pb)
+{
multimaster_mtnode_extension *mtnode_ext;
PRThread *thread = NULL;
- Repl_Connection *conn;
- const Slapi_DN *dn;
- Replica *r = NULL;
- Object *agmt_obj;
- Repl_Agmt *agmt;
- ConnResult crc;
- cleanruv_data *data = NULL;
- struct berval *extop_value;
+ cleanruv_data *data;
+ Replica *r;
+ ReplicaId rid;
+ CSN *maxcsn;
+ struct berval *extop_payload;
char *extop_oid;
char *repl_root;
char *payload = NULL;
char *iter;
- int send_msgid = 0;
- int agmt_count = 0;
- int rid = 0;
int rc = 0;
slapi_pblock_get(pb, SLAPI_EXT_OP_REQ_OID, &extop_oid);
- slapi_pblock_get(pb, SLAPI_EXT_OP_REQ_VALUE, &extop_value);
+ slapi_pblock_get(pb, SLAPI_EXT_OP_REQ_VALUE, &extop_payload);
if (NULL == extop_oid || strcmp(extop_oid, REPL_CLEANRUV_OID) != 0 ||
- NULL == extop_value || NULL == extop_value->bv_val){
+ NULL == extop_payload || NULL == extop_payload->bv_val){
/* something is wrong, error out */
- return -1;
+ return LDAP_OPERATIONS_ERROR;
}
/*
- * Extract the rid and repl_root from the payload
+ * Decode the payload, and grab our settings
*/
- if(decode_cleanruv_payload(extop_value, &payload)){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: failed to decode payload. Aborting ext op\n");
- return -1;
+ if(decode_cleanruv_payload(extop_payload, &payload)){
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "Abort cleanAllRUV task: failed to decode payload. Aborting ext op\n");
+ return LDAP_OPERATIONS_ERROR;
}
rid = atoi(ldap_utf8strtok_r(payload, ":", &iter));
repl_root = ldap_utf8strtok_r(iter, ":", &iter);
- /*
- * If we already cleaned this server, just return success
- */
- if(is_cleaned_rid(rid)){
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "cleanAllRUV_extop: rid (%d) has already been cleaned, skipping\n",rid);
- return rc;
+ if(!is_cleaned_rid(rid) || is_task_aborted(rid)){
+ /* This replica has already been aborted, or was never cleaned, or already finished cleaning */
+ goto out;
} else {
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: cleaning rid (%d)...\n", rid);
- set_cleaned_rid(rid);
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "Abort cleanAllRUV task: aborting cleanallruv task for rid(%d)\n", rid);
}
-
/*
* Get the node, so we can get the replica and its agreements
*/
if((mtnode_ext = replica_config_get_mtnode_by_dn(repl_root)) == NULL){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: failed to get replication node "
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "Abort cleanAllRUV task: failed to get replication node "
"from (%s), aborting operation\n", repl_root);
- return -1;
+ rc = LDAP_OPERATIONS_ERROR;
+ goto out;
}
- if (mtnode_ext->replica)
+ if (mtnode_ext->replica){
object_acquire (mtnode_ext->replica);
- if (mtnode_ext->replica == NULL){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: replica is missing from (%s), "
+ } else {
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "Abort cleanAllRUV task: replica is missing from (%s), "
"aborting operation\n",repl_root);
rc = LDAP_OPERATIONS_ERROR;
- goto free_and_return;
+ goto out;
}
r = (Replica*)object_get_data (mtnode_ext->replica);
+ if(r == NULL){
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "Abort cleanAllRUV task: replica is NULL, aborting task\n");
+ rc = LDAP_OPERATIONS_ERROR;
+ goto out;
+ }
/*
- * Send out extended ops to each repl agreement
+ * Prepare the abort data
*/
- agmt_obj = agmtlist_get_first_agreement_for_replica (r);
- while (agmt_obj)
- {
- agmt = (Repl_Agmt*)object_get_data (agmt_obj);
- dn = agmt_get_dn_byref(agmt);
- conn = (Repl_Connection *)agmt_get_connection(agmt);
- if(conn == NULL){
- /* no connection for this agreement, move on to the next agmt */
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: the replica (%s), is "
- "missing the connection. This replica will not be cleaned.\n", slapi_sdn_get_dn(dn));
- agmt_obj = agmtlist_get_next_agreement_for_replica (r, agmt_obj);
- continue;
- }
- crc = conn_connect(conn);
- if (CONN_OPERATION_FAILED == crc ){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: failed to connect "
- "to repl agreement connection (%s), error %d\n",slapi_sdn_get_dn(dn), ACQUIRE_TRANSIENT_ERROR);
- rc = LDAP_OPERATIONS_ERROR;
- } else if (CONN_SSL_NOT_ENABLED == crc){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: failed to acquire "
- "repl agmt connection (%s), error %d\n",slapi_sdn_get_dn(dn), ACQUIRE_FATAL_ERROR);
- rc = LDAP_OPERATIONS_ERROR;
- } else {
- conn_cancel_linger(conn);
- crc = conn_send_extended_operation(conn, REPL_CLEANRUV_OID, extop_value, NULL, &send_msgid);
- if (CONN_OPERATION_SUCCESS != crc){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: failed to send "
- "clean_ruv extended op to repl agmt (%s), error %d\n", slapi_sdn_get_dn(dn), crc);
- rc = LDAP_OPERATIONS_ERROR;
- } else {
- /* success */
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: successfully sent "
- "extended op to (%s)\n",slapi_sdn_get_dn(dn) );
- agmt_count++;
- }
- conn_start_linger(conn);
- }
- if(crc != CONN_OPERATION_SUCCESS){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: replica (%s) has not "
- "been cleaned. You will need to rerun the CLEANALLRUV task on this replica\n",
- slapi_sdn_get_dn(dn) );
- rc = LDAP_OPERATIONS_ERROR;
- }
- agmt_obj = agmtlist_get_next_agreement_for_replica (r, agmt_obj);
- }
-
- /* now clean the ruv */
- replica_execute_cleanruv_task_ext(mtnode_ext->replica, rid);
-
-free_and_return:
-
- if(rc == 0 && agmt_count > 0){
- /*
- * Launch the cleanruv monitoring thread. Once all the replicas are cleaned it will release the rid
- */
- data = (cleanruv_data*)slapi_ch_calloc(1, sizeof(cleanruv_data));
- if (data == NULL) {
- slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: failed to allocate "
- "cleanruv_Data\n");
- return -1;
- }
- data->repl_obj = mtnode_ext->replica;
- data->rid = rid;
-
- thread = PR_CreateThread(PR_USER_THREAD, replica_cleanallruv_monitor_thread,
- (void *)data, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
- PR_UNJOINABLE_THREAD, SLAPD_DEFAULT_THREAD_STACKSIZE);
- if (thread == NULL) {
- slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: unable to create cleanAllRUV "
- "monitoring thread. Aborting task.\n");
+ data = (cleanruv_data*)slapi_ch_calloc(1, sizeof(cleanruv_data));
+ if (data == NULL) {
+ slapi_log_error( SLAPI_LOG_REPL, repl_plugin_name, "Abort cleanAllRUV task: failed to allocate "
+ "abort_cleanruv_data. Aborting task.\n");
+ rc = LDAP_OPERATIONS_ERROR;
+ goto out;
+ }
+ data->repl_obj = mtnode_ext->replica; /* released in replica_abort_task_thread() */
+ data->replica = r;
+ data->task = NULL;
+ data->payload = slapi_ch_bvdup(extop_payload);
+ data->rid = rid;
+ data->repl_root = slapi_ch_strdup(repl_root);
+ /*
+ * Stop the cleaning, and delete the rid
+ */
+ maxcsn = replica_get_cleanruv_maxcsn(r, rid);
+ delete_cleaned_rid(r, rid, maxcsn);
+ csn_free(&maxcsn);
+ add_aborted_rid(rid, r, repl_root);
+ stop_ruv_cleaning();
+ /*
+ * Send out the extended ops to the replicas
+ */
+ thread = PR_CreateThread(PR_USER_THREAD, replica_abort_task_thread,
+ (void *)data, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
+ PR_UNJOINABLE_THREAD, SLAPD_DEFAULT_THREAD_STACKSIZE);
+ if (thread == NULL) {
+ if(mtnode_ext->replica){
+ object_release(mtnode_ext->replica);
}
- } else if (rc == 0){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: Successfully Finished.\n");
- } else {
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanALLRUV_extop: failed to clean rid (%d), error (%d)\n",rid, rc);
+ slapi_log_error( SLAPI_LOG_REPL, repl_plugin_name, "Abort cleanAllRUV task: unable to create abort "
+ "thread. Aborting task.\n");
+ rc = LDAP_OPERATIONS_ERROR;
}
- if (mtnode_ext->replica)
- object_release (mtnode_ext->replica);
+out:
+ slapi_ch_free_string(&payload);
return rc;
}
-
/*
- * Process the REPL_RELEASERUV_OID extended operation
+ * Process the REPL_CLEANRUV_OID extended operation.
*
- * Once, all the replicas in the replication farm have been cleaned, then
- * we need to "release" the cleaned_rid, or else we will reject all updates
- * that come from that rid until we restart the server.
+ * The payload consists of the replica ID, repl root dn, and the maxcsn. Since this is
+ * basically a replication operation, it could of originated here and bounced
+ * back from another master. So check the rid against the "cleaned_rid". If
+ * it's a match, then we were already here, and we can just return success.
*
- * We set the cleaned_ruv to zero(invalid rid), and then fire off extended
- * operations to all of the replicas
+ * Otherwise, we the set the cleaned_rid from the payload, fire off extended ops
+ * to all the replica agreements on this replica. Then perform the actual
+ * cleanruv_task on this replica.
*/
int
-multimaster_extop_releaseruv(Slapi_PBlock *pb){
+multimaster_extop_cleanruv(Slapi_PBlock *pb)
+{
multimaster_mtnode_extension *mtnode_ext;
- Repl_Connection *conn;
- const Slapi_DN *dn;
+ PRThread *thread = NULL;
Replica *r = NULL;
- Object *agmt_obj;
- Repl_Agmt *agmt;
- ConnResult crc;
- struct berval *extop_value;
- char *payload = NULL;
+ cleanruv_data *data = NULL;
+ CSN *maxcsn;
+ struct berval *extop_payload;
+ struct berval *resp_bval = NULL;
+ BerElement *resp_bere = NULL;
char *extop_oid;
char *repl_root;
+ char *payload = NULL;
+ char *csnstr = NULL;
char *iter;
- int send_msgid = 0;
+ int release_it = 0;
int rid = 0;
int rc = 0;
slapi_pblock_get(pb, SLAPI_EXT_OP_REQ_OID, &extop_oid);
- slapi_pblock_get(pb, SLAPI_EXT_OP_REQ_VALUE, &extop_value);
+ slapi_pblock_get(pb, SLAPI_EXT_OP_REQ_VALUE, &extop_payload);
- if (NULL == extop_oid || strcmp(extop_oid, REPL_RELEASERUV_OID) != 0 ||
- NULL == extop_value || NULL == extop_value->bv_val){
+ if (NULL == extop_oid || strcmp(extop_oid, REPL_CLEANRUV_OID) != 0 ||
+ NULL == extop_payload || NULL == extop_payload->bv_val){
/* something is wrong, error out */
- return -1;
+ rc = -1;
+ goto free_and_return;
}
-
- if(decode_cleanruv_payload(extop_value, &payload)){
- slapi_log_error(SLAPI_LOG_FATAL,repl_plugin_name, "releaseRUV_extop: failed to decode payload, aborting ext op.\n");
- return -1;
+ /*
+ * Decode the payload
+ */
+ if(decode_cleanruv_payload(extop_payload, &payload)){
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: failed to decode payload. Aborting ext op\n");
+ rc = -1;
+ goto free_and_return;
}
rid = atoi(ldap_utf8strtok_r(payload, ":", &iter));
repl_root = ldap_utf8strtok_r(iter, ":", &iter);
-
+ csnstr = ldap_utf8strtok_r(iter, ":", &iter);
+ maxcsn = csn_new();
+ csn_init_by_string(maxcsn, csnstr);
/*
- * If we already released this ruv, just return.
+ * If we already cleaned this server, just return success
*/
- if(is_released_rid(rid) || is_already_released_rid()){
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "cleanAllRUV_extop: rid (%d) has already been released, skipping.\n",rid);
- return 0;
+ if(is_cleaned_rid(rid)){
+ csn_free(&maxcsn);
+ rc = 1;
+ goto free_and_return;
} else {
- /* set the released rid, and trigger trimming */
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: releasing rid (%d)...\n", rid);
- set_released_rid((int)rid);
- trigger_cl_trimming();
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: cleaning rid (%d)...\n", rid);
}
+ /*
+ * Get the node, so we can get the replica and its agreements
+ */
if((mtnode_ext = replica_config_get_mtnode_by_dn(repl_root)) == NULL){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "releaseRUV_extop: failed to get node "
- "from replication root dn(%s), aborting operation.\n", repl_root);
- return -1;
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: failed to get replication node "
+ "from (%s), aborting operation\n", repl_root);
+ rc = -1;
+ goto free_and_return;
}
- if (mtnode_ext->replica)
+
+ if (mtnode_ext->replica){
object_acquire (mtnode_ext->replica);
+ release_it = 1;
+ }
if (mtnode_ext->replica == NULL){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "releaseRUV_extop: replica is missing from (%s), "
- "aborting operation.\n", repl_root);
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: replica is missing from (%s), "
+ "aborting operation\n",repl_root);
rc = LDAP_OPERATIONS_ERROR;
goto free_and_return;
}
+
r = (Replica*)object_get_data (mtnode_ext->replica);
- /*
- * Loop over the agreements, and send out extended ops
- */
- agmt_obj = agmtlist_get_first_agreement_for_replica (r);
- while (agmt_obj)
- {
- agmt = (Repl_Agmt*)object_get_data (agmt_obj);
- dn = agmt_get_dn_byref(agmt);
- conn = (Repl_Connection *)agmt_get_connection(agmt);
- if(conn == NULL){
- /* no connection for this agreement, log error, and move on */
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: the replica (%s), is "
- "missing the connection. This replica will not be released.\n", slapi_sdn_get_dn(dn));
- agmt_obj = agmtlist_get_next_agreement_for_replica (r, agmt_obj);
- continue;
+ if(r == NULL){
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: replica is NULL, aborting task\n");
+ rc = -1;
+ goto free_and_return;
+ }
+
+ if(replica_get_type(r) != REPLICA_TYPE_READONLY){
+ /*
+ * Launch the cleanruv monitoring thread. Once all the replicas are cleaned it will release the rid
+ *
+ * This will also release mtnode_ext->replica
+ */
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: launching cleanAllRUV thread...\n");
+ data = (cleanruv_data*)slapi_ch_calloc(1, sizeof(cleanruv_data));
+ if (data == NULL) {
+ slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: failed to allocate "
+ "cleanruv_Data\n");
+ rc = -1;
+ goto free_and_return;
}
- crc = conn_connect(conn);
- if (CONN_OPERATION_FAILED == crc ){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "releaseRUV_extop: failed to connect "
- "to repl agreement connection (%s), error %d\n",slapi_sdn_get_dn(dn), ACQUIRE_TRANSIENT_ERROR);
- rc = LDAP_OPERATIONS_ERROR;
- } else if (CONN_SSL_NOT_ENABLED == crc){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "releaseRUV_extop: failed to acquire "
- "repl agmt connection (%s), error %d\n",slapi_sdn_get_dn(dn), ACQUIRE_FATAL_ERROR);
- rc = LDAP_OPERATIONS_ERROR;
- } else {
- conn_cancel_linger(conn);
- crc = conn_send_extended_operation(conn, REPL_RELEASERUV_OID, extop_value, NULL, &send_msgid);
- if (CONN_OPERATION_SUCCESS != crc){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: failed to send "
- "releaseRUV extended op to repl agmt (%s), error %d\n", slapi_sdn_get_dn(dn), crc);
- rc = LDAP_OPERATIONS_ERROR;
+ data->repl_obj = mtnode_ext->replica;
+ data->replica = r;
+ data->rid = rid;
+ data->task = NULL;
+ data->maxcsn = maxcsn;
+ data->payload = slapi_ch_bvdup(extop_payload);
+
+ thread = PR_CreateThread(PR_USER_THREAD, replica_cleanallruv_thread_ext,
+ (void *)data, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
+ PR_UNJOINABLE_THREAD, SLAPD_DEFAULT_THREAD_STACKSIZE);
+ if (thread == NULL) {
+ rc = -1;
+ slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: unable to create cleanAllRUV "
+ "monitoring thread. Aborting task.\n");
+ }
+ } else { /* this is a read-only consumer */
+ /*
+ * wait for the maxcsn to be covered
+ */
+ Object *ruv_obj;
+ const RUV *ruv;
+
+ ruv_obj = replica_get_ruv(r);
+ ruv = object_get_data (ruv_obj);
+
+ while(!is_task_aborted(rid) && !slapi_is_shutting_down()){
+ if(!ruv_contains_replica(ruv, rid)){
+ /* we've already been cleaned */
+ break;
+ }
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: checking if we're caught up...\n");
+ if(ruv_covers_csn(ruv,maxcsn) || csn_get_replicaid(maxcsn) == 0){
+ /* We are caught up */
+ break;
} else {
- /* success */
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: successfully sent "
- "releaseRUV extended op to (%s)\n",slapi_sdn_get_dn(dn) );
- rc = 0;
+ char csnstr[CSN_STRSIZE];
+ csn_as_string(maxcsn, PR_FALSE, csnstr);
+ slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: not ruv caught up maxcsn(%s)\n", csnstr);
}
- conn_start_linger(conn);
- }
- if(crc){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: replica (%s) has not "
- "been released. You will need to rerun the task.\n",
- slapi_sdn_get_dn(dn) );
+ DS_Sleep(PR_SecondsToInterval(5));
}
- agmt_obj = agmtlist_get_next_agreement_for_replica (r, agmt_obj);
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: we're caught up...\n");
+ /*
+ * Set cleaned rid in memory only - does not survive a server restart
+ */
+ set_cleaned_rid(rid);
+ /*
+ * Clean the ruv
+ */
+ replica_execute_cleanruv_task_ext(mtnode_ext->replica, rid);
+
+ /* free everything */
+ object_release(ruv_obj);
+ csn_free(&maxcsn);
+ if (mtnode_ext->replica && release_it)
+ object_release (mtnode_ext->replica);
+ /*
+ * This read-only replica has no easy way to tell when it's safe to release the rid.
+ * So we won't release it, not until a server restart.
+ */
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: You must restart the server if you want to reuse rid(%d).\n", rid);
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: Successfully cleaned rid(%d).\n", rid);
}
free_and_return:
+ if(rc && release_it){
+ if (mtnode_ext->replica)
+ object_release (mtnode_ext->replica);
+ }
+ slapi_ch_free_string(&payload);
+
/*
- * Set the rid as "ALREADY_RELEASED, and remove the cleaned ruv
+ * Craft a message so we know this replica supports the task
*/
- if(rc == 0){
- set_released_rid(ALREADY_RELEASED);
- delete_cleaned_rid();
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: Successfully released rid (%d)\n", rid);
- } else {
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: Failed to release rid(%d), error (%d), "
- "please retry the task.\n",rid, rc);
- }
+ if ((resp_bere = der_alloc())){
- if(mtnode_ext->replica)
- object_release (mtnode_ext->replica);
+ ber_int_t response = 1;
+
+ ber_printf(resp_bere, "{e}", response);
+ ber_flatten(resp_bere, &resp_bval);
+ slapi_pblock_set(pb, SLAPI_EXT_OP_RET_VALUE, resp_bval);
+ slapi_send_ldap_result(pb, LDAP_SUCCESS, NULL, NULL, 0, NULL);
+ /* resp_bere */
+ if (NULL != resp_bere)
+ {
+ ber_free(resp_bere, 1);
+ }
+ /* resp_bval */
+ if (NULL != resp_bval)
+ {
+ ber_bvfree(resp_bval);
+ }
+ }
return rc;
}
diff --git a/ldap/servers/plugins/replication/repl_globals.c b/ldap/servers/plugins/replication/repl_globals.c
index f0aea12..85b0ca9 100644
--- a/ldap/servers/plugins/replication/repl_globals.c
+++ b/ldap/servers/plugins/replication/repl_globals.c
@@ -110,6 +110,8 @@ const char *type_replicaChangeCount = "nsds5ReplicaChangeCount";
const char *type_replicaTombstonePurgeInterval = "nsds5ReplicaTombstonePurgeInterval";
const char *type_replicaLegacyConsumer = "nsds5ReplicaLegacyConsumer";
const char *type_ruvElementUpdatetime = "nsruvReplicaLastModified";
+const char *type_replicaCleanRUV = "nsds5ReplicaCleanRUV";
+const char *type_replicaAbortCleanRUV = "nsds5ReplicaAbortCleanRUV";
/* Attribute names for replication agreement attributes */
const char *type_nsds5ReplicaHost = "nsds5ReplicaHost";
@@ -126,6 +128,7 @@ const char *type_nsds5ReplicaInitialize = "nsds5BeginReplicaRefresh";
const char *type_nsds5ReplicaTimeout = "nsds5ReplicaTimeout";
const char *type_nsds5ReplicaBusyWaitTime = "nsds5ReplicaBusyWaitTime";
const char *type_nsds5ReplicaSessionPauseTime = "nsds5ReplicaSessionPauseTime";
+const char *type_nsds5ReplicaCleanRUVnotified = "nsds5ReplicaCleanRUVNotified";
/* windows sync specific attributes */
const char *type_nsds7WindowsReplicaArea = "nsds7WindowsReplicaSubtree";
@@ -137,7 +140,7 @@ const char *type_nsds7DirsyncCookie = "nsds7DirsyncCookie";
const char *type_winSyncInterval = "winSyncInterval";
const char *type_oneWaySync = "oneWaySync";
-/* To Allow Consumer Initialisation when adding an agreement - */
+/* To Allow Consumer Initialization when adding an agreement - */
const char *type_nsds5BeginReplicaRefresh = "nsds5BeginReplicaRefresh";
static int repl_active_threads;
diff --git a/ldap/servers/slapd/log.c b/ldap/servers/slapd/log.c
index ebec254..529dc80 100644
--- a/ldap/servers/slapd/log.c
+++ b/ldap/servers/slapd/log.c
@@ -1969,6 +1969,33 @@ slapi_log_error( int severity, char *subsystem, char *fmt, ... )
}
int
+slapi_log_error_ext(int severity, char *subsystem, char *fmt, va_list varg1, va_list varg2)
+{
+ int rc = 0;
+
+ if ( severity < SLAPI_LOG_MIN || severity > SLAPI_LOG_MAX ) {
+ (void)slapd_log_error_proc( subsystem, "slapi_log_error: invalid severity %d (message %s)\n",
+ severity, fmt );
+ return( -1 );
+ }
+
+ if (
+ #ifdef _WIN32
+ *module_ldap_debug
+ #else
+ slapd_ldap_debug
+ #endif
+ & slapi_log_map[ severity ] )
+ {
+ rc = slapd_log_error_proc_internal( subsystem, fmt, varg1, varg2 );
+ } else {
+ rc = 0; /* nothing to be logged --> always return success */
+ }
+
+ return( rc );
+}
+
+int
slapi_is_loglevel_set ( const int loglevel )
{
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
index 81f7c1a..381a301 100644
--- a/ldap/servers/slapd/slapi-plugin.h
+++ b/ldap/servers/slapd/slapi-plugin.h
@@ -5526,6 +5526,7 @@ int slapi_log_error( int severity, char *subsystem, char *fmt, ... )
#else
;
#endif
+int slapi_log_error_ext( int severity, char *subsystem, char *fmt, va_list varg1, va_list varg2);
/* allowed values for the "severity" parameter */
#define SLAPI_LOG_FATAL 0
@@ -6036,6 +6037,8 @@ void slapi_task_log_notice(Slapi_Task *task, char *format, ...)
#else
;
#endif
+void slapi_task_log_status_ext(Slapi_Task *task, char *format, va_list varg);
+void slapi_task_log_notice_ext(Slapi_Task *task, char *format, va_list varg);
/*
* slapi_new_task: create new task, fill in DN, and setup modify callback
diff --git a/ldap/servers/slapd/task.c b/ldap/servers/slapd/task.c
index 6d60775..5fc0b08 100644
--- a/ldap/servers/slapd/task.c
+++ b/ldap/servers/slapd/task.c
@@ -215,6 +215,17 @@ void slapi_task_log_status(Slapi_Task *task, char *format, ...)
slapi_task_status_changed(task);
}
+void slapi_task_log_status_ext(Slapi_Task *task, char *format, va_list ap)
+{
+ if (! task->task_status)
+ task->task_status = (char *)slapi_ch_malloc(10 * LOG_BUFFER);
+ if (! task->task_status)
+ return; /* out of memory? */
+
+ PR_vsnprintf(task->task_status, (10 * LOG_BUFFER), format, ap);
+ slapi_task_status_changed(task);
+}
+
/* this adds a line to the 'nsTaskLog' value, which is cumulative (anything
* logged here is added to the end)
*/
@@ -266,6 +277,51 @@ void slapi_task_log_notice(Slapi_Task *task, char *format, ...)
slapi_task_status_changed(task);
}
+void slapi_task_log_notice_ext(Slapi_Task *task, char *format, va_list ap)
+{
+ char buffer[LOG_BUFFER];
+ size_t len;
+
+ PR_vsnprintf(buffer, LOG_BUFFER, format, ap);
+
+ if (task->task_log_lock) {
+ PR_Lock(task->task_log_lock);
+ }
+ len = 2 + strlen(buffer) + (task->task_log ? strlen(task->task_log) : 0);
+ if ((len > MAX_SCROLLBACK_BUFFER) && task->task_log) {
+ size_t i;
+ char *newbuf;
+
+ /* start from middle of buffer, and find next linefeed */
+ i = strlen(task->task_log)/2;
+ while (task->task_log[i] && (task->task_log[i] != '\n'))
+ i++;
+ if (task->task_log[i])
+ i++;
+ len = strlen(task->task_log) - i + 2 + strlen(buffer);
+ newbuf = (char *)slapi_ch_malloc(len);
+ strcpy(newbuf, task->task_log + i);
+ slapi_ch_free((void **)&task->task_log);
+ task->task_log = newbuf;
+ } else {
+ if (! task->task_log) {
+ task->task_log = (char *)slapi_ch_malloc(len);
+ task->task_log[0] = 0;
+ } else {
+ task->task_log = (char *)slapi_ch_realloc(task->task_log, len);
+ }
+ }
+
+ if (task->task_log[0])
+ strcat(task->task_log, "\n");
+ strcat(task->task_log, buffer);
+ if (task->task_log_lock) {
+ PR_Unlock(task->task_log_lock);
+ }
+
+ slapi_task_status_changed(task);
+}
+
/* update attributes in the entry under "cn=tasks" to match the current
* status of the task. */
void slapi_task_status_changed(Slapi_Task *task)
commit 4753f9774454b90adea73d18b777539bc9c84071
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Wed May 30 13:30:44 2012 -0400
Update the slapi-plugin documentation on new slapi functions, and added a slapi function for checking on shutdowns
Fix Description: removed the g_get_shutdown() functions from the plugins, and replaced them with the slapi version
Reviewed by: Richm (Thanks!)
(cherry picked from commit 4d564ef42db022a5102c9b6ae1bdd41a18c1dd7f)
branch 389-ds-base-1.2.10
Cherry-picked from 07601165b5c062b385df00d1275c1cccca5593e9
- needed for slapi_is_shutting_down
- did not pick slapi_re_subs_ext patch
diff --git a/ldap/servers/plugins/linkedattrs/fixup_task.c b/ldap/servers/plugins/linkedattrs/fixup_task.c
index c1af2f2..1ad12eb 100644
--- a/ldap/servers/plugins/linkedattrs/fixup_task.c
+++ b/ldap/servers/plugins/linkedattrs/fixup_task.c
@@ -371,7 +371,7 @@ linked_attrs_add_backlinks_callback(Slapi_Entry *e, void *callback_data)
int perform_update = 0;
Slapi_DN *targetsdn = NULL;
- if (g_get_shutdown()) {
+ if (slapi_is_shutting_down()) {
rc = -1;
goto done;
}
diff --git a/ldap/servers/plugins/linkedattrs/linked_attrs.h b/ldap/servers/plugins/linkedattrs/linked_attrs.h
index 137e317..b79b26e 100644
--- a/ldap/servers/plugins/linkedattrs/linked_attrs.h
+++ b/ldap/servers/plugins/linkedattrs/linked_attrs.h
@@ -137,8 +137,6 @@ int linked_attrs_fixup_task_add(Slapi_PBlock *pb, Slapi_Entry *e,
Slapi_Entry *eAfter, int *returncode,
char *returntext, void *arg);
-int g_get_shutdown(); /* declared in proto-slap.h */
-
/*
* misc
*/
diff --git a/ldap/servers/plugins/memberof/memberof.c b/ldap/servers/plugins/memberof/memberof.c
index 229b962..7f29298 100644
--- a/ldap/servers/plugins/memberof/memberof.c
+++ b/ldap/servers/plugins/memberof/memberof.c
@@ -67,8 +67,10 @@
#endif
#include "slapi-plugin.h"
+
#include "string.h"
#include "nspr.h"
+
#include "memberof.h"
static Slapi_PluginDesc pdesc = { "memberof", VENDOR,
@@ -90,6 +92,7 @@ typedef struct _memberof_get_groups_data
MemberOfConfig *config;
Slapi_Value *memberdn_val;
Slapi_ValueSet **groupvals;
+ void *txn;
} memberof_get_groups_data;
/*** function prototypes ***/
@@ -110,55 +113,55 @@ static int memberof_postop_close(Slapi_PBlock *pb);
static int memberof_oktodo(Slapi_PBlock *pb);
static char *memberof_getdn(Slapi_PBlock *pb);
static int memberof_modop_one(Slapi_PBlock *pb, MemberOfConfig *config, int mod_op,
- char *op_this, char *op_to);
+ char *op_this, char *op_to, void *txn);
static int memberof_modop_one_r(Slapi_PBlock *pb, MemberOfConfig *config, int mod_op,
- char *group_dn, char *op_this, char *op_to, memberofstringll *stack);
+ char *group_dn, char *op_this, char *op_to, memberofstringll *stack, void *txn);
static int memberof_add_one(Slapi_PBlock *pb, MemberOfConfig *config, char *addthis,
- char *addto);
+ char *addto, void *txn);
static int memberof_del_one(Slapi_PBlock *pb, MemberOfConfig *config, char *delthis,
- char *delfrom);
+ char *delfrom, void *txn);
static int memberof_mod_smod_list(Slapi_PBlock *pb, MemberOfConfig *config, int mod,
- char *groupdn, Slapi_Mod *smod);
+ char *groupdn, Slapi_Mod *smod, void *txn);
static int memberof_add_smod_list(Slapi_PBlock *pb, MemberOfConfig *config,
- char *groupdn, Slapi_Mod *smod);
+ char *groupdn, Slapi_Mod *smod, void *txn);
static int memberof_del_smod_list(Slapi_PBlock *pb, MemberOfConfig *config,
- char *groupdn, Slapi_Mod *smod);
+ char *groupdn, Slapi_Mod *smod, void *txn);
static int memberof_mod_attr_list(Slapi_PBlock *pb, MemberOfConfig *config, int mod,
- char *groupdn, Slapi_Attr *attr);
+ char *groupdn, Slapi_Attr *attr, void *txn);
static int memberof_mod_attr_list_r(Slapi_PBlock *pb, MemberOfConfig *config,
- int mod, char *group_dn, char *op_this, Slapi_Attr *attr, memberofstringll *stack);
+ int mod, char *group_dn, char *op_this, Slapi_Attr *attr, memberofstringll *stack, void *txn);
static int memberof_add_attr_list(Slapi_PBlock *pb, MemberOfConfig *config,
- char *groupdn, Slapi_Attr *attr);
+ char *groupdn, Slapi_Attr *attr, void *txn);
static int memberof_del_attr_list(Slapi_PBlock *pb, MemberOfConfig *config,
- char *groupdn, Slapi_Attr *attr);
+ char *groupdn, Slapi_Attr *attr, void *txn);
static int memberof_moddn_attr_list(Slapi_PBlock *pb, MemberOfConfig *config,
- char *pre_dn, char *post_dn, Slapi_Attr *attr);
-static int memberof_replace_list(Slapi_PBlock *pb, MemberOfConfig *config, char *group_dn);
+ char *pre_dn, char *post_dn, Slapi_Attr *attr, void *txn);
+static int memberof_replace_list(Slapi_PBlock *pb, MemberOfConfig *config, char *group_dn, void *txn);
static void memberof_set_plugin_id(void * plugin_id);
static void *memberof_get_plugin_id();
static int memberof_compare(MemberOfConfig *config, const void *a, const void *b);
static int memberof_qsort_compare(const void *a, const void *b);
static void memberof_load_array(Slapi_Value **array, Slapi_Attr *attr);
-static void memberof_del_dn_from_groups(Slapi_PBlock *pb, MemberOfConfig *config, char *dn);
+static void memberof_del_dn_from_groups(Slapi_PBlock *pb, MemberOfConfig *config, char *dn, void *txn);
static int memberof_call_foreach_dn(Slapi_PBlock *pb, char *dn,
- char **types, plugin_search_entry_callback callback, void *callback_data);
+ char **types, plugin_search_entry_callback callback, void *callback_data, void *txn);
static int memberof_is_direct_member(MemberOfConfig *config, Slapi_Value *groupdn,
- Slapi_Value *memberdn);
+ Slapi_Value *memberdn, void *txn);
static int memberof_is_grouping_attr(char *type, MemberOfConfig *config);
-static Slapi_ValueSet *memberof_get_groups(MemberOfConfig *config, char *memberdn);
+static Slapi_ValueSet *memberof_get_groups(MemberOfConfig *config, char *memberdn, void *txn);
static int memberof_get_groups_r(MemberOfConfig *config, char *memberdn,
- memberof_get_groups_data *data);
+ memberof_get_groups_data *data, void *txn);
static int memberof_get_groups_callback(Slapi_Entry *e, void *callback_data);
static int memberof_test_membership(Slapi_PBlock *pb, MemberOfConfig *config,
- char *group_dn);
+ char *group_dn, void *txn);
static int memberof_test_membership_callback(Slapi_Entry *e, void *callback_data);
static int memberof_del_dn_type_callback(Slapi_Entry *e, void *callback_data);
static int memberof_replace_dn_type_callback(Slapi_Entry *e, void *callback_data);
static void memberof_replace_dn_from_groups(Slapi_PBlock *pb, MemberOfConfig *config,
- char *pre_dn, char *post_dn);
+ char *pre_dn, char *post_dn, void *txn);
static int memberof_modop_one_replace_r(Slapi_PBlock *pb, MemberOfConfig *config,
int mod_op, char *group_dn, char *op_this, char *replace_with, char *op_to,
- memberofstringll *stack);
+ memberofstringll *stack, void *txn);
static int memberof_task_add(Slapi_PBlock *pb, Slapi_Entry *e,
Slapi_Entry *eAfter, int *returncode, char *returntext,
void *arg);
@@ -166,7 +169,7 @@ static void memberof_task_destructor(Slapi_Task *task);
static const char *fetch_attr(Slapi_Entry *e, const char *attrname,
const char *default_val);
static void memberof_fixup_task_thread(void *arg);
-static int memberof_fix_memberof(MemberOfConfig *config, char *dn, char *filter_str);
+static int memberof_fix_memberof(MemberOfConfig *config, char *dn, char *filter_str, void *txn);
static int memberof_fix_memberof_callback(Slapi_Entry *e, void *callback_data);
@@ -396,8 +399,10 @@ int memberof_postop_del(Slapi_PBlock *pb)
if(memberof_oktodo(pb) && (normdn = memberof_getdn(pb)))
{
struct slapi_entry *e = NULL;
+ void *txn = NULL;
slapi_pblock_get( pb, SLAPI_ENTRY_PRE_OP, &e );
+ slapi_pblock_get( pb, SLAPI_TXN, &txn );
/* We need to get the config lock first. Trying to get the
* config lock after we already hold the op lock can cause
@@ -413,7 +418,7 @@ int memberof_postop_del(Slapi_PBlock *pb)
/* remove this DN from the
* membership lists of groups
*/
- memberof_del_dn_from_groups(pb, &configCopy, normdn);
+ memberof_del_dn_from_groups(pb, &configCopy, normdn, txn);
/* is the entry of interest as a group? */
if(e && configCopy.group_filter && !slapi_filter_test_simple(e, configCopy.group_filter))
@@ -426,7 +431,7 @@ int memberof_postop_del(Slapi_PBlock *pb)
{
if (0 == slapi_entry_attr_find(e, configCopy.groupattrs[i], &attr))
{
- memberof_del_attr_list(pb, &configCopy, normdn, attr);
+ memberof_del_attr_list(pb, &configCopy, normdn, attr, txn);
}
}
}
@@ -445,11 +450,12 @@ typedef struct _memberof_del_dn_data
{
char *dn;
char *type;
+ void *txn;
} memberof_del_dn_data;
/* Deletes a member dn from all groups that refer to it. */
static void
-memberof_del_dn_from_groups(Slapi_PBlock *pb, MemberOfConfig *config, char *dn)
+memberof_del_dn_from_groups(Slapi_PBlock *pb, MemberOfConfig *config, char *dn, void *txn)
{
int i = 0;
char *groupattrs[2] = {0, 0};
@@ -459,12 +465,12 @@ memberof_del_dn_from_groups(Slapi_PBlock *pb, MemberOfConfig *config, char *dn)
* same grouping attribute. */
for (i = 0; config->groupattrs[i]; i++)
{
- memberof_del_dn_data data = {dn, config->groupattrs[i]};
+ memberof_del_dn_data data = {dn, config->groupattrs[i], txn};
groupattrs[0] = config->groupattrs[i];
memberof_call_foreach_dn(pb, dn, groupattrs,
- memberof_del_dn_type_callback, &data);
+ memberof_del_dn_type_callback, &data, txn);
}
}
@@ -493,6 +499,7 @@ int memberof_del_dn_type_callback(Slapi_Entry *e, void *callback_data)
mods, 0, 0,
memberof_get_plugin_id(), 0);
+ slapi_pblock_set(mod_pb, SLAPI_TXN, ((memberof_del_dn_data *)callback_data)->txn);
slapi_modify_internal_pb(mod_pb);
slapi_pblock_get(mod_pb,
@@ -505,101 +512,95 @@ int memberof_del_dn_type_callback(Slapi_Entry *e, void *callback_data)
}
/*
- * Does a callback search of "type=dn" under the db suffix that "dn" is in,
- * unless all_backends is set, then we look at all the backends. If "dn"
- * is a user, you'd want "type" to be "member". If "dn" is a group, you
- * could want type to be either "member" or "memberOf" depending on the case.
+ * Does a callback search of "type=dn" under the db suffix that "dn" is in.
+ * If "dn" is a user, you'd want "type" to be "member". If "dn" is a group,
+ * you could want type to be either "member" or "memberOf" depending on the
+ * case.
*/
int memberof_call_foreach_dn(Slapi_PBlock *pb, char *dn,
- char **types, plugin_search_entry_callback callback, void *callback_data)
+ char **types, plugin_search_entry_callback callback, void *callback_data, void *txn)
{
+ int rc = 0;
Slapi_PBlock *search_pb = slapi_pblock_new();
- Slapi_DN *base_sdn = NULL;
- Slapi_Backend *be = NULL;
- Slapi_DN *sdn = NULL;
- char *filter_str = NULL;
- char *cookie = NULL;
- int all_backends = memberof_config_get_all_backends();
- int types_name_len = 0;
+ Slapi_Backend *be = 0;
+ Slapi_DN *sdn = 0;
+ Slapi_DN *base_sdn = 0;
+ char *filter_str = 0;
int num_types = 0;
- int dn_len = strlen(dn);
- int rc = 0;
+ int types_name_len = 0;
+ int dn_len = 0;
int i = 0;
- /* Count the number of types. */
- for (num_types = 0; types && types[num_types]; num_types++)
+ slapi_pblock_set(search_pb, SLAPI_TXN, txn);
+ /* get the base dn for the backend we are in
+ (we don't support having members and groups in
+ different backends - issues with offline / read only backends)
+ */
+ sdn = slapi_sdn_new_normdn_byref(dn);
+ be = slapi_be_select(sdn);
+ if(be)
{
- /* Add up the total length of all attribute names.
- * We need to know this for building the filter. */
- types_name_len += strlen(types[num_types]);
+ base_sdn = (Slapi_DN*)slapi_be_getsuffix(be,0);
}
- /* Build the search filter. */
- if (num_types > 1)
+ if(base_sdn)
{
- int bytes_out = 0;
- int filter_str_len = types_name_len + (num_types * (3 + dn_len)) + 4;
-
- /* Allocate enough space for the filter */
- filter_str = slapi_ch_malloc(filter_str_len);
+ /* Find the length of the dn */
+ dn_len = strlen(dn);
- /* Add beginning of filter. */
- bytes_out = snprintf(filter_str, filter_str_len - bytes_out, "(|");
-
- /* Add filter section for each type. */
- for (i = 0; types[i]; i++)
+ /* Count the number of types. */
+ for (num_types = 0; types && types[num_types]; num_types++)
{
- bytes_out += snprintf(filter_str + bytes_out, filter_str_len - bytes_out,
- "(%s=%s)", types[i], dn);
+ /* Add up the total length of all attribute names.
+ * We need to know this for building the filter. */
+ types_name_len += strlen(types[num_types]);
}
- /* Add end of filter. */
- snprintf(filter_str + bytes_out, filter_str_len - bytes_out, ")");
- }
- else if (num_types == 1)
- {
- filter_str = slapi_ch_smprintf("(%s=%s)", types[0], dn);
- }
+ /* Build the search filter. */
+ if (num_types > 1)
+ {
+ int bytes_out = 0;
+ int filter_str_len = types_name_len + (num_types * (3 + dn_len)) + 4;
- if(filter_str == NULL){
- return rc;
- }
+ /* Allocate enough space for the filter */
+ filter_str = slapi_ch_malloc(filter_str_len);
- be = slapi_get_first_backend(&cookie);
- while(be){
- if(!all_backends){
- sdn = slapi_sdn_new_normdn_byref(dn);
- be = slapi_be_select(sdn);
- if(be == NULL){
- break;
+ /* Add beginning of filter. */
+ bytes_out = snprintf(filter_str, filter_str_len - bytes_out, "(|");
+
+ /* Add filter section for each type. */
+ for (i = 0; types[i]; i++)
+ {
+ bytes_out += snprintf(filter_str + bytes_out, filter_str_len - bytes_out,
+ "(%s=%s)", types[i], dn);
}
+
+ /* Add end of filter. */
+ snprintf(filter_str + bytes_out, filter_str_len - bytes_out, ")");
}
- if((base_sdn = (Slapi_DN *)slapi_be_getsuffix(be,0)) == NULL){
- if(!all_backends){
- break;
- } else {
- /* its ok, goto the next backend */
- be = slapi_get_next_backend(cookie);
- continue;
- }
+ else if (num_types == 1)
+ {
+ filter_str = slapi_ch_smprintf("(%s=%s)", types[0], dn);
}
+ }
+ if(filter_str)
+ {
slapi_search_internal_set_pb(search_pb, slapi_sdn_get_dn(base_sdn),
- LDAP_SCOPE_SUBTREE, filter_str, 0, 0, 0, 0, memberof_get_plugin_id(), 0);
- slapi_search_internal_callback_pb(search_pb, callback_data, 0, callback, 0);
-
- if(!all_backends){
- break;
- }
- slapi_pblock_init(search_pb);
- be = slapi_get_next_backend(cookie);
+ LDAP_SCOPE_SUBTREE, filter_str, 0, 0,
+ 0, 0,
+ memberof_get_plugin_id(),
+ 0);
+
+ slapi_search_internal_callback_pb(search_pb,
+ callback_data,
+ 0, callback,
+ 0);
}
slapi_sdn_free(&sdn);
slapi_pblock_destroy(search_pb);
- slapi_ch_free((void **)&cookie);
slapi_ch_free_string(&filter_str);
-
return rc;
}
@@ -633,9 +634,11 @@ int memberof_postop_modrdn(Slapi_PBlock *pb)
struct slapi_entry *post_e = NULL;
char *pre_dn = 0;
char *post_dn = 0;
+ void *txn = NULL;
slapi_pblock_get( pb, SLAPI_ENTRY_PRE_OP, &pre_e );
slapi_pblock_get( pb, SLAPI_ENTRY_POST_OP, &post_e );
+ slapi_pblock_get( pb, SLAPI_TXN, &txn );
if(pre_e && post_e)
{
@@ -664,7 +667,7 @@ int memberof_postop_modrdn(Slapi_PBlock *pb)
{
if(0 == slapi_entry_attr_find(post_e, configCopy.groupattrs[i], &attr))
{
- if(memberof_moddn_attr_list(pb, &configCopy, pre_dn, post_dn, attr) != 0){
+ if(memberof_moddn_attr_list(pb, &configCopy, pre_dn, post_dn, attr, txn) != 0){
break;
}
}
@@ -675,7 +678,7 @@ int memberof_postop_modrdn(Slapi_PBlock *pb)
* of other group entries. We need to update any member
* attributes to refer to the new name. */
if (pre_dn && post_dn) {
- memberof_replace_dn_from_groups(pb, &configCopy, pre_dn, post_dn);
+ memberof_replace_dn_from_groups(pb, &configCopy, pre_dn, post_dn, txn);
}
memberof_unlock();
@@ -693,6 +696,7 @@ typedef struct _replace_dn_data
char *pre_dn;
char *post_dn;
char *type;
+ void *txn;
} replace_dn_data;
@@ -700,7 +704,7 @@ typedef struct _replace_dn_data
* to use post_dn instead. */
static void
memberof_replace_dn_from_groups(Slapi_PBlock *pb, MemberOfConfig *config,
- char *pre_dn, char *post_dn)
+ char *pre_dn, char *post_dn, void *txn)
{
int i = 0;
char *groupattrs[2] = {0, 0};
@@ -710,12 +714,12 @@ memberof_replace_dn_from_groups(Slapi_PBlock *pb, MemberOfConfig *config,
* using the same grouping attribute. */
for (i = 0; config->groupattrs[i]; i++)
{
- replace_dn_data data = {pre_dn, post_dn, config->groupattrs[i]};
+ replace_dn_data data = {pre_dn, post_dn, config->groupattrs[i], txn};
groupattrs[0] = config->groupattrs[i];
memberof_call_foreach_dn(pb, pre_dn, groupattrs,
- memberof_replace_dn_type_callback, &data);
+ memberof_replace_dn_type_callback, &data, txn);
}
}
@@ -755,6 +759,7 @@ int memberof_replace_dn_type_callback(Slapi_Entry *e, void *callback_data)
mods, 0, 0,
memberof_get_plugin_id(), 0);
+ slapi_pblock_set(mod_pb, SLAPI_TXN, ((replace_dn_data *)callback_data)->txn);
slapi_modify_internal_pb(mod_pb);
slapi_pblock_get(mod_pb,
@@ -807,7 +812,9 @@ int memberof_postop_modify(Slapi_PBlock *pb)
int config_copied = 0;
MemberOfConfig *mainConfig = 0;
MemberOfConfig configCopy = {0, 0, 0, 0};
+ void *txn = NULL;
+ slapi_pblock_get(pb, SLAPI_TXN, &txn);
/* get the mod set */
slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &mods);
smods = slapi_mods_new();
@@ -858,7 +865,7 @@ int memberof_postop_modify(Slapi_PBlock *pb)
case LDAP_MOD_ADD:
{
/* add group DN to targets */
- memberof_add_smod_list(pb, &configCopy, normdn, smod);
+ memberof_add_smod_list(pb, &configCopy, normdn, smod, txn);
break;
}
@@ -870,12 +877,12 @@ int memberof_postop_modify(Slapi_PBlock *pb)
* entry, which the replace code deals with. */
if (slapi_mod_get_num_values(smod) == 0)
{
- memberof_replace_list(pb, &configCopy, normdn);
+ memberof_replace_list(pb, &configCopy, normdn, txn);
}
else
{
/* remove group DN from target values in smod*/
- memberof_del_smod_list(pb, &configCopy, normdn, smod);
+ memberof_del_smod_list(pb, &configCopy, normdn, smod, txn);
}
break;
}
@@ -883,7 +890,7 @@ int memberof_postop_modify(Slapi_PBlock *pb)
case LDAP_MOD_REPLACE:
{
/* replace current values */
- memberof_replace_list(pb, &configCopy, normdn);
+ memberof_replace_list(pb, &configCopy, normdn, txn);
break;
}
@@ -948,9 +955,10 @@ int memberof_postop_add(Slapi_PBlock *pb)
MemberOfConfig *mainConfig = 0;
MemberOfConfig configCopy = {0, 0, 0, 0};
struct slapi_entry *e = NULL;
+ void *txn = NULL;
slapi_pblock_get( pb, SLAPI_ENTRY_POST_OP, &e );
-
+ slapi_pblock_get( pb, SLAPI_TXN, &txn );
/* is the entry of interest? */
memberof_rlock_config();
@@ -975,7 +983,7 @@ int memberof_postop_add(Slapi_PBlock *pb)
{
if(0 == slapi_entry_attr_find(e, configCopy.groupattrs[i], &attr))
{
- memberof_add_attr_list(pb, &configCopy, normdn, attr);
+ memberof_add_attr_list(pb, &configCopy, normdn, attr, txn);
}
}
@@ -1065,9 +1073,9 @@ char *memberof_getdn(Slapi_PBlock *pb)
* Also, we must not delete entries that are a member of the group
*/
int memberof_modop_one(Slapi_PBlock *pb, MemberOfConfig *config, int mod_op,
- char *op_this, char *op_to)
+ char *op_this, char *op_to, void *txn)
{
- return memberof_modop_one_r(pb, config, mod_op, op_this, op_this, op_to, 0);
+ return memberof_modop_one_r(pb, config, mod_op, op_this, op_this, op_to, 0, txn);
}
/* memberof_modop_one_r()
@@ -1076,19 +1084,24 @@ int memberof_modop_one(Slapi_PBlock *pb, MemberOfConfig *config, int mod_op,
*/
int memberof_modop_one_r(Slapi_PBlock *pb, MemberOfConfig *config, int mod_op,
- char *group_dn, char *op_this, char *op_to, memberofstringll *stack)
+ char *group_dn, char *op_this, char *op_to, memberofstringll *stack, void *txn)
{
return memberof_modop_one_replace_r(
- pb, config, mod_op, group_dn, op_this, 0, op_to, stack);
+ pb, config, mod_op, group_dn, op_this, 0, op_to, stack, txn);
}
+struct fix_memberof_callback_data {
+ MemberOfConfig *config;
+ void *txn;
+};
+
/* memberof_modop_one_replace_r()
*
* recursive function to perform above (with added replace arg)
*/
int memberof_modop_one_replace_r(Slapi_PBlock *pb, MemberOfConfig *config,
int mod_op, char *group_dn, char *op_this, char *replace_with,
- char *op_to, memberofstringll *stack)
+ char *op_to, memberofstringll *stack, void *txn)
{
int rc = 0;
LDAPMod mod;
@@ -1112,8 +1125,8 @@ int memberof_modop_one_replace_r(Slapi_PBlock *pb, MemberOfConfig *config,
/* determine if this is a group op or single entry */
op_to_sdn = slapi_sdn_new_normdn_byref(op_to);
- slapi_search_internal_get_entry( op_to_sdn, config->groupattrs,
- &e, memberof_get_plugin_id());
+ slapi_search_internal_get_entry_ext( op_to_sdn, config->groupattrs,
+ &e, memberof_get_plugin_id(), txn);
if(!e)
{
/* In the case of a delete, we need to worry about the
@@ -1128,72 +1141,61 @@ int memberof_modop_one_replace_r(Slapi_PBlock *pb, MemberOfConfig *config,
Slapi_DN *base_sdn = 0;
Slapi_Backend *be = 0;
char *filter_str = 0;
- char *cookie = NULL;
int n_entries = 0;
- int all_backends = config->allBackends;
-
- filter_str = slapi_ch_smprintf("(%s=%s)", config->memberof_attr, op_to);
- be = slapi_get_first_backend(&cookie);
- while(be){
- /*
- * We can't tell for sure if the op_to entry is a
- * user or a group since the entry doesn't exist
- * anymore. We can safely ignore the missing entry
- * if no other entries have a memberOf attribute that
- * points to the missing entry.
- */
- if(!all_backends){
- be = slapi_be_select(op_to_sdn);
- if(be == NULL){
- break;
- }
- }
- if((base_sdn = (Slapi_DN*)slapi_be_getsuffix(be,0)) == NULL){
- if(!all_backends){
- break;
- } else {
- be = slapi_get_next_backend (cookie);
- continue;
- }
- }
- if(filter_str)
- {
- slapi_search_internal_set_pb(search_pb, slapi_sdn_get_dn(base_sdn),
- LDAP_SCOPE_SUBTREE, filter_str, 0, 0, 0, 0,
- memberof_get_plugin_id(), 0);
- if (slapi_search_internal_pb(search_pb))
+ /* We can't tell for sure if the op_to entry is a
+ * user or a group since the entry doesn't exist
+ * anymore. We can safely ignore the missing entry
+ * if no other entries have a memberOf attribute that
+ * points to the missing entry. */
+ be = slapi_be_select(op_to_sdn);
+ if(be)
+ {
+ base_sdn = (Slapi_DN*)slapi_be_getsuffix(be,0);
+ }
+
+ if(base_sdn)
+ {
+ filter_str = slapi_ch_smprintf("(%s=%s)",
+ config->memberof_attr, op_to);
+ }
+
+ if(filter_str)
+ {
+ slapi_search_internal_set_pb(search_pb, slapi_sdn_get_dn(base_sdn),
+ LDAP_SCOPE_SUBTREE, filter_str, 0, 0, 0, 0,
+ memberof_get_plugin_id(), 0);
+ slapi_pblock_set(search_pb, SLAPI_TXN, txn);
+
+ if (slapi_search_internal_pb(search_pb))
+ {
+ /* get result and log an error */
+ int res = 0;
+ slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_RESULT, &res);
+ slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM,
+ "memberof_modop_one_replace_r: error searching for members: "
+ "%d", res);
+ } else {
+ slapi_pblock_get(search_pb, SLAPI_NENTRIES, &n_entries);
+
+ if(n_entries > 0)
{
- /* get result and log an error */
- int res = 0;
- slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_RESULT, &res);
- slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM,
- "memberof_modop_one_replace_r: error searching for members: "
- "%d", res);
- } else {
- slapi_pblock_get(search_pb, SLAPI_NENTRIES, &n_entries);
- if(n_entries > 0)
- {
- /* We want to fixup the membership for the
- * entries that referred to the missing group
- * entry. This will fix the references to
- * the missing group as well as the group
- * represented by op_this. */
- memberof_test_membership(pb, config, op_to);
- }
+ /* We want to fixup the membership for the
+ * entries that referred to the missing group
+ * entry. This will fix the references to
+ * the missing group as well as the group
+ * represented by op_this. */
+ memberof_test_membership(pb, config, op_to, txn);
}
- slapi_free_search_results_internal(search_pb);
- }
- slapi_pblock_init(search_pb);
- if(!all_backends){
- break;
}
- be = slapi_get_next_backend (cookie);
+
+ slapi_free_search_results_internal(search_pb);
+ slapi_ch_free_string(&filter_str);
}
+
slapi_pblock_destroy(search_pb);
- slapi_ch_free_string(&filter_str);
- slapi_ch_free((void **)&cookie);
}
+
goto bail;
}
@@ -1266,7 +1268,7 @@ int memberof_modop_one_replace_r(Slapi_PBlock *pb, MemberOfConfig *config,
slapi_entry_attr_find( e, config->groupattrs[i], &members );
if(members)
{
- if(memberof_mod_attr_list_r(pb, config, mod_op, group_dn, op_this, members, ll) != 0){
+ if(memberof_mod_attr_list_r(pb, config, mod_op, group_dn, op_this, members, ll, txn) != 0){
rc = -1;
goto bail;
}
@@ -1307,7 +1309,8 @@ int memberof_modop_one_replace_r(Slapi_PBlock *pb, MemberOfConfig *config,
if(LDAP_MOD_DELETE == mod_op || LDAP_MOD_ADD == mod_op)
{
/* find parent groups and replace our member attr */
- memberof_fix_memberof_callback(e, config);
+ struct fix_memberof_callback_data cb_data = {config, txn};
+ memberof_fix_memberof_callback(e, &cb_data);
} else {
/* single entry - do mod */
mod_pb = slapi_pblock_new();
@@ -1344,6 +1347,7 @@ int memberof_modop_one_replace_r(Slapi_PBlock *pb, MemberOfConfig *config,
mods, 0, 0,
memberof_get_plugin_id(), 0);
+ slapi_pblock_set(mod_pb, SLAPI_TXN, txn);
slapi_modify_internal_pb(mod_pb);
slapi_pblock_get(mod_pb,
@@ -1369,9 +1373,9 @@ bail:
* Add addthis DN to the memberof attribute of addto
*
*/
-int memberof_add_one(Slapi_PBlock *pb, MemberOfConfig *config, char *addthis, char *addto)
+int memberof_add_one(Slapi_PBlock *pb, MemberOfConfig *config, char *addthis, char *addto, void *txn)
{
- return memberof_modop_one(pb, config, LDAP_MOD_ADD, addthis, addto);
+ return memberof_modop_one(pb, config, LDAP_MOD_ADD, addthis, addto, txn);
}
/*
@@ -1380,9 +1384,9 @@ int memberof_add_one(Slapi_PBlock *pb, MemberOfConfig *config, char *addthis, ch
* Delete delthis DN from the memberof attribute of delfrom
*
*/
-int memberof_del_one(Slapi_PBlock *pb, MemberOfConfig *config, char *delthis, char *delfrom)
+int memberof_del_one(Slapi_PBlock *pb, MemberOfConfig *config, char *delthis, char *delfrom, void *txn)
{
- return memberof_modop_one(pb, config, LDAP_MOD_DELETE, delthis, delfrom);
+ return memberof_modop_one(pb, config, LDAP_MOD_DELETE, delthis, delfrom, txn);
}
/*
@@ -1392,7 +1396,7 @@ int memberof_del_one(Slapi_PBlock *pb, MemberOfConfig *config, char *delthis, ch
*
*/
int memberof_mod_smod_list(Slapi_PBlock *pb, MemberOfConfig *config, int mod,
- char *group_dn, Slapi_Mod *smod)
+ char *group_dn, Slapi_Mod *smod, void *txn)
{
int rc = 0;
struct berval *bv = slapi_mod_get_first_value(smod);
@@ -1424,7 +1428,7 @@ int memberof_mod_smod_list(Slapi_PBlock *pb, MemberOfConfig *config, int mod,
strncpy(dn_str, bv->bv_val, (size_t)bv->bv_len);
- memberof_modop_one(pb, config, mod, group_dn, dn_str);
+ memberof_modop_one(pb, config, mod, group_dn, dn_str, txn);
bv = slapi_mod_get_next_value(smod);
}
@@ -1442,9 +1446,9 @@ int memberof_mod_smod_list(Slapi_PBlock *pb, MemberOfConfig *config, int mod,
*
*/
int memberof_add_smod_list(Slapi_PBlock *pb, MemberOfConfig *config,
- char *groupdn, Slapi_Mod *smod)
+ char *groupdn, Slapi_Mod *smod, void *txn)
{
- return memberof_mod_smod_list(pb, config, LDAP_MOD_ADD, groupdn, smod);
+ return memberof_mod_smod_list(pb, config, LDAP_MOD_ADD, groupdn, smod, txn);
}
@@ -1455,9 +1459,9 @@ int memberof_add_smod_list(Slapi_PBlock *pb, MemberOfConfig *config,
*
*/
int memberof_del_smod_list(Slapi_PBlock *pb, MemberOfConfig *config,
- char *groupdn, Slapi_Mod *smod)
+ char *groupdn, Slapi_Mod *smod, void *txn)
{
- return memberof_mod_smod_list(pb, config, LDAP_MOD_DELETE, groupdn, smod);
+ return memberof_mod_smod_list(pb, config, LDAP_MOD_DELETE, groupdn, smod, txn);
}
/**
@@ -1481,13 +1485,13 @@ void * memberof_get_plugin_id()
*
*/
int memberof_mod_attr_list(Slapi_PBlock *pb, MemberOfConfig *config, int mod,
- char *group_dn, Slapi_Attr *attr)
+ char *group_dn, Slapi_Attr *attr, void *txn)
{
- return memberof_mod_attr_list_r(pb, config, mod, group_dn, group_dn, attr, 0);
+ return memberof_mod_attr_list_r(pb, config, mod, group_dn, group_dn, attr, 0, txn);
}
int memberof_mod_attr_list_r(Slapi_PBlock *pb, MemberOfConfig *config, int mod,
- char *group_dn, char *op_this, Slapi_Attr *attr, memberofstringll *stack)
+ char *group_dn, char *op_this, Slapi_Attr *attr, memberofstringll *stack, void *txn)
{
int rc = 0;
Slapi_Value *val = 0;
@@ -1534,11 +1538,11 @@ int memberof_mod_attr_list_r(Slapi_PBlock *pb, MemberOfConfig *config, int mod,
if(mod == LDAP_MOD_REPLACE)
{
memberof_modop_one_replace_r(pb, config, mod, group_dn, op_this,
- group_dn, dn_str, stack);
+ group_dn, dn_str, stack, txn);
}
else
{
- memberof_modop_one_r(pb, config, mod, group_dn, op_this, dn_str, stack);
+ memberof_modop_one_r(pb, config, mod, group_dn, op_this, dn_str, stack, txn);
}
}
@@ -1560,9 +1564,9 @@ int memberof_mod_attr_list_r(Slapi_PBlock *pb, MemberOfConfig *config, int mod,
*
*/
int memberof_add_attr_list(Slapi_PBlock *pb, MemberOfConfig *config, char *groupdn,
- Slapi_Attr *attr)
+ Slapi_Attr *attr, void *txn)
{
- return memberof_mod_attr_list(pb, config, LDAP_MOD_ADD, groupdn, attr);
+ return memberof_mod_attr_list(pb, config, LDAP_MOD_ADD, groupdn, attr, txn);
}
/*
@@ -1572,9 +1576,9 @@ int memberof_add_attr_list(Slapi_PBlock *pb, MemberOfConfig *config, char *group
*
*/
int memberof_del_attr_list(Slapi_PBlock *pb, MemberOfConfig *config, char *groupdn,
- Slapi_Attr *attr)
+ Slapi_Attr *attr, void *txn)
{
- return memberof_mod_attr_list(pb, config, LDAP_MOD_DELETE, groupdn, attr);
+ return memberof_mod_attr_list(pb, config, LDAP_MOD_DELETE, groupdn, attr, txn);
}
/*
@@ -1584,7 +1588,7 @@ int memberof_del_attr_list(Slapi_PBlock *pb, MemberOfConfig *config, char *group
*
*/
int memberof_moddn_attr_list(Slapi_PBlock *pb, MemberOfConfig *config,
- char *pre_dn, char *post_dn, Slapi_Attr *attr)
+ char *pre_dn, char *post_dn, Slapi_Attr *attr, void *txn)
{
int rc = 0;
Slapi_Value *val = 0;
@@ -1619,7 +1623,7 @@ int memberof_moddn_attr_list(Slapi_PBlock *pb, MemberOfConfig *config,
strncpy(dn_str, bv->bv_val, (size_t)bv->bv_len);
memberof_modop_one_replace_r(pb, config, LDAP_MOD_REPLACE,
- post_dn, pre_dn, post_dn, dn_str, 0);
+ post_dn, pre_dn, post_dn, dn_str, 0, txn);
hint = slapi_attr_next_value(attr, hint, &val);
}
@@ -1637,25 +1641,25 @@ int memberof_moddn_attr_list(Slapi_PBlock *pb, MemberOfConfig *config,
* A Slapi_ValueSet* is returned. It is up to the caller to
* free it.
*/
-Slapi_ValueSet *memberof_get_groups(MemberOfConfig *config, char *memberdn)
+Slapi_ValueSet *memberof_get_groups(MemberOfConfig *config, char *memberdn, void *txn)
{
Slapi_Value *memberdn_val = slapi_value_new_string(memberdn);
Slapi_ValueSet *groupvals = slapi_valueset_new();
- memberof_get_groups_data data = {config, memberdn_val, &groupvals};
+ memberof_get_groups_data data = {config, memberdn_val, &groupvals, txn};
- memberof_get_groups_r(config, memberdn, &data);
+ memberof_get_groups_r(config, memberdn, &data, txn);
slapi_value_free(&memberdn_val);
return groupvals;
}
-int memberof_get_groups_r(MemberOfConfig *config, char *memberdn, memberof_get_groups_data *data)
+int memberof_get_groups_r(MemberOfConfig *config, char *memberdn, memberof_get_groups_data *data, void *txn)
{
/* Search for any grouping attributes that point to memberdn.
* For each match, add it to the list, recurse and do same search */
return memberof_call_foreach_dn(NULL, memberdn, config->groupattrs,
- memberof_get_groups_callback, data);
+ memberof_get_groups_callback, data, txn);
}
/* memberof_get_groups_callback()
@@ -1669,7 +1673,7 @@ int memberof_get_groups_callback(Slapi_Entry *e, void *callback_data)
Slapi_ValueSet *groupvals = *((memberof_get_groups_data*)callback_data)->groupvals;
int rc = 0;
- if(g_get_shutdown()){
+ if(slapi_is_shutting_down()){
rc = -1;
goto bail;
}
@@ -1724,7 +1728,7 @@ int memberof_get_groups_callback(Slapi_Entry *e, void *callback_data)
/* now recurse to find parent groups of e */
memberof_get_groups_r(((memberof_get_groups_data*)callback_data)->config,
- group_dn, callback_data);
+ group_dn, callback_data, ((memberof_get_groups_data*)callback_data)->txn);
bail:
return rc;
@@ -1736,7 +1740,7 @@ bail:
* returns non-zero when true, zero otherwise
*/
int memberof_is_direct_member(MemberOfConfig *config, Slapi_Value *groupdn,
- Slapi_Value *memberdn)
+ Slapi_Value *memberdn, void *txn)
{
int rc = 0;
Slapi_DN *sdn = 0;
@@ -1746,8 +1750,8 @@ int memberof_is_direct_member(MemberOfConfig *config, Slapi_Value *groupdn,
sdn = slapi_sdn_new_normdn_byref(slapi_value_get_string(groupdn));
- slapi_search_internal_get_entry(sdn, config->groupattrs,
- &group_e, memberof_get_plugin_id());
+ slapi_search_internal_get_entry_ext(sdn, config->groupattrs,
+ &group_e, memberof_get_plugin_id(), txn);
if(group_e)
{
@@ -1794,6 +1798,11 @@ static int memberof_is_grouping_attr(char *type, MemberOfConfig *config)
return match;
}
+struct test_membership_cb_data {
+ MemberOfConfig *config;
+ void *txn;
+};
+
/* memberof_test_membership()
*
* Finds all entries who are a "memberOf" the group
@@ -1809,12 +1818,13 @@ static int memberof_is_grouping_attr(char *type, MemberOfConfig *config)
* iterate until a pass fails to move a group over to member groups
* remaining groups should be deleted
*/
-int memberof_test_membership(Slapi_PBlock *pb, MemberOfConfig *config, char *group_dn)
+int memberof_test_membership(Slapi_PBlock *pb, MemberOfConfig *config, char *group_dn, void *txn)
{
char *attrs[2] = {config->memberof_attr, 0};
+ struct test_membership_cb_data cb_data = {config, txn};
return memberof_call_foreach_dn(pb, group_dn, attrs,
- memberof_test_membership_callback , config);
+ memberof_test_membership_callback , &cb_data, txn);
}
/*
@@ -1832,7 +1842,8 @@ int memberof_test_membership_callback(Slapi_Entry *e, void *callback_data)
Slapi_Value **member_array = 0;
Slapi_Value **candidate_array = 0;
Slapi_Value *entry_dn = 0;
- MemberOfConfig *config = (MemberOfConfig *)callback_data;
+ struct test_membership_cb_data *cb_data = (struct test_membership_cb_data *)callback_data;
+ MemberOfConfig *config = cb_data->config;
entry_dn = slapi_value_new_string(slapi_entry_get_dn(e));
@@ -1869,7 +1880,7 @@ int memberof_test_membership_callback(Slapi_Entry *e, void *callback_data)
while(val)
{
/* test for direct membership */
- if(memberof_is_direct_member(config, val, entry_dn))
+ if(memberof_is_direct_member(config, val, entry_dn, cb_data->txn))
{
/* it is a member */
member_array[m_index] = val;
@@ -1918,7 +1929,7 @@ int memberof_test_membership_callback(Slapi_Entry *e, void *callback_data)
if(memberof_is_direct_member(
config,
candidate_array[inner_index],
- member_array[outer_index]))
+ member_array[outer_index], cb_data->txn))
{
member_array[m_index] =
candidate_array
@@ -1958,7 +1969,7 @@ int memberof_test_membership_callback(Slapi_Entry *e, void *callback_data)
0, config,
(char*)slapi_value_get_string(
candidate_array[outer_index]),
- (char*)slapi_value_get_string(entry_dn));
+ (char*)slapi_value_get_string(entry_dn), cb_data->txn);
outer_index++;
}
@@ -1990,7 +2001,7 @@ bail:
* Perform replace the group DN list in the memberof attribute of the list of targets
*
*/
-int memberof_replace_list(Slapi_PBlock *pb, MemberOfConfig *config, char *group_dn)
+int memberof_replace_list(Slapi_PBlock *pb, MemberOfConfig *config, char *group_dn, void *txn)
{
struct slapi_entry *pre_e = NULL;
struct slapi_entry *post_e = NULL;
@@ -2080,7 +2091,7 @@ int memberof_replace_list(Slapi_PBlock *pb, MemberOfConfig *config, char *group_
pb, config,
group_dn,
(char*)slapi_value_get_string(
- post_array[post_index]));
+ post_array[post_index]), txn);
post_index++;
}
@@ -2091,7 +2102,7 @@ int memberof_replace_list(Slapi_PBlock *pb, MemberOfConfig *config, char *group_
pb, config,
group_dn,
(char*)slapi_value_get_string(
- pre_array[pre_index]));
+ pre_array[pre_index]), txn);
pre_index++;
}
@@ -2110,7 +2121,7 @@ int memberof_replace_list(Slapi_PBlock *pb, MemberOfConfig *config, char *group_
pb, config,
group_dn,
(char*)slapi_value_get_string(
- pre_array[pre_index]));
+ pre_array[pre_index]), txn);
pre_index++;
}
@@ -2121,7 +2132,7 @@ int memberof_replace_list(Slapi_PBlock *pb, MemberOfConfig *config, char *group_
pb, config,
group_dn,
(char*)slapi_value_get_string(
- post_array[post_index]));
+ post_array[post_index]), txn);
post_index++;
}
@@ -2212,7 +2223,6 @@ void memberof_unlock()
typedef struct _task_data
{
char *dn;
- char *bind_dn;
char *filter_str;
} task_data;
@@ -2226,9 +2236,6 @@ void memberof_fixup_task_thread(void *arg)
/* Fetch our task data from the task */
td = (task_data *)slapi_task_get_data(task);
- /* set bind DN in the thread data */
- slapi_td_set_dn(slapi_ch_strdup(td->bind_dn));
-
slapi_task_begin(task, 1);
slapi_task_log_notice(task, "Memberof task starts (arg: %s) ...\n",
td->filter_str);
@@ -2245,7 +2252,7 @@ void memberof_fixup_task_thread(void *arg)
memberof_lock();
/* do real work */
- rc = memberof_fix_memberof(&configCopy, td->dn, td->filter_str);
+ rc = memberof_fix_memberof(&configCopy, td->dn, td->filter_str, NULL /* no txn? */);
/* release the memberOf operation lock */
memberof_unlock();
@@ -2284,7 +2291,6 @@ int memberof_task_add(Slapi_PBlock *pb, Slapi_Entry *e,
int rv = SLAPI_DSE_CALLBACK_OK;
task_data *mytaskdata = NULL;
Slapi_Task *task = NULL;
- char *bind_dn;
const char *filter;
const char *dn = 0;
@@ -2314,7 +2320,6 @@ int memberof_task_add(Slapi_PBlock *pb, Slapi_Entry *e,
}
/* setup our task data */
- slapi_pblock_get(pb, SLAPI_REQUESTOR_DN, &bind_dn);
mytaskdata = (task_data*)slapi_ch_malloc(sizeof(task_data));
if (mytaskdata == NULL)
{
@@ -2324,7 +2329,6 @@ int memberof_task_add(Slapi_PBlock *pb, Slapi_Entry *e,
}
mytaskdata->dn = slapi_ch_strdup(dn);
mytaskdata->filter_str = slapi_ch_strdup(filter);
- mytaskdata->bind_dn = slapi_ch_strdup(bind_dn);
/* allocate new task now */
task = slapi_new_task(slapi_entry_get_ndn(e));
@@ -2361,7 +2365,6 @@ memberof_task_destructor(Slapi_Task *task)
task_data *mydata = (task_data *)slapi_task_get_data(task);
if (mydata) {
slapi_ch_free_string(&mydata->dn);
- slapi_ch_free_string(&mydata->bind_dn);
slapi_ch_free_string(&mydata->filter_str);
/* Need to cast to avoid a compiler warning */
slapi_ch_free((void **)&mydata);
@@ -2369,9 +2372,10 @@ memberof_task_destructor(Slapi_Task *task)
}
}
-int memberof_fix_memberof(MemberOfConfig *config, char *dn, char *filter_str)
+int memberof_fix_memberof(MemberOfConfig *config, char *dn, char *filter_str, void *txn)
{
int rc = 0;
+ struct fix_memberof_callback_data cb_data = {config, txn};
Slapi_PBlock *search_pb = slapi_pblock_new();
slapi_search_internal_set_pb(search_pb, dn,
@@ -2380,8 +2384,9 @@ int memberof_fix_memberof(MemberOfConfig *config, char *dn, char *filter_str)
memberof_get_plugin_id(),
0);
+ slapi_pblock_set(search_pb, SLAPI_TXN, txn);
rc = slapi_search_internal_callback_pb(search_pb,
- config,
+ &cb_data,
0, memberof_fix_memberof_callback,
0);
@@ -2402,12 +2407,13 @@ int memberof_fix_memberof_callback(Slapi_Entry *e, void *callback_data)
int rc = 0;
char *dn = slapi_entry_get_dn(e);
Slapi_DN *sdn = slapi_entry_get_sdn(e);
- MemberOfConfig *config = (MemberOfConfig *)callback_data;
- memberof_del_dn_data del_data = {0, config->memberof_attr};
+ struct fix_memberof_callback_data *cb_data = (struct fix_memberof_callback_data *)callback_data;
+ MemberOfConfig *config = cb_data->config;
+ memberof_del_dn_data del_data = {0, config->memberof_attr, cb_data->txn};
Slapi_ValueSet *groups = 0;
/* get a list of all of the groups this user belongs to */
- groups = memberof_get_groups(config, dn);
+ groups = memberof_get_groups(config, dn, cb_data->txn);
/* If we found some groups, replace the existing memberOf attribute
* with the found values. */
@@ -2440,6 +2446,7 @@ int memberof_fix_memberof_callback(Slapi_Entry *e, void *callback_data)
mod_pb, sdn, mods, 0, 0,
memberof_get_plugin_id(), 0);
+ slapi_pblock_set(mod_pb, SLAPI_TXN, cb_data->txn);
slapi_modify_internal_pb(mod_pb);
slapi_pblock_get(mod_pb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
diff --git a/ldap/servers/plugins/memberof/memberof.h b/ldap/servers/plugins/memberof/memberof.h
index fdf1253..d509875 100644
--- a/ldap/servers/plugins/memberof/memberof.h
+++ b/ldap/servers/plugins/memberof/memberof.h
@@ -93,6 +93,4 @@ void memberof_rlock_config();
void memberof_wlock_config();
void memberof_unlock_config();
-int g_get_shutdown(); /* declared in proto-slap.h */
-
#endif /* _MEMBEROF_H_ */
diff --git a/ldap/servers/plugins/replication/cl5_api.c b/ldap/servers/plugins/replication/cl5_api.c
index d6ddc37..b10ac9d 100644
--- a/ldap/servers/plugins/replication/cl5_api.c
+++ b/ldap/servers/plugins/replication/cl5_api.c
@@ -257,8 +257,6 @@ typedef struct cl5desc
typedef void (*VFP)(void *);
-int g_get_shutdown(); /* declared in proto-slap.h */
-
/***** Global Variables *****/
static CL5Desc s_cl5Desc;
@@ -3464,7 +3462,7 @@ static void _cl5TrimFile (Object *obj, long *numToTrim)
entry.op = &op;
- while ( !finished && !g_get_shutdown() )
+ while ( !finished && !slapi_is_shutting_down() )
{
it = NULL;
count = 0;
diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c
index db8d5be..293e55a 100644
--- a/ldap/servers/plugins/replication/repl5_replica.c
+++ b/ldap/servers/plugins/replication/repl5_replica.c
@@ -50,9 +50,6 @@
#include "csnpl.h"
#include "cl5_api.h"
-/* from proto-slap.h */
-int g_get_shutdown();
-
#define RUV_SAVE_INTERVAL (30 * 1000) /* 30 seconds */
#define START_UPDATE_DELAY 2 /* 2 second */
@@ -2527,7 +2524,7 @@ process_reap_entry (Slapi_Entry *entry, void *cb_data)
int rc = -1;
/* abort reaping if we've been told to stop or we're shutting down */
- if (*tombstone_reap_stop || g_get_shutdown()) {
+ if (*tombstone_reap_stop || slapi_is_shutting_down()) {
slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name,
"process_reap_entry: the tombstone reap process "
" has been stopped\n");
diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
index 3d2c0c4..d16dc28 100644
--- a/ldap/servers/plugins/replication/repl5_replica_config.c
+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
@@ -86,7 +86,6 @@ static struct berval *create_ruv_payload(char *value);
static int replica_cleanup_task (Object *r, const char *task_name, char *returntext, int apply_mods);
static int replica_task_done(Replica *replica);
static multimaster_mtnode_extension * _replica_config_get_mtnode_ext (const Slapi_Entry *e);
-int g_get_shutdown();
/*
* Note: internal add/modify/delete operations should not be run while
@@ -1324,7 +1323,7 @@ replica_cleanallruv_monitor_thread(void *arg)
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: Waiting for all the replicas to get cleaned...\n");
- while(!g_get_shutdown())
+ while(!slapi_is_shutting_down())
{
DS_Sleep(PR_SecondsToInterval(10));
found = 0;
diff --git a/ldap/servers/plugins/usn/usn_cleanup.c b/ldap/servers/plugins/usn/usn_cleanup.c
index 12a48e3..2038abd 100644
--- a/ldap/servers/plugins/usn/usn_cleanup.c
+++ b/ldap/servers/plugins/usn/usn_cleanup.c
@@ -143,7 +143,7 @@ usn_cleanup_thread(void *arg)
const Slapi_DN *sdn = slapi_entry_get_sdn_const(*ep);
/* check for shutdown */
- if(g_get_shutdown()){
+ if(slapi_is_shutting_down()){
slapi_task_log_notice(task, "USN tombstone cleanup task aborted due to shutdown.");
slapi_task_log_status(task, "USN tombstone cleanup task aborted due to shutdown.");
slapi_log_error(SLAPI_LOG_FATAL, USN_PLUGIN_SUBSYSTEM,
diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c
index 14f8f20..ca21929 100644
--- a/ldap/servers/slapd/libglobs.c
+++ b/ldap/servers/slapd/libglobs.c
@@ -861,6 +861,11 @@ int g_get_shutdown()
return slapd_shutdown;
}
+int slapi_is_shutting_down()
+{
+ return slapd_shutdown;
+}
+
static int cmd_shutdown;
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
index 1b1ed95..81f7c1a 100644
--- a/ldap/servers/slapd/slapi-plugin.h
+++ b/ldap/servers/slapd/slapi-plugin.h
@@ -5273,6 +5273,13 @@ char ** slapi_ch_array_dup( char **array );
void slapi_ch_array_add( char ***array, char *string );
+/**
+ * Check if the server has started shutting down
+ *
+ * \return 1 if the server is shutting down
+ */
+int slapi_is_shutting_down();
+
/*
* checking routines for allocating and freeing memory
*/
commit b3f5a7156e670bf05a83446ac6f1629ce0b9a228
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Mon Jun 18 10:24:50 2012 -0400
Coverity Fix
issue 12777
Bug Description: incorrectly used var r instead of rc
cherry-picked from ef4e3171c308cec2ca36e02cbc16d0f8da056a64
(cherry picked from commit bcfa9e3aa2b8a2add085dae6e3e7416ee863ba80)
diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
index 9b6e75a..3d2c0c4 100644
--- a/ldap/servers/plugins/replication/repl5_replica_config.c
+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
@@ -1277,8 +1277,7 @@ done:
slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: unable to create cleanAllRUV "
"monitoring thread. Aborting task.\n");
}
-
- } else if(r == 0){ /* success */
+ } else if(rc == 0){ /* success */
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: Successfully Finished.\n");
} else {
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: Task failed (%d)\n",rc);
commit 8aba7a1aa1d17c5fc2877d1b16467106d54f54e9
Author: Mark Reynolds <mareynol(a)redhat.com>
Date: Wed May 16 11:28:01 2012 -0400
Ticket 368 - Make the cleanAllRUV task one step
Bug Description: The first version of this fix required a second releaseRUV step.
Fix Description: Created a new "monitoring" thread that checks all the replicas RUV's
to see if the rid was cleaned. Once they are cleaned, we automatically
release the RID for reuse.
I also refined the logging so it easy to track the status of the task.
https://fedorahosted.org/389/ticket/368
reviewed by: richm (Thanks Rich!)
(cherry picked from commit 507b593fa47efeb8a4fc3c2d6b75428e7a69a480)
(cherry picked from commit 1b4b9d53d2cfec92802f6fd4fdbc0101e987c6ee)
diff --git a/ldap/servers/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h
index e315150..6caa332 100644
--- a/ldap/servers/plugins/replication/repl5.h
+++ b/ldap/servers/plugins/replication/repl5.h
@@ -434,6 +434,9 @@ long conn_get_timeout(Repl_Connection *conn);
void conn_set_agmt_changed(Repl_Connection *conn);
ConnResult conn_read_result(Repl_Connection *conn, int *message_id);
ConnResult conn_read_result_ex(Repl_Connection *conn, char **retoidp, struct berval **retdatap, LDAPControl ***returned_controls, int send_msgid, int *resp_msgid, int noblock);
+LDAP * conn_get_ldap(Repl_Connection *conn);
+void conn_lock(Repl_Connection *conn);
+void conn_unlock(Repl_Connection *conn);
/* In repl5_protocol.c */
typedef struct repl_protocol Repl_Protocol;
@@ -593,9 +596,16 @@ void set_released_rid(int rid);
int is_released_rid(int rid);
int is_already_released_rid();
void delete_released_rid();
+void replica_cleanallruv_monitor_thread(void *arg);
#define ALREADY_RELEASED -1
+typedef struct _cleanruv_data
+{
+ Object *repl_obj;
+ ReplicaId rid;
+} cleanruv_data;
+
/* replutil.c */
LDAPControl* create_managedsait_control ();
LDAPControl* create_backend_control(Slapi_DN *sdn);
diff --git a/ldap/servers/plugins/replication/repl5_connection.c b/ldap/servers/plugins/replication/repl5_connection.c
index a074a9f..5fdc601 100644
--- a/ldap/servers/plugins/replication/repl5_connection.c
+++ b/ldap/servers/plugins/replication/repl5_connection.c
@@ -1710,6 +1710,16 @@ conn_get_timeout(Repl_Connection *conn)
return retval;
}
+LDAP *
+conn_get_ldap(Repl_Connection *conn)
+{
+ if(conn){
+ return conn->ld;
+ } else {
+ return NULL;
+ }
+}
+
void conn_set_agmt_changed(Repl_Connection *conn)
{
PR_ASSERT(NULL != conn);
@@ -1908,3 +1918,19 @@ repl5_debug_timeout_callback(time_t when, void *arg)
"repl5_debug_timeout_callback: set debug level to %d at %ld\n",
s_debug_level, when);
}
+
+void
+conn_lock(Repl_Connection *conn)
+{
+ if(conn){
+ PR_Lock(conn->lock);
+ }
+}
+
+void
+conn_unlock(Repl_Connection *conn)
+{
+ if(conn){
+ PR_Unlock(conn->lock);
+ }
+}
diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
index ff3c882..9b6e75a 100644
--- a/ldap/servers/plugins/replication/repl5_replica_config.c
+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
@@ -81,12 +81,12 @@ static int replica_execute_cl2ldif_task (Object *r, char *returntext);
static int replica_execute_ldif2cl_task (Object *r, char *returntext);
static int replica_execute_cleanruv_task (Object *r, ReplicaId rid, char *returntext);
static int replica_execute_cleanall_ruv_task (Object *r, ReplicaId rid, char *returntext);
-static int replica_execute_release_ruv_task(Object *r, ReplicaId rid, char *returntext);
+static int replica_execute_release_ruv_task(Object *r, ReplicaId rid);
static struct berval *create_ruv_payload(char *value);
static int replica_cleanup_task (Object *r, const char *task_name, char *returntext, int apply_mods);
static int replica_task_done(Replica *replica);
-
static multimaster_mtnode_extension * _replica_config_get_mtnode_ext (const Slapi_Entry *e);
+int g_get_shutdown();
/*
* Note: internal add/modify/delete operations should not be run while
@@ -862,21 +862,6 @@ static int replica_execute_task (Object *r, const char *task_name, char *returnt
else
return LDAP_SUCCESS;
}
- else if (strncasecmp (task_name, RELEASERUV, RELEASERUVLEN) == 0)
- {
- int temprid = atoi(&(task_name[RELEASERUVLEN]));
- if (temprid <= 0 || temprid >= READ_ONLY_REPLICA_ID){
- PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Invalid replica id for task - %s", task_name);
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,"replica_execute_task: %s\n", returntext);
- return LDAP_OPERATIONS_ERROR;
- }
- if (apply_mods)
- {
- return replica_execute_release_ruv_task(r, (ReplicaId)temprid, returntext);
- }
- else
- return LDAP_SUCCESS;
- }
else
{
PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "unsupported replica task - %s", task_name);
@@ -1180,7 +1165,6 @@ replica_execute_cleanruv_task (Object *r, ReplicaId rid, char *returntext /* not
* Clean the changelog RUV's, and set the rids
*/
cl5CleanRUV(rid);
- set_cleaned_rid(rid);
delete_released_rid();
if (rc != RUV_SUCCESS){
@@ -1194,19 +1178,22 @@ replica_execute_cleanruv_task (Object *r, ReplicaId rid, char *returntext /* not
static int
replica_execute_cleanall_ruv_task (Object *r, ReplicaId rid, char *returntext)
{
+ PRThread *thread = NULL;
Repl_Connection *conn;
Replica *replica = (Replica*)object_get_data (r);
Object *agmt_obj;
Repl_Agmt *agmt;
ConnResult crc;
+ cleanruv_data *data = NULL;
const Slapi_DN *dn = NULL;
struct berval *payload = NULL;
char *ridstr = NULL;
int send_msgid = 0;
+ int agmt_count = 0;
int rc = 0;
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "cleanAllRUV_task: cleaning rid (%d)...\n",(int)rid);
-
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: cleaning rid (%d)...\n",(int)rid);
+ set_cleaned_rid(rid);
/*
* Create payload
*/
@@ -1244,8 +1231,9 @@ replica_execute_cleanall_ruv_task (Object *r, ReplicaId rid, char *returntext)
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: failed to send "
"cleanruv extended op to repl agmt (%s), error %d\n", slapi_sdn_get_dn(dn), crc);
} else {
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "cleanAllRUV_task: successfully sent "
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: successfully sent "
"cleanruv extended op to (%s)\n",slapi_sdn_get_dn(dn));
+ agmt_count++;
}
conn_start_linger(conn);
}
@@ -1269,17 +1257,218 @@ done:
*/
replica_execute_cleanruv_task (r, rid, returntext);
- if(rc == 0){
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "cleanAllRUV_task: operation successful\n");
+ if(rc == 0 && agmt_count > 0){ /* success, but we need to check our replicas */
+ /*
+ * Launch the cleanruv monitoring thread. Once all the replicas are cleaned it will release the rid
+ */
+ data = (cleanruv_data*)slapi_ch_calloc(1, sizeof(cleanruv_data));
+ if (data == NULL) {
+ slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: failed to allocate "
+ "cleanruv_data. Aborting task.\n");
+ return -1;
+ }
+ data->repl_obj = r;
+ data->rid = rid;
+
+ thread = PR_CreateThread(PR_USER_THREAD, replica_cleanallruv_monitor_thread,
+ (void *)data, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
+ PR_UNJOINABLE_THREAD, SLAPD_DEFAULT_THREAD_STACKSIZE);
+ if (thread == NULL) {
+ slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: unable to create cleanAllRUV "
+ "monitoring thread. Aborting task.\n");
+ }
+
+ } else if(r == 0){ /* success */
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: Successfully Finished.\n");
} else {
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: operation failed (%d)\n",rc);
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: Task failed (%d)\n",rc);
}
return rc;
}
+/*
+ * After all the cleanAllRUV extended ops have been sent, we need to monitoring those replicas'
+ * RUVs. Once the rid is cleaned, then we need to release it, and push this "release"
+ * to the other replicas
+ */
+void
+replica_cleanallruv_monitor_thread(void *arg)
+{
+ Object *agmt_obj;
+ LDAP *ld;
+ Repl_Connection *conn;
+ Repl_Agmt *agmt;
+ Replica *replica;;
+ cleanruv_data *data = arg;
+ LDAPMessage *result, *entry;
+ BerElement *ber;
+ time_t start_time;
+ struct berval **vals;
+ char *rid_text;
+ char *attrs[2];
+ char *attr;
+ int replicas_cleaned = 0;
+ int found = 0;
+ int crc;
+ int rc = 0;
+ int i;
+
+ /*
+ * Initialize our settings
+ */
+ attrs[0] = "nsds50ruv";
+ attrs[1] = NULL;
+ rid_text = slapi_ch_smprintf("{replica %d ldap", data->rid);
+ replica = (Replica*)object_get_data (data->repl_obj);
+ start_time = current_time();
+
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: Waiting for all the replicas to get cleaned...\n");
+
+ while(!g_get_shutdown())
+ {
+ DS_Sleep(PR_SecondsToInterval(10));
+ found = 0;
+ agmt_obj = agmtlist_get_first_agreement_for_replica (replica);
+ 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;
+ }
+ /*
+ * Get the replication connection
+ */
+ conn = (Repl_Connection *)agmt_get_connection(agmt);
+ crc = conn_connect(conn);
+ if (CONN_OPERATION_FAILED == crc ){
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: monitor thread failed to connect "
+ "to repl agreement connection (%s), error %d\n","", ACQUIRE_TRANSIENT_ERROR);
+ continue;
+ } else if (CONN_SSL_NOT_ENABLED == crc){
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: monitor thread failed to acquire "
+ "repl agmt connection (%s), error %d\n","", ACQUIRE_FATAL_ERROR);
+ continue;
+ }
+ /*
+ * Get the LDAP connection handle from the conn
+ */
+ ld = conn_get_ldap(conn);
+ if(ld == NULL){
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: monitor thread failed to get LDAP "
+ "handle from the replication agmt (%s). Moving on to the next agmt.\n",agmt_get_long_name(agmt));
+ continue;
+ }
+ /*
+ * Search this replica for its tombstone/ruv entry
+ */
+ conn_cancel_linger(conn);
+ conn_lock(conn);
+ rc = ldap_search_ext_s(ld, slapi_sdn_get_dn(agmt_get_replarea(agmt)), LDAP_SCOPE_SUBTREE,
+ "(&(nsuniqueid=ffffffff-ffffffff-ffffffff-ffffffff)(objectclass=nstombstone))",
+ attrs, 0, NULL, NULL, NULL, 0, &result);
+ if(rc != LDAP_SUCCESS){
+ /*
+ * Couldn't contact ldap server, what should we do?
+ *
+ * Skip it and move on! It's the admin's job to make sure all the replicas are up and running
+ */
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: monitor thread failed to contact "
+ "agmt (%s), moving on to the next agmt.\n", agmt_get_long_name(agmt));
+ conn_unlock(conn);
+ conn_start_linger(conn);
+ continue;
+ }
+ /*
+ * There is only one entry. Check its "nsds50ruv" for our cleaned rid
+ */
+ entry = ldap_first_entry( ld, result );
+ if ( entry != NULL ) {
+ for ( attr = ldap_first_attribute( ld, entry, &ber ); attr != NULL; attr = ldap_next_attribute( ld, entry, ber ) ){
+ /* make sure the attribute is nsds50ruv */
+ if(strcasecmp(attr,"nsds50ruv") != 0){
+ continue;
+ }
+ if ((vals = ldap_get_values_len( ld, entry, attr)) != NULL ) {
+ for ( i = 0; vals[i] && vals[i]->bv_val; i++ ) {
+ /* look for this replica */
+ if(strstr(rid_text, vals[i]->bv_val)){
+ /* rid has not been cleaned yet, start over */
+ found = 1;
+ break;
+ }
+ }
+ ldap_value_free_len(vals);
+ }
+ ldap_memfree( attr );
+ }
+ if ( ber != NULL ) {
+ ber_free( ber, 0 );
+ }
+ }
+ ldap_msgfree( result );
+ /*
+ * Unlock the connection, and start the linger timer
+ */
+ conn_unlock(conn);
+ conn_start_linger(conn);
+
+ if(found){
+ /*
+ * If we've been trying to clean these replicas for over an hour, just quit
+ */
+ if( (current_time() - start_time) > 3600){
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: timed out checking if replicas have "
+ "been cleaned. The rid has not been released, you need to rerun the task.\n");
+ goto done;
+ }
+ /*
+ * a rid has not been cleaned yet, go back to sleep and check them again
+ */
+ break;
+ }
+
+ agmt_obj = agmtlist_get_next_agreement_for_replica (replica, agmt_obj);
+ }
+ if(!found){
+ /*
+ * The replicas have been cleaned! Next, release the rid
+ */
+ replicas_cleaned = 1;
+ break;
+ }
+ } /* while */
+
+ /*
+ * If the replicas are cleaned, release the rid
+ */
+ if(replicas_cleaned){
+ rc = replica_execute_release_ruv_task(data->repl_obj, data->rid);
+ if(rc == 0){
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: Successfully Finished. All active "
+ "replicas have been cleaned.\n");
+ } else {
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: Failed: Replica ID was not released (%d) "
+ "You will need to rerun the task.\n", rc);
+ }
+ } else {
+ /*
+ * Shutdown
+ */
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: slapd shutting down, you will need to rerun the task.\n");
+ }
+
+done:
+ slapi_ch_free((void **)&rid_text);
+ slapi_ch_free((void **)&data);
+}
+
+/*
+ * This function releases the cleaned rid so that it can be reused.
+ * We send this operation to all the known active replicas.
+ */
static int
-replica_execute_release_ruv_task(Object *r, ReplicaId rid, char *returntext)
+replica_execute_release_ruv_task(Object *r, ReplicaId rid)
{
Repl_Connection *conn;
Replica *replica = (Replica*)object_get_data (r);
@@ -1292,7 +1481,7 @@ replica_execute_release_ruv_task(Object *r, ReplicaId rid, char *returntext)
int send_msgid = 0;
int rc = 0;
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "releaseRUV_task: releasing rid (%d)...\n", rid);
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: releasing rid (%d)...\n", rid);
/*
* Set the released rid, and trigger cl trimmming
@@ -1334,18 +1523,18 @@ replica_execute_release_ruv_task(Object *r, ReplicaId rid, char *returntext)
conn_cancel_linger(conn);
crc = conn_send_extended_operation(conn, REPL_RELEASERUV_OID, payload, NULL, &send_msgid);
if (CONN_OPERATION_SUCCESS != crc){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "releaseRUV_task: failed to send "
- "releaseruv extended op to repl agmt (%s), error %d\n", slapi_sdn_get_dn(dn), crc);
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: failed to send "
+ "releaseRUV extended op to repl agmt (%s), error %d\n", slapi_sdn_get_dn(dn), crc);
rc = LDAP_OPERATIONS_ERROR;
} else {
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "releaseRUV_task: successfully sent "
- "extended op to (%s)\n",slapi_sdn_get_dn(dn));
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: successfully sent "
+ "releaseRUV extended op to (%s)\n",slapi_sdn_get_dn(dn));
}
conn_start_linger(conn);
}
if(crc){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "releaseRUV_task: replica (%s) has not "
- "been cleaned. You will need to rerun the RELEASERUV task on this replica\n",
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: replica (%s) has not "
+ "been released. You will need to rerun the task\n",
slapi_sdn_get_dn(dn));
rc = crc;
}
@@ -1359,9 +1548,9 @@ done:
if(rc == 0){
set_released_rid(ALREADY_RELEASED);
delete_cleaned_rid();
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "releaseRUV_task: Successfully released rid (%d)\n", rid);
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: Successfully released rid (%d)\n", rid);
} else {
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "releaseRUV_task: Failed to release rid (%d), error (%d)\n", rid, rc);
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: Failed to release rid (%d), error (%d)\n", rid, rc);
}
if(payload)
diff --git a/ldap/servers/plugins/replication/repl_extop.c b/ldap/servers/plugins/replication/repl_extop.c
index eba480f..63e2bb9 100644
--- a/ldap/servers/plugins/replication/repl_extop.c
+++ b/ldap/servers/plugins/replication/repl_extop.c
@@ -1388,18 +1388,21 @@ free_and_return:
int
multimaster_extop_cleanruv(Slapi_PBlock *pb){
multimaster_mtnode_extension *mtnode_ext;
+ PRThread *thread = NULL;
Repl_Connection *conn;
const Slapi_DN *dn;
Replica *r = NULL;
Object *agmt_obj;
Repl_Agmt *agmt;
ConnResult crc;
+ cleanruv_data *data = NULL;
struct berval *extop_value;
char *extop_oid;
char *repl_root;
char *payload = NULL;
char *iter;
int send_msgid = 0;
+ int agmt_count = 0;
int rid = 0;
int rc = 0;
@@ -1411,41 +1414,39 @@ multimaster_extop_cleanruv(Slapi_PBlock *pb){
/* something is wrong, error out */
return -1;
}
-
/*
* Extract the rid and repl_root from the payload
*/
if(decode_cleanruv_payload(extop_value, &payload)){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanruv_extop: failed to decode payload. Aborting ext op\n");
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: failed to decode payload. Aborting ext op\n");
return -1;
}
rid = atoi(ldap_utf8strtok_r(payload, ":", &iter));
repl_root = ldap_utf8strtok_r(iter, ":", &iter);
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "cleanruv_extop: cleaning rid (%d)...\n",rid);
-
/*
* If we already cleaned this server, just return success
*/
if(is_cleaned_rid(rid)){
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "cleanruv_extop: rid (%d) has already been cleaned, skipping\n",rid);
+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "cleanAllRUV_extop: rid (%d) has already been cleaned, skipping\n",rid);
return rc;
} else {
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "cleanruv_extop: cleaning rid (%d)...\n", rid);
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: cleaning rid (%d)...\n", rid);
+ set_cleaned_rid(rid);
}
/*
* Get the node, so we can get the replica and its agreements
*/
if((mtnode_ext = replica_config_get_mtnode_by_dn(repl_root)) == NULL){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanruv_extop: failed to get replication node "
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: failed to get replication node "
"from (%s), aborting operation\n", repl_root);
return -1;
}
if (mtnode_ext->replica)
object_acquire (mtnode_ext->replica);
if (mtnode_ext->replica == NULL){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanruv_extop: replica is missing from (%s), "
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: replica is missing from (%s), "
"aborting operation\n",repl_root);
rc = LDAP_OPERATIONS_ERROR;
goto free_and_return;
@@ -1462,36 +1463,37 @@ multimaster_extop_cleanruv(Slapi_PBlock *pb){
conn = (Repl_Connection *)agmt_get_connection(agmt);
if(conn == NULL){
/* no connection for this agreement, move on to the next agmt */
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanruv_extop: the replica (%s), is "
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: the replica (%s), is "
"missing the connection. This replica will not be cleaned.\n", slapi_sdn_get_dn(dn));
agmt_obj = agmtlist_get_next_agreement_for_replica (r, agmt_obj);
continue;
}
crc = conn_connect(conn);
if (CONN_OPERATION_FAILED == crc ){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanruv_extop: failed to connect "
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: failed to connect "
"to repl agreement connection (%s), error %d\n",slapi_sdn_get_dn(dn), ACQUIRE_TRANSIENT_ERROR);
rc = LDAP_OPERATIONS_ERROR;
} else if (CONN_SSL_NOT_ENABLED == crc){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanruv_extop: failed to acquire "
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: failed to acquire "
"repl agmt connection (%s), error %d\n",slapi_sdn_get_dn(dn), ACQUIRE_FATAL_ERROR);
rc = LDAP_OPERATIONS_ERROR;
} else {
conn_cancel_linger(conn);
crc = conn_send_extended_operation(conn, REPL_CLEANRUV_OID, extop_value, NULL, &send_msgid);
if (CONN_OPERATION_SUCCESS != crc){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanruv_extop: failed to send "
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: failed to send "
"clean_ruv extended op to repl agmt (%s), error %d\n", slapi_sdn_get_dn(dn), crc);
rc = LDAP_OPERATIONS_ERROR;
} else {
/* success */
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "cleanruv_extop: successfully sent "
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: successfully sent "
"extended op to (%s)\n",slapi_sdn_get_dn(dn) );
+ agmt_count++;
}
conn_start_linger(conn);
}
if(crc != CONN_OPERATION_SUCCESS){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanruv_extop: replica (%s) has not "
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: replica (%s) has not "
"been cleaned. You will need to rerun the CLEANALLRUV task on this replica\n",
slapi_sdn_get_dn(dn) );
rc = LDAP_OPERATIONS_ERROR;
@@ -1504,10 +1506,30 @@ multimaster_extop_cleanruv(Slapi_PBlock *pb){
free_and_return:
- if(rc == 0){
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "cleanruv_extop: cleaned rid (%d)\n", rid);
+ if(rc == 0 && agmt_count > 0){
+ /*
+ * Launch the cleanruv monitoring thread. Once all the replicas are cleaned it will release the rid
+ */
+ data = (cleanruv_data*)slapi_ch_calloc(1, sizeof(cleanruv_data));
+ if (data == NULL) {
+ slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: failed to allocate "
+ "cleanruv_Data\n");
+ return -1;
+ }
+ data->repl_obj = mtnode_ext->replica;
+ data->rid = rid;
+
+ thread = PR_CreateThread(PR_USER_THREAD, replica_cleanallruv_monitor_thread,
+ (void *)data, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
+ PR_UNJOINABLE_THREAD, SLAPD_DEFAULT_THREAD_STACKSIZE);
+ if (thread == NULL) {
+ slapi_log_error( SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: unable to create cleanAllRUV "
+ "monitoring thread. Aborting task.\n");
+ }
+ } else if (rc == 0){
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: Successfully Finished.\n");
} else {
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanruv_extop: failed to clean rid (%d), error (%d)\n",rid, rc);
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanALLRUV_extop: failed to clean rid (%d), error (%d)\n",rid, rc);
}
if (mtnode_ext->replica)
@@ -1554,34 +1576,34 @@ multimaster_extop_releaseruv(Slapi_PBlock *pb){
}
if(decode_cleanruv_payload(extop_value, &payload)){
- slapi_log_error(SLAPI_LOG_FATAL,repl_plugin_name, "releaseruv_extop: failed to decode payload, aborting ext op\n");
+ slapi_log_error(SLAPI_LOG_FATAL,repl_plugin_name, "releaseRUV_extop: failed to decode payload, aborting ext op.\n");
return -1;
}
rid = atoi(ldap_utf8strtok_r(payload, ":", &iter));
repl_root = ldap_utf8strtok_r(iter, ":", &iter);
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "releaseruv_extop: releasing rid (%d)...\n",rid);
/*
* If we already released this ruv, just return.
*/
if(is_released_rid(rid) || is_already_released_rid()){
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "releaseruv_extop: rid (%d) has already been released, skipping\n",rid);
+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "cleanAllRUV_extop: rid (%d) has already been released, skipping.\n",rid);
return 0;
} else {
/* set the released rid, and trigger trimming */
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: releasing rid (%d)...\n", rid);
set_released_rid((int)rid);
trigger_cl_trimming();
}
if((mtnode_ext = replica_config_get_mtnode_by_dn(repl_root)) == NULL){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "releaseruv_extop: failed to get node "
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "releaseRUV_extop: failed to get node "
"from replication root dn(%s), aborting operation.\n", repl_root);
return -1;
}
if (mtnode_ext->replica)
object_acquire (mtnode_ext->replica);
if (mtnode_ext->replica == NULL){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "releaseruv_extop: replica is missing from (%s), "
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "releaseRUV_extop: replica is missing from (%s), "
"aborting operation.\n", repl_root);
rc = LDAP_OPERATIONS_ERROR;
goto free_and_return;
@@ -1598,38 +1620,38 @@ multimaster_extop_releaseruv(Slapi_PBlock *pb){
conn = (Repl_Connection *)agmt_get_connection(agmt);
if(conn == NULL){
/* no connection for this agreement, log error, and move on */
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "releaseruv_extop: the replica (%s), is "
- "missing the connection. This replica will not be cleaned.\n", slapi_sdn_get_dn(dn));
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: the replica (%s), is "
+ "missing the connection. This replica will not be released.\n", slapi_sdn_get_dn(dn));
agmt_obj = agmtlist_get_next_agreement_for_replica (r, agmt_obj);
continue;
}
crc = conn_connect(conn);
if (CONN_OPERATION_FAILED == crc ){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "releaseruv_extop: failed to connect "
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "releaseRUV_extop: failed to connect "
"to repl agreement connection (%s), error %d\n",slapi_sdn_get_dn(dn), ACQUIRE_TRANSIENT_ERROR);
rc = LDAP_OPERATIONS_ERROR;
} else if (CONN_SSL_NOT_ENABLED == crc){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "releaseruv_extop: failed to acquire "
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "releaseRUV_extop: failed to acquire "
"repl agmt connection (%s), error %d\n",slapi_sdn_get_dn(dn), ACQUIRE_FATAL_ERROR);
rc = LDAP_OPERATIONS_ERROR;
} else {
conn_cancel_linger(conn);
crc = conn_send_extended_operation(conn, REPL_RELEASERUV_OID, extop_value, NULL, &send_msgid);
if (CONN_OPERATION_SUCCESS != crc){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "releaseruv_extop: failed to send "
- "releaseruv extended op to repl agmt (%s), error %d\n", slapi_sdn_get_dn(dn), crc);
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: failed to send "
+ "releaseRUV extended op to repl agmt (%s), error %d\n", slapi_sdn_get_dn(dn), crc);
rc = LDAP_OPERATIONS_ERROR;
} else {
/* success */
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "releaseruv_extop: successfully sent "
- "extended op to (%s)\n",slapi_sdn_get_dn(dn) );
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: successfully sent "
+ "releaseRUV extended op to (%s)\n",slapi_sdn_get_dn(dn) );
rc = 0;
}
conn_start_linger(conn);
}
if(crc){
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "releaseruv_extop: replica (%s) has not "
- "been cleaned. You will need to rerun the RELEASERUV task on this replica\n",
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: replica (%s) has not "
+ "been released. You will need to rerun the task.\n",
slapi_sdn_get_dn(dn) );
}
agmt_obj = agmtlist_get_next_agreement_for_replica (r, agmt_obj);
@@ -1642,9 +1664,10 @@ free_and_return:
if(rc == 0){
set_released_rid(ALREADY_RELEASED);
delete_cleaned_rid();
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "releaseruv_extop: released rid (%d) successfully\n", rid);
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: Successfully released rid (%d)\n", rid);
} else {
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "releaseruv_extop: failed to release rid(%d), error (%d), please retry the task\n",rid, rc);
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_extop: Failed to release rid(%d), error (%d), "
+ "please retry the task.\n",rid, rc);
}
if(mtnode_ext->replica)
commit 53e6744b3ac203508750c7c75c0bfce9394e1b71
Author: Mark Reynolds <mareynol(a)redhat.com>
Date: Wed May 9 15:29:51 2012 -0400
Ticket #337 - Improve CLEANRUV task
Bug Description: After restarting a replica, regardless if it was cleaned, would trigger
ruv_compare_ruv errors at startup.
Fix Description: There were simple typos in the fix when checking if the rid was already cleaned.
(cherry picked from commit da3f9226ca20ab6b9c71ea75080e6f0be9220de6)
diff --git a/ldap/servers/plugins/replication/cl5_api.c b/ldap/servers/plugins/replication/cl5_api.c
index 51accab..d6ddc37 100644
--- a/ldap/servers/plugins/replication/cl5_api.c
+++ b/ldap/servers/plugins/replication/cl5_api.c
@@ -3891,7 +3891,7 @@ static int _cl5UpdateRUV (Object *obj, CSN *csn, PRBool newReplica, PRBool purge
{
if (ruv_contains_replica (file->purgeRUV, rid))
return CL5_SUCCESS;
- else if(is_cleaned_rid(rid))
+ else if(!is_cleaned_rid(rid))
{
/* if the replica is not part of the purgeRUV yet, add it unless it's from a cleaned rid */
ruv_add_replica (file->purgeRUV, rid, multimaster_get_local_purl());
@@ -3901,8 +3901,8 @@ static int _cl5UpdateRUV (Object *obj, CSN *csn, PRBool newReplica, PRBool purge
{
if (purge)
rc = ruv_set_csns(file->purgeRUV, csn, NULL);
- else if(is_cleaned_rid(rid)){
- /* don't update maxRuv is if rid is cleaned */
+ else if(!is_cleaned_rid(rid)){
+ /* don't update maxRuv if rid is cleaned */
rc = ruv_set_csns(file->maxRUV, csn, NULL);
}
}
diff --git a/ldap/servers/plugins/replication/repl_extop.c b/ldap/servers/plugins/replication/repl_extop.c
index 7e2ebbd..eba480f 100644
--- a/ldap/servers/plugins/replication/repl_extop.c
+++ b/ldap/servers/plugins/replication/repl_extop.c
@@ -1542,7 +1542,7 @@ multimaster_extop_releaseruv(Slapi_PBlock *pb){
char *iter;
int send_msgid = 0;
int rid = 0;
- int rc = -1;
+ int rc = 0;
slapi_pblock_get(pb, SLAPI_EXT_OP_REQ_OID, &extop_oid);
slapi_pblock_get(pb, SLAPI_EXT_OP_REQ_VALUE, &extop_value);
commit a2f05e023bbd7023fd00b4c6dc557eab84e4ab8d
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Wed May 2 09:17:52 2012 -0600
Ticket #353 - coverity 12625-12629 - leaks, dead code, unchecked return
https://fedorahosted.org/389/ticket/353
Resolves: Ticket #353
Bug Description: coverity 12625-12629 - leaks, dead code, unchecked return
Reviewed by: mreynolds (Thanks!)
Branch: master
Fix Description: In addition to the errors fixed, I added the use of
slapi_entry_attr_get_bool() so that values of true, yes, etc. could
be used in addition to on/off.
Platforms tested: RHEL6 x86_64
Flag Day: no
Doc impact: no
Cherry-picked from fc6a0cd3362dfdb73a43d3b52ae42a48678c2a24
- did not pick memberof changes
- removed replica enabled code
diff --git a/ldap/servers/plugins/memberof/memberof.c b/ldap/servers/plugins/memberof/memberof.c
index 5100b1a..229b962 100644
--- a/ldap/servers/plugins/memberof/memberof.c
+++ b/ldap/servers/plugins/memberof/memberof.c
@@ -67,10 +67,8 @@
#endif
#include "slapi-plugin.h"
-
#include "string.h"
#include "nspr.h"
-
#include "memberof.h"
static Slapi_PluginDesc pdesc = { "memberof", VENDOR,
@@ -92,7 +90,6 @@ typedef struct _memberof_get_groups_data
MemberOfConfig *config;
Slapi_Value *memberdn_val;
Slapi_ValueSet **groupvals;
- void *txn;
} memberof_get_groups_data;
/*** function prototypes ***/
@@ -113,55 +110,55 @@ static int memberof_postop_close(Slapi_PBlock *pb);
static int memberof_oktodo(Slapi_PBlock *pb);
static char *memberof_getdn(Slapi_PBlock *pb);
static int memberof_modop_one(Slapi_PBlock *pb, MemberOfConfig *config, int mod_op,
- char *op_this, char *op_to, void *txn);
+ char *op_this, char *op_to);
static int memberof_modop_one_r(Slapi_PBlock *pb, MemberOfConfig *config, int mod_op,
- char *group_dn, char *op_this, char *op_to, memberofstringll *stack, void *txn);
+ char *group_dn, char *op_this, char *op_to, memberofstringll *stack);
static int memberof_add_one(Slapi_PBlock *pb, MemberOfConfig *config, char *addthis,
- char *addto, void *txn);
+ char *addto);
static int memberof_del_one(Slapi_PBlock *pb, MemberOfConfig *config, char *delthis,
- char *delfrom, void *txn);
+ char *delfrom);
static int memberof_mod_smod_list(Slapi_PBlock *pb, MemberOfConfig *config, int mod,
- char *groupdn, Slapi_Mod *smod, void *txn);
+ char *groupdn, Slapi_Mod *smod);
static int memberof_add_smod_list(Slapi_PBlock *pb, MemberOfConfig *config,
- char *groupdn, Slapi_Mod *smod, void *txn);
+ char *groupdn, Slapi_Mod *smod);
static int memberof_del_smod_list(Slapi_PBlock *pb, MemberOfConfig *config,
- char *groupdn, Slapi_Mod *smod, void *txn);
+ char *groupdn, Slapi_Mod *smod);
static int memberof_mod_attr_list(Slapi_PBlock *pb, MemberOfConfig *config, int mod,
- char *groupdn, Slapi_Attr *attr, void *txn);
+ char *groupdn, Slapi_Attr *attr);
static int memberof_mod_attr_list_r(Slapi_PBlock *pb, MemberOfConfig *config,
- int mod, char *group_dn, char *op_this, Slapi_Attr *attr, memberofstringll *stack, void *txn);
+ int mod, char *group_dn, char *op_this, Slapi_Attr *attr, memberofstringll *stack);
static int memberof_add_attr_list(Slapi_PBlock *pb, MemberOfConfig *config,
- char *groupdn, Slapi_Attr *attr, void *txn);
+ char *groupdn, Slapi_Attr *attr);
static int memberof_del_attr_list(Slapi_PBlock *pb, MemberOfConfig *config,
- char *groupdn, Slapi_Attr *attr, void *txn);
+ char *groupdn, Slapi_Attr *attr);
static int memberof_moddn_attr_list(Slapi_PBlock *pb, MemberOfConfig *config,
- char *pre_dn, char *post_dn, Slapi_Attr *attr, void *txn);
-static int memberof_replace_list(Slapi_PBlock *pb, MemberOfConfig *config, char *group_dn, void *txn);
+ char *pre_dn, char *post_dn, Slapi_Attr *attr);
+static int memberof_replace_list(Slapi_PBlock *pb, MemberOfConfig *config, char *group_dn);
static void memberof_set_plugin_id(void * plugin_id);
static void *memberof_get_plugin_id();
static int memberof_compare(MemberOfConfig *config, const void *a, const void *b);
static int memberof_qsort_compare(const void *a, const void *b);
static void memberof_load_array(Slapi_Value **array, Slapi_Attr *attr);
-static void memberof_del_dn_from_groups(Slapi_PBlock *pb, MemberOfConfig *config, char *dn, void *txn);
+static void memberof_del_dn_from_groups(Slapi_PBlock *pb, MemberOfConfig *config, char *dn);
static int memberof_call_foreach_dn(Slapi_PBlock *pb, char *dn,
- char **types, plugin_search_entry_callback callback, void *callback_data, void *txn);
+ char **types, plugin_search_entry_callback callback, void *callback_data);
static int memberof_is_direct_member(MemberOfConfig *config, Slapi_Value *groupdn,
- Slapi_Value *memberdn, void *txn);
+ Slapi_Value *memberdn);
static int memberof_is_grouping_attr(char *type, MemberOfConfig *config);
-static Slapi_ValueSet *memberof_get_groups(MemberOfConfig *config, char *memberdn, void *txn);
+static Slapi_ValueSet *memberof_get_groups(MemberOfConfig *config, char *memberdn);
static int memberof_get_groups_r(MemberOfConfig *config, char *memberdn,
- memberof_get_groups_data *data, void *txn);
+ memberof_get_groups_data *data);
static int memberof_get_groups_callback(Slapi_Entry *e, void *callback_data);
static int memberof_test_membership(Slapi_PBlock *pb, MemberOfConfig *config,
- char *group_dn, void *txn);
+ char *group_dn);
static int memberof_test_membership_callback(Slapi_Entry *e, void *callback_data);
static int memberof_del_dn_type_callback(Slapi_Entry *e, void *callback_data);
static int memberof_replace_dn_type_callback(Slapi_Entry *e, void *callback_data);
static void memberof_replace_dn_from_groups(Slapi_PBlock *pb, MemberOfConfig *config,
- char *pre_dn, char *post_dn, void *txn);
+ char *pre_dn, char *post_dn);
static int memberof_modop_one_replace_r(Slapi_PBlock *pb, MemberOfConfig *config,
int mod_op, char *group_dn, char *op_this, char *replace_with, char *op_to,
- memberofstringll *stack, void *txn);
+ memberofstringll *stack);
static int memberof_task_add(Slapi_PBlock *pb, Slapi_Entry *e,
Slapi_Entry *eAfter, int *returncode, char *returntext,
void *arg);
@@ -169,7 +166,7 @@ static void memberof_task_destructor(Slapi_Task *task);
static const char *fetch_attr(Slapi_Entry *e, const char *attrname,
const char *default_val);
static void memberof_fixup_task_thread(void *arg);
-static int memberof_fix_memberof(MemberOfConfig *config, char *dn, char *filter_str, void *txn);
+static int memberof_fix_memberof(MemberOfConfig *config, char *dn, char *filter_str);
static int memberof_fix_memberof_callback(Slapi_Entry *e, void *callback_data);
@@ -399,10 +396,8 @@ int memberof_postop_del(Slapi_PBlock *pb)
if(memberof_oktodo(pb) && (normdn = memberof_getdn(pb)))
{
struct slapi_entry *e = NULL;
- void *txn = NULL;
slapi_pblock_get( pb, SLAPI_ENTRY_PRE_OP, &e );
- slapi_pblock_get( pb, SLAPI_TXN, &txn );
/* We need to get the config lock first. Trying to get the
* config lock after we already hold the op lock can cause
@@ -418,7 +413,7 @@ int memberof_postop_del(Slapi_PBlock *pb)
/* remove this DN from the
* membership lists of groups
*/
- memberof_del_dn_from_groups(pb, &configCopy, normdn, txn);
+ memberof_del_dn_from_groups(pb, &configCopy, normdn);
/* is the entry of interest as a group? */
if(e && configCopy.group_filter && !slapi_filter_test_simple(e, configCopy.group_filter))
@@ -431,7 +426,7 @@ int memberof_postop_del(Slapi_PBlock *pb)
{
if (0 == slapi_entry_attr_find(e, configCopy.groupattrs[i], &attr))
{
- memberof_del_attr_list(pb, &configCopy, normdn, attr, txn);
+ memberof_del_attr_list(pb, &configCopy, normdn, attr);
}
}
}
@@ -450,12 +445,11 @@ typedef struct _memberof_del_dn_data
{
char *dn;
char *type;
- void *txn;
} memberof_del_dn_data;
/* Deletes a member dn from all groups that refer to it. */
static void
-memberof_del_dn_from_groups(Slapi_PBlock *pb, MemberOfConfig *config, char *dn, void *txn)
+memberof_del_dn_from_groups(Slapi_PBlock *pb, MemberOfConfig *config, char *dn)
{
int i = 0;
char *groupattrs[2] = {0, 0};
@@ -465,12 +459,12 @@ memberof_del_dn_from_groups(Slapi_PBlock *pb, MemberOfConfig *config, char *dn,
* same grouping attribute. */
for (i = 0; config->groupattrs[i]; i++)
{
- memberof_del_dn_data data = {dn, config->groupattrs[i], txn};
+ memberof_del_dn_data data = {dn, config->groupattrs[i]};
groupattrs[0] = config->groupattrs[i];
memberof_call_foreach_dn(pb, dn, groupattrs,
- memberof_del_dn_type_callback, &data, txn);
+ memberof_del_dn_type_callback, &data);
}
}
@@ -499,7 +493,6 @@ int memberof_del_dn_type_callback(Slapi_Entry *e, void *callback_data)
mods, 0, 0,
memberof_get_plugin_id(), 0);
- slapi_pblock_set(mod_pb, SLAPI_TXN, ((memberof_del_dn_data *)callback_data)->txn);
slapi_modify_internal_pb(mod_pb);
slapi_pblock_get(mod_pb,
@@ -512,95 +505,101 @@ int memberof_del_dn_type_callback(Slapi_Entry *e, void *callback_data)
}
/*
- * Does a callback search of "type=dn" under the db suffix that "dn" is in.
- * If "dn" is a user, you'd want "type" to be "member". If "dn" is a group,
- * you could want type to be either "member" or "memberOf" depending on the
- * case.
+ * Does a callback search of "type=dn" under the db suffix that "dn" is in,
+ * unless all_backends is set, then we look at all the backends. If "dn"
+ * is a user, you'd want "type" to be "member". If "dn" is a group, you
+ * could want type to be either "member" or "memberOf" depending on the case.
*/
int memberof_call_foreach_dn(Slapi_PBlock *pb, char *dn,
- char **types, plugin_search_entry_callback callback, void *callback_data, void *txn)
+ char **types, plugin_search_entry_callback callback, void *callback_data)
{
- int rc = 0;
Slapi_PBlock *search_pb = slapi_pblock_new();
- Slapi_Backend *be = 0;
- Slapi_DN *sdn = 0;
- Slapi_DN *base_sdn = 0;
- char *filter_str = 0;
- int num_types = 0;
+ Slapi_DN *base_sdn = NULL;
+ Slapi_Backend *be = NULL;
+ Slapi_DN *sdn = NULL;
+ char *filter_str = NULL;
+ char *cookie = NULL;
+ int all_backends = memberof_config_get_all_backends();
int types_name_len = 0;
- int dn_len = 0;
+ int num_types = 0;
+ int dn_len = strlen(dn);
+ int rc = 0;
int i = 0;
- slapi_pblock_set(search_pb, SLAPI_TXN, txn);
- /* get the base dn for the backend we are in
- (we don't support having members and groups in
- different backends - issues with offline / read only backends)
- */
- sdn = slapi_sdn_new_normdn_byref(dn);
- be = slapi_be_select(sdn);
- if(be)
+ /* Count the number of types. */
+ for (num_types = 0; types && types[num_types]; num_types++)
{
- base_sdn = (Slapi_DN*)slapi_be_getsuffix(be,0);
+ /* Add up the total length of all attribute names.
+ * We need to know this for building the filter. */
+ types_name_len += strlen(types[num_types]);
}
- if(base_sdn)
+ /* Build the search filter. */
+ if (num_types > 1)
{
- /* Find the length of the dn */
- dn_len = strlen(dn);
+ int bytes_out = 0;
+ int filter_str_len = types_name_len + (num_types * (3 + dn_len)) + 4;
- /* Count the number of types. */
- for (num_types = 0; types && types[num_types]; num_types++)
- {
- /* Add up the total length of all attribute names.
- * We need to know this for building the filter. */
- types_name_len += strlen(types[num_types]);
- }
+ /* Allocate enough space for the filter */
+ filter_str = slapi_ch_malloc(filter_str_len);
+
+ /* Add beginning of filter. */
+ bytes_out = snprintf(filter_str, filter_str_len - bytes_out, "(|");
- /* Build the search filter. */
- if (num_types > 1)
+ /* Add filter section for each type. */
+ for (i = 0; types[i]; i++)
{
- int bytes_out = 0;
- int filter_str_len = types_name_len + (num_types * (3 + dn_len)) + 4;
+ bytes_out += snprintf(filter_str + bytes_out, filter_str_len - bytes_out,
+ "(%s=%s)", types[i], dn);
+ }
- /* Allocate enough space for the filter */
- filter_str = slapi_ch_malloc(filter_str_len);
+ /* Add end of filter. */
+ snprintf(filter_str + bytes_out, filter_str_len - bytes_out, ")");
+ }
+ else if (num_types == 1)
+ {
+ filter_str = slapi_ch_smprintf("(%s=%s)", types[0], dn);
+ }
- /* Add beginning of filter. */
- bytes_out = snprintf(filter_str, filter_str_len - bytes_out, "(|");
+ if(filter_str == NULL){
+ return rc;
+ }
- /* Add filter section for each type. */
- for (i = 0; types[i]; i++)
- {
- bytes_out += snprintf(filter_str + bytes_out, filter_str_len - bytes_out,
- "(%s=%s)", types[i], dn);
+ be = slapi_get_first_backend(&cookie);
+ while(be){
+ if(!all_backends){
+ sdn = slapi_sdn_new_normdn_byref(dn);
+ be = slapi_be_select(sdn);
+ if(be == NULL){
+ break;
}
-
- /* Add end of filter. */
- snprintf(filter_str + bytes_out, filter_str_len - bytes_out, ")");
}
- else if (num_types == 1)
- {
- filter_str = slapi_ch_smprintf("(%s=%s)", types[0], dn);
+ if((base_sdn = (Slapi_DN *)slapi_be_getsuffix(be,0)) == NULL){
+ if(!all_backends){
+ break;
+ } else {
+ /* its ok, goto the next backend */
+ be = slapi_get_next_backend(cookie);
+ continue;
+ }
}
- }
- if(filter_str)
- {
slapi_search_internal_set_pb(search_pb, slapi_sdn_get_dn(base_sdn),
- LDAP_SCOPE_SUBTREE, filter_str, 0, 0,
- 0, 0,
- memberof_get_plugin_id(),
- 0);
-
- slapi_search_internal_callback_pb(search_pb,
- callback_data,
- 0, callback,
- 0);
+ LDAP_SCOPE_SUBTREE, filter_str, 0, 0, 0, 0, memberof_get_plugin_id(), 0);
+ slapi_search_internal_callback_pb(search_pb, callback_data, 0, callback, 0);
+
+ if(!all_backends){
+ break;
+ }
+ slapi_pblock_init(search_pb);
+ be = slapi_get_next_backend(cookie);
}
slapi_sdn_free(&sdn);
slapi_pblock_destroy(search_pb);
+ slapi_ch_free((void **)&cookie);
slapi_ch_free_string(&filter_str);
+
return rc;
}
@@ -634,11 +633,9 @@ int memberof_postop_modrdn(Slapi_PBlock *pb)
struct slapi_entry *post_e = NULL;
char *pre_dn = 0;
char *post_dn = 0;
- void *txn = NULL;
slapi_pblock_get( pb, SLAPI_ENTRY_PRE_OP, &pre_e );
slapi_pblock_get( pb, SLAPI_ENTRY_POST_OP, &post_e );
- slapi_pblock_get( pb, SLAPI_TXN, &txn );
if(pre_e && post_e)
{
@@ -667,7 +664,7 @@ int memberof_postop_modrdn(Slapi_PBlock *pb)
{
if(0 == slapi_entry_attr_find(post_e, configCopy.groupattrs[i], &attr))
{
- if(memberof_moddn_attr_list(pb, &configCopy, pre_dn, post_dn, attr, txn) != 0){
+ if(memberof_moddn_attr_list(pb, &configCopy, pre_dn, post_dn, attr) != 0){
break;
}
}
@@ -678,7 +675,7 @@ int memberof_postop_modrdn(Slapi_PBlock *pb)
* of other group entries. We need to update any member
* attributes to refer to the new name. */
if (pre_dn && post_dn) {
- memberof_replace_dn_from_groups(pb, &configCopy, pre_dn, post_dn, txn);
+ memberof_replace_dn_from_groups(pb, &configCopy, pre_dn, post_dn);
}
memberof_unlock();
@@ -696,7 +693,6 @@ typedef struct _replace_dn_data
char *pre_dn;
char *post_dn;
char *type;
- void *txn;
} replace_dn_data;
@@ -704,7 +700,7 @@ typedef struct _replace_dn_data
* to use post_dn instead. */
static void
memberof_replace_dn_from_groups(Slapi_PBlock *pb, MemberOfConfig *config,
- char *pre_dn, char *post_dn, void *txn)
+ char *pre_dn, char *post_dn)
{
int i = 0;
char *groupattrs[2] = {0, 0};
@@ -714,12 +710,12 @@ memberof_replace_dn_from_groups(Slapi_PBlock *pb, MemberOfConfig *config,
* using the same grouping attribute. */
for (i = 0; config->groupattrs[i]; i++)
{
- replace_dn_data data = {pre_dn, post_dn, config->groupattrs[i], txn};
+ replace_dn_data data = {pre_dn, post_dn, config->groupattrs[i]};
groupattrs[0] = config->groupattrs[i];
memberof_call_foreach_dn(pb, pre_dn, groupattrs,
- memberof_replace_dn_type_callback, &data, txn);
+ memberof_replace_dn_type_callback, &data);
}
}
@@ -759,7 +755,6 @@ int memberof_replace_dn_type_callback(Slapi_Entry *e, void *callback_data)
mods, 0, 0,
memberof_get_plugin_id(), 0);
- slapi_pblock_set(mod_pb, SLAPI_TXN, ((replace_dn_data *)callback_data)->txn);
slapi_modify_internal_pb(mod_pb);
slapi_pblock_get(mod_pb,
@@ -812,9 +807,7 @@ int memberof_postop_modify(Slapi_PBlock *pb)
int config_copied = 0;
MemberOfConfig *mainConfig = 0;
MemberOfConfig configCopy = {0, 0, 0, 0};
- void *txn = NULL;
- slapi_pblock_get(pb, SLAPI_TXN, &txn);
/* get the mod set */
slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &mods);
smods = slapi_mods_new();
@@ -865,7 +858,7 @@ int memberof_postop_modify(Slapi_PBlock *pb)
case LDAP_MOD_ADD:
{
/* add group DN to targets */
- memberof_add_smod_list(pb, &configCopy, normdn, smod, txn);
+ memberof_add_smod_list(pb, &configCopy, normdn, smod);
break;
}
@@ -877,12 +870,12 @@ int memberof_postop_modify(Slapi_PBlock *pb)
* entry, which the replace code deals with. */
if (slapi_mod_get_num_values(smod) == 0)
{
- memberof_replace_list(pb, &configCopy, normdn, txn);
+ memberof_replace_list(pb, &configCopy, normdn);
}
else
{
/* remove group DN from target values in smod*/
- memberof_del_smod_list(pb, &configCopy, normdn, smod, txn);
+ memberof_del_smod_list(pb, &configCopy, normdn, smod);
}
break;
}
@@ -890,7 +883,7 @@ int memberof_postop_modify(Slapi_PBlock *pb)
case LDAP_MOD_REPLACE:
{
/* replace current values */
- memberof_replace_list(pb, &configCopy, normdn, txn);
+ memberof_replace_list(pb, &configCopy, normdn);
break;
}
@@ -955,10 +948,9 @@ int memberof_postop_add(Slapi_PBlock *pb)
MemberOfConfig *mainConfig = 0;
MemberOfConfig configCopy = {0, 0, 0, 0};
struct slapi_entry *e = NULL;
- void *txn = NULL;
slapi_pblock_get( pb, SLAPI_ENTRY_POST_OP, &e );
- slapi_pblock_get( pb, SLAPI_TXN, &txn );
+
/* is the entry of interest? */
memberof_rlock_config();
@@ -983,7 +975,7 @@ int memberof_postop_add(Slapi_PBlock *pb)
{
if(0 == slapi_entry_attr_find(e, configCopy.groupattrs[i], &attr))
{
- memberof_add_attr_list(pb, &configCopy, normdn, attr, txn);
+ memberof_add_attr_list(pb, &configCopy, normdn, attr);
}
}
@@ -1073,9 +1065,9 @@ char *memberof_getdn(Slapi_PBlock *pb)
* Also, we must not delete entries that are a member of the group
*/
int memberof_modop_one(Slapi_PBlock *pb, MemberOfConfig *config, int mod_op,
- char *op_this, char *op_to, void *txn)
+ char *op_this, char *op_to)
{
- return memberof_modop_one_r(pb, config, mod_op, op_this, op_this, op_to, 0, txn);
+ return memberof_modop_one_r(pb, config, mod_op, op_this, op_this, op_to, 0);
}
/* memberof_modop_one_r()
@@ -1084,24 +1076,19 @@ int memberof_modop_one(Slapi_PBlock *pb, MemberOfConfig *config, int mod_op,
*/
int memberof_modop_one_r(Slapi_PBlock *pb, MemberOfConfig *config, int mod_op,
- char *group_dn, char *op_this, char *op_to, memberofstringll *stack, void *txn)
+ char *group_dn, char *op_this, char *op_to, memberofstringll *stack)
{
return memberof_modop_one_replace_r(
- pb, config, mod_op, group_dn, op_this, 0, op_to, stack, txn);
+ pb, config, mod_op, group_dn, op_this, 0, op_to, stack);
}
-struct fix_memberof_callback_data {
- MemberOfConfig *config;
- void *txn;
-};
-
/* memberof_modop_one_replace_r()
*
* recursive function to perform above (with added replace arg)
*/
int memberof_modop_one_replace_r(Slapi_PBlock *pb, MemberOfConfig *config,
int mod_op, char *group_dn, char *op_this, char *replace_with,
- char *op_to, memberofstringll *stack, void *txn)
+ char *op_to, memberofstringll *stack)
{
int rc = 0;
LDAPMod mod;
@@ -1125,8 +1112,8 @@ int memberof_modop_one_replace_r(Slapi_PBlock *pb, MemberOfConfig *config,
/* determine if this is a group op or single entry */
op_to_sdn = slapi_sdn_new_normdn_byref(op_to);
- slapi_search_internal_get_entry_ext( op_to_sdn, config->groupattrs,
- &e, memberof_get_plugin_id(), txn);
+ slapi_search_internal_get_entry( op_to_sdn, config->groupattrs,
+ &e, memberof_get_plugin_id());
if(!e)
{
/* In the case of a delete, we need to worry about the
@@ -1141,61 +1128,72 @@ int memberof_modop_one_replace_r(Slapi_PBlock *pb, MemberOfConfig *config,
Slapi_DN *base_sdn = 0;
Slapi_Backend *be = 0;
char *filter_str = 0;
+ char *cookie = NULL;
int n_entries = 0;
-
- /* We can't tell for sure if the op_to entry is a
- * user or a group since the entry doesn't exist
- * anymore. We can safely ignore the missing entry
- * if no other entries have a memberOf attribute that
- * points to the missing entry. */
- be = slapi_be_select(op_to_sdn);
- if(be)
- {
- base_sdn = (Slapi_DN*)slapi_be_getsuffix(be,0);
- }
-
- if(base_sdn)
- {
- filter_str = slapi_ch_smprintf("(%s=%s)",
- config->memberof_attr, op_to);
- }
-
- if(filter_str)
- {
- slapi_search_internal_set_pb(search_pb, slapi_sdn_get_dn(base_sdn),
- LDAP_SCOPE_SUBTREE, filter_str, 0, 0, 0, 0,
- memberof_get_plugin_id(), 0);
- slapi_pblock_set(search_pb, SLAPI_TXN, txn);
-
- if (slapi_search_internal_pb(search_pb))
+ int all_backends = config->allBackends;
+
+ filter_str = slapi_ch_smprintf("(%s=%s)", config->memberof_attr, op_to);
+ be = slapi_get_first_backend(&cookie);
+ while(be){
+ /*
+ * We can't tell for sure if the op_to entry is a
+ * user or a group since the entry doesn't exist
+ * anymore. We can safely ignore the missing entry
+ * if no other entries have a memberOf attribute that
+ * points to the missing entry.
+ */
+ if(!all_backends){
+ be = slapi_be_select(op_to_sdn);
+ if(be == NULL){
+ break;
+ }
+ }
+ if((base_sdn = (Slapi_DN*)slapi_be_getsuffix(be,0)) == NULL){
+ if(!all_backends){
+ break;
+ } else {
+ be = slapi_get_next_backend (cookie);
+ continue;
+ }
+ }
+ if(filter_str)
{
- /* get result and log an error */
- int res = 0;
- slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_RESULT, &res);
- slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM,
- "memberof_modop_one_replace_r: error searching for members: "
- "%d", res);
- } else {
- slapi_pblock_get(search_pb, SLAPI_NENTRIES, &n_entries);
-
- if(n_entries > 0)
+ slapi_search_internal_set_pb(search_pb, slapi_sdn_get_dn(base_sdn),
+ LDAP_SCOPE_SUBTREE, filter_str, 0, 0, 0, 0,
+ memberof_get_plugin_id(), 0);
+
+ if (slapi_search_internal_pb(search_pb))
{
- /* We want to fixup the membership for the
- * entries that referred to the missing group
- * entry. This will fix the references to
- * the missing group as well as the group
- * represented by op_this. */
- memberof_test_membership(pb, config, op_to, txn);
+ /* get result and log an error */
+ int res = 0;
+ slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_RESULT, &res);
+ slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM,
+ "memberof_modop_one_replace_r: error searching for members: "
+ "%d", res);
+ } else {
+ slapi_pblock_get(search_pb, SLAPI_NENTRIES, &n_entries);
+ if(n_entries > 0)
+ {
+ /* We want to fixup the membership for the
+ * entries that referred to the missing group
+ * entry. This will fix the references to
+ * the missing group as well as the group
+ * represented by op_this. */
+ memberof_test_membership(pb, config, op_to);
+ }
}
+ slapi_free_search_results_internal(search_pb);
}
-
- slapi_free_search_results_internal(search_pb);
- slapi_ch_free_string(&filter_str);
+ slapi_pblock_init(search_pb);
+ if(!all_backends){
+ break;
+ }
+ be = slapi_get_next_backend (cookie);
}
-
slapi_pblock_destroy(search_pb);
+ slapi_ch_free_string(&filter_str);
+ slapi_ch_free((void **)&cookie);
}
-
goto bail;
}
@@ -1268,7 +1266,7 @@ int memberof_modop_one_replace_r(Slapi_PBlock *pb, MemberOfConfig *config,
slapi_entry_attr_find( e, config->groupattrs[i], &members );
if(members)
{
- if(memberof_mod_attr_list_r(pb, config, mod_op, group_dn, op_this, members, ll, txn) != 0){
+ if(memberof_mod_attr_list_r(pb, config, mod_op, group_dn, op_this, members, ll) != 0){
rc = -1;
goto bail;
}
@@ -1309,8 +1307,7 @@ int memberof_modop_one_replace_r(Slapi_PBlock *pb, MemberOfConfig *config,
if(LDAP_MOD_DELETE == mod_op || LDAP_MOD_ADD == mod_op)
{
/* find parent groups and replace our member attr */
- struct fix_memberof_callback_data cb_data = {config, txn};
- memberof_fix_memberof_callback(e, &cb_data);
+ memberof_fix_memberof_callback(e, config);
} else {
/* single entry - do mod */
mod_pb = slapi_pblock_new();
@@ -1347,7 +1344,6 @@ int memberof_modop_one_replace_r(Slapi_PBlock *pb, MemberOfConfig *config,
mods, 0, 0,
memberof_get_plugin_id(), 0);
- slapi_pblock_set(mod_pb, SLAPI_TXN, txn);
slapi_modify_internal_pb(mod_pb);
slapi_pblock_get(mod_pb,
@@ -1373,9 +1369,9 @@ bail:
* Add addthis DN to the memberof attribute of addto
*
*/
-int memberof_add_one(Slapi_PBlock *pb, MemberOfConfig *config, char *addthis, char *addto, void *txn)
+int memberof_add_one(Slapi_PBlock *pb, MemberOfConfig *config, char *addthis, char *addto)
{
- return memberof_modop_one(pb, config, LDAP_MOD_ADD, addthis, addto, txn);
+ return memberof_modop_one(pb, config, LDAP_MOD_ADD, addthis, addto);
}
/*
@@ -1384,9 +1380,9 @@ int memberof_add_one(Slapi_PBlock *pb, MemberOfConfig *config, char *addthis, ch
* Delete delthis DN from the memberof attribute of delfrom
*
*/
-int memberof_del_one(Slapi_PBlock *pb, MemberOfConfig *config, char *delthis, char *delfrom, void *txn)
+int memberof_del_one(Slapi_PBlock *pb, MemberOfConfig *config, char *delthis, char *delfrom)
{
- return memberof_modop_one(pb, config, LDAP_MOD_DELETE, delthis, delfrom, txn);
+ return memberof_modop_one(pb, config, LDAP_MOD_DELETE, delthis, delfrom);
}
/*
@@ -1396,7 +1392,7 @@ int memberof_del_one(Slapi_PBlock *pb, MemberOfConfig *config, char *delthis, ch
*
*/
int memberof_mod_smod_list(Slapi_PBlock *pb, MemberOfConfig *config, int mod,
- char *group_dn, Slapi_Mod *smod, void *txn)
+ char *group_dn, Slapi_Mod *smod)
{
int rc = 0;
struct berval *bv = slapi_mod_get_first_value(smod);
@@ -1428,7 +1424,7 @@ int memberof_mod_smod_list(Slapi_PBlock *pb, MemberOfConfig *config, int mod,
strncpy(dn_str, bv->bv_val, (size_t)bv->bv_len);
- memberof_modop_one(pb, config, mod, group_dn, dn_str, txn);
+ memberof_modop_one(pb, config, mod, group_dn, dn_str);
bv = slapi_mod_get_next_value(smod);
}
@@ -1446,9 +1442,9 @@ int memberof_mod_smod_list(Slapi_PBlock *pb, MemberOfConfig *config, int mod,
*
*/
int memberof_add_smod_list(Slapi_PBlock *pb, MemberOfConfig *config,
- char *groupdn, Slapi_Mod *smod, void *txn)
+ char *groupdn, Slapi_Mod *smod)
{
- return memberof_mod_smod_list(pb, config, LDAP_MOD_ADD, groupdn, smod, txn);
+ return memberof_mod_smod_list(pb, config, LDAP_MOD_ADD, groupdn, smod);
}
@@ -1459,9 +1455,9 @@ int memberof_add_smod_list(Slapi_PBlock *pb, MemberOfConfig *config,
*
*/
int memberof_del_smod_list(Slapi_PBlock *pb, MemberOfConfig *config,
- char *groupdn, Slapi_Mod *smod, void *txn)
+ char *groupdn, Slapi_Mod *smod)
{
- return memberof_mod_smod_list(pb, config, LDAP_MOD_DELETE, groupdn, smod, txn);
+ return memberof_mod_smod_list(pb, config, LDAP_MOD_DELETE, groupdn, smod);
}
/**
@@ -1485,13 +1481,13 @@ void * memberof_get_plugin_id()
*
*/
int memberof_mod_attr_list(Slapi_PBlock *pb, MemberOfConfig *config, int mod,
- char *group_dn, Slapi_Attr *attr, void *txn)
+ char *group_dn, Slapi_Attr *attr)
{
- return memberof_mod_attr_list_r(pb, config, mod, group_dn, group_dn, attr, 0, txn);
+ return memberof_mod_attr_list_r(pb, config, mod, group_dn, group_dn, attr, 0);
}
int memberof_mod_attr_list_r(Slapi_PBlock *pb, MemberOfConfig *config, int mod,
- char *group_dn, char *op_this, Slapi_Attr *attr, memberofstringll *stack, void *txn)
+ char *group_dn, char *op_this, Slapi_Attr *attr, memberofstringll *stack)
{
int rc = 0;
Slapi_Value *val = 0;
@@ -1538,11 +1534,11 @@ int memberof_mod_attr_list_r(Slapi_PBlock *pb, MemberOfConfig *config, int mod,
if(mod == LDAP_MOD_REPLACE)
{
memberof_modop_one_replace_r(pb, config, mod, group_dn, op_this,
- group_dn, dn_str, stack, txn);
+ group_dn, dn_str, stack);
}
else
{
- memberof_modop_one_r(pb, config, mod, group_dn, op_this, dn_str, stack, txn);
+ memberof_modop_one_r(pb, config, mod, group_dn, op_this, dn_str, stack);
}
}
@@ -1564,9 +1560,9 @@ int memberof_mod_attr_list_r(Slapi_PBlock *pb, MemberOfConfig *config, int mod,
*
*/
int memberof_add_attr_list(Slapi_PBlock *pb, MemberOfConfig *config, char *groupdn,
- Slapi_Attr *attr, void *txn)
+ Slapi_Attr *attr)
{
- return memberof_mod_attr_list(pb, config, LDAP_MOD_ADD, groupdn, attr, txn);
+ return memberof_mod_attr_list(pb, config, LDAP_MOD_ADD, groupdn, attr);
}
/*
@@ -1576,9 +1572,9 @@ int memberof_add_attr_list(Slapi_PBlock *pb, MemberOfConfig *config, char *group
*
*/
int memberof_del_attr_list(Slapi_PBlock *pb, MemberOfConfig *config, char *groupdn,
- Slapi_Attr *attr, void *txn)
+ Slapi_Attr *attr)
{
- return memberof_mod_attr_list(pb, config, LDAP_MOD_DELETE, groupdn, attr, txn);
+ return memberof_mod_attr_list(pb, config, LDAP_MOD_DELETE, groupdn, attr);
}
/*
@@ -1588,7 +1584,7 @@ int memberof_del_attr_list(Slapi_PBlock *pb, MemberOfConfig *config, char *group
*
*/
int memberof_moddn_attr_list(Slapi_PBlock *pb, MemberOfConfig *config,
- char *pre_dn, char *post_dn, Slapi_Attr *attr, void *txn)
+ char *pre_dn, char *post_dn, Slapi_Attr *attr)
{
int rc = 0;
Slapi_Value *val = 0;
@@ -1623,7 +1619,7 @@ int memberof_moddn_attr_list(Slapi_PBlock *pb, MemberOfConfig *config,
strncpy(dn_str, bv->bv_val, (size_t)bv->bv_len);
memberof_modop_one_replace_r(pb, config, LDAP_MOD_REPLACE,
- post_dn, pre_dn, post_dn, dn_str, 0, txn);
+ post_dn, pre_dn, post_dn, dn_str, 0);
hint = slapi_attr_next_value(attr, hint, &val);
}
@@ -1641,25 +1637,25 @@ int memberof_moddn_attr_list(Slapi_PBlock *pb, MemberOfConfig *config,
* A Slapi_ValueSet* is returned. It is up to the caller to
* free it.
*/
-Slapi_ValueSet *memberof_get_groups(MemberOfConfig *config, char *memberdn, void *txn)
+Slapi_ValueSet *memberof_get_groups(MemberOfConfig *config, char *memberdn)
{
Slapi_Value *memberdn_val = slapi_value_new_string(memberdn);
Slapi_ValueSet *groupvals = slapi_valueset_new();
- memberof_get_groups_data data = {config, memberdn_val, &groupvals, txn};
+ memberof_get_groups_data data = {config, memberdn_val, &groupvals};
- memberof_get_groups_r(config, memberdn, &data, txn);
+ memberof_get_groups_r(config, memberdn, &data);
slapi_value_free(&memberdn_val);
return groupvals;
}
-int memberof_get_groups_r(MemberOfConfig *config, char *memberdn, memberof_get_groups_data *data, void *txn)
+int memberof_get_groups_r(MemberOfConfig *config, char *memberdn, memberof_get_groups_data *data)
{
/* Search for any grouping attributes that point to memberdn.
* For each match, add it to the list, recurse and do same search */
return memberof_call_foreach_dn(NULL, memberdn, config->groupattrs,
- memberof_get_groups_callback, data, txn);
+ memberof_get_groups_callback, data);
}
/* memberof_get_groups_callback()
@@ -1728,7 +1724,7 @@ int memberof_get_groups_callback(Slapi_Entry *e, void *callback_data)
/* now recurse to find parent groups of e */
memberof_get_groups_r(((memberof_get_groups_data*)callback_data)->config,
- group_dn, callback_data, ((memberof_get_groups_data*)callback_data)->txn);
+ group_dn, callback_data);
bail:
return rc;
@@ -1740,7 +1736,7 @@ bail:
* returns non-zero when true, zero otherwise
*/
int memberof_is_direct_member(MemberOfConfig *config, Slapi_Value *groupdn,
- Slapi_Value *memberdn, void *txn)
+ Slapi_Value *memberdn)
{
int rc = 0;
Slapi_DN *sdn = 0;
@@ -1750,8 +1746,8 @@ int memberof_is_direct_member(MemberOfConfig *config, Slapi_Value *groupdn,
sdn = slapi_sdn_new_normdn_byref(slapi_value_get_string(groupdn));
- slapi_search_internal_get_entry_ext(sdn, config->groupattrs,
- &group_e, memberof_get_plugin_id(), txn);
+ slapi_search_internal_get_entry(sdn, config->groupattrs,
+ &group_e, memberof_get_plugin_id());
if(group_e)
{
@@ -1798,11 +1794,6 @@ static int memberof_is_grouping_attr(char *type, MemberOfConfig *config)
return match;
}
-struct test_membership_cb_data {
- MemberOfConfig *config;
- void *txn;
-};
-
/* memberof_test_membership()
*
* Finds all entries who are a "memberOf" the group
@@ -1818,13 +1809,12 @@ struct test_membership_cb_data {
* iterate until a pass fails to move a group over to member groups
* remaining groups should be deleted
*/
-int memberof_test_membership(Slapi_PBlock *pb, MemberOfConfig *config, char *group_dn, void *txn)
+int memberof_test_membership(Slapi_PBlock *pb, MemberOfConfig *config, char *group_dn)
{
char *attrs[2] = {config->memberof_attr, 0};
- struct test_membership_cb_data cb_data = {config, txn};
return memberof_call_foreach_dn(pb, group_dn, attrs,
- memberof_test_membership_callback , &cb_data, txn);
+ memberof_test_membership_callback , config);
}
/*
@@ -1842,8 +1832,7 @@ int memberof_test_membership_callback(Slapi_Entry *e, void *callback_data)
Slapi_Value **member_array = 0;
Slapi_Value **candidate_array = 0;
Slapi_Value *entry_dn = 0;
- struct test_membership_cb_data *cb_data = (struct test_membership_cb_data *)callback_data;
- MemberOfConfig *config = cb_data->config;
+ MemberOfConfig *config = (MemberOfConfig *)callback_data;
entry_dn = slapi_value_new_string(slapi_entry_get_dn(e));
@@ -1880,7 +1869,7 @@ int memberof_test_membership_callback(Slapi_Entry *e, void *callback_data)
while(val)
{
/* test for direct membership */
- if(memberof_is_direct_member(config, val, entry_dn, cb_data->txn))
+ if(memberof_is_direct_member(config, val, entry_dn))
{
/* it is a member */
member_array[m_index] = val;
@@ -1929,7 +1918,7 @@ int memberof_test_membership_callback(Slapi_Entry *e, void *callback_data)
if(memberof_is_direct_member(
config,
candidate_array[inner_index],
- member_array[outer_index], cb_data->txn))
+ member_array[outer_index]))
{
member_array[m_index] =
candidate_array
@@ -1969,7 +1958,7 @@ int memberof_test_membership_callback(Slapi_Entry *e, void *callback_data)
0, config,
(char*)slapi_value_get_string(
candidate_array[outer_index]),
- (char*)slapi_value_get_string(entry_dn), cb_data->txn);
+ (char*)slapi_value_get_string(entry_dn));
outer_index++;
}
@@ -2001,7 +1990,7 @@ bail:
* Perform replace the group DN list in the memberof attribute of the list of targets
*
*/
-int memberof_replace_list(Slapi_PBlock *pb, MemberOfConfig *config, char *group_dn, void *txn)
+int memberof_replace_list(Slapi_PBlock *pb, MemberOfConfig *config, char *group_dn)
{
struct slapi_entry *pre_e = NULL;
struct slapi_entry *post_e = NULL;
@@ -2091,7 +2080,7 @@ int memberof_replace_list(Slapi_PBlock *pb, MemberOfConfig *config, char *group_
pb, config,
group_dn,
(char*)slapi_value_get_string(
- post_array[post_index]), txn);
+ post_array[post_index]));
post_index++;
}
@@ -2102,7 +2091,7 @@ int memberof_replace_list(Slapi_PBlock *pb, MemberOfConfig *config, char *group_
pb, config,
group_dn,
(char*)slapi_value_get_string(
- pre_array[pre_index]), txn);
+ pre_array[pre_index]));
pre_index++;
}
@@ -2121,7 +2110,7 @@ int memberof_replace_list(Slapi_PBlock *pb, MemberOfConfig *config, char *group_
pb, config,
group_dn,
(char*)slapi_value_get_string(
- pre_array[pre_index]), txn);
+ pre_array[pre_index]));
pre_index++;
}
@@ -2132,7 +2121,7 @@ int memberof_replace_list(Slapi_PBlock *pb, MemberOfConfig *config, char *group_
pb, config,
group_dn,
(char*)slapi_value_get_string(
- post_array[post_index]), txn);
+ post_array[post_index]));
post_index++;
}
@@ -2223,6 +2212,7 @@ void memberof_unlock()
typedef struct _task_data
{
char *dn;
+ char *bind_dn;
char *filter_str;
} task_data;
@@ -2236,6 +2226,9 @@ void memberof_fixup_task_thread(void *arg)
/* Fetch our task data from the task */
td = (task_data *)slapi_task_get_data(task);
+ /* set bind DN in the thread data */
+ slapi_td_set_dn(slapi_ch_strdup(td->bind_dn));
+
slapi_task_begin(task, 1);
slapi_task_log_notice(task, "Memberof task starts (arg: %s) ...\n",
td->filter_str);
@@ -2252,7 +2245,7 @@ void memberof_fixup_task_thread(void *arg)
memberof_lock();
/* do real work */
- rc = memberof_fix_memberof(&configCopy, td->dn, td->filter_str, NULL /* no txn? */);
+ rc = memberof_fix_memberof(&configCopy, td->dn, td->filter_str);
/* release the memberOf operation lock */
memberof_unlock();
@@ -2291,6 +2284,7 @@ int memberof_task_add(Slapi_PBlock *pb, Slapi_Entry *e,
int rv = SLAPI_DSE_CALLBACK_OK;
task_data *mytaskdata = NULL;
Slapi_Task *task = NULL;
+ char *bind_dn;
const char *filter;
const char *dn = 0;
@@ -2320,6 +2314,7 @@ int memberof_task_add(Slapi_PBlock *pb, Slapi_Entry *e,
}
/* setup our task data */
+ slapi_pblock_get(pb, SLAPI_REQUESTOR_DN, &bind_dn);
mytaskdata = (task_data*)slapi_ch_malloc(sizeof(task_data));
if (mytaskdata == NULL)
{
@@ -2329,6 +2324,7 @@ int memberof_task_add(Slapi_PBlock *pb, Slapi_Entry *e,
}
mytaskdata->dn = slapi_ch_strdup(dn);
mytaskdata->filter_str = slapi_ch_strdup(filter);
+ mytaskdata->bind_dn = slapi_ch_strdup(bind_dn);
/* allocate new task now */
task = slapi_new_task(slapi_entry_get_ndn(e));
@@ -2365,6 +2361,7 @@ memberof_task_destructor(Slapi_Task *task)
task_data *mydata = (task_data *)slapi_task_get_data(task);
if (mydata) {
slapi_ch_free_string(&mydata->dn);
+ slapi_ch_free_string(&mydata->bind_dn);
slapi_ch_free_string(&mydata->filter_str);
/* Need to cast to avoid a compiler warning */
slapi_ch_free((void **)&mydata);
@@ -2372,10 +2369,9 @@ memberof_task_destructor(Slapi_Task *task)
}
}
-int memberof_fix_memberof(MemberOfConfig *config, char *dn, char *filter_str, void *txn)
+int memberof_fix_memberof(MemberOfConfig *config, char *dn, char *filter_str)
{
int rc = 0;
- struct fix_memberof_callback_data cb_data = {config, txn};
Slapi_PBlock *search_pb = slapi_pblock_new();
slapi_search_internal_set_pb(search_pb, dn,
@@ -2384,9 +2380,8 @@ int memberof_fix_memberof(MemberOfConfig *config, char *dn, char *filter_str, vo
memberof_get_plugin_id(),
0);
- slapi_pblock_set(search_pb, SLAPI_TXN, txn);
rc = slapi_search_internal_callback_pb(search_pb,
- &cb_data,
+ config,
0, memberof_fix_memberof_callback,
0);
@@ -2407,13 +2402,12 @@ int memberof_fix_memberof_callback(Slapi_Entry *e, void *callback_data)
int rc = 0;
char *dn = slapi_entry_get_dn(e);
Slapi_DN *sdn = slapi_entry_get_sdn(e);
- struct fix_memberof_callback_data *cb_data = (struct fix_memberof_callback_data *)callback_data;
- MemberOfConfig *config = cb_data->config;
- memberof_del_dn_data del_data = {0, config->memberof_attr, cb_data->txn};
+ MemberOfConfig *config = (MemberOfConfig *)callback_data;
+ memberof_del_dn_data del_data = {0, config->memberof_attr};
Slapi_ValueSet *groups = 0;
/* get a list of all of the groups this user belongs to */
- groups = memberof_get_groups(config, dn, cb_data->txn);
+ groups = memberof_get_groups(config, dn);
/* If we found some groups, replace the existing memberOf attribute
* with the found values. */
@@ -2446,7 +2440,6 @@ int memberof_fix_memberof_callback(Slapi_Entry *e, void *callback_data)
mod_pb, sdn, mods, 0, 0,
memberof_get_plugin_id(), 0);
- slapi_pblock_set(mod_pb, SLAPI_TXN, cb_data->txn);
slapi_modify_internal_pb(mod_pb);
slapi_pblock_get(mod_pb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
diff --git a/ldap/servers/plugins/replication/cl5_api.c b/ldap/servers/plugins/replication/cl5_api.c
index 92356a8..51accab 100644
--- a/ldap/servers/plugins/replication/cl5_api.c
+++ b/ldap/servers/plugins/replication/cl5_api.c
@@ -6543,9 +6543,6 @@ cl5CleanRUV(ReplicaId rid){
ruv_delete_replica(file->maxRUV, rid);
obj = objset_next_obj(s_cl5Desc.dbFiles, obj);
}
-
- if (obj)
- object_release (obj);
}
void trigger_cl_trimming(){
@@ -6572,7 +6569,11 @@ trigger_cl_trimming_thread(){
if(s_cl5Desc.dbState == CL5_STATE_CLOSED || s_cl5Desc.dbState == CL5_STATE_CLOSING){
return;
}
- _cl5AddThread();
+ if (CL5_SUCCESS != _cl5AddThread()) {
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
+ "trigger_cl_trimming: failed to increment thread count "
+ "NSPR error - %d\n", PR_GetError ());
+ }
_cl5DoTrimming();
_cl5RemoveThread();
}
commit d049fb96713ec37f1fe0376f32934f55937a6792
Author: root <root(a)localhost.localdomain>
Date: Mon Apr 23 13:36:04 2012 -0400
Ticket #337 - RFE - Improve CLEANRUV functionality
Bug Description: Previously the steps to remove a replica and its RUV was problematic.
I created two new "tasks" to take care of the entire replication environment.
Fix Description:
[1] The new task "CLEANALLRUV<rid>" - run it once on any master
This marks the rid as invalid. Used to reject updates to the changelog, and the database RUV
It then sends a "CLEANRUV" extended operation to each agreement.
Then it cleans its own RUV.
The CLEANRUV extended op then triggers that replica to send the the same CLEANRUV extop to its replicas, then it cleans its own RID. Basically
this operation cascades through the entire replication environment.
[2] The "RELEASERUV<rid>" task - run it once on any master
Once the RUV's have been cleaned on all the replicas, you need to "release" the rid so that it can be reused. This operation also cascades thro
ugh the entire replication environment. This also triggers changelog trimming.
For all of this to work correctly, there is a list of steps that needs to be followed. This procedure is attached to the ticket.
https://fedorahosted.org/389/ticket/337
reviewed by: ?
(cherry picked from commit 0f50544b9567907edd0ba645951d7cd325354107)
diff --git a/ldap/servers/plugins/replication/cl5_api.c b/ldap/servers/plugins/replication/cl5_api.c
index 0ea90d1..92356a8 100644
--- a/ldap/servers/plugins/replication/cl5_api.c
+++ b/ldap/servers/plugins/replication/cl5_api.c
@@ -347,6 +347,7 @@ static int _cl5WriteRUV (CL5DBFile *file, PRBool purge);
static int _cl5ConstructRUV (const char *replGen, Object *obj, PRBool purge);
static int _cl5UpdateRUV (Object *obj, CSN *csn, PRBool newReplica, PRBool purge);
static int _cl5GetRUV2Purge2 (Object *fileObj, RUV **ruv);
+void trigger_cl_trimming_thread();
/* bakup/recovery, import/export */
static int _cl5LDIF2Operation (char *ldifEntry, slapi_operation_parameters *op,
@@ -3469,6 +3470,7 @@ static void _cl5TrimFile (Object *obj, long *numToTrim)
count = 0;
txnid = NULL;
abort = PR_FALSE;
+ ReplicaId rid;
/* DB txn lock accessed pages until the end of the transaction. */
@@ -3489,13 +3491,14 @@ static void _cl5TrimFile (Object *obj, long *numToTrim)
* This change can be trimmed if it exceeds purge
* parameters and has been seen by all consumers.
*/
+ rid = csn_get_replicaid (op.csn);
if ( (*numToTrim > 0 || _cl5CanTrim (entry.time, numToTrim)) &&
ruv_covers_csn_strict (ruv, op.csn) )
- {
+ {
rc = _cl5CurrentDeleteEntry (it);
- if ( rc == CL5_SUCCESS )
+ if ( rc == CL5_SUCCESS && !is_released_rid(rid))
{
- /* update purge vector */
+ /* update purge vector, unless this is a released rid */
rc = _cl5UpdateRUV (obj, op.csn, PR_FALSE, PR_TRUE);
}
if ( rc == CL5_SUCCESS)
@@ -3521,8 +3524,6 @@ static void _cl5TrimFile (Object *obj, long *numToTrim)
* the trim forever.
*/
CSN *maxcsn = NULL;
- ReplicaId rid;
-
rid = csn_get_replicaid (op.csn);
ruv_get_largest_csn_for_replica (ruv, rid, &maxcsn);
if ( csn_compare (op.csn, maxcsn) != 0 )
@@ -3612,10 +3613,10 @@ static PRBool _cl5CanTrim (time_t time, long *numToTrim)
*numToTrim = cl5GetOperationCount (NULL) - s_cl5Desc.dbTrim.maxEntries;
return ( *numToTrim > 0 );
}
-
+
if (s_cl5Desc.dbTrim.maxEntries > 0 &&
(*numToTrim = cl5GetOperationCount (NULL) - s_cl5Desc.dbTrim.maxEntries) > 0)
- return PR_TRUE;
+ return PR_TRUE;
if (time)
return (current_time () - time > s_cl5Desc.dbTrim.maxAge);
@@ -3797,6 +3798,7 @@ static int _cl5ConstructRUV (const char *replGen, Object *obj, PRBool purge)
void *iterator = NULL;
slapi_operation_parameters op = {0};
CL5DBFile *file;
+ ReplicaId rid;
PR_ASSERT (replGen && obj);
@@ -3820,6 +3822,15 @@ static int _cl5ConstructRUV (const char *replGen, Object *obj, PRBool purge)
rc = _cl5GetFirstEntry (obj, &entry, &iterator, NULL);
while (rc == CL5_SUCCESS)
{
+ rid = csn_get_replicaid (op.csn);
+ if(is_cleaned_rid(rid)){
+ /* skip this entry as the rid is invalid */
+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name_cl, "_cl5ConstructRUV: "
+ "skipping entry because its csn contains a cleaned rid(%d)\n", rid);
+ cl5_operation_parameters_done (&op);
+ rc = _cl5GetNextEntry (&entry, iterator);
+ continue;
+ }
if (purge)
rc = ruv_set_csns_keep_smallest(file->purgeRUV, op.csn);
else
@@ -3868,28 +3879,32 @@ static int _cl5UpdateRUV (Object *obj, CSN *csn, PRBool newReplica, PRBool purge
file = (CL5DBFile*)object_get_data (obj);
- /* if purge is TRUE, file->purgeRUV must be set;
- if purge is FALSE, maxRUV must be set */
+ /*
+ * if purge is TRUE, file->purgeRUV must be set;
+ * if purge is FALSE, maxRUV must be set
+ */
PR_ASSERT (file && ((purge && file->purgeRUV) || (!purge && file->maxRUV)));
+ rid = csn_get_replicaid(csn);
/* update vector only if this replica is not yet part of RUV */
if (purge && newReplica)
{
- rid = csn_get_replicaid(csn);
if (ruv_contains_replica (file->purgeRUV, rid))
return CL5_SUCCESS;
- else
+ else if(is_cleaned_rid(rid))
{
- /* if the replica is not part of the purgeRUV yet, add it */
- ruv_add_replica (file->purgeRUV, rid, multimaster_get_local_purl());
+ /* if the replica is not part of the purgeRUV yet, add it unless it's from a cleaned rid */
+ ruv_add_replica (file->purgeRUV, rid, multimaster_get_local_purl());
}
}
else
{
if (purge)
rc = ruv_set_csns(file->purgeRUV, csn, NULL);
- else
- rc = ruv_set_csns(file->maxRUV, csn, NULL);
+ else if(is_cleaned_rid(rid)){
+ /* don't update maxRuv is if rid is cleaned */
+ rc = ruv_set_csns(file->maxRUV, csn, NULL);
+ }
}
if (rc != RUV_SUCCESS)
@@ -4494,9 +4509,17 @@ static int _cl5WriteOperationTxn(const char *replName, const char *replGen,
CL5Entry entry;
CL5DBFile *file = NULL;
Object *file_obj = NULL;
+ ReplicaId rid = csn_get_replicaid (op->csn);
DB_TXN *txnid = NULL;
DB_TXN *parent_txnid = (DB_TXN *)txn;
+ /*
+ * If the op csn contains the cleaned rid, don't write it
+ */
+ if(is_cleaned_rid(rid)){
+ return CL5_SUCCESS;
+ }
+
rc = _cl5GetDBFileByReplicaName (replName, replGen, &file_obj);
if (rc == CL5_NOTFOUND)
{
@@ -4762,7 +4785,7 @@ static int _cl5GetFirstEntry (Object *obj, CL5Entry *entry, void **iterator, DB_
rc, db_strerror(rc));
rc = CL5_DB_ERROR;
-done:;
+done:
/* error occured */
/* We didn't success in assigning this cursor to the iterator,
* so we need to free the cursor here */
@@ -6504,3 +6527,52 @@ bail:
changelog5_config_done(&config);
return rc;
}
+
+/*
+ * Clean the in memory RUV, at shutdown we will write the update to the db
+ */
+void
+cl5CleanRUV(ReplicaId rid){
+ CL5DBFile *file;
+ Object *obj;
+
+ obj = objset_first_obj(s_cl5Desc.dbFiles);
+ while (obj){
+ file = (CL5DBFile *)object_get_data(obj);
+ ruv_delete_replica(file->purgeRUV, rid);
+ ruv_delete_replica(file->maxRUV, rid);
+ obj = objset_next_obj(s_cl5Desc.dbFiles, obj);
+ }
+
+ if (obj)
+ object_release (obj);
+}
+
+void trigger_cl_trimming(){
+ PRThread *trim_tid = NULL;
+ ReplicaId rid = get_released_rid();
+
+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name_cl, "trigger_cl_trimming: rid (%d)\n",(int)rid);
+ trim_tid = PR_CreateThread(PR_USER_THREAD, (VFP)(void*)trigger_cl_trimming_thread,
+ NULL, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
+ PR_UNJOINABLE_THREAD, DEFAULT_THREAD_STACKSIZE);
+ if (NULL == trim_tid){
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
+ "trigger_cl_trimming: failed to create trimming "
+ "thread; NSPR error - %d\n", PR_GetError ());
+ } else {
+ /* need a little time for the thread to get started */
+ DS_Sleep(PR_SecondsToInterval(1));
+ }
+}
+
+void
+trigger_cl_trimming_thread(){
+ /* make sure we have a change log, and we aren't closing it */
+ if(s_cl5Desc.dbState == CL5_STATE_CLOSED || s_cl5Desc.dbState == CL5_STATE_CLOSING){
+ return;
+ }
+ _cl5AddThread();
+ _cl5DoTrimming();
+ _cl5RemoveThread();
+}
diff --git a/ldap/servers/plugins/replication/cl5_api.h b/ldap/servers/plugins/replication/cl5_api.h
index 6f2552f..b9c3dd8 100644
--- a/ldap/servers/plugins/replication/cl5_api.h
+++ b/ldap/servers/plugins/replication/cl5_api.h
@@ -487,4 +487,8 @@ int cl5WriteRUV();
Return: TRUE
*/
int cl5DeleteRUV();
+void cl5CleanRUV(ReplicaId rid);
+void cl5NotifyCleanup(int rid);
+void trigger_cl_trimming();
+
#endif
diff --git a/ldap/servers/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h
index ac2cd88..e315150 100644
--- a/ldap/servers/plugins/replication/repl5.h
+++ b/ldap/servers/plugins/replication/repl5.h
@@ -94,6 +94,9 @@
* new set of start and response extops. */
#define REPL_START_NSDS90_REPLICATION_REQUEST_OID "2.16.840.1.113730.3.5.12"
#define REPL_NSDS90_REPLICATION_RESPONSE_OID "2.16.840.1.113730.3.5.13"
+/* cleanruv/releaseruv extended ops */
+#define REPL_CLEANRUV_OID "2.16.840.1.113730.3.6.5"
+#define REPL_RELEASERUV_OID "2.16.840.1.113730.3.6.6"
/* DS 5.0 replication protocol error codes */
@@ -218,6 +221,8 @@ char* get_repl_session_id (Slapi_PBlock *pb, char *id, CSN **opcsn);
/* In repl_extop.c */
int multimaster_extop_StartNSDS50ReplicationRequest(Slapi_PBlock *pb);
int multimaster_extop_EndNSDS50ReplicationRequest(Slapi_PBlock *pb);
+int multimaster_extop_cleanruv(Slapi_PBlock *pb);
+int multimaster_extop_releaseruv(Slapi_PBlock *pb);
int extop_noop(Slapi_PBlock *pb);
struct berval *NSDS50StartReplicationRequest_new(const char *protocol_oid,
const char *repl_root, char **extra_referrals, CSN *csn);
@@ -345,8 +350,8 @@ char **agmt_get_fractional_attrs_total(const Repl_Agmt *ra);
char **agmt_validate_replicated_attributes(Repl_Agmt *ra, int total);
void* agmt_get_priv (const Repl_Agmt *agmt);
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);
typedef struct replica Replica;
@@ -579,6 +584,17 @@ void multimaster_be_state_change (void *handle, char *be_name, int old_be_state,
int replica_config_init();
void replica_config_destroy ();
int get_replica_type(Replica *r);
+int replica_execute_cleanruv_task_ext(Object *r, ReplicaId rid);
+void set_cleaned_rid(ReplicaId rid);
+void delete_cleaned_rid();
+int is_cleaned_rid(ReplicaId rid);
+int get_released_rid();
+void set_released_rid(int rid);
+int is_released_rid(int rid);
+int is_already_released_rid();
+void delete_released_rid();
+
+#define ALREADY_RELEASED -1
/* replutil.c */
LDAPControl* create_managedsait_control ();
diff --git a/ldap/servers/plugins/replication/repl5_agmt.c b/ldap/servers/plugins/replication/repl5_agmt.c
index 1d9affa..8714021 100644
--- a/ldap/servers/plugins/replication/repl5_agmt.c
+++ b/ldap/servers/plugins/replication/repl5_agmt.c
@@ -2425,6 +2425,15 @@ ReplicaId agmt_get_consumerRID(Repl_Agmt *ra)
return ra->consumerRID;
}
+void* agmt_get_connection(Repl_Agmt *ra)
+{
+ if(ra->protocol){
+ return (void *)prot_get_connection(ra->protocol);
+ } else {
+ return NULL;
+ }
+}
+
int
agmt_has_protocol(Repl_Agmt *agmt)
{
diff --git a/ldap/servers/plugins/replication/repl5_init.c b/ldap/servers/plugins/replication/repl5_init.c
index 4e2464c..a878b19 100644
--- a/ldap/servers/plugins/replication/repl5_init.c
+++ b/ldap/servers/plugins/replication/repl5_init.c
@@ -118,6 +118,22 @@ static char *response_name_list[] = {
NSDS_REPL_NAME_PREFIX " Response",
NULL
};
+static char *cleanruv_oid_list[] = {
+ REPL_CLEANRUV_OID,
+ NULL
+};
+static char *cleanruv_name_list[] = {
+ NSDS_REPL_NAME_PREFIX " Cleanruv",
+ NULL
+};
+static char *releaseruv_oid_list[] = {
+ REPL_RELEASERUV_OID,
+ NULL
+};
+static char *releaseruv_name_list[] = {
+ NSDS_REPL_NAME_PREFIX " Releaseruv",
+ NULL
+};
/* List of plugin identities for every plugin registered. Plugin identity
is passed by the server in the plugin init function and must be supplied
@@ -434,6 +450,51 @@ multimaster_response_extop_init( Slapi_PBlock *pb )
return rc;
}
+int
+multimaster_cleanruv_extop_init( Slapi_PBlock *pb )
+{
+ int rc= 0; /* OK */
+ void *identity = NULL;
+
+ /* get plugin identity and store it to pass to internal operations */
+ slapi_pblock_get (pb, SLAPI_PLUGIN_IDENTITY, &identity);
+ PR_ASSERT (identity);
+
+ if (slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION, SLAPI_PLUGIN_VERSION_01 ) != 0 ||
+ slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION, (void *)&multimasterextopdesc ) != 0 ||
+ slapi_pblock_set( pb, SLAPI_PLUGIN_EXT_OP_OIDLIST, (void *)cleanruv_oid_list ) != 0 ||
+ slapi_pblock_set( pb, SLAPI_PLUGIN_EXT_OP_NAMELIST, (void *)cleanruv_name_list ) != 0 ||
+ slapi_pblock_set( pb, SLAPI_PLUGIN_EXT_OP_FN, (void *)multimaster_extop_cleanruv ))
+ {
+ slapi_log_error( SLAPI_LOG_PLUGIN, repl_plugin_name, "multimaster_cleanruv_extop_init failed\n" );
+ rc= -1;
+ }
+
+ return rc;
+}
+
+int
+multimaster_releaseruv_extop_init( Slapi_PBlock *pb )
+{
+ int rc= 0; /* OK */
+ void *identity = NULL;
+
+ /* get plugin identity and store it to pass to internal operations */
+ slapi_pblock_get (pb, SLAPI_PLUGIN_IDENTITY, &identity);
+ PR_ASSERT (identity);
+
+ if (slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION, SLAPI_PLUGIN_VERSION_01 ) != 0 ||
+ slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION, (void *)&multimasterextopdesc ) != 0 ||
+ slapi_pblock_set( pb, SLAPI_PLUGIN_EXT_OP_OIDLIST, (void *)releaseruv_oid_list ) != 0 ||
+ slapi_pblock_set( pb, SLAPI_PLUGIN_EXT_OP_NAMELIST, (void *)releaseruv_name_list ) != 0 ||
+ slapi_pblock_set( pb, SLAPI_PLUGIN_EXT_OP_FN, (void *)multimaster_extop_releaseruv ))
+ {
+ slapi_log_error( SLAPI_LOG_PLUGIN, repl_plugin_name, "multimaster_releaseruv_extop_init failed\n" );
+ rc= -1;
+ }
+
+ return rc;
+}
static PRBool
check_for_ldif_dump(Slapi_PBlock *pb)
@@ -618,6 +679,8 @@ int replication_multimaster_plugin_init(Slapi_PBlock *pb)
rc= slapi_register_plugin("extendedop", 1 /* Enabled */, "multimaster_end_extop_init", multimaster_end_extop_init, "Multimaster replication end extended operation plugin", NULL, identity);
rc= slapi_register_plugin("extendedop", 1 /* Enabled */, "multimaster_total_extop_init", multimaster_total_extop_init, "Multimaster replication total update extended operation plugin", NULL, identity);
rc= slapi_register_plugin("extendedop", 1 /* Enabled */, "multimaster_response_extop_init", multimaster_response_extop_init, "Multimaster replication extended response plugin", NULL, identity);
+ rc= slapi_register_plugin("extendedop", 1 /* Enabled */, "multimaster_cleanruv_extop_init", multimaster_cleanruv_extop_init, "Multimaster replication cleanruv extended operation plugin", NULL, identity);
+ rc= slapi_register_plugin("extendedop", 1 /* Enabled */, "multimaster_releaseruv_extop_init", multimaster_releaseruv_extop_init, "Multimaster replication releaserid extended response plugin", NULL, identity);
if (0 == rc)
{
multimaster_initialised = 1;
diff --git a/ldap/servers/plugins/replication/repl5_plugins.c b/ldap/servers/plugins/replication/repl5_plugins.c
index c806c08..dfbb80e 100644
--- a/ldap/servers/plugins/replication/repl5_plugins.c
+++ b/ldap/servers/plugins/replication/repl5_plugins.c
@@ -1005,6 +1005,15 @@ write_changelog_and_ruv (Slapi_PBlock *pb)
r = (Replica*)object_get_data (repl_obj);
PR_ASSERT (r);
+ /*
+ * In case we had to run cleanruv, we don't want to continue to write
+ * updates to the changelog/database ruv from that replica(rid).
+ */
+ if( is_cleaned_rid(replica_get_rid(r))){
+ /* this RID has been cleaned, just goto done */
+ goto done;
+ }
+
if (replica_is_flag_set (r, REPLICA_LOG_CHANGES) &&
(cl5GetState () == CL5_STATE_OPEN))
{
@@ -1111,6 +1120,7 @@ write_changelog_and_ruv (Slapi_PBlock *pb)
update_ruv_component(r, opcsn, pb);
}
+done:
object_release (repl_obj);
return return_value;
}
diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
index e0e11e9..ff3c882 100644
--- a/ldap/servers/plugins/replication/repl5_replica_config.c
+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
@@ -56,9 +56,15 @@
#define LDIF2CL_TASK "LDIF2CL"
#define CLEANRUV "CLEANRUV"
#define CLEANRUVLEN 8
+#define CLEANALLRUV "CLEANALLRUV"
+#define CLEANALLRUVLEN 11
+#define RELEASERUV "RELEASERUV"
+#define RELEASERUVLEN 10
#define REPLICA_RDN "cn=replica"
int slapi_log_urp = SLAPI_LOG_REPL;
+static ReplicaId cleaned_rid = 0;
+static int released_rid = 0;
/* Forward Declartions */
static int replica_config_add (Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry* entryAfter, int *returncode, char *returntext, void *arg);
@@ -74,6 +80,9 @@ static int replica_execute_task (Object *r, const char *task_name, char *returnt
static int replica_execute_cl2ldif_task (Object *r, char *returntext);
static int replica_execute_ldif2cl_task (Object *r, char *returntext);
static int replica_execute_cleanruv_task (Object *r, ReplicaId rid, char *returntext);
+static int replica_execute_cleanall_ruv_task (Object *r, ReplicaId rid, char *returntext);
+static int replica_execute_release_ruv_task(Object *r, ReplicaId rid, char *returntext);
+static struct berval *create_ruv_payload(char *value);
static int replica_cleanup_task (Object *r, const char *task_name, char *returntext, int apply_mods);
static int replica_task_done(Replica *replica);
@@ -827,10 +836,8 @@ static int replica_execute_task (Object *r, const char *task_name, char *returnt
{
int temprid = atoi(&(task_name[CLEANRUVLEN]));
if (temprid <= 0 || temprid >= READ_ONLY_REPLICA_ID){
- PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
- "Invalid replica id for task - %s", task_name);
- slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
- "replica_execute_task: %s\n", returntext);
+ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Invalid replica id (%d) for task - %s", temprid, task_name);
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "replica_execute_task: %s\n", returntext);
return LDAP_OPERATIONS_ERROR;
}
if (apply_mods)
@@ -840,6 +847,36 @@ static int replica_execute_task (Object *r, const char *task_name, char *returnt
else
return LDAP_SUCCESS;
}
+ else if (strncasecmp (task_name, CLEANALLRUV, CLEANALLRUVLEN) == 0)
+ {
+ int temprid = atoi(&(task_name[CLEANALLRUVLEN]));
+ if (temprid <= 0 || temprid >= READ_ONLY_REPLICA_ID){
+ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Invalid replica id (%d) for task - (%s)", temprid, task_name);
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "replica_execute_task: %s\n", returntext);
+ return LDAP_OPERATIONS_ERROR;
+ }
+ if (apply_mods)
+ {
+ return replica_execute_cleanall_ruv_task(r, (ReplicaId)temprid, returntext);
+ }
+ else
+ return LDAP_SUCCESS;
+ }
+ else if (strncasecmp (task_name, RELEASERUV, RELEASERUVLEN) == 0)
+ {
+ int temprid = atoi(&(task_name[RELEASERUVLEN]));
+ if (temprid <= 0 || temprid >= READ_ONLY_REPLICA_ID){
+ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Invalid replica id for task - %s", task_name);
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,"replica_execute_task: %s\n", returntext);
+ return LDAP_OPERATIONS_ERROR;
+ }
+ if (apply_mods)
+ {
+ return replica_execute_release_ruv_task(r, (ReplicaId)temprid, returntext);
+ }
+ else
+ return LDAP_SUCCESS;
+ }
else
{
PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "unsupported replica task - %s", task_name);
@@ -1102,16 +1139,24 @@ _replica_config_get_mtnode_ext (const Slapi_Entry *e)
return ext;
}
+int
+replica_execute_cleanruv_task_ext(Object *r, ReplicaId rid)
+{
+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "cleanruv_extop: calling clean_ruv_ext\n");
+ return replica_execute_cleanruv_task(r, rid, NULL);
+}
+
static int
-replica_execute_cleanruv_task (Object *r, ReplicaId rid, char *returntext)
+replica_execute_cleanruv_task (Object *r, ReplicaId rid, char *returntext /* not used */)
{
int rc = 0;
Object *RUVObj;
RUV *local_ruv = NULL;
- Replica *replica = (Replica*)object_get_data (r);
+ Replica *replica = (Replica*)object_get_data (r);
- PR_ASSERT (replica);
+ PR_ASSERT (replica);
+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "cleanruv_task: cleaning rid (%d)...\n",(int)rid);
RUVObj = replica_get_ruv(replica);
PR_ASSERT(RUVObj);
local_ruv = (RUV*)object_get_data (RUVObj);
@@ -1131,10 +1176,295 @@ replica_execute_cleanruv_task (Object *r, ReplicaId rid, char *returntext)
/* Update Mapping Tree to reflect RUV changes */
consumer5_set_mapping_tree_state_for_replica(replica, NULL);
+ /*
+ * Clean the changelog RUV's, and set the rids
+ */
+ cl5CleanRUV(rid);
+ set_cleaned_rid(rid);
+ delete_released_rid();
+
if (rc != RUV_SUCCESS){
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanruv_task: task failed(%d)\n",rc);
return LDAP_OPERATIONS_ERROR;
}
+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "cleanruv_task: finished successfully\n");
return LDAP_SUCCESS;
}
+static int
+replica_execute_cleanall_ruv_task (Object *r, ReplicaId rid, char *returntext)
+{
+ Repl_Connection *conn;
+ Replica *replica = (Replica*)object_get_data (r);
+ Object *agmt_obj;
+ Repl_Agmt *agmt;
+ ConnResult crc;
+ const Slapi_DN *dn = NULL;
+ struct berval *payload = NULL;
+ char *ridstr = NULL;
+ int send_msgid = 0;
+ int rc = 0;
+
+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "cleanAllRUV_task: cleaning rid (%d)...\n",(int)rid);
+
+ /*
+ * Create payload
+ */
+ ridstr = slapi_ch_smprintf("%d:%s", rid, slapi_sdn_get_dn(replica_get_root(replica)));
+ payload = create_ruv_payload(ridstr);
+ if(payload == NULL){
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: failed to create ext op payload, aborting task\n");
+ goto done;
+ }
+
+ agmt_obj = agmtlist_get_first_agreement_for_replica (replica);
+ while (agmt_obj)
+ {
+ agmt = (Repl_Agmt*)object_get_data (agmt_obj);
+ dn = agmt_get_dn_byref(agmt);
+ conn = (Repl_Connection *)agmt_get_connection(agmt);
+ if(conn == NULL){
+ /* no connection for this agreement, and move on */
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: the replica (%s), is "
+ "missing the connection. This replica will not be cleaned.\n", slapi_sdn_get_dn(dn));
+ agmt_obj = agmtlist_get_next_agreement_for_replica (replica, agmt_obj);
+ continue;
+ }
+ crc = conn_connect(conn);
+ if (CONN_OPERATION_FAILED == crc ){
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: failed to connect "
+ "to repl agreement connection (%s), error %d\n",slapi_sdn_get_dn(dn), ACQUIRE_TRANSIENT_ERROR);
+ } else if (CONN_SSL_NOT_ENABLED == crc){
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: failed to acquire "
+ "repl agmt connection (%s), errror %d\n",slapi_sdn_get_dn(dn), ACQUIRE_FATAL_ERROR);
+ } else {
+ conn_cancel_linger(conn);
+ crc = conn_send_extended_operation(conn, REPL_CLEANRUV_OID, payload, NULL, &send_msgid);
+ if (CONN_OPERATION_SUCCESS != crc){
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: failed to send "
+ "cleanruv extended op to repl agmt (%s), error %d\n", slapi_sdn_get_dn(dn), crc);
+ } else {
+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "cleanAllRUV_task: successfully sent "
+ "cleanruv extended op to (%s)\n",slapi_sdn_get_dn(dn));
+ }
+ conn_start_linger(conn);
+ }
+ if(crc){
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: replica (%s) has not "
+ "been cleaned. You will need to rerun the CLEANALLRUV task on this replica.\n", slapi_sdn_get_dn(dn));
+ rc = crc;
+ }
+ agmt_obj = agmtlist_get_next_agreement_for_replica (replica, agmt_obj);
+ }
+
+done:
+
+ if(payload)
+ ber_bvfree(payload);
+
+ slapi_ch_free_string(&ridstr);
+
+ /*
+ * Now run the cleanruv task
+ */
+ replica_execute_cleanruv_task (r, rid, returntext);
+
+ if(rc == 0){
+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "cleanAllRUV_task: operation successful\n");
+ } else {
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanAllRUV_task: operation failed (%d)\n",rc);
+ }
+
+ return rc;
+}
+
+static int
+replica_execute_release_ruv_task(Object *r, ReplicaId rid, char *returntext)
+{
+ Repl_Connection *conn;
+ Replica *replica = (Replica*)object_get_data (r);
+ Object *agmt_obj;
+ Repl_Agmt *agmt;
+ ConnResult crc;
+ const Slapi_DN *dn = NULL;
+ struct berval *payload = NULL;
+ char *ridstr = NULL;
+ int send_msgid = 0;
+ int rc = 0;
+
+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "releaseRUV_task: releasing rid (%d)...\n", rid);
+
+ /*
+ * Set the released rid, and trigger cl trimmming
+ */
+ set_released_rid((int)rid);
+ trigger_cl_trimming();
+ /*
+ * Create payload
+ */
+ ridstr = slapi_ch_smprintf("%d:%s", rid, slapi_sdn_get_dn(replica_get_root(replica)));
+ payload = create_ruv_payload(ridstr);
+ if(payload == NULL){
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "releaseRUV_task: failed to create ext op payload, aborting op\n");
+ rc = -1;
+ goto done;
+ }
+
+ agmt_obj = agmtlist_get_first_agreement_for_replica (replica);
+ while (agmt_obj)
+ {
+ agmt = (Repl_Agmt*)object_get_data (agmt_obj);
+ dn = agmt_get_dn_byref(agmt);
+ conn = (Repl_Connection *)agmt_get_connection(agmt);
+ if(conn == NULL){
+ /* no connection for this agreement, log error, and move on */
+ agmt_obj = agmtlist_get_next_agreement_for_replica (replica, agmt_obj);
+ continue;
+ }
+ crc = conn_connect(conn);
+ if (CONN_OPERATION_FAILED == crc ){
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "releaseRUV_task: failed to connect "
+ "to repl agmt (%s), error %d\n",slapi_sdn_get_dn(dn), ACQUIRE_TRANSIENT_ERROR);
+ rc = LDAP_OPERATIONS_ERROR;
+ } else if (CONN_SSL_NOT_ENABLED == crc){
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "releaseRUV_task: failed to acquire "
+ "repl agmt (%s), error %d\n",slapi_sdn_get_dn(dn), ACQUIRE_FATAL_ERROR);
+ rc = LDAP_OPERATIONS_ERROR;
+ } else {
+ conn_cancel_linger(conn);
+ crc = conn_send_extended_operation(conn, REPL_RELEASERUV_OID, payload, NULL, &send_msgid);
+ if (CONN_OPERATION_SUCCESS != crc){
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "releaseRUV_task: failed to send "
+ "releaseruv extended op to repl agmt (%s), error %d\n", slapi_sdn_get_dn(dn), crc);
+ rc = LDAP_OPERATIONS_ERROR;
+ } else {
+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "releaseRUV_task: successfully sent "
+ "extended op to (%s)\n",slapi_sdn_get_dn(dn));
+ }
+ conn_start_linger(conn);
+ }
+ if(crc){
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "releaseRUV_task: replica (%s) has not "
+ "been cleaned. You will need to rerun the RELEASERUV task on this replica\n",
+ slapi_sdn_get_dn(dn));
+ rc = crc;
+ }
+ agmt_obj = agmtlist_get_next_agreement_for_replica (replica, agmt_obj);
+ }
+
+done:
+ /*
+ * reset the released/clean rid
+ */
+ if(rc == 0){
+ set_released_rid(ALREADY_RELEASED);
+ delete_cleaned_rid();
+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "releaseRUV_task: Successfully released rid (%d)\n", rid);
+ } else {
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "releaseRUV_task: Failed to release rid (%d), error (%d)\n", rid, rc);
+ }
+
+ if(payload)
+ ber_bvfree(payload);
+
+ slapi_ch_free_string(&ridstr);
+
+ return rc;
+}
+
+static struct berval *
+create_ruv_payload(char *value){
+ struct berval *req_data = NULL;
+ BerElement *tmp_bere = NULL;
+ if ((tmp_bere = der_alloc()) == NULL){
+ goto error;
+ }
+ if (ber_printf(tmp_bere, "{s", value) == -1){
+ goto error;
+ }
+
+ if (ber_printf(tmp_bere, "}") == -1){
+ goto error;
+ }
+
+ if (ber_flatten(tmp_bere, &req_data) == -1){
+ goto error;
+ }
+
+ goto done;
+
+error:
+ if (NULL != req_data){
+ ber_bvfree(req_data);
+ req_data = NULL;
+ }
+
+done:
+ if (NULL != tmp_bere){
+ ber_free(tmp_bere, 1);
+ tmp_bere = NULL;
+ }
+
+ return req_data;
+}
+
+int
+is_cleaned_rid(ReplicaId rid)
+{
+ if(rid == cleaned_rid){
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+void
+set_cleaned_rid( ReplicaId rid )
+{
+ cleaned_rid = rid;
+}
+
+void
+delete_cleaned_rid()
+{
+ cleaned_rid = 0;
+}
+
+int
+get_released_rid()
+{
+ return released_rid;
+}
+
+int
+is_released_rid(int rid)
+{
+ if(rid == released_rid){
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+int
+is_already_released_rid()
+{
+ if(released_rid == ALREADY_RELEASED){
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+void
+set_released_rid( int rid )
+{
+ released_rid = rid;
+}
+
+void
+delete_released_rid()
+{
+ released_rid = 0;
+}
diff --git a/ldap/servers/plugins/replication/repl5_ruv.c b/ldap/servers/plugins/replication/repl5_ruv.c
index e0b10ae..501cedc 100644
--- a/ldap/servers/plugins/replication/repl5_ruv.c
+++ b/ldap/servers/plugins/replication/repl5_ruv.c
@@ -863,10 +863,27 @@ ruv_covers_csn_internal(const RUV *ruv, const CSN *csn, PRBool strict)
{
rid = csn_get_replicaid(csn);
replica = ruvGetReplica (ruv, rid);
+ if((is_released_rid(rid)) || (replica == NULL && is_already_released_rid()) ){
+ /* this is a released rid, so return true */
+ return PR_TRUE;
+ }
if (replica == NULL)
{
- slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "ruv_covers_csn: replica for id %d not found\n", rid);
- return_value = PR_FALSE;
+ /*
+ * We don't know anything about this replica change in the cl, mark it to be zapped.
+ * This could of been a previously cleaned ruv, but the server was restarted before
+ * the change could be trimmed.
+ *
+ * Only the change log trimming calls this function with "strict" set. So we'll return success
+ * if strict is set.
+ */
+ if(strict){
+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "ruv_covers_csn: replica for id %d not found.\n", rid);
+ return_value = PR_TRUE;
+ } else {
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "ruv_covers_csn: replica for id %d not found.\n", rid);
+ return_value = PR_FALSE;
+ }
}
else
{
@@ -1403,12 +1420,20 @@ int ruv_add_csn_inprogress (RUV *ruv, const CSN *csn)
RUVElement* replica;
char csn_str[CSN_STRSIZE];
int rc = RUV_SUCCESS;
+ int rid = csn_get_replicaid (csn);
PR_ASSERT (ruv && csn);
/* locate ruvElement */
slapi_rwlock_wrlock (ruv->lock);
- replica = ruvGetReplica (ruv, csn_get_replicaid (csn));
+
+ if(is_cleaned_rid(rid)){
+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "ruv_add_csn_inprogress: invalid replica ID"
+ "(%d), aborting update\n", rid);
+ /* return success because we want to consume the update, but not perform it */
+ goto done;
+ }
+ replica = ruvGetReplica (ruv, rid);
if (replica == NULL)
{
replica = ruvAddReplicaNoCSN (ruv, csn_get_replicaid (csn), NULL/*purl*/);
@@ -1416,7 +1441,7 @@ int ruv_add_csn_inprogress (RUV *ruv, const CSN *csn)
{
if (slapi_is_loglevel_set(SLAPI_LOG_REPL)) {
slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "ruv_add_csn_inprogress: failed to add replica"
- " that created csn %s\n", csn_as_string (csn, PR_FALSE, csn_str));
+ " that created csn %s\n", csn_as_string (csn, PR_FALSE, csn_str));
}
rc = RUV_MEMORY_ERROR;
goto done;
diff --git a/ldap/servers/plugins/replication/repl_extop.c b/ldap/servers/plugins/replication/repl_extop.c
index 2ff3627..7e2ebbd 100644
--- a/ldap/servers/plugins/replication/repl_extop.c
+++ b/ldap/servers/plugins/replication/repl_extop.c
@@ -71,6 +71,7 @@
*
*/
static int check_replica_id_uniqueness(Replica *replica, RUV *supplier_ruv);
+static multimaster_mtnode_extension *replica_config_get_mtnode_by_dn(const char *dn);
static int
encode_ruv (BerElement *ber, const RUV *ruv)
@@ -1260,7 +1261,6 @@ multimaster_extop_EndNSDS50ReplicationRequest(Slapi_PBlock *pb)
{
/* The ruv from the supplier may have changed. Report the change on the
consumer side */
-
replica_update_ruv_consumer(r, connext->supplier_ruv);
}
@@ -1315,6 +1315,345 @@ free_and_return:
}
/*
+ * Return the mtnode extension of the dn
+ */
+static multimaster_mtnode_extension *
+replica_config_get_mtnode_by_dn(const char *dn)
+{
+ Slapi_DN *sdn;
+ mapping_tree_node *mtnode;
+ multimaster_mtnode_extension *ext = NULL;
+
+ sdn = slapi_sdn_new_dn_byval(dn);
+ mtnode = slapi_get_mapping_tree_node_by_dn (sdn);
+ if (mtnode) {
+ /* check if the replica object already exists in the subtree */
+ ext = (multimaster_mtnode_extension *)repl_con_get_ext (REPL_CON_EXT_MTNODE, mtnode);
+ }
+ slapi_sdn_free (&sdn);
+
+ return ext;
+}
+
+/*
+ * Decode the ber element passed to us by the cleanAllRUV task
+ */
+static int
+decode_cleanruv_payload(struct berval *extop_value, char **payload)
+{
+ BerElement *tmp_bere = NULL;
+ int rc = 0;
+
+ if ((tmp_bere = ber_init(extop_value)) == NULL){
+ rc = -1;
+ goto free_and_return;
+ }
+ if (ber_scanf(tmp_bere, "{") == LBER_ERROR){
+ rc = -1;
+ goto free_and_return;
+ }
+ if (ber_get_stringa(tmp_bere, payload) == LBER_DEFAULT){
+ rc = -1;
+ goto free_and_return;
+ }
+
+ if (ber_scanf(tmp_bere, "}") == LBER_ERROR){
+ rc = -1;
+ goto free_and_return;
+ }
+
+free_and_return:
+ if (-1 == rc){
+ slapi_ch_free_string(payload);
+ }
+ if (NULL != tmp_bere){
+ ber_free(tmp_bere, 1);
+ tmp_bere = NULL;
+ }
+ return rc;
+}
+
+/*
+ * Process the REPL_CLEANRUV_OID extended operation.
+ *
+ * The payload consists of the replica ID, and the repl root dn. Since this is
+ * basically a replication operation, it could of originated here and bounced
+ * back from another master. So check the rid against the "cleaned_rid". If
+ * it's a match, then we were already here, and we can just return success.
+ *
+ * Otherwise, we the set the cleaned_rid from the payload, fire off extended ops
+ * to all the replica agreements on this replica. Then perform the actual
+ * cleanruv_task on this replica.
+ */
+int
+multimaster_extop_cleanruv(Slapi_PBlock *pb){
+ multimaster_mtnode_extension *mtnode_ext;
+ Repl_Connection *conn;
+ const Slapi_DN *dn;
+ Replica *r = NULL;
+ Object *agmt_obj;
+ Repl_Agmt *agmt;
+ ConnResult crc;
+ struct berval *extop_value;
+ char *extop_oid;
+ char *repl_root;
+ char *payload = NULL;
+ char *iter;
+ int send_msgid = 0;
+ int rid = 0;
+ int rc = 0;
+
+ slapi_pblock_get(pb, SLAPI_EXT_OP_REQ_OID, &extop_oid);
+ slapi_pblock_get(pb, SLAPI_EXT_OP_REQ_VALUE, &extop_value);
+
+ if (NULL == extop_oid || strcmp(extop_oid, REPL_CLEANRUV_OID) != 0 ||
+ NULL == extop_value || NULL == extop_value->bv_val){
+ /* something is wrong, error out */
+ return -1;
+ }
+
+ /*
+ * Extract the rid and repl_root from the payload
+ */
+ if(decode_cleanruv_payload(extop_value, &payload)){
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanruv_extop: failed to decode payload. Aborting ext op\n");
+ return -1;
+ }
+ rid = atoi(ldap_utf8strtok_r(payload, ":", &iter));
+ repl_root = ldap_utf8strtok_r(iter, ":", &iter);
+
+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "cleanruv_extop: cleaning rid (%d)...\n",rid);
+
+ /*
+ * If we already cleaned this server, just return success
+ */
+ if(is_cleaned_rid(rid)){
+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "cleanruv_extop: rid (%d) has already been cleaned, skipping\n",rid);
+ return rc;
+ } else {
+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "cleanruv_extop: cleaning rid (%d)...\n", rid);
+ }
+
+ /*
+ * Get the node, so we can get the replica and its agreements
+ */
+ if((mtnode_ext = replica_config_get_mtnode_by_dn(repl_root)) == NULL){
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanruv_extop: failed to get replication node "
+ "from (%s), aborting operation\n", repl_root);
+ return -1;
+ }
+ if (mtnode_ext->replica)
+ object_acquire (mtnode_ext->replica);
+ if (mtnode_ext->replica == NULL){
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanruv_extop: replica is missing from (%s), "
+ "aborting operation\n",repl_root);
+ rc = LDAP_OPERATIONS_ERROR;
+ goto free_and_return;
+ }
+ r = (Replica*)object_get_data (mtnode_ext->replica);
+ /*
+ * Send out extended ops to each repl agreement
+ */
+ agmt_obj = agmtlist_get_first_agreement_for_replica (r);
+ while (agmt_obj)
+ {
+ agmt = (Repl_Agmt*)object_get_data (agmt_obj);
+ dn = agmt_get_dn_byref(agmt);
+ conn = (Repl_Connection *)agmt_get_connection(agmt);
+ if(conn == NULL){
+ /* no connection for this agreement, move on to the next agmt */
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanruv_extop: the replica (%s), is "
+ "missing the connection. This replica will not be cleaned.\n", slapi_sdn_get_dn(dn));
+ agmt_obj = agmtlist_get_next_agreement_for_replica (r, agmt_obj);
+ continue;
+ }
+ crc = conn_connect(conn);
+ if (CONN_OPERATION_FAILED == crc ){
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanruv_extop: failed to connect "
+ "to repl agreement connection (%s), error %d\n",slapi_sdn_get_dn(dn), ACQUIRE_TRANSIENT_ERROR);
+ rc = LDAP_OPERATIONS_ERROR;
+ } else if (CONN_SSL_NOT_ENABLED == crc){
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanruv_extop: failed to acquire "
+ "repl agmt connection (%s), error %d\n",slapi_sdn_get_dn(dn), ACQUIRE_FATAL_ERROR);
+ rc = LDAP_OPERATIONS_ERROR;
+ } else {
+ conn_cancel_linger(conn);
+ crc = conn_send_extended_operation(conn, REPL_CLEANRUV_OID, extop_value, NULL, &send_msgid);
+ if (CONN_OPERATION_SUCCESS != crc){
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanruv_extop: failed to send "
+ "clean_ruv extended op to repl agmt (%s), error %d\n", slapi_sdn_get_dn(dn), crc);
+ rc = LDAP_OPERATIONS_ERROR;
+ } else {
+ /* success */
+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "cleanruv_extop: successfully sent "
+ "extended op to (%s)\n",slapi_sdn_get_dn(dn) );
+ }
+ conn_start_linger(conn);
+ }
+ if(crc != CONN_OPERATION_SUCCESS){
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanruv_extop: replica (%s) has not "
+ "been cleaned. You will need to rerun the CLEANALLRUV task on this replica\n",
+ slapi_sdn_get_dn(dn) );
+ rc = LDAP_OPERATIONS_ERROR;
+ }
+ agmt_obj = agmtlist_get_next_agreement_for_replica (r, agmt_obj);
+ }
+
+ /* now clean the ruv */
+ replica_execute_cleanruv_task_ext(mtnode_ext->replica, rid);
+
+free_and_return:
+
+ if(rc == 0){
+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "cleanruv_extop: cleaned rid (%d)\n", rid);
+ } else {
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "cleanruv_extop: failed to clean rid (%d), error (%d)\n",rid, rc);
+ }
+
+ if (mtnode_ext->replica)
+ object_release (mtnode_ext->replica);
+
+ return rc;
+}
+
+/*
+ * Process the REPL_RELEASERUV_OID extended operation
+ *
+ * Once, all the replicas in the replication farm have been cleaned, then
+ * we need to "release" the cleaned_rid, or else we will reject all updates
+ * that come from that rid until we restart the server.
+ *
+ * We set the cleaned_ruv to zero(invalid rid), and then fire off extended
+ * operations to all of the replicas
+ */
+int
+multimaster_extop_releaseruv(Slapi_PBlock *pb){
+ multimaster_mtnode_extension *mtnode_ext;
+ Repl_Connection *conn;
+ const Slapi_DN *dn;
+ Replica *r = NULL;
+ Object *agmt_obj;
+ Repl_Agmt *agmt;
+ ConnResult crc;
+ struct berval *extop_value;
+ char *payload = NULL;
+ char *extop_oid;
+ char *repl_root;
+ char *iter;
+ int send_msgid = 0;
+ int rid = 0;
+ int rc = -1;
+
+ slapi_pblock_get(pb, SLAPI_EXT_OP_REQ_OID, &extop_oid);
+ slapi_pblock_get(pb, SLAPI_EXT_OP_REQ_VALUE, &extop_value);
+
+ if (NULL == extop_oid || strcmp(extop_oid, REPL_RELEASERUV_OID) != 0 ||
+ NULL == extop_value || NULL == extop_value->bv_val){
+ /* something is wrong, error out */
+ return -1;
+ }
+
+ if(decode_cleanruv_payload(extop_value, &payload)){
+ slapi_log_error(SLAPI_LOG_FATAL,repl_plugin_name, "releaseruv_extop: failed to decode payload, aborting ext op\n");
+ return -1;
+ }
+ rid = atoi(ldap_utf8strtok_r(payload, ":", &iter));
+ repl_root = ldap_utf8strtok_r(iter, ":", &iter);
+
+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "releaseruv_extop: releasing rid (%d)...\n",rid);
+ /*
+ * If we already released this ruv, just return.
+ */
+ if(is_released_rid(rid) || is_already_released_rid()){
+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "releaseruv_extop: rid (%d) has already been released, skipping\n",rid);
+ return 0;
+ } else {
+ /* set the released rid, and trigger trimming */
+ set_released_rid((int)rid);
+ trigger_cl_trimming();
+ }
+
+ if((mtnode_ext = replica_config_get_mtnode_by_dn(repl_root)) == NULL){
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "releaseruv_extop: failed to get node "
+ "from replication root dn(%s), aborting operation.\n", repl_root);
+ return -1;
+ }
+ if (mtnode_ext->replica)
+ object_acquire (mtnode_ext->replica);
+ if (mtnode_ext->replica == NULL){
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "releaseruv_extop: replica is missing from (%s), "
+ "aborting operation.\n", repl_root);
+ rc = LDAP_OPERATIONS_ERROR;
+ goto free_and_return;
+ }
+ r = (Replica*)object_get_data (mtnode_ext->replica);
+ /*
+ * Loop over the agreements, and send out extended ops
+ */
+ agmt_obj = agmtlist_get_first_agreement_for_replica (r);
+ while (agmt_obj)
+ {
+ agmt = (Repl_Agmt*)object_get_data (agmt_obj);
+ dn = agmt_get_dn_byref(agmt);
+ conn = (Repl_Connection *)agmt_get_connection(agmt);
+ if(conn == NULL){
+ /* no connection for this agreement, log error, and move on */
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "releaseruv_extop: the replica (%s), is "
+ "missing the connection. This replica will not be cleaned.\n", slapi_sdn_get_dn(dn));
+ agmt_obj = agmtlist_get_next_agreement_for_replica (r, agmt_obj);
+ continue;
+ }
+ crc = conn_connect(conn);
+ if (CONN_OPERATION_FAILED == crc ){
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "releaseruv_extop: failed to connect "
+ "to repl agreement connection (%s), error %d\n",slapi_sdn_get_dn(dn), ACQUIRE_TRANSIENT_ERROR);
+ rc = LDAP_OPERATIONS_ERROR;
+ } else if (CONN_SSL_NOT_ENABLED == crc){
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "releaseruv_extop: failed to acquire "
+ "repl agmt connection (%s), error %d\n",slapi_sdn_get_dn(dn), ACQUIRE_FATAL_ERROR);
+ rc = LDAP_OPERATIONS_ERROR;
+ } else {
+ conn_cancel_linger(conn);
+ crc = conn_send_extended_operation(conn, REPL_RELEASERUV_OID, extop_value, NULL, &send_msgid);
+ if (CONN_OPERATION_SUCCESS != crc){
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "releaseruv_extop: failed to send "
+ "releaseruv extended op to repl agmt (%s), error %d\n", slapi_sdn_get_dn(dn), crc);
+ rc = LDAP_OPERATIONS_ERROR;
+ } else {
+ /* success */
+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "releaseruv_extop: successfully sent "
+ "extended op to (%s)\n",slapi_sdn_get_dn(dn) );
+ rc = 0;
+ }
+ conn_start_linger(conn);
+ }
+ if(crc){
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "releaseruv_extop: replica (%s) has not "
+ "been cleaned. You will need to rerun the RELEASERUV task on this replica\n",
+ slapi_sdn_get_dn(dn) );
+ }
+ agmt_obj = agmtlist_get_next_agreement_for_replica (r, agmt_obj);
+ }
+
+free_and_return:
+ /*
+ * Set the rid as "ALREADY_RELEASED, and remove the cleaned ruv
+ */
+ if(rc == 0){
+ set_released_rid(ALREADY_RELEASED);
+ delete_cleaned_rid();
+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "releaseruv_extop: released rid (%d) successfully\n", rid);
+ } else {
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "releaseruv_extop: failed to release rid(%d), error (%d), please retry the task\n",rid, rc);
+ }
+
+ if(mtnode_ext->replica)
+ object_release (mtnode_ext->replica);
+
+ return rc;
+}
+
+/*
* This plugin entry point is a noop entry
* point. It's used when registering extops that
* are only used as responses. We'll never receive
11 years, 5 months
Branch '389-ds-base-1.2.11' - configure configure.ac
by Mark Reynolds
configure | 142 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
configure.ac | 2
2 files changed, 144 insertions(+)
New commits:
commit 96b9abe9f38766c83db69c0f25803b9b5f47429a
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Mon Oct 15 14:49:13 2012 -0400
Ticket 468 - if pam_passthru is enabled, need to AC_CHECK_HEADERS([security/pam_appl.h])
Bug Description: There is no check for a required header file in plugins/pam_passthrough/pam_ptimpl.h
Fix Description: Add header file check to configure.ac
https://fedorahosted.org/389/ticket/468
Reviewed by: richm(Thanks!)
(cherry picked from commit dbc0a95e675d8fba1bd4d4910dc01ea4f246f5c6)
diff --git a/configure b/configure
index 809b471..fba5e4f 100755
--- a/configure
+++ b/configure
@@ -20210,6 +20210,148 @@ if test "${enable_pam_passthru+set}" = set; then
fi
if test "$enable_pam_passthru" = yes ; then
+ # check for pam header file used by plugins/pass_passthru/pam_ptimpl.c
+ if test "${ac_cv_header_security_pam_appl_h+set}" = set; then
+ { $as_echo "$as_me:$LINENO: checking for security/pam_appl.h" >&5
+$as_echo_n "checking for security/pam_appl.h... " >&6; }
+if test "${ac_cv_header_security_pam_appl_h+set}" = set; then
+ $as_echo_n "(cached) " >&6
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_security_pam_appl_h" >&5
+$as_echo "$ac_cv_header_security_pam_appl_h" >&6; }
+else
+ # Is the header compilable?
+{ $as_echo "$as_me:$LINENO: checking security/pam_appl.h usability" >&5
+$as_echo_n "checking security/pam_appl.h usability... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <security/pam_appl.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_header_compiler=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:$LINENO: checking security/pam_appl.h presence" >&5
+$as_echo_n "checking security/pam_appl.h presence... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <security/pam_appl.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ ac_header_preproc=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { $as_echo "$as_me:$LINENO: WARNING: security/pam_appl.h: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: security/pam_appl.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: security/pam_appl.h: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: security/pam_appl.h: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { $as_echo "$as_me:$LINENO: WARNING: security/pam_appl.h: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: security/pam_appl.h: present but cannot be compiled" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: security/pam_appl.h: check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: security/pam_appl.h: check for missing prerequisite headers?" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: security/pam_appl.h: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: security/pam_appl.h: see the Autoconf documentation" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: security/pam_appl.h: section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: security/pam_appl.h: section \"Present But Cannot Be Compiled\"" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: security/pam_appl.h: proceeding with the preprocessor's result" >&5
+$as_echo "$as_me: WARNING: security/pam_appl.h: proceeding with the preprocessor's result" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: security/pam_appl.h: in the future, the compiler will take precedence" >&5
+$as_echo "$as_me: WARNING: security/pam_appl.h: in the future, the compiler will take precedence" >&2;}
+ ( cat <<\_ASBOX
+## ------------------------------------------ ##
+## Report this to http://bugzilla.redhat.com/ ##
+## ------------------------------------------ ##
+_ASBOX
+ ) | sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+{ $as_echo "$as_me:$LINENO: checking for security/pam_appl.h" >&5
+$as_echo_n "checking for security/pam_appl.h... " >&6; }
+if test "${ac_cv_header_security_pam_appl_h+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_header_security_pam_appl_h=$ac_header_preproc
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_security_pam_appl_h" >&5
+$as_echo "$ac_cv_header_security_pam_appl_h" >&6; }
+
+fi
+if test "x$ac_cv_header_security_pam_appl_h" = x""yes; then
+ :
+else
+ { { $as_echo "$as_me:$LINENO: error: Missing header file security/pam_appl.h" >&5
+$as_echo "$as_me: error: Missing header file security/pam_appl.h" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+
{ $as_echo "$as_me:$LINENO: result: yes" >&5
$as_echo "yes" >&6; }
diff --git a/configure.ac b/configure.ac
index df02cff..8281d67 100644
--- a/configure.ac
+++ b/configure.ac
@@ -97,6 +97,8 @@ AC_ARG_ENABLE(pam-passthru,
AS_HELP_STRING([--enable-pam-passthru],
[enable the PAM passthrough auth plugin (default: yes)]))
if test "$enable_pam_passthru" = yes ; then
+ # check for pam header file used by plugins/pass_passthru/pam_ptimpl.c
+ AC_CHECK_HEADER([security/pam_appl.h], [], [AC_MSG_ERROR([Missing header file security/pam_appl.h])])
AC_MSG_RESULT(yes)
AC_DEFINE([ENABLE_PAM_PASSTHRU], [1], [enable the pam passthru auth plugin])
else
11 years, 5 months
configure configure.ac
by Mark Reynolds
configure | 142 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
configure.ac | 2
2 files changed, 144 insertions(+)
New commits:
commit dbc0a95e675d8fba1bd4d4910dc01ea4f246f5c6
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Mon Oct 15 14:49:13 2012 -0400
Ticket 468 - if pam_passthru is enabled, need to AC_CHECK_HEADERS([security/pam_appl.h])
Bug Description: There is no check for a required header file in plugins/pam_passthrough/pam_ptimpl.h
Fix Description: Add header file check to configure.ac
https://fedorahosted.org/389/ticket/468
Reviewed by: richm(Thanks!)
diff --git a/configure b/configure
index 2793602..3737dc9 100755
--- a/configure
+++ b/configure
@@ -20211,6 +20211,148 @@ if test "${enable_pam_passthru+set}" = set; then
fi
if test "$enable_pam_passthru" = yes ; then
+ # check for pam header file used by plugins/pass_passthru/pam_ptimpl.c
+ if test "${ac_cv_header_security_pam_appl_h+set}" = set; then
+ { $as_echo "$as_me:$LINENO: checking for security/pam_appl.h" >&5
+$as_echo_n "checking for security/pam_appl.h... " >&6; }
+if test "${ac_cv_header_security_pam_appl_h+set}" = set; then
+ $as_echo_n "(cached) " >&6
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_security_pam_appl_h" >&5
+$as_echo "$ac_cv_header_security_pam_appl_h" >&6; }
+else
+ # Is the header compilable?
+{ $as_echo "$as_me:$LINENO: checking security/pam_appl.h usability" >&5
+$as_echo_n "checking security/pam_appl.h usability... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <security/pam_appl.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_header_compiler=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:$LINENO: checking security/pam_appl.h presence" >&5
+$as_echo_n "checking security/pam_appl.h presence... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <security/pam_appl.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ ac_header_preproc=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { $as_echo "$as_me:$LINENO: WARNING: security/pam_appl.h: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: security/pam_appl.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: security/pam_appl.h: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: security/pam_appl.h: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { $as_echo "$as_me:$LINENO: WARNING: security/pam_appl.h: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: security/pam_appl.h: present but cannot be compiled" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: security/pam_appl.h: check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: security/pam_appl.h: check for missing prerequisite headers?" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: security/pam_appl.h: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: security/pam_appl.h: see the Autoconf documentation" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: security/pam_appl.h: section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: security/pam_appl.h: section \"Present But Cannot Be Compiled\"" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: security/pam_appl.h: proceeding with the preprocessor's result" >&5
+$as_echo "$as_me: WARNING: security/pam_appl.h: proceeding with the preprocessor's result" >&2;}
+ { $as_echo "$as_me:$LINENO: WARNING: security/pam_appl.h: in the future, the compiler will take precedence" >&5
+$as_echo "$as_me: WARNING: security/pam_appl.h: in the future, the compiler will take precedence" >&2;}
+ ( cat <<\_ASBOX
+## ------------------------------------------ ##
+## Report this to http://bugzilla.redhat.com/ ##
+## ------------------------------------------ ##
+_ASBOX
+ ) | sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+{ $as_echo "$as_me:$LINENO: checking for security/pam_appl.h" >&5
+$as_echo_n "checking for security/pam_appl.h... " >&6; }
+if test "${ac_cv_header_security_pam_appl_h+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_header_security_pam_appl_h=$ac_header_preproc
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_security_pam_appl_h" >&5
+$as_echo "$ac_cv_header_security_pam_appl_h" >&6; }
+
+fi
+if test "x$ac_cv_header_security_pam_appl_h" = x""yes; then
+ :
+else
+ { { $as_echo "$as_me:$LINENO: error: Missing header file security/pam_appl.h" >&5
+$as_echo "$as_me: error: Missing header file security/pam_appl.h" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+
{ $as_echo "$as_me:$LINENO: result: yes" >&5
$as_echo "yes" >&6; }
diff --git a/configure.ac b/configure.ac
index 85eb3d8..975961c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -97,6 +97,8 @@ AC_ARG_ENABLE(pam-passthru,
AS_HELP_STRING([--enable-pam-passthru],
[enable the PAM passthrough auth plugin (default: yes)]))
if test "$enable_pam_passthru" = yes ; then
+ # check for pam header file used by plugins/pass_passthru/pam_ptimpl.c
+ AC_CHECK_HEADER([security/pam_appl.h], [], [AC_MSG_ERROR([Missing header file security/pam_appl.h])])
AC_MSG_RESULT(yes)
AC_DEFINE([ENABLE_PAM_PASSTHRU], [1], [enable the pam passthru auth plugin])
else
11 years, 5 months
Branch '389-ds-base-1.2.11' - ldap/schema
by Mark Reynolds
ldap/schema/01core389.ldif | 32 ++++++++++++++++----------------
1 file changed, 16 insertions(+), 16 deletions(-)
New commits:
commit 283561b3382e76e92e72a7cff3007220e5bcaab8
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Mon Oct 15 15:27:13 2012 -0400
Ticket 486 - nsslapd-enablePlugin should not be multivalued
Bug Description: Certain core DS schema attributes are defined multivalued, but some should be single valued.
Fix Description: Went through all the plugin, snmp, and replication attributes, and correctly set which
ones should be single valued.
https://fedorahosted.org/389/ticket/486
Reviewed by: richm(Thanks!)
(cherry picked from commit 70117a15bf70259ec978fd696cb0da08faf2cc29)
diff --git a/ldap/schema/01core389.ldif b/ldap/schema/01core389.ldif
index d9d1c33..fb707d3 100644
--- a/ldap/schema/01core389.ldif
+++ b/ldap/schema/01core389.ldif
@@ -46,22 +46,22 @@ dn: cn=schema
# attribute types:
#
attributeTypes: ( 2.16.840.1.113730.3.1.215 NAME 'oid' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
-attributeTypes: ( 2.16.840.1.113730.3.1.224 NAME 'nsslapd-pluginPath' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
-attributeTypes: ( 2.16.840.1.113730.3.1.225 NAME 'nsslapd-pluginInitfunc' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
-attributeTypes: ( 2.16.840.1.113730.3.1.226 NAME 'nsslapd-pluginType' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
-attributeTypes: ( 2.16.840.1.113730.3.1.227 NAME 'nsslapd-pluginId' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
-attributeTypes: ( 2.16.840.1.113730.3.1.228 NAME 'nsslapd-pluginVersion' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
-attributeTypes: ( 2.16.840.1.113730.3.1.229 NAME 'nsslapd-pluginVendor' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
-attributeTypes: ( 2.16.840.1.113730.3.1.230 NAME 'nsslapd-pluginDescription' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
-attributeTypes: ( 2.16.840.1.113730.3.1.231 NAME 'nsslapd-pluginEnabled' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
+attributeTypes: ( 2.16.840.1.113730.3.1.224 NAME 'nsslapd-pluginPath' 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.225 NAME 'nsslapd-pluginInitfunc' 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.226 NAME 'nsslapd-pluginType' 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.227 NAME 'nsslapd-pluginId' 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.228 NAME 'nsslapd-pluginVersion' 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.229 NAME 'nsslapd-pluginVendor' 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.230 NAME 'nsslapd-pluginDescription' 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.231 NAME 'nsslapd-pluginEnabled' 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.2104 NAME 'nsslapd-pluginConfigArea' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )
-attributeTypes: ( 2.16.840.1.113730.3.1.232 NAME 'nsSNMPEnabled' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
+attributeTypes: ( 2.16.840.1.113730.3.1.232 NAME 'nsSNMPEnabled' 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.233 NAME 'nsSNMPOrganization' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
attributeTypes: ( 2.16.840.1.113730.3.1.234 NAME 'nsSNMPLocation' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
attributeTypes: ( 2.16.840.1.113730.3.1.235 NAME 'nsSNMPContact' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
attributeTypes: ( 2.16.840.1.113730.3.1.236 NAME 'nsSNMPDescription' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
-attributeTypes: ( 2.16.840.1.113730.3.1.237 NAME 'nsSNMPMasterHost' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
-attributeTypes: ( 2.16.840.1.113730.3.1.238 NAME 'nsSNMPMasterPort' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
+attributeTypes: ( 2.16.840.1.113730.3.1.237 NAME 'nsSNMPMasterHost' 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.238 NAME 'nsSNMPMasterPort' 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.593 NAME 'nsSNMPName' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
attributeTypes: ( 2.16.840.1.113730.3.1.242 NAME 'nsSystemIndex' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
attributeTypes: ( 2.16.840.1.113730.3.1.327 NAME 'nsIndexType' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
@@ -83,14 +83,14 @@ attributeTypes: ( 2.16.840.1.113730.3.1.594 NAME 'nsDS5ReplicatedAttributeListTo
attributeTypes: ( 2.16.840.1.113730.3.1.586 NAME 'nsDS5ReplicaUpdateSchedule' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
attributeTypes: ( 2.16.840.1.113730.3.1.587 NAME 'nsds50ruv' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
attributeTypes: ( 2.16.840.1.113730.3.1.2027 NAME 'nsruvReplicaLastModified' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
-attributeTypes: ( 2.16.840.1.113730.3.1.588 NAME 'nsDS5ReplicaId' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
-attributeTypes: ( 2.16.840.1.113730.3.1.589 NAME 'nsDS5ReplicaType' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
-attributeTypes: ( 2.16.840.1.113730.3.1.590 NAME 'nsDS5ReplicaName' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
+attributeTypes: ( 2.16.840.1.113730.3.1.588 NAME 'nsDS5ReplicaId' 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.589 NAME 'nsDS5ReplicaType' 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.590 NAME 'nsDS5ReplicaName' 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.591 NAME 'nsDS5ReplicaReferral' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
attributeTypes: ( 2.16.840.1.113730.3.1.592 NAME 'nsDS5ReplicaAutoReferral' 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.607 NAME 'nsDS5Flags' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
+attributeTypes: ( 2.16.840.1.113730.3.1.607 NAME 'nsDS5Flags' 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.608 NAME 'nsDS5Task' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
-attributeTypes: ( 2.16.840.1.113730.3.1.609 NAME 'nsds5BeginReplicaRefresh' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
+attributeTypes: ( 2.16.840.1.113730.3.1.609 NAME 'nsds5BeginReplicaRefresh' 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.682 NAME 'nsds5ReplicaPurgeDelay' 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.684 NAME 'nsds5ReplicaChangeCount' 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.683 NAME 'nsds5ReplicaTombstonePurgeInterval' 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' )
11 years, 5 months
ldap/schema
by Mark Reynolds
ldap/schema/01core389.ldif | 32 ++++++++++++++++----------------
1 file changed, 16 insertions(+), 16 deletions(-)
New commits:
commit 70117a15bf70259ec978fd696cb0da08faf2cc29
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Mon Oct 15 15:27:13 2012 -0400
Ticket 486 - nsslapd-enablePlugin should not be multivalued
Bug Description: Certain core DS schema attributes are defined multivalued, but some should be single valued.
Fix Description: Went through all the plugin, snmp, and replication attributes, and correctly set which
ones should be single valued.
https://fedorahosted.org/389/ticket/486
Reviewed by: richm(Thanks!)
diff --git a/ldap/schema/01core389.ldif b/ldap/schema/01core389.ldif
index d9d1c33..fb707d3 100644
--- a/ldap/schema/01core389.ldif
+++ b/ldap/schema/01core389.ldif
@@ -46,22 +46,22 @@ dn: cn=schema
# attribute types:
#
attributeTypes: ( 2.16.840.1.113730.3.1.215 NAME 'oid' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
-attributeTypes: ( 2.16.840.1.113730.3.1.224 NAME 'nsslapd-pluginPath' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
-attributeTypes: ( 2.16.840.1.113730.3.1.225 NAME 'nsslapd-pluginInitfunc' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
-attributeTypes: ( 2.16.840.1.113730.3.1.226 NAME 'nsslapd-pluginType' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
-attributeTypes: ( 2.16.840.1.113730.3.1.227 NAME 'nsslapd-pluginId' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
-attributeTypes: ( 2.16.840.1.113730.3.1.228 NAME 'nsslapd-pluginVersion' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
-attributeTypes: ( 2.16.840.1.113730.3.1.229 NAME 'nsslapd-pluginVendor' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
-attributeTypes: ( 2.16.840.1.113730.3.1.230 NAME 'nsslapd-pluginDescription' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
-attributeTypes: ( 2.16.840.1.113730.3.1.231 NAME 'nsslapd-pluginEnabled' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
+attributeTypes: ( 2.16.840.1.113730.3.1.224 NAME 'nsslapd-pluginPath' 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.225 NAME 'nsslapd-pluginInitfunc' 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.226 NAME 'nsslapd-pluginType' 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.227 NAME 'nsslapd-pluginId' 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.228 NAME 'nsslapd-pluginVersion' 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.229 NAME 'nsslapd-pluginVendor' 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.230 NAME 'nsslapd-pluginDescription' 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.231 NAME 'nsslapd-pluginEnabled' 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.2104 NAME 'nsslapd-pluginConfigArea' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )
-attributeTypes: ( 2.16.840.1.113730.3.1.232 NAME 'nsSNMPEnabled' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
+attributeTypes: ( 2.16.840.1.113730.3.1.232 NAME 'nsSNMPEnabled' 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.233 NAME 'nsSNMPOrganization' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
attributeTypes: ( 2.16.840.1.113730.3.1.234 NAME 'nsSNMPLocation' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
attributeTypes: ( 2.16.840.1.113730.3.1.235 NAME 'nsSNMPContact' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
attributeTypes: ( 2.16.840.1.113730.3.1.236 NAME 'nsSNMPDescription' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
-attributeTypes: ( 2.16.840.1.113730.3.1.237 NAME 'nsSNMPMasterHost' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
-attributeTypes: ( 2.16.840.1.113730.3.1.238 NAME 'nsSNMPMasterPort' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
+attributeTypes: ( 2.16.840.1.113730.3.1.237 NAME 'nsSNMPMasterHost' 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.238 NAME 'nsSNMPMasterPort' 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.593 NAME 'nsSNMPName' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
attributeTypes: ( 2.16.840.1.113730.3.1.242 NAME 'nsSystemIndex' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
attributeTypes: ( 2.16.840.1.113730.3.1.327 NAME 'nsIndexType' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
@@ -83,14 +83,14 @@ attributeTypes: ( 2.16.840.1.113730.3.1.594 NAME 'nsDS5ReplicatedAttributeListTo
attributeTypes: ( 2.16.840.1.113730.3.1.586 NAME 'nsDS5ReplicaUpdateSchedule' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
attributeTypes: ( 2.16.840.1.113730.3.1.587 NAME 'nsds50ruv' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
attributeTypes: ( 2.16.840.1.113730.3.1.2027 NAME 'nsruvReplicaLastModified' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
-attributeTypes: ( 2.16.840.1.113730.3.1.588 NAME 'nsDS5ReplicaId' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
-attributeTypes: ( 2.16.840.1.113730.3.1.589 NAME 'nsDS5ReplicaType' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
-attributeTypes: ( 2.16.840.1.113730.3.1.590 NAME 'nsDS5ReplicaName' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
+attributeTypes: ( 2.16.840.1.113730.3.1.588 NAME 'nsDS5ReplicaId' 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.589 NAME 'nsDS5ReplicaType' 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.590 NAME 'nsDS5ReplicaName' 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.591 NAME 'nsDS5ReplicaReferral' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
attributeTypes: ( 2.16.840.1.113730.3.1.592 NAME 'nsDS5ReplicaAutoReferral' 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.607 NAME 'nsDS5Flags' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
+attributeTypes: ( 2.16.840.1.113730.3.1.607 NAME 'nsDS5Flags' 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.608 NAME 'nsDS5Task' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
-attributeTypes: ( 2.16.840.1.113730.3.1.609 NAME 'nsds5BeginReplicaRefresh' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
+attributeTypes: ( 2.16.840.1.113730.3.1.609 NAME 'nsds5BeginReplicaRefresh' 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.682 NAME 'nsds5ReplicaPurgeDelay' 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.684 NAME 'nsds5ReplicaChangeCount' 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.683 NAME 'nsds5ReplicaTombstonePurgeInterval' 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' )
11 years, 5 months