summaryrefslogtreecommitdiffstats
path: root/daemons/attrd/attrd_corosync.c
diff options
context:
space:
mode:
Diffstat (limited to 'daemons/attrd/attrd_corosync.c')
-rw-r--r--daemons/attrd/attrd_corosync.c295
1 files changed, 143 insertions, 152 deletions
diff --git a/daemons/attrd/attrd_corosync.c b/daemons/attrd/attrd_corosync.c
index 86dc67b..fb3b4e5 100644
--- a/daemons/attrd/attrd_corosync.c
+++ b/daemons/attrd/attrd_corosync.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2023 the Pacemaker project contributors
+ * Copyright 2013-2024 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
@@ -19,19 +19,19 @@
#include <crm/common/logging.h>
#include <crm/common/results.h>
#include <crm/common/strings_internal.h>
-#include <crm/msg_xml.h>
+#include <crm/common/xml.h>
#include "pacemaker-attrd.h"
static xmlNode *
attrd_confirmation(int callid)
{
- xmlNode *node = create_xml_node(NULL, __func__);
+ xmlNode *node = pcmk__xe_create(NULL, __func__);
- crm_xml_add(node, F_TYPE, T_ATTRD);
- crm_xml_add(node, F_ORIG, get_local_node_name());
- crm_xml_add(node, PCMK__XA_TASK, PCMK__ATTRD_CMD_CONFIRM);
- crm_xml_add_int(node, XML_LRM_ATTR_CALLID, callid);
+ crm_xml_add(node, PCMK__XA_T, PCMK__VALUE_ATTRD);
+ crm_xml_add(node, PCMK__XA_SRC, pcmk__cluster_local_node_name());
+ crm_xml_add(node, PCMK_XA_TASK, PCMK__ATTRD_CMD_CONFIRM);
+ crm_xml_add_int(node, PCMK__XA_CALL_ID, callid);
return node;
}
@@ -39,7 +39,7 @@ attrd_confirmation(int callid)
static void
attrd_peer_message(crm_node_t *peer, xmlNode *xml)
{
- const char *election_op = crm_element_value(xml, F_CRM_TASK);
+ const char *election_op = crm_element_value(xml, PCMK__XA_CRM_TASK);
if (election_op) {
attrd_handle_election_op(peer, xml);
@@ -64,7 +64,7 @@ attrd_peer_message(crm_node_t *peer, xmlNode *xml)
.result = PCMK__UNKNOWN_RESULT,
};
- request.op = crm_element_value_copy(request.xml, PCMK__XA_TASK);
+ request.op = crm_element_value_copy(request.xml, PCMK_XA_TASK);
CRM_CHECK(request.op != NULL, return);
attrd_handle_request(&request);
@@ -81,7 +81,7 @@ attrd_peer_message(crm_node_t *peer, xmlNode *xml)
* response so the originating peer knows what they're a confirmation
* for.
*/
- crm_element_value_int(xml, XML_LRM_ATTR_CALLID, &callid);
+ crm_element_value_int(xml, PCMK__XA_CALL_ID, &callid);
reply = attrd_confirmation(callid);
/* And then send the confirmation back to the originating peer. This
@@ -106,22 +106,22 @@ attrd_cpg_dispatch(cpg_handle_t handle,
uint32_t kind = 0;
xmlNode *xml = NULL;
const char *from = NULL;
- char *data = pcmk_message_common_cs(handle, nodeid, pid, msg, &kind, &from);
+ char *data = pcmk__cpg_message_data(handle, nodeid, pid, msg, &kind, &from);
if(data == NULL) {
return;
}
if (kind == crm_class_cluster) {
- xml = string2xml(data);
+ xml = pcmk__xml_parse(data);
}
if (xml == NULL) {
crm_err("Bad message of class %d received from %s[%u]: '%.120s'", kind, from, nodeid, data);
} else {
- crm_node_t *peer = crm_get_peer(nodeid, from);
-
- attrd_peer_message(peer, xml);
+ attrd_peer_message(pcmk__get_node(nodeid, from, NULL,
+ pcmk__node_search_cluster_member),
+ xml);
}
free_xml(xml);
@@ -143,86 +143,24 @@ attrd_cpg_destroy(gpointer unused)
/*!
* \internal
- * \brief Override an attribute sync with a local value
- *
- * Broadcast the local node's value for an attribute that's different from the
- * value provided in a peer's attribute synchronization response. This ensures a
- * node's values for itself take precedence and all peers are kept in sync.
+ * \brief Broadcast an update for a single attribute value
*
- * \param[in] a Attribute entry to override
- *
- * \return Local instance of attribute value
+ * \param[in] a Attribute to broadcast
+ * \param[in] v Attribute value to broadcast
*/
-static attribute_value_t *
-broadcast_local_value(const attribute_t *a)
-{
- attribute_value_t *v = g_hash_table_lookup(a->values, attrd_cluster->uname);
- xmlNode *sync = create_xml_node(NULL, __func__);
-
- crm_xml_add(sync, PCMK__XA_TASK, PCMK__ATTRD_CMD_SYNC_RESPONSE);
- attrd_add_value_xml(sync, a, v, false);
- attrd_send_message(NULL, sync, false);
- free_xml(sync);
- return v;
-}
-
-/*!
- * \internal
- * \brief Ensure a Pacemaker Remote node is in the correct peer cache
- *
- * \param[in] node_name Name of Pacemaker Remote node to check
- */
-static void
-cache_remote_node(const char *node_name)
+void
+attrd_broadcast_value(const attribute_t *a, const attribute_value_t *v)
{
- /* If we previously assumed this node was an unseen cluster node,
- * remove its entry from the cluster peer cache.
- */
- crm_node_t *dup = pcmk__search_cluster_node_cache(0, node_name, NULL);
+ xmlNode *op = pcmk__xe_create(NULL, PCMK_XE_OP);
- if (dup && (dup->uuid == NULL)) {
- reap_crm_member(0, node_name);
- }
-
- // Ensure node is in the remote peer cache
- CRM_ASSERT(crm_remote_peer_get(node_name) != NULL);
+ crm_xml_add(op, PCMK_XA_TASK, PCMK__ATTRD_CMD_UPDATE);
+ attrd_add_value_xml(op, a, v, false);
+ attrd_send_message(NULL, op, false);
+ free_xml(op);
}
#define state_text(state) pcmk__s((state), "in unknown state")
-/*!
- * \internal
- * \brief Return host's hash table entry (creating one if needed)
- *
- * \param[in,out] values Hash table of values
- * \param[in] host Name of peer to look up
- * \param[in] xml XML describing the attribute
- *
- * \return Pointer to new or existing hash table entry
- */
-static attribute_value_t *
-attrd_lookup_or_create_value(GHashTable *values, const char *host,
- const xmlNode *xml)
-{
- attribute_value_t *v = g_hash_table_lookup(values, host);
- int is_remote = 0;
-
- crm_element_value_int(xml, PCMK__XA_ATTR_IS_REMOTE, &is_remote);
- if (is_remote) {
- cache_remote_node(host);
- }
-
- if (v == NULL) {
- v = calloc(1, sizeof(attribute_value_t));
- CRM_ASSERT(v != NULL);
-
- pcmk__str_update(&v->nodename, host);
- v->is_remote = is_remote;
- g_hash_table_replace(values, v->nodename, v);
- }
- return(v);
-}
-
static void
attrd_peer_change_cb(enum crm_status_type kind, crm_node_t *peer, const void *data)
{
@@ -254,7 +192,7 @@ attrd_peer_change_cb(enum crm_status_type kind, crm_node_t *peer, const void *da
*/
if (attrd_election_won()
&& !pcmk_is_set(peer->flags, crm_remote_node)) {
- attrd_peer_sync(peer, NULL);
+ attrd_peer_sync(peer);
}
} else {
// Remove all attribute values associated with lost nodes
@@ -269,17 +207,14 @@ attrd_peer_change_cb(enum crm_status_type kind, crm_node_t *peer, const void *da
attrd_remove_voter(peer);
attrd_remove_peer_protocol_ver(peer->uname);
attrd_do_not_expect_from_peer(peer->uname);
-
- // Ensure remote nodes that come up are in the remote node cache
- } else if (!gone && is_remote) {
- cache_remote_node(peer->uname);
}
}
static void
record_peer_nodeid(attribute_value_t *v, const char *host)
{
- crm_node_t *known_peer = crm_get_peer(v->nodeid, host);
+ crm_node_t *known_peer = pcmk__get_node(v->nodeid, host, NULL,
+ pcmk__node_search_cluster_member);
crm_trace("Learned %s has node id %s", known_peer->uname, known_peer->uuid);
if (attrd_election_won()) {
@@ -287,34 +222,63 @@ record_peer_nodeid(attribute_value_t *v, const char *host)
}
}
+#define readable_value(rv_v) pcmk__s((rv_v)->current, "(unset)")
+
+#define readable_peer(p) \
+ (((p) == NULL)? "all peers" : pcmk__s((p)->uname, "unknown peer"))
+
static void
update_attr_on_host(attribute_t *a, const crm_node_t *peer, const xmlNode *xml,
const char *attr, const char *value, const char *host,
- bool filter, int is_force_write)
+ bool filter)
{
+ int is_remote = 0;
+ bool changed = false;
attribute_value_t *v = NULL;
- v = attrd_lookup_or_create_value(a->values, host, xml);
+ // Create entry for value if not already existing
+ v = g_hash_table_lookup(a->values, host);
+ if (v == NULL) {
+ v = pcmk__assert_alloc(1, sizeof(attribute_value_t));
+
+ v->nodename = pcmk__str_copy(host);
+ g_hash_table_replace(a->values, v->nodename, v);
+ }
+
+ // If value is for a Pacemaker Remote node, remember that
+ crm_element_value_int(xml, PCMK__XA_ATTR_IS_REMOTE, &is_remote);
+ if (is_remote) {
+ attrd_set_value_flags(v, attrd_value_remote);
+ CRM_ASSERT(pcmk__cluster_lookup_remote_node(host) != NULL);
+ }
- if (filter && !pcmk__str_eq(v->current, value, pcmk__str_casei)
- && pcmk__str_eq(host, attrd_cluster->uname, pcmk__str_casei)) {
+ // Check whether the value changed
+ changed = !pcmk__str_eq(v->current, value, pcmk__str_casei);
+ if (changed && filter && pcmk__str_eq(host, attrd_cluster->uname,
+ pcmk__str_casei)) {
+ /* Broadcast the local value for an attribute that differs from the
+ * value provided in a peer's attribute synchronization response. This
+ * ensures a node's values for itself take precedence and all peers are
+ * kept in sync.
+ */
+ v = g_hash_table_lookup(a->values, attrd_cluster->uname);
crm_notice("%s[%s]: local value '%s' takes priority over '%s' from %s",
- attr, host, v->current, value, peer->uname);
- v = broadcast_local_value(a);
+ attr, host, readable_value(v), value, peer->uname);
+ attrd_broadcast_value(a, v);
- } else if (!pcmk__str_eq(v->current, value, pcmk__str_casei)) {
+ } else if (changed) {
crm_notice("Setting %s[%s]%s%s: %s -> %s "
CRM_XS " from %s with %s write delay",
attr, host, a->set_type ? " in " : "",
- pcmk__s(a->set_type, ""), pcmk__s(v->current, "(unset)"),
+ pcmk__s(a->set_type, ""), readable_value(v),
pcmk__s(value, "(unset)"), peer->uname,
(a->timeout_ms == 0)? "no" : pcmk__readable_interval(a->timeout_ms));
pcmk__str_update(&v->current, value);
- a->changed = true;
+ attrd_set_attr_flags(a, attrd_attr_changed);
if (pcmk__str_eq(host, attrd_cluster->uname, pcmk__str_casei)
- && pcmk__str_eq(attr, XML_CIB_ATTR_SHUTDOWN, pcmk__str_none)) {
+ && pcmk__str_eq(attr, PCMK__NODE_ATTR_SHUTDOWN, pcmk__str_none)) {
if (!pcmk__str_eq(value, "0", pcmk__str_null_matches)) {
attrd_set_requesting_shutdown();
@@ -326,30 +290,37 @@ update_attr_on_host(attribute_t *a, const crm_node_t *peer, const xmlNode *xml,
// Write out new value or start dampening timer
if (a->timeout_ms && a->timer) {
- crm_trace("Delayed write out (%dms) for %s", a->timeout_ms, attr);
+ crm_trace("Delaying write of %s %s for dampening",
+ attr, pcmk__readable_interval(a->timeout_ms));
mainloop_timer_start(a->timer);
} else {
attrd_write_or_elect_attribute(a);
}
} else {
+ int is_force_write = 0;
+
+ crm_element_value_int(xml, PCMK__XA_ATTRD_IS_FORCE_WRITE,
+ &is_force_write);
+
if (is_force_write == 1 && a->timeout_ms && a->timer) {
/* Save forced writing and set change flag. */
/* The actual attribute is written by Writer after election. */
- crm_trace("Unchanged %s[%s] from %s is %s(Set the forced write flag)",
- attr, host, peer->uname, value);
- a->force_write = TRUE;
+ crm_trace("%s[%s] from %s is unchanged (%s), forcing write",
+ attr, host, peer->uname, pcmk__s(value, "unset"));
+ attrd_set_attr_flags(a, attrd_attr_force_write);
} else {
- crm_trace("Unchanged %s[%s] from %s is %s", attr, host, peer->uname, value);
+ crm_trace("%s[%s] from %s is unchanged (%s)",
+ attr, host, peer->uname, pcmk__s(value, "unset"));
}
}
- /* Set the seen flag for attribute processing held only in the own node. */
- v->seen = TRUE;
+ // This allows us to later detect local values that peer doesn't know about
+ attrd_set_value_flags(v, attrd_value_from_peer);
/* If this is a cluster node whose node ID we are learning, remember it */
- if ((v->nodeid == 0) && (v->is_remote == FALSE)
- && (crm_element_value_int(xml, PCMK__XA_ATTR_NODE_ID,
+ if ((v->nodeid == 0) && !pcmk_is_set(v->flags, attrd_value_remote)
+ && (crm_element_value_int(xml, PCMK__XA_ATTR_HOST_ID,
(int*)&v->nodeid) == 0) && (v->nodeid > 0)) {
record_peer_nodeid(v, host);
}
@@ -361,16 +332,13 @@ attrd_peer_update_one(const crm_node_t *peer, xmlNode *xml, bool filter)
attribute_t *a = NULL;
const char *attr = crm_element_value(xml, PCMK__XA_ATTR_NAME);
const char *value = crm_element_value(xml, PCMK__XA_ATTR_VALUE);
- const char *host = crm_element_value(xml, PCMK__XA_ATTR_NODE_NAME);
- int is_force_write = 0;
+ const char *host = crm_element_value(xml, PCMK__XA_ATTR_HOST);
if (attr == NULL) {
crm_warn("Could not update attribute: peer did not specify name");
return;
}
- crm_element_value_int(xml, PCMK__XA_ATTR_FORCE, &is_force_write);
-
a = attrd_populate_attribute(xml, attr);
if (a == NULL) {
return;
@@ -381,16 +349,16 @@ attrd_peer_update_one(const crm_node_t *peer, xmlNode *xml, bool filter)
GHashTableIter vIter;
crm_debug("Setting %s for all hosts to %s", attr, value);
- xml_remove_prop(xml, PCMK__XA_ATTR_NODE_ID);
+ pcmk__xe_remove_attr(xml, PCMK__XA_ATTR_HOST_ID);
g_hash_table_iter_init(&vIter, a->values);
while (g_hash_table_iter_next(&vIter, (gpointer *) & host, NULL)) {
- update_attr_on_host(a, peer, xml, attr, value, host, filter, is_force_write);
+ update_attr_on_host(a, peer, xml, attr, value, host, filter);
}
} else {
// Update attribute value for the given host
- update_attr_on_host(a, peer, xml, attr, value, host, filter, is_force_write);
+ update_attr_on_host(a, peer, xml, attr, value, host, filter);
}
/* If this is a message from some attrd instance broadcasting its protocol
@@ -412,13 +380,18 @@ broadcast_unseen_local_values(void)
g_hash_table_iter_init(&aIter, attributes);
while (g_hash_table_iter_next(&aIter, NULL, (gpointer *) & a)) {
+
g_hash_table_iter_init(&vIter, a->values);
while (g_hash_table_iter_next(&vIter, NULL, (gpointer *) & v)) {
- if (!(v->seen) && pcmk__str_eq(v->nodename, attrd_cluster->uname,
- pcmk__str_casei)) {
+
+ if (!pcmk_is_set(v->flags, attrd_value_from_peer)
+ && pcmk__str_eq(v->nodename, attrd_cluster->uname,
+ pcmk__str_casei)) {
+ crm_trace("* %s[%s]='%s' is local-only",
+ a->id, v->nodename, readable_value(v));
if (sync == NULL) {
- sync = create_xml_node(NULL, __func__);
- crm_xml_add(sync, PCMK__XA_TASK, PCMK__ATTRD_CMD_SYNC_RESPONSE);
+ sync = pcmk__xe_create(NULL, __func__);
+ crm_xml_add(sync, PCMK_XA_TASK, PCMK__ATTRD_CMD_SYNC_RESPONSE);
}
attrd_add_value_xml(sync, a, v, a->timeout_ms && a->timer);
}
@@ -435,17 +408,21 @@ broadcast_unseen_local_values(void)
int
attrd_cluster_connect(void)
{
+ int rc = pcmk_rc_ok;
+
attrd_cluster = pcmk_cluster_new();
- attrd_cluster->destroy = attrd_cpg_destroy;
- attrd_cluster->cpg.cpg_deliver_fn = attrd_cpg_dispatch;
- attrd_cluster->cpg.cpg_confchg_fn = pcmk_cpg_membership;
+ pcmk_cluster_set_destroy_fn(attrd_cluster, attrd_cpg_destroy);
+ pcmk_cpg_set_deliver_fn(attrd_cluster, attrd_cpg_dispatch);
+ pcmk_cpg_set_confchg_fn(attrd_cluster, pcmk__cpg_confchg_cb);
- crm_set_status_callback(&attrd_peer_change_cb);
+ pcmk__cluster_set_status_callback(&attrd_peer_change_cb);
- if (crm_cluster_connect(attrd_cluster) == FALSE) {
+ rc = pcmk_cluster_connect(attrd_cluster);
+ rc = pcmk_rc2legacy(rc);
+ if (rc != pcmk_ok) {
crm_err("Cluster connection failed");
- return -ENOTCONN;
+ return rc;
}
return pcmk_ok;
}
@@ -455,15 +432,19 @@ attrd_peer_clear_failure(pcmk__request_t *request)
{
xmlNode *xml = request->xml;
const char *rsc = crm_element_value(xml, PCMK__XA_ATTR_RESOURCE);
- const char *host = crm_element_value(xml, PCMK__XA_ATTR_NODE_NAME);
- const char *op = crm_element_value(xml, PCMK__XA_ATTR_OPERATION);
- const char *interval_spec = crm_element_value(xml, PCMK__XA_ATTR_INTERVAL);
- guint interval_ms = crm_parse_interval_spec(interval_spec);
+ const char *host = crm_element_value(xml, PCMK__XA_ATTR_HOST);
+ const char *op = crm_element_value(xml, PCMK__XA_ATTR_CLEAR_OPERATION);
+ const char *interval_spec = crm_element_value(xml,
+ PCMK__XA_ATTR_CLEAR_INTERVAL);
+ guint interval_ms = 0U;
char *attr = NULL;
GHashTableIter iter;
regex_t regex;
- crm_node_t *peer = crm_get_peer(0, request->peer);
+ crm_node_t *peer = pcmk__get_node(0, request->peer, NULL,
+ pcmk__node_search_cluster_member);
+
+ pcmk_parse_interval_spec(interval_spec, &interval_ms);
if (attrd_failure_regex(&regex, rsc, op, interval_ms) != pcmk_ok) {
crm_info("Ignoring invalid request to clear failures for %s",
@@ -471,10 +452,10 @@ attrd_peer_clear_failure(pcmk__request_t *request)
return;
}
- crm_xml_add(xml, PCMK__XA_TASK, PCMK__ATTRD_CMD_UPDATE);
+ crm_xml_add(xml, PCMK_XA_TASK, PCMK__ATTRD_CMD_UPDATE);
/* Make sure value is not set, so we delete */
- xml_remove_prop(xml, PCMK__XA_ATTR_VALUE);
+ pcmk__xe_remove_attr(xml, PCMK__XA_ATTR_VALUE);
g_hash_table_iter_init(&iter, attributes);
while (g_hash_table_iter_next(&iter, (gpointer *) &attr, NULL)) {
@@ -492,7 +473,7 @@ attrd_peer_clear_failure(pcmk__request_t *request)
* \internal
* \brief Load attributes from a peer sync response
*
- * \param[in] peer Peer that sent clear request
+ * \param[in] peer Peer that sent sync response
* \param[in] peer_won Whether peer is the attribute writer
* \param[in,out] xml Request XML
*/
@@ -510,11 +491,11 @@ attrd_peer_sync_response(const crm_node_t *peer, bool peer_won, xmlNode *xml)
}
// Process each attribute update in the sync response
- for (xmlNode *child = pcmk__xml_first_child(xml); child != NULL;
- child = pcmk__xml_next(child)) {
+ for (xmlNode *child = pcmk__xe_first_child(xml, NULL, NULL, NULL);
+ child != NULL; child = pcmk__xe_next(child)) {
+
attrd_peer_update(peer, child,
- crm_element_value(child, PCMK__XA_ATTR_NODE_NAME),
- true);
+ crm_element_value(child, PCMK__XA_ATTR_HOST), true);
}
if (peer_won) {
@@ -540,7 +521,9 @@ attrd_peer_remove(const char *host, bool uncache, const char *source)
GHashTableIter aIter;
CRM_CHECK(host != NULL, return);
- crm_notice("Removing all %s attributes for peer %s", host, source);
+ crm_notice("Removing all %s attributes for node %s "
+ CRM_XS " %s reaping node from cache",
+ host, source, (uncache? "and" : "without"));
g_hash_table_iter_init(&aIter, attributes);
while (g_hash_table_iter_next(&aIter, NULL, (gpointer *) & a)) {
@@ -550,33 +533,40 @@ attrd_peer_remove(const char *host, bool uncache, const char *source)
}
if (uncache) {
- crm_remote_peer_cache_remove(host);
- reap_crm_member(0, host);
+ pcmk__purge_node_from_cache(host, 0);
}
}
+/*!
+ * \internal
+ * \brief Send all known attributes and values to a peer
+ *
+ * \param[in] peer Peer to send sync to (if NULL, broadcast to all peers)
+ */
void
-attrd_peer_sync(crm_node_t *peer, xmlNode *xml)
+attrd_peer_sync(crm_node_t *peer)
{
GHashTableIter aIter;
GHashTableIter vIter;
attribute_t *a = NULL;
attribute_value_t *v = NULL;
- xmlNode *sync = create_xml_node(NULL, __func__);
+ xmlNode *sync = pcmk__xe_create(NULL, __func__);
- crm_xml_add(sync, PCMK__XA_TASK, PCMK__ATTRD_CMD_SYNC_RESPONSE);
+ crm_xml_add(sync, PCMK_XA_TASK, PCMK__ATTRD_CMD_SYNC_RESPONSE);
g_hash_table_iter_init(&aIter, attributes);
while (g_hash_table_iter_next(&aIter, NULL, (gpointer *) & a)) {
g_hash_table_iter_init(&vIter, a->values);
while (g_hash_table_iter_next(&vIter, NULL, (gpointer *) & v)) {
- crm_debug("Syncing %s[%s] = %s to %s", a->id, v->nodename, v->current, peer?peer->uname:"everyone");
+ crm_debug("Syncing %s[%s]='%s' to %s",
+ a->id, v->nodename, readable_value(v),
+ readable_peer(peer));
attrd_add_value_xml(sync, a, v, false);
}
}
- crm_debug("Syncing values to %s", peer?peer->uname:"everyone");
+ crm_debug("Syncing values to %s", readable_peer(peer));
attrd_send_message(peer, sync, false);
free_xml(sync);
}
@@ -589,9 +579,10 @@ attrd_peer_update(const crm_node_t *peer, xmlNode *xml, const char *host,
CRM_CHECK((peer != NULL) && (xml != NULL), return);
if (xml->children != NULL) {
- for (xmlNode *child = first_named_child(xml, XML_ATTR_OP); child != NULL;
- child = crm_next_same_xml(child)) {
- attrd_copy_xml_attributes(xml, child);
+ for (xmlNode *child = pcmk__xe_first_child(xml, PCMK_XE_OP, NULL, NULL);
+ child != NULL; child = pcmk__xe_next_same(child)) {
+
+ pcmk__xe_copy_attrs(child, xml, pcmk__xaf_no_overwrite);
attrd_peer_update_one(peer, child, filter);
if (attrd_request_has_sync_point(child)) {