replmd: Avoid duplicated debug/warnings
authorTim Beale <timbeale@catalyst.net.nz>
Fri, 11 Aug 2017 03:39:35 +0000 (15:39 +1200)
committerGarming Sam <garming@samba.org>
Mon, 18 Sep 2017 03:51:25 +0000 (05:51 +0200)
We display warnings if a target object is missing but it's still OK to
continue the replication. Currently we need to check the target twice -
once to verify it when we first receive it, and once when we actually
commit it (we can't skip the 2nd check altogether because in the join
case, they could occur quite far apart).

One annoying side-effect is we get the same warning message coming out
twice in these special cases.

In the cases where we're checking the dsdb_repl_flags, we can actually
just bypass the verification checks for the target object (if it doesn't
exist we still continue anyway). This may save us a tiny bit of
unnecessary work.

For cross-partition links, we can limit logging these warnings to when
the objects are actually being committed. This avoids spurious warnings
in the join case (i.e. we receive the link before we receive the target
object's partition, but we have received all partitions by the time we
actually commit the objects).

Signed-off-by: Tim Beale <timbeale@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12972
Reviewed-by: Garming Sam <garming@catalyst.net.nz>
source4/dsdb/samdb/ldb_modules/repl_meta_data.c

index 1e78045e7238e12594ed95c2d5dff4ad0c7d99a2..909a1be3e7504bf166361a1d1e320b00ffb66789 100644 (file)
@@ -6734,6 +6734,7 @@ static int replmd_allow_missing_target(struct ldb_module *module,
                                       TALLOC_CTX *mem_ctx,
                                       struct ldb_dn *target_dn,
                                       struct ldb_dn *source_dn,
+                                      bool is_obj_commit,
                                       struct GUID *guid,
                                       uint32_t dsdb_repl_flags,
                                       bool *ignore_link,
@@ -6793,18 +6794,27 @@ static int replmd_allow_missing_target(struct ldb_module *module,
                                       ldb_dn_get_linearized(source_dn));
                return LDB_ERR_NO_SUCH_OBJECT;
        }
-       
+
        /*
         * The target of the cross-partition link is missing. Continue
         * and try to at least add the forward-link. This isn't great,
         * but a partial link can be fixed by dbcheck, so it's better
         * than dropping the link completely.
         */
-       DBG_WARNING("%s cross-partition target %s linked from %s\n",
-                   missing_str, ldb_dn_get_linearized(target_dn),
-                   ldb_dn_get_linearized(source_dn));
        *ignore_link = false;
 
+       if (is_obj_commit) {
+
+               /*
+                * Only log this when we're actually committing the objects.
+                * This avoids spurious logs, i.e. if we're just verifying the
+                * received link during a join.
+                */
+               DBG_WARNING("%s cross-partition target %s linked from %s\n",
+                           missing_str, ldb_dn_get_linearized(target_dn),
+                           ldb_dn_get_linearized(source_dn));
+       }
+       
        return LDB_SUCCESS;
 }
 
@@ -6818,6 +6828,7 @@ static int replmd_check_target_exists(struct ldb_module *module,
                                      struct dsdb_dn *dsdb_dn,
                                      struct la_entry *la_entry,
                                      struct ldb_dn *source_dn,
+                                     bool is_obj_commit,
                                      struct GUID *guid,
                                      bool *ignore_link)
 {
@@ -6894,7 +6905,7 @@ static int replmd_check_target_exists(struct ldb_module *module,
                 * fail the replication, or add a partial link
                 */
                ret = replmd_allow_missing_target(module, tmp_ctx, dsdb_dn->dn,
-                                                 source_dn, guid,
+                                                 source_dn, is_obj_commit, guid,
                                                  la_entry->dsdb_repl_flags,
                                                  ignore_link, "Unknown");
 
@@ -6925,8 +6936,8 @@ static int replmd_check_target_exists(struct ldb_module *module,
                         * link, fail the replication, or add a partial link
                         */
                        ret = replmd_allow_missing_target(module, tmp_ctx,
-                                                         dsdb_dn->dn,
-                                                         source_dn, guid,
+                                                         dsdb_dn->dn, source_dn,
+                                                         is_obj_commit, guid,
                                                          la_entry->dsdb_repl_flags,
                                                          ignore_link, "Deleted");
                }
@@ -7084,8 +7095,18 @@ static int replmd_verify_linked_attribute(struct replmd_replicated_request *ar,
                return ret;
        }
 
-       ret = replmd_check_target_exists(module, tgt_dsdb_dn, la,
-                                        src_msg->dn, &guid, &dummy);
+       /*
+        * We can skip the target object checks if we're only syncing critical
+        * objects, or we know the target is up-to-date. If either case, we
+        * still continue even if the target doesn't exist
+        */
+       if ((la->dsdb_repl_flags & (DSDB_REPL_FLAG_OBJECT_SUBSET |
+                                   DSDB_REPL_FLAG_TARGETS_UPTODATE)) == 0) {
+
+               ret = replmd_check_target_exists(module, tgt_dsdb_dn, la,
+                                                src_msg->dn, false, &guid,
+                                                &dummy);
+       }
 
        /*
         * When we fail to find the target object, the error code we pass
@@ -7173,7 +7194,7 @@ static int replmd_process_linked_attribute(struct ldb_module *module,
        }
 
        ret = replmd_check_target_exists(module, dsdb_dn, la_entry, msg->dn,
-                                        &guid, &ignore_link);
+                                        true, &guid, &ignore_link);
 
        if (ret != LDB_SUCCESS) {
                talloc_free(tmp_ctx);