diff --git a/include/crm/cib/cib_types.h b/include/crm/cib/cib_types.h
index def8d27b84..3992f1f12b 100644
--- a/include/crm/cib/cib_types.h
+++ b/include/crm/cib/cib_types.h
@@ -1,351 +1,347 @@
 /*
  * Copyright 2004-2024 the Pacemaker project contributors
  *
  * The version control history for this file may have further details.
  *
  * This source code is licensed under the GNU Lesser General Public License
  * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
  */
 
 #ifndef PCMK__CRM_CIB_CIB_TYPES__H
 #  define PCMK__CRM_CIB_CIB_TYPES__H
 
 #  include <glib.h>             // gboolean, GList
 #  include <libxml/tree.h>      // xmlNode
 #  include <crm/common/ipc.h>
 #  include <crm/common/xml.h>
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 /**
  * \file
  * \brief Data types for Cluster Information Base access
  * \ingroup cib
  */
 
 enum cib_variant {
     cib_undefined = 0,
     cib_native    = 1,
     cib_file      = 2,
     cib_remote    = 3,
 };
 
 enum cib_state {
     // NOTE: sbd (as of at least 1.5.2) uses this value
     cib_connected_command,
 
     // NOTE: sbd (as of at least 1.5.2) uses this value
     cib_connected_query,
 
     cib_disconnected
 };
 
 enum cib_conn_type {
     cib_command,
 
     // NOTE: sbd (as of at least 1.5.2) uses this value
     cib_query,
 
     cib_no_connection,
     cib_command_nonblocking,
 };
 
 enum cib_call_options {
     cib_none            = 0,
     cib_verbose         = (1 << 0),  //!< Prefer stderr to logs
     cib_xpath           = (1 << 1),
     cib_multiple        = (1 << 2),
     cib_can_create      = (1 << 3),
     cib_discard_reply   = (1 << 4),
     cib_no_children     = (1 << 5),
     cib_xpath_address   = (1 << 6),
 
 #if !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1)
     // NOTE: sbd (as of at least 1.5.2) uses this value
     //! \deprecated This value will be removed in a future release
     cib_scope_local     = (1 << 8),
 #endif // !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1)
 
     cib_dryrun          = (1 << 9),
 
     /*!
      * \brief Process request when the client commits the active transaction
      *
      * Add the request to the client's active transaction instead of processing
      * it immediately. If the client has no active transaction, or if the
      * request is not supported in transactions, the call will fail.
      *
      * The request is added to the transaction synchronously, and the return
      * value indicates whether it was added successfully.
      *
      * Refer to \p cib_api_operations_t:init_transaction() and
      * \p cib_api_operations_t:end_transaction() for more details on CIB
      * transactions.
      */
     cib_transaction     = (1 << 10),
 
     /*!
      * \brief Treat new attribute values as atomic score updates where possible
      *
      * This option takes effect when updating XML attributes. For an attribute
      * named \c "name", if the new value is \c "name++" or \c "name+=X" for some
      * score \c X, the new value is set as follows:
      * * If attribute \c "name" is not already set to some value in the element
      *   being updated, the new value is set as a literal string.
      * * If the new value is \c "name++", then the attribute is set to its
      *   existing value (parsed as a score) plus 1.
      * * If the new value is \c "name+=X" for some score \c X, then the
      *   attribute is set to its existing value plus \c X, where the existing
      *   value and \c X are parsed and added as scores.
      *
      * Scores are integer values capped at \c INFINITY and \c -INFINITY. Refer
      * to Pacemaker Explained and to the \c char2score() function for more
      * details on scores, including how they're parsed and added.
      *
      * Note: This is implemented only for modify operations.
      */
     cib_score_update    = (1 << 11),
 
     // NOTE: sbd (as of at least 1.5.2) uses this value
     cib_sync_call       = (1 << 12),
 
     cib_no_mtime        = (1 << 13),
     cib_inhibit_notify  = (1 << 16),
     cib_force_diff      = (1 << 28),
 };
 
 typedef struct cib_s cib_t;
 
 typedef struct cib_api_operations_s {
     // NOTE: sbd (as of at least 1.5.2) uses this
     // @COMPAT At compatibility break, drop name (always use crm_system_name)
     int (*signon) (cib_t *cib, const char *name, enum cib_conn_type type);
 
     // NOTE: sbd (as of at least 1.5.2) uses this
     int (*signoff) (cib_t *cib);
 
     int (*free) (cib_t *cib);
 
     // NOTE: sbd (as of at least 1.5.2) uses this
     int (*add_notify_callback) (cib_t *cib, const char *event,
                                 void (*callback) (const char *event,
                                                   xmlNode *msg));
 
     // NOTE: sbd (as of at least 1.5.2) uses this
     int (*del_notify_callback) (cib_t *cib, const char *event,
                                 void (*callback) (const char *event,
                                                   xmlNode *msg));
     // NOTE: sbd (as of at least 1.5.2) uses this
     int (*set_connection_dnotify) (cib_t *cib,
                                    void (*dnotify) (gpointer user_data));
 
     // NOTE: sbd (as of at least 1.5.2) uses this
     //! \deprecated This method will be removed and should not be used
     int (*noop) (cib_t *cib, int call_options);
 
     int (*ping) (cib_t *cib, xmlNode **output_data, int call_options);
 
     // NOTE: sbd (as of at least 1.5.2) uses this
     int (*query) (cib_t *cib, const char *section, xmlNode **output_data,
                   int call_options);
 
     int (*query_from) (cib_t *cib, const char *host, const char *section,
                        xmlNode **output_data, int call_options);
 
     int (*sync) (cib_t *cib, const char *section, int call_options);
     int (*sync_from) (cib_t *cib, const char *host, const char *section,
                       int call_options);
     int (*upgrade) (cib_t *cib, int call_options);
     int (*bump_epoch) (cib_t *cib, int call_options);
 
     /*!
      * The \c <failed> element in the reply to a failed creation call is
      * deprecated since 2.1.8.
      */
     int (*create) (cib_t *cib, const char *section, xmlNode *data,
                    int call_options);
     int (*modify) (cib_t *cib, const char *section, xmlNode *data,
                    int call_options);
 
-    //! \deprecated Use the \p modify() method instead
-    int (*update) (cib_t *cib, const char *section, xmlNode *data,
-                   int call_options);
-
     int (*replace) (cib_t *cib, const char *section, xmlNode *data,
                     int call_options);
     int (*remove) (cib_t *cib, const char *section, xmlNode *data,
                    int call_options);
     int (*erase) (cib_t *cib, xmlNode **output_data, int call_options);
 
     //! \deprecated This method does nothing and should not be called
     int (*delete_absolute) (cib_t *cib, const char *section, xmlNode *data,
                             int call_options);
 
     //! \deprecated This method is not implemented and should not be used
     int (*quit) (cib_t *cib, int call_options);
 
     int (*register_notification) (cib_t *cib, const char *callback,
                                   int enabled);
     gboolean (*register_callback) (cib_t *cib, int call_id, int timeout,
                                    gboolean only_success, void *user_data,
                                    const char *callback_name,
                                    void (*callback) (xmlNode*, int, int,
                                                      xmlNode*, void *));
     gboolean (*register_callback_full)(cib_t *cib, int call_id, int timeout,
                                        gboolean only_success, void *user_data,
                                        const char *callback_name,
                                        void (*callback)(xmlNode *, int, int,
                                                         xmlNode *, void *),
                                        void (*free_func)(void *));
 
     /*!
      * \brief Set the local CIB manager as the cluster's primary instance
      *
      * \param[in,out] cib           CIB connection
      * \param[in]     call_options  Group of enum cib_call_options flags
      *
      * \return Legacy Pacemaker return code (in particular, pcmk_ok on success)
      */
     int (*set_primary)(cib_t *cib, int call_options);
 
     /*!
      * \brief Set the local CIB manager as a secondary instance
      *
      * \param[in,out] cib           CIB connection
      * \param[in]     call_options  Group of enum cib_call_options flags
      *
      * \return Legacy Pacemaker return code (in particular, pcmk_ok on success)
      */
     int (*set_secondary)(cib_t *cib, int call_options);
 
     /*!
      * \brief Get the given CIB connection's unique client identifier(s)
      *
      * These can be used to check whether this client requested the action that
      * triggered a CIB notification.
      *
      * \param[in]  cib       CIB connection
      * \param[out] async_id  If not \p NULL, where to store asynchronous client
      *                       ID
      * \param[out] sync_id   If not \p NULL, where to store synchronous client
      *                       ID
      *
      * \return Legacy Pacemaker return code
      *
      * \note Some variants may have only one client for both asynchronous and
      *       synchronous requests.
      */
     int (*client_id)(const cib_t *cib, const char **async_id,
                      const char **sync_id);
 
     /*!
      * \brief Initiate an atomic CIB transaction for this client
      *
      * If the client has initiated a transaction and a new request's call
      * options contain \p cib_transaction, the new request is appended to the
      * transaction for later processing.
      *
      * Supported requests are those that meet the following conditions:
      * * can be processed synchronously (with any changes applied to a working
      *   CIB copy)
      * * are not queries
      * * do not involve other nodes
      * * do not affect the state of pacemaker-based itself
      *
      * Currently supported CIB API functions include:
      * * \p bump_epoch()
      * * \p create()
      * * \p erase()
      * * \p modify()
      * * \p remove()
      * * \p replace()
      * * \p upgrade()
      *
      * Because the transaction is atomic, individual requests do not trigger
      * callbacks or notifications when they are processed, and they do not
      * receive output XML. The commit request itself can trigger callbacks and
      * notifications if any are registered.
      *
      * An \c init_transaction() call is always synchronous.
      *
      * \param[in,out] cib           CIB connection
      *
      * \return Legacy Pacemaker return code
      */
     int (*init_transaction)(cib_t *cib);
 
     /*!
      * \brief End and optionally commit this client's CIB transaction
      *
      * When a client commits a transaction, all requests in the transaction are
      * processed in a FIFO manner until either a request fails or all requests
      * have been processed. Changes are applied to a working copy of the CIB.
      * If a request fails, the transaction and working CIB copy are discarded,
      * and an error is returned. If all requests succeed, the working CIB copy
      * replaces the initial CIB copy.
      *
      * Callbacks and notifications can be triggered by the commit request itself
      * but not by the individual requests in a transaction.
      *
      * An \c end_transaction() call with \p commit set to \c false is always
      * synchronous.
      *
      * \param[in,out] cib           CIB connection
      * \param[in]     commit        If \p true, commit transaction; otherwise,
      *                              discard it
      * \param[in]     call_options  Group of <tt>enum cib_call_options</tt>
      *                              flags
      *
      * \return Legacy Pacemaker return code
      */
     int (*end_transaction)(cib_t *cib, bool commit, int call_options);
 
     /*!
      * \brief Set the user as whom all CIB requests via methods will be executed
      *
      * By default, the value of the \c CIB_user environment variable is used if
      * set. Otherwise, the current effective user is used.
      *
      * \param[in,out] cib   CIB connection
      * \param[in]     user  Name of user whose permissions to use when
      *                      processing requests
      */
     void (*set_user)(cib_t *cib, const char *user);
 
     int (*fetch_schemas)(cib_t *cib, xmlNode **output_data, const char *after_ver,
                          int call_options);
 } cib_api_operations_t;
 
 struct cib_s {
     // NOTE: sbd (as of at least 1.5.2) uses this
     enum cib_state state;
 
     enum cib_conn_type type;
     enum cib_variant variant;
 
     int call_id;
     int call_timeout;
     void *variant_opaque;
     void *delegate_fn;
 
     GList *notify_list;
 
     //! \deprecated This method will be removed in a future release
     void (*op_callback) (const xmlNode *msg, int call_id, int rc,
                          xmlNode *output);
 
     // NOTE: sbd (as of at least 1.5.2) uses this
     cib_api_operations_t *cmds;
 
     xmlNode *transaction;
 
     char *user;
 };
 
 #ifdef __cplusplus
 }
 #endif
 
 #endif // PCMK__CRM_CIB_CIB_TYPES__H
diff --git a/lib/cib/cib_client.c b/lib/cib/cib_client.c
index d4cdf2e2a2..5572551a10 100644
--- a/lib/cib/cib_client.c
+++ b/lib/cib/cib_client.c
@@ -1,801 +1,800 @@
 /*
  * Copyright 2004-2024 the Pacemaker project contributors
  *
  * The version control history for this file may have further details.
  *
  * This source code is licensed under the GNU Lesser General Public License
  * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
  */
 
 #include <crm_internal.h>
 #include <unistd.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <stdarg.h>
 #include <string.h>
 #include <pwd.h>
 
 #include <sys/stat.h>
 #include <sys/types.h>
 
 #include <glib.h>
 
 #include <crm/crm.h>
 #include <crm/cib/internal.h>
 #include <crm/common/xml.h>
 
 static GHashTable *cib_op_callback_table = NULL;
 
 #define op_common(cib) do {                                             \
         if(cib == NULL) {                                               \
             return -EINVAL;						\
         } else if(cib->delegate_fn == NULL) {                           \
             return -EPROTONOSUPPORT;                                    \
         }                                                               \
     } while(0)
 
 static gint
 ciblib_GCompareFunc(gconstpointer a, gconstpointer b)
 {
     int rc = 0;
     const cib_notify_client_t *a_client = a;
     const cib_notify_client_t *b_client = b;
 
     CRM_CHECK(a_client->event != NULL && b_client->event != NULL, return 0);
     rc = strcmp(a_client->event, b_client->event);
     if (rc == 0) {
         if (a_client->callback == b_client->callback) {
             return 0;
         } else if (((long)a_client->callback) < ((long)b_client->callback)) {
             crm_trace("callbacks for %s are not equal: %p < %p",
                       a_client->event, a_client->callback, b_client->callback);
             return -1;
         }
         crm_trace("callbacks for %s are not equal: %p > %p",
                   a_client->event, a_client->callback, b_client->callback);
         return 1;
     }
     return rc;
 }
 
 static int
 cib_client_add_notify_callback(cib_t * cib, const char *event,
                                void (*callback) (const char *event,
                                                  xmlNode * msg))
 {
     GList *list_item = NULL;
     cib_notify_client_t *new_client = NULL;
 
     if ((cib->variant != cib_native) && (cib->variant != cib_remote)) {
         return -EPROTONOSUPPORT;
     }
 
     crm_trace("Adding callback for %s events (%d)",
               event, g_list_length(cib->notify_list));
 
     new_client = pcmk__assert_alloc(1, sizeof(cib_notify_client_t));
     new_client->event = event;
     new_client->callback = callback;
 
     list_item = g_list_find_custom(cib->notify_list, new_client,
                                    ciblib_GCompareFunc);
 
     if (list_item != NULL) {
         crm_warn("Callback already present");
         free(new_client);
         return -EINVAL;
 
     } else {
         cib->notify_list = g_list_append(cib->notify_list, new_client);
 
         cib->cmds->register_notification(cib, event, 1);
 
         crm_trace("Callback added (%d)", g_list_length(cib->notify_list));
     }
     return pcmk_ok;
 }
 
 static int
 get_notify_list_event_count(cib_t *cib, const char *event)
 {
     int count = 0;
 
     for (GList *iter = g_list_first(cib->notify_list); iter != NULL;
          iter = iter->next) {
         cib_notify_client_t *client = (cib_notify_client_t *) iter->data;
 
         if (strcmp(client->event, event) == 0) {
             count++;
         }
     }
     crm_trace("event(%s) count : %d", event, count);
     return count;
 }
 
 static int
 cib_client_del_notify_callback(cib_t *cib, const char *event,
                                void (*callback) (const char *event,
                                                  xmlNode *msg))
 {
     GList *list_item = NULL;
     cib_notify_client_t *new_client = NULL;
 
     if (cib->variant != cib_native && cib->variant != cib_remote) {
         return -EPROTONOSUPPORT;
     }
 
     if (get_notify_list_event_count(cib, event) == 0) {
         crm_debug("The callback of the event does not exist(%s)", event);
         return pcmk_ok;
     }
 
     crm_debug("Removing callback for %s events", event);
 
     new_client = pcmk__assert_alloc(1, sizeof(cib_notify_client_t));
     new_client->event = event;
     new_client->callback = callback;
 
     list_item = g_list_find_custom(cib->notify_list, new_client, ciblib_GCompareFunc);
 
     if (list_item != NULL) {
         cib_notify_client_t *list_client = list_item->data;
 
         cib->notify_list = g_list_remove(cib->notify_list, list_client);
         free(list_client);
 
         crm_trace("Removed callback");
 
     } else {
         crm_trace("Callback not present");
     }
 
     if (get_notify_list_event_count(cib, event) == 0) {
         /* When there is not the registration of the event, the processing turns off a notice. */
         cib->cmds->register_notification(cib, event, 0);
     }
 
     free(new_client);
     return pcmk_ok;
 }
 
 static gboolean
 cib_async_timeout_handler(gpointer data)
 {
     struct timer_rec_s *timer = data;
 
     crm_debug("Async call %d timed out after %ds",
               timer->call_id, timer->timeout);
     cib_native_callback(timer->cib, NULL, timer->call_id, -ETIME);
 
     // We remove the handler in remove_cib_op_callback()
     return G_SOURCE_CONTINUE;
 }
 
 static gboolean
 cib_client_register_callback_full(cib_t *cib, int call_id, int timeout,
                                   gboolean only_success, void *user_data,
                                   const char *callback_name,
                                   void (*callback)(xmlNode *, int, int,
                                                    xmlNode *, void *),
                                   void (*free_func)(void *))
 {
     cib_callback_client_t *blob = NULL;
 
     if (call_id < 0) {
         if (only_success == FALSE) {
             callback(NULL, call_id, call_id, NULL, user_data);
         } else {
             crm_warn("CIB call failed: %s", pcmk_strerror(call_id));
         }
         if (user_data && free_func) {
             free_func(user_data);
         }
         return FALSE;
     }
 
     blob = pcmk__assert_alloc(1, sizeof(cib_callback_client_t));
     blob->id = callback_name;
     blob->only_success = only_success;
     blob->user_data = user_data;
     blob->callback = callback;
     blob->free_func = free_func;
 
     if (timeout > 0) {
         struct timer_rec_s *async_timer =
             pcmk__assert_alloc(1, sizeof(struct timer_rec_s));
 
         blob->timer = async_timer;
 
         async_timer->cib = cib;
         async_timer->call_id = call_id;
         async_timer->timeout = timeout * 1000;
         async_timer->ref = g_timeout_add(async_timer->timeout,
                                          cib_async_timeout_handler,
                                          async_timer);
     }
 
     crm_trace("Adding callback %s for call %d", callback_name, call_id);
     pcmk__intkey_table_insert(cib_op_callback_table, call_id, blob);
 
     return TRUE;
 }
 
 static gboolean
 cib_client_register_callback(cib_t *cib, int call_id, int timeout,
                              gboolean only_success, void *user_data,
                              const char *callback_name,
                              void (*callback) (xmlNode *, int, int, xmlNode *,
                                                void *))
 {
     return cib_client_register_callback_full(cib, call_id, timeout,
                                              only_success, user_data,
                                              callback_name, callback, NULL);
 }
 
 static int
 cib_client_noop(cib_t * cib, int call_options)
 {
     op_common(cib);
     return cib_internal_op(cib, PCMK__CIB_REQUEST_NOOP, NULL, NULL, NULL, NULL,
                            call_options, cib->user);
 }
 
 static int
 cib_client_ping(cib_t * cib, xmlNode ** output_data, int call_options)
 {
     op_common(cib);
     return cib_internal_op(cib, CRM_OP_PING, NULL, NULL, NULL, output_data,
                            call_options, cib->user);
 }
 
 static int
 cib_client_query(cib_t * cib, const char *section, xmlNode ** output_data, int call_options)
 {
     return cib->cmds->query_from(cib, NULL, section, output_data, call_options);
 }
 
 static int
 cib_client_query_from(cib_t * cib, const char *host, const char *section,
                       xmlNode ** output_data, int call_options)
 {
     op_common(cib);
     return cib_internal_op(cib, PCMK__CIB_REQUEST_QUERY, host, section, NULL,
                            output_data, call_options, cib->user);
 }
 
 static int
 set_secondary(cib_t *cib, int call_options)
 {
     op_common(cib);
     return cib_internal_op(cib, PCMK__CIB_REQUEST_SECONDARY, NULL, NULL, NULL,
                            NULL, call_options, cib->user);
 }
 
 static int
 set_primary(cib_t *cib, int call_options)
 {
     op_common(cib);
     return cib_internal_op(cib, PCMK__CIB_REQUEST_PRIMARY, NULL, NULL, NULL,
                            NULL, call_options, cib->user);
 }
 
 static int
 cib_client_bump_epoch(cib_t * cib, int call_options)
 {
     op_common(cib);
     return cib_internal_op(cib, PCMK__CIB_REQUEST_BUMP, NULL, NULL, NULL, NULL,
                            call_options, cib->user);
 }
 
 static int
 cib_client_upgrade(cib_t * cib, int call_options)
 {
     op_common(cib);
     return cib_internal_op(cib, PCMK__CIB_REQUEST_UPGRADE, NULL, NULL, NULL,
                            NULL, call_options, cib->user);
 }
 
 static int
 cib_client_sync(cib_t * cib, const char *section, int call_options)
 {
     return cib->cmds->sync_from(cib, NULL, section, call_options);
 }
 
 static int
 cib_client_sync_from(cib_t * cib, const char *host, const char *section, int call_options)
 {
     op_common(cib);
     return cib_internal_op(cib, PCMK__CIB_REQUEST_SYNC_TO_ALL, host, section,
                            NULL, NULL, call_options, cib->user);
 }
 
 static int
 cib_client_create(cib_t * cib, const char *section, xmlNode * data, int call_options)
 {
     op_common(cib);
     return cib_internal_op(cib, PCMK__CIB_REQUEST_CREATE, NULL, section, data,
                            NULL, call_options, cib->user);
 }
 
 static int
 cib_client_modify(cib_t * cib, const char *section, xmlNode * data, int call_options)
 {
     op_common(cib);
     return cib_internal_op(cib, PCMK__CIB_REQUEST_MODIFY, NULL, section, data,
                            NULL, call_options, cib->user);
 }
 
 static int
 cib_client_replace(cib_t * cib, const char *section, xmlNode * data, int call_options)
 {
     op_common(cib);
     return cib_internal_op(cib, PCMK__CIB_REQUEST_REPLACE, NULL, section, data,
                            NULL, call_options, cib->user);
 }
 
 static int
 cib_client_delete(cib_t * cib, const char *section, xmlNode * data, int call_options)
 {
     op_common(cib);
     return cib_internal_op(cib, PCMK__CIB_REQUEST_DELETE, NULL, section, data,
                            NULL, call_options, cib->user);
 }
 
 static int
 cib_client_delete_absolute(cib_t * cib, const char *section, xmlNode * data, int call_options)
 {
     op_common(cib);
     return cib_internal_op(cib, PCMK__CIB_REQUEST_ABS_DELETE, NULL, section,
                            data, NULL, call_options, cib->user);
 }
 
 static int
 cib_client_erase(cib_t * cib, xmlNode ** output_data, int call_options)
 {
     op_common(cib);
     return cib_internal_op(cib, PCMK__CIB_REQUEST_ERASE, NULL, NULL, NULL,
                            output_data, call_options, cib->user);
 }
 
 static int
 cib_client_init_transaction(cib_t *cib)
 {
     int rc = pcmk_rc_ok;
 
     op_common(cib);
 
     if (cib->transaction != NULL) {
         // A client can have at most one transaction at a time
         rc = pcmk_rc_already;
     }
 
     if (rc == pcmk_rc_ok) {
         cib->transaction = pcmk__xe_create(NULL, PCMK__XE_CIB_TRANSACTION);
     }
 
     if (rc != pcmk_rc_ok) {
         const char *client_id = NULL;
 
         cib->cmds->client_id(cib, NULL, &client_id);
         crm_err("Failed to initialize CIB transaction for client %s: %s",
                 client_id, pcmk_rc_str(rc));
     }
     return pcmk_rc2legacy(rc);
 }
 
 static int
 cib_client_end_transaction(cib_t *cib, bool commit, int call_options)
 {
     const char *client_id = NULL;
     int rc = pcmk_ok;
 
     op_common(cib);
     cib->cmds->client_id(cib, NULL, &client_id);
     client_id = pcmk__s(client_id, "(unidentified)");
 
     if (commit) {
         if (cib->transaction == NULL) {
             rc = pcmk_rc_no_transaction;
 
             crm_err("Failed to commit transaction for CIB client %s: %s",
                     client_id, pcmk_rc_str(rc));
             return pcmk_rc2legacy(rc);
         }
         rc = cib_internal_op(cib, PCMK__CIB_REQUEST_COMMIT_TRANSACT, NULL, NULL,
                              cib->transaction, NULL, call_options, cib->user);
 
     } else {
         // Discard always succeeds
         if (cib->transaction != NULL) {
             crm_trace("Discarded transaction for CIB client %s", client_id);
         } else {
             crm_trace("No transaction found for CIB client %s", client_id);
         }
     }
     pcmk__xml_free(cib->transaction);
     cib->transaction = NULL;
     return rc;
 }
 
 static int
 cib_client_fetch_schemas(cib_t *cib, xmlNode **output_data, const char *after_ver,
                          int call_options)
 {
     xmlNode *data = pcmk__xe_create(NULL, PCMK__XA_SCHEMA);
     int rc = pcmk_ok;
 
     crm_xml_add(data, PCMK_XA_VERSION, after_ver);
 
     rc = cib_internal_op(cib, PCMK__CIB_REQUEST_SCHEMAS, NULL, NULL, data,
                          output_data, call_options, NULL);
     pcmk__xml_free(data);
     return rc;
 }
 
 static void
 cib_client_set_user(cib_t *cib, const char *user)
 {
     pcmk__str_update(&(cib->user), user);
 }
 
 static void
 cib_destroy_op_callback(gpointer data)
 {
     cib_callback_client_t *blob = data;
 
     if (blob->timer && blob->timer->ref > 0) {
         g_source_remove(blob->timer->ref);
     }
     free(blob->timer);
 
     if (blob->user_data && blob->free_func) {
         blob->free_func(blob->user_data);
     }
 
     free(blob);
 }
 
 static void
 destroy_op_callback_table(void)
 {
     if (cib_op_callback_table != NULL) {
         g_hash_table_destroy(cib_op_callback_table);
         cib_op_callback_table = NULL;
     }
 }
 
 char *
 get_shadow_file(const char *suffix)
 {
     char *cib_home = NULL;
     char *fullname = NULL;
     char *name = crm_strdup_printf("shadow.%s", suffix);
     const char *dir = getenv("CIB_shadow_dir");
 
     if (dir == NULL) {
         uid_t uid = geteuid();
         struct passwd *pwent = getpwuid(uid);
         const char *user = NULL;
 
         if (pwent) {
             user = pwent->pw_name;
         } else {
             user = getenv("USER");
             crm_perror(LOG_ERR,
                        "Assuming %s because cannot get user details for user ID %d",
                        (user? user : "unprivileged user"), uid);
         }
 
         if (pcmk__strcase_any_of(user, "root", CRM_DAEMON_USER, NULL)) {
             dir = CRM_CONFIG_DIR;
 
         } else {
             const char *home = NULL;
 
             if ((home = getenv("HOME")) == NULL) {
                 if (pwent) {
                     home = pwent->pw_dir;
                 }
             }
 
             dir = pcmk__get_tmpdir();
             if (home && home[0] == '/') {
                 int rc = 0;
 
                 cib_home = crm_strdup_printf("%s/.cib", home);
 
                 rc = mkdir(cib_home, 0700);
                 if (rc < 0 && errno != EEXIST) {
                     crm_perror(LOG_ERR, "Couldn't create user-specific shadow directory: %s",
                                cib_home);
                     errno = 0;
 
                 } else {
                     dir = cib_home;
                 }
             }
         }
     }
 
     fullname = crm_strdup_printf("%s/%s", dir, name);
     free(cib_home);
     free(name);
 
     return fullname;
 }
 
 cib_t *
 cib_shadow_new(const char *shadow)
 {
     cib_t *new_cib = NULL;
     char *shadow_file = NULL;
 
     CRM_CHECK(shadow != NULL, return NULL);
 
     shadow_file = get_shadow_file(shadow);
     new_cib = cib_file_new(shadow_file);
     free(shadow_file);
 
     return new_cib;
 }
 
 /*!
  * \brief Create a new CIB connection object, ignoring any active shadow CIB
  *
  * Create a new live, file, or remote CIB connection object based on the values
  * of CIB-related environment variables (CIB_file, CIB_port, CIB_server,
  * CIB_user, and CIB_passwd). The object will not be connected.
  *
  * \return Newly allocated CIB connection object
  * \note The CIB API does not fully support opening multiple CIB connection
  *       objects simultaneously, so the returned object should be treated as a
  *       singleton.
  */
 cib_t *
 cib_new_no_shadow(void)
 {
     const char *shadow = getenv("CIB_shadow");
     cib_t *cib = NULL;
 
     unsetenv("CIB_shadow");
     cib = cib_new();
 
     if (shadow != NULL) {
         setenv("CIB_shadow", shadow, 1);
     }
     return cib;
 }
 
 /*!
  * \brief Create a new CIB connection object
  *
  * Create a new live, remote, file, or shadow file CIB connection object based
  * on the values of CIB-related environment variables (CIB_shadow, CIB_file,
  * CIB_port, CIB_server, CIB_user, and CIB_passwd). The object will not be
  * connected.
  *
  * \return Newly allocated CIB connection object
  * \note The CIB API does not fully support opening multiple CIB connection
  *       objects simultaneously, so the returned object should be treated as a
  *       singleton.
  */
 /* @TODO Ensure all APIs support multiple simultaneous CIB connection objects
  * (at least cib_free_callbacks() currently does not).
  */
 cib_t *
 cib_new(void)
 {
     const char *value = getenv("CIB_shadow");
     int port;
 
     if (value && value[0] != 0) {
         return cib_shadow_new(value);
     }
 
     value = getenv("CIB_file");
     if (value) {
         return cib_file_new(value);
     }
 
     value = getenv("CIB_port");
     if (value) {
         gboolean encrypted = TRUE;
         const char *server = getenv("CIB_server");
         const char *user = getenv("CIB_user");
         const char *pass = getenv("CIB_passwd");
 
         /* We don't ensure port is valid (>= 0) because cib_new() currently
          * can't return NULL in practice, and introducing a NULL return here
          * could cause core dumps that would previously just cause signon()
          * failures.
          */
         pcmk__scan_port(value, &port);
 
         value = getenv("CIB_encrypted");
         if (value && crm_is_true(value) == FALSE) {
             crm_info("Disabling TLS");
             encrypted = FALSE;
         }
 
         if (user == NULL) {
             user = CRM_DAEMON_USER;
             crm_info("Defaulting to user: %s", user);
         }
 
         if (server == NULL) {
             server = "localhost";
             crm_info("Defaulting to localhost");
         }
 
         return cib_remote_new(server, user, pass, port, encrypted);
     }
 
     return cib_native_new();
 }
 
 /*!
  * \internal
  * \brief Create a generic CIB connection instance
  *
  * \return Newly allocated and initialized cib_t instance
  *
  * \note This is called by each variant's cib_*_new() function before setting
  *       variant-specific values.
  */
 cib_t *
 cib_new_variant(void)
 {
     cib_t *new_cib = NULL;
 
     new_cib = calloc(1, sizeof(cib_t));
 
     if (new_cib == NULL) {
         return NULL;
     }
 
     remove_cib_op_callback(0, TRUE); /* remove all */
 
     new_cib->call_id = 1;
     new_cib->variant = cib_undefined;
 
     new_cib->type = cib_no_connection;
     new_cib->state = cib_disconnected;
 
     new_cib->op_callback = NULL;
     new_cib->variant_opaque = NULL;
     new_cib->notify_list = NULL;
 
     /* the rest will get filled in by the variant constructor */
     new_cib->cmds = calloc(1, sizeof(cib_api_operations_t));
 
     if (new_cib->cmds == NULL) {
         free(new_cib);
         return NULL;
     }
 
     new_cib->cmds->add_notify_callback = cib_client_add_notify_callback;
     new_cib->cmds->del_notify_callback = cib_client_del_notify_callback;
     new_cib->cmds->register_callback = cib_client_register_callback;
     new_cib->cmds->register_callback_full = cib_client_register_callback_full;
 
     new_cib->cmds->noop = cib_client_noop; // Deprecated method
     new_cib->cmds->ping = cib_client_ping;
     new_cib->cmds->query = cib_client_query;
     new_cib->cmds->sync = cib_client_sync;
 
     new_cib->cmds->query_from = cib_client_query_from;
     new_cib->cmds->sync_from = cib_client_sync_from;
 
     new_cib->cmds->set_primary = set_primary;
     new_cib->cmds->set_secondary = set_secondary;
 
     new_cib->cmds->upgrade = cib_client_upgrade;
     new_cib->cmds->bump_epoch = cib_client_bump_epoch;
 
     new_cib->cmds->create = cib_client_create;
     new_cib->cmds->modify = cib_client_modify;
-    new_cib->cmds->update = cib_client_modify; // Deprecated method
     new_cib->cmds->replace = cib_client_replace;
     new_cib->cmds->remove = cib_client_delete;
     new_cib->cmds->erase = cib_client_erase;
 
     // Deprecated method
     new_cib->cmds->delete_absolute = cib_client_delete_absolute;
 
     new_cib->cmds->init_transaction = cib_client_init_transaction;
     new_cib->cmds->end_transaction = cib_client_end_transaction;
 
     new_cib->cmds->set_user = cib_client_set_user;
 
     new_cib->cmds->fetch_schemas = cib_client_fetch_schemas;
 
     return new_cib;
 }
 
 void 
 cib_free_notify(cib_t *cib)
 {
 
     if (cib) {
         GList *list = cib->notify_list;
 
         while (list != NULL) {
             cib_notify_client_t *client = g_list_nth_data(list, 0);
 
             list = g_list_remove(list, client);
             free(client);
         }
         cib->notify_list = NULL;
     }
 }
 
 /*!
  * \brief Free all callbacks for a CIB connection
  *
  * \param[in,out] cib  CIB connection to clean up
  */
 void
 cib_free_callbacks(cib_t *cib)
 {
     cib_free_notify(cib);
 
     destroy_op_callback_table();
 }
 
 /*!
  * \brief Free all memory used by CIB connection
  *
  * \param[in,out] cib  CIB connection to delete
  */
 void
 cib_delete(cib_t *cib)
 {
     cib_free_callbacks(cib);
     if (cib) {
         cib->cmds->free(cib);
     }
 }
 
 void
 remove_cib_op_callback(int call_id, gboolean all_callbacks)
 {
     if (all_callbacks) {
         destroy_op_callback_table();
         cib_op_callback_table = pcmk__intkey_table(cib_destroy_op_callback);
     } else {
         pcmk__intkey_table_remove(cib_op_callback_table, call_id);
     }
 }
 
 int
 num_cib_op_callbacks(void)
 {
     if (cib_op_callback_table == NULL) {
         return 0;
     }
     return g_hash_table_size(cib_op_callback_table);
 }
 
 static void
 cib_dump_pending_op(gpointer key, gpointer value, gpointer user_data)
 {
     int call = GPOINTER_TO_INT(key);
     cib_callback_client_t *blob = value;
 
     crm_debug("Call %d (%s): pending", call, pcmk__s(blob->id, "without ID"));
 }
 
 void
 cib_dump_pending_callbacks(void)
 {
     if (cib_op_callback_table == NULL) {
         return;
     }
     return g_hash_table_foreach(cib_op_callback_table, cib_dump_pending_op, NULL);
 }
 
 cib_callback_client_t*
 cib__lookup_id (int call_id)
 {
     return pcmk__intkey_table_lookup(cib_op_callback_table, call_id);
 }