ldap/servers/plugins/replication/repl5_inc_protocol.c | 53 +++++++++++++++---
1 file changed, 47 insertions(+), 6 deletions(-)
New commits:
commit c72f6ba1e991f6e1a4fef5fac04ee474ec846692
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Thu Mar 8 12:06:37 2012 -0700
Ticket 317 - RHDS fractional replication with excluded password policy attributes
leads to wrong error messages.
https://fedorahosted.org/389/ticket/317
Resolves: Ticket 317
Bug Description: RHDS fractional replication with excluded password policy attributes
leads to wrong error messages.
Reviewed by: nhosoi (Thanks!)
Branch: master
Fix Description: Fractional replication can remove _all_ mods in an add or
modify operation. The code should just skip add and modify operations
that contain no data.
Platforms tested: RHEL6 x86_64
Flag Day: no
Doc impact: no
cherry picked and ported from 72401ea2588d3aec7622155fdf5dd9e5af7f8f95 on
Directory_Server_8_2_Branch
diff --git a/ldap/servers/plugins/replication/repl5_inc_protocol.c
b/ldap/servers/plugins/replication/repl5_inc_protocol.c
index c9ad6fc..a615a29 100644
--- a/ldap/servers/plugins/replication/repl5_inc_protocol.c
+++ b/ldap/servers/plugins/replication/repl5_inc_protocol.c
@@ -163,6 +163,9 @@ typedef struct result_data
*/
#define PROTOCOL_IS_SHUTDOWN(prp) (event_occurred(prp, EVENT_PROTOCOL_SHUTDOWN) ||
prp->terminate)
+/* mods should be LDAPMod **mods */
+#define MODS_ARE_EMPTY(mods) ((mods == NULL) || (mods[0] == NULL))
+
/* Forward declarations */
static PRUint32 event_occurred(Private_Repl_Protocol *prp, PRUint32 event);
static void reset_events (Private_Repl_Protocol *prp);
@@ -1385,6 +1388,12 @@ replay_update(Private_Repl_Protocol *prp,
slapi_operation_parameters *op, int *m
LDAPMod **modrdn_mods = NULL;
char csn_str[CSN_STRSIZE]; /* For logging only */
+ if (message_id) {
+ /* if we get out of this function without setting message_id, it means
+ we didn't send an op, so no result needs to be processed */
+ *message_id = 0;
+ }
+
/* Construct the replication info control that accompanies the operation */
if (SLAPI_OPERATION_ADD == op->operation_type)
{
@@ -1445,8 +1454,21 @@ replay_update(Private_Repl_Protocol *prp,
slapi_operation_parameters *op, int *m
{
repl5_strip_fractional_mods(prp->agmt,entryattrs);
}
- return_value = conn_send_add(prp->conn, REPL_GET_DN(&op->target_address),
- entryattrs, update_control, message_id);
+ if (MODS_ARE_EMPTY(entryattrs)) {
+ if (slapi_is_loglevel_set(SLAPI_LOG_REPL)) {
+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name,
+ "%s: replay_update: %s operation (dn=\"%s\" csn=%s) "
+ "not sent - empty\n",
+ agmt_get_long_name(prp->agmt),
+ op2string(op->operation_type),
+ REPL_GET_DN(&op->target_address),
+ csn_as_string(op->csn, PR_FALSE, csn_str));
+ }
+ return_value = CONN_OPERATION_SUCCESS;
+ } else {
+ return_value = conn_send_add(prp->conn, REPL_GET_DN(&op->target_address),
+ entryattrs, update_control, message_id);
+ }
ldap_mods_free(entryattrs, 1);
}
break;
@@ -1457,8 +1479,21 @@ replay_update(Private_Repl_Protocol *prp,
slapi_operation_parameters *op, int *m
{
repl5_strip_fractional_mods(prp->agmt,op->p.p_modify.modify_mods);
}
- return_value = conn_send_modify(prp->conn,
REPL_GET_DN(&op->target_address),
- op->p.p_modify.modify_mods, update_control, message_id);
+ if (MODS_ARE_EMPTY(op->p.p_modify.modify_mods)) {
+ if (slapi_is_loglevel_set(SLAPI_LOG_REPL)) {
+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name,
+ "%s: replay_update: %ss operation (dn=\"%s\" csn=%s) "
+ "not sent - empty\n",
+ agmt_get_long_name(prp->agmt),
+ op2string(op->operation_type),
+ REPL_GET_DN(&op->target_address),
+ csn_as_string(op->csn, PR_FALSE, csn_str));
+ }
+ return_value = CONN_OPERATION_SUCCESS;
+ } else {
+ return_value = conn_send_modify(prp->conn,
REPL_GET_DN(&op->target_address),
+ op->p.p_modify.modify_mods, update_control, message_id);
+ }
break;
case SLAPI_OPERATION_DELETE:
return_value = conn_send_delete(prp->conn,
REPL_GET_DN(&op->target_address),
@@ -1869,7 +1904,7 @@ send_updates(Private_Repl_Protocol *prp, RUV *remote_update_vector,
PRUint32 *nu
replica_id = csn_get_replicaid(entry.op->csn);
uniqueid = entry.op->target_address.uniqueid;
- if (prp->repl50consumer)
+ if (prp->repl50consumer && message_id)
{
int operation, error = 0;
@@ -1881,7 +1916,7 @@ send_updates(Private_Repl_Protocol *prp, RUV *remote_update_vector,
PRUint32 *nu
csn_as_string(entry.op->csn, PR_FALSE, csn_str);
return_value = repl5_inc_update_from_op_result(prp, replay_crc, error, csn_str,
uniqueid, replica_id, &finished, num_changes_sent);
}
- else {
+ else if (message_id) {
/* Queue the details for pickup later in the response thread */
repl5_inc_operation *sop = NULL;
sop = repl5_inc_operation_new();
@@ -1891,6 +1926,12 @@ send_updates(Private_Repl_Protocol *prp, RUV *remote_update_vector,
PRUint32 *nu
sop->replica_id = replica_id;
PL_strncpyz(sop->uniqueid, uniqueid, sizeof(sop->uniqueid));
repl5_int_push_operation(rd,sop);
+ } else {
+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name,
+ "%s: Skipping update operation with no message_id (uniqueid %s, CSN
%s):\n",
+ agmt_get_long_name(prp->agmt),
+ entry.op->target_address.uniqueid, csn_str);
+ agmt_inc_last_update_changecount (prp->agmt,
csn_get_replicaid(entry.op->csn), 1 /*skipped*/);
}
}
break;