19 #include <sys/types.h>    27 static GHashTable *cib_op_callback_table = NULL;
    29 #define op_common(cib) do {                                             \    32         } else if(cib->delegate_fn == NULL) {                           \    33             return -EPROTONOSUPPORT;                                    \    38 cib_client_set_op_callback(
cib_t *cib,
    39                            void (*callback) (
const xmlNode * msg, 
int call_id,
    40                                              int rc, xmlNode * output))
    42     if (callback == NULL) {
    43         crm_info(
"Un-Setting operation callback");
    53 ciblib_GCompareFunc(gconstpointer a, gconstpointer b)
    65             crm_trace(
"callbacks for %s are not equal: %p < %p",
    69         crm_trace(
"callbacks for %s are not equal: %p > %p",
    77 cib_client_add_notify_callback(
cib_t * cib, 
const char *event,
    78                                void (*callback) (
const char *event,
    81     GList *list_item = NULL;
    85         return -EPROTONOSUPPORT;
    88     crm_trace(
"Adding callback for %s events (%d)",
    92     new_client->
event = event;
    95     list_item = g_list_find_custom(cib->
notify_list, new_client,
    98     if (list_item != NULL) {
    99         crm_warn(
"Callback already present");
   114 get_notify_list_event_count(
cib_t *cib, 
const char *event)
   118     for (GList *iter = g_list_first(cib->
notify_list); iter != NULL;
   122         if (strcmp(client->
event, event) == 0) {
   126     crm_trace(
"event(%s) count : %d", event, count);
   131 cib_client_del_notify_callback(
cib_t *cib, 
const char *event,
   132                                void (*callback) (
const char *event,
   135     GList *list_item = NULL;
   139         return -EPROTONOSUPPORT;
   142     if (get_notify_list_event_count(cib, event) == 0) {
   143         crm_debug(
"The callback of the event does not exist(%s)", event);
   147     crm_debug(
"Removing callback for %s events", event);
   150     new_client->
event = event;
   153     list_item = g_list_find_custom(cib->
notify_list, new_client, ciblib_GCompareFunc);
   155     if (list_item != NULL) {
   167     if (get_notify_list_event_count(cib, event) == 0) {
   177 cib_async_timeout_handler(gpointer 
data)
   181     crm_debug(
"Async call %d timed out after %ds",
   186     return G_SOURCE_CONTINUE;
   191                                   gboolean only_success, 
void *user_data,
   192                                   const char *callback_name,
   193                                   void (*callback)(xmlNode *, 
int, 
int,
   195                                   void (*free_func)(
void *))
   200         if (only_success == FALSE) {
   205         if (user_data && free_func) {
   206             free_func(user_data);
   212     blob->
id = callback_name;
   222         blob->
timer = async_timer;
   227         async_timer->
ref = g_timeout_add(async_timer->
timeout,
   228                                          cib_async_timeout_handler,
   233     pcmk__intkey_table_insert(cib_op_callback_table, 
call_id, blob);
   240                              gboolean only_success, 
void *user_data,
   241                              const char *callback_name,
   242                              void (*callback) (xmlNode *, 
int, 
int, xmlNode *,
   246                                              only_success, user_data,
   247                                              callback_name, callback, NULL);
   251 cib_client_noop(
cib_t * 
cib, 
int call_options)
   259 cib_client_ping(
cib_t * 
cib, xmlNode ** output_data, 
int call_options)
   267 cib_client_query(
cib_t * 
cib, 
const char *section, xmlNode ** output_data, 
int call_options)
   273 cib_client_query_from(
cib_t * 
cib, 
const char *
host, 
const char *section,
   274                       xmlNode ** output_data, 
int call_options)
   278                            output_data, call_options, 
cib->
user);
   290 set_secondary(
cib_t *
cib, 
int call_options)
   294                            NULL, call_options, 
cib->
user);
   298 set_all_secondary(
cib_t * 
cib, 
int call_options)
   300     return -EPROTONOSUPPORT;
   304 set_primary(
cib_t *
cib, 
int call_options)
   307     crm_trace(
"Adding cib_scope_local to options");
   313 cib_client_bump_epoch(
cib_t * 
cib, 
int call_options)
   321 cib_client_upgrade(
cib_t * 
cib, 
int call_options)
   325                            NULL, call_options, 
cib->
user);
   329 cib_client_sync(
cib_t * 
cib, 
const char *section, 
int call_options)
   335 cib_client_sync_from(
cib_t * 
cib, 
const char *
host, 
const char *section, 
int call_options)
   339                            NULL, NULL, call_options, 
cib->
user);
   343 cib_client_create(
cib_t * 
cib, 
const char *section, xmlNode * 
data, 
int call_options)
   347                            NULL, call_options, 
cib->
user);
   351 cib_client_modify(
cib_t * 
cib, 
const char *section, xmlNode * 
data, 
int call_options)
   355                            NULL, call_options, 
cib->
user);
   359 cib_client_replace(
cib_t * 
cib, 
const char *section, xmlNode * 
data, 
int call_options)
   363                            NULL, call_options, 
cib->
user);
   367 cib_client_delete(
cib_t * 
cib, 
const char *section, xmlNode * 
data, 
int call_options)
   371                            NULL, call_options, 
cib->
user);
   375 cib_client_delete_absolute(
cib_t * 
cib, 
const char *section, xmlNode * 
data, 
int call_options)
   383 cib_client_erase(
cib_t * 
cib, xmlNode ** output_data, 
int call_options)
   387                            output_data, call_options, 
cib->
user);
   391 cib_client_init_transaction(
cib_t *
cib)
   407         const char *client_id = NULL;
   410         crm_err(
"Failed to initialize CIB transaction for client %s: %s",
   417 cib_client_end_transaction(
cib_t *
cib, 
bool commit, 
int call_options)
   419     const char *client_id = NULL;
   424     client_id = pcmk__s(client_id, 
"(unidentified)");
   430             crm_err(
"Failed to commit transaction for CIB client %s: %s",
   440             crm_trace(
"Discarded transaction for CIB client %s", client_id);
   442             crm_trace(
"No transaction found for CIB client %s", client_id);
   451 cib_client_fetch_schemas(
cib_t *
cib, xmlNode **output_data, 
const char *after_ver,
   460                          output_data, call_options, NULL);
   466 cib_client_set_user(
cib_t *
cib, 
const char *user)
   472 cib_destroy_op_callback(gpointer 
data)
   489 destroy_op_callback_table(
void)
   491     if (cib_op_callback_table != NULL) {
   492         g_hash_table_destroy(cib_op_callback_table);
   493         cib_op_callback_table = NULL;
   500     char *cib_home = NULL;
   501     char *fullname = NULL;
   503     const char *dir = getenv(
"CIB_shadow_dir");
   506         uid_t uid = geteuid();
   507         struct passwd *pwent = getpwuid(uid);
   508         const char *user = NULL;
   511             user = pwent->pw_name;
   513             user = getenv(
"USER");
   515                        "Assuming %s because cannot get user details for user ID %d",
   516                        (user? user : 
"unprivileged user"), uid);
   523             const char *home = NULL;
   525             if ((home = getenv(
"HOME")) == NULL) {
   527                     home = pwent->pw_dir;
   532             if (home && home[0] == 
'/') {
   537                 rc = mkdir(cib_home, 0700);
   538                 if (rc < 0 && errno != EEXIST) {
   539                     crm_perror(LOG_ERR, 
"Couldn't create user-specific shadow directory: %s",
   560     cib_t *new_cib = NULL;
   561     char *shadow_file = NULL;
   587     const char *shadow = getenv(
"CIB_shadow");
   590     unsetenv(
"CIB_shadow");
   593     if (shadow != NULL) {
   594         setenv(
"CIB_shadow", shadow, 1);
   618     const char *value = getenv(
"CIB_shadow");
   621     if (value && value[0] != 0) {
   625     value = getenv(
"CIB_file");
   630     value = getenv(
"CIB_port");
   632         gboolean encrypted = TRUE;
   633         const char *server = getenv(
"CIB_server");
   634         const char *user = getenv(
"CIB_user");
   635         const char *pass = getenv(
"CIB_passwd");
   644         value = getenv(
"CIB_encrypted");
   652             crm_info(
"Defaulting to user: %s", user);
   655         if (server == NULL) {
   656             server = 
"localhost";
   657             crm_info(
"Defaulting to localhost");
   678     cib_t *new_cib = NULL;
   680     new_cib = calloc(1, 
sizeof(
cib_t));
   682     if (new_cib == NULL) {
   701     if (new_cib->
cmds == NULL) {
   714     new_cib->
cmds->
noop = cib_client_noop; 
   715     new_cib->
cmds->
ping = cib_client_ping;
   717     new_cib->
cmds->
sync = cib_client_sync;
   762         while (list != NULL) {
   765             list = g_list_remove(list, client);
   782     destroy_op_callback_table();
   803         destroy_op_callback_table();
   804         cib_op_callback_table = pcmk__intkey_table(cib_destroy_op_callback);
   806         pcmk__intkey_table_remove(cib_op_callback_table, call_id);
   813     if (cib_op_callback_table == NULL) {
   816     return g_hash_table_size(cib_op_callback_table);
   820 cib_dump_pending_op(gpointer key, gpointer value, gpointer user_data)
   822     int call = GPOINTER_TO_INT(key);
   825     crm_debug(
"Call %d (%s): pending", call, pcmk__s(blob->
id, 
"without ID"));
   831     if (cib_op_callback_table == NULL) {
   834     return g_hash_table_foreach(cib_op_callback_table, cib_dump_pending_op, NULL);
   840     return pcmk__intkey_table_lookup(cib_op_callback_table, call_id);
 
#define CRM_CHECK(expr, failure_action)
 
const char * pcmk_strerror(int rc)
 
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 *))
 
cib_t * cib_remote_new(const char *server, const char *user, const char *passwd, int port, gboolean encrypted)
 
int pcmk_rc2legacy(int rc)
 
#define PCMK__CIB_REQUEST_PRIMARY
 
void cib_dump_pending_callbacks(void)
 
#define PCMK__CIB_REQUEST_CREATE
 
bool pcmk__strcase_any_of(const char *s,...) G_GNUC_NULL_TERMINATED
 
int(* delete_absolute)(cib_t *cib, const char *section, xmlNode *data, int call_options)
 
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 *))
 
void(* callback)(const char *event, xmlNode *msg)
 
#define PCMK__CIB_REQUEST_QUERY
 
#define PCMK__CIB_REQUEST_COMMIT_TRANSACT
 
void cib_free_callbacks(cib_t *cib)
Free all callbacks for a CIB connection. 
 
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value. 
 
const char * pcmk_rc_str(int rc)
Get a user-friendly description of a return code. 
 
int(* fetch_schemas)(cib_t *cib, xmlNode **output_data, const char *after_ver, int call_options)
 
cib_t * cib_new(void)
Create a new CIB connection object. 
 
cib_t * cib_shadow_new(const char *shadow)
 
int(* set_secondary)(cib_t *cib, int call_options)
Set the local CIB manager as a secondary instance. 
 
#define PCMK__CIB_REQUEST_ERASE
 
int(* set_op_callback)(cib_t *cib, void(*callback)(const xmlNode *msg, int callid, int rc, xmlNode *output))
 
int(* sync)(cib_t *cib, const char *section, int call_options)
 
#define PCMK__CIB_REQUEST_ABS_DELETE
 
#define crm_warn(fmt, args...)
 
struct timer_rec_s * timer
 
int(* query_from)(cib_t *cib, const char *host, const char *section, xmlNode **output_data, int call_options)
 
int pcmk__scan_port(const char *text, int *port)
 
cib_api_operations_t * cmds
 
#define crm_debug(fmt, args...)
 
int num_cib_op_callbacks(void)
 
int(* set_slave)(cib_t *cib, int call_options)
 
#define PCMK__CIB_REQUEST_IS_PRIMARY
 
void(* callback)(xmlNode *, int, int, xmlNode *, void *)
 
#define crm_trace(fmt, args...)
 
char * crm_strdup_printf(char const *format,...) G_GNUC_PRINTF(1
 
int(* modify)(cib_t *cib, const char *section, xmlNode *data, int call_options)
 
void(* op_callback)(const xmlNode *msg, int call_id, int rc, xmlNode *output)
 
char * get_shadow_file(const char *suffix)
 
int(* create)(cib_t *cib, const char *section, xmlNode *data, int call_options)
 
void pcmk__str_update(char **str, const char *value)
 
Wrappers for and extensions to libxml2. 
 
int(* query)(cib_t *cib, const char *section, xmlNode **output_data, int call_options)
 
int(* is_master)(cib_t *cib)
 
cib_t * cib_new_no_shadow(void)
Create a new CIB connection object, ignoring any active shadow CIB. 
 
cib_t * cib_native_new(void)
 
int(* replace)(cib_t *cib, const char *section, xmlNode *data, int call_options)
 
void free_xml(xmlNode *child)
 
int(* add_notify_callback)(cib_t *cib, const char *event, void(*callback)(const char *event, xmlNode *msg))
 
int(* sync_from)(cib_t *cib, const char *host, const char *section, int call_options)
 
int(* register_notification)(cib_t *cib, const char *callback, int enabled)
 
int(* ping)(cib_t *cib, xmlNode **output_data, int call_options)
 
int(* update)(cib_t *cib, const char *section, xmlNode *data, int call_options)
 
#define PCMK__CIB_REQUEST_UPGRADE
 
cib_t * cib_file_new(const char *filename)
 
cib_callback_client_t * cib__lookup_id(int call_id)
 
#define PCMK__CIB_REQUEST_BUMP
 
int(* set_primary)(cib_t *cib, int call_options)
Set the local CIB manager as the cluster's primary instance. 
 
int(* noop)(cib_t *cib, int call_options)
 
const char * pcmk__get_tmpdir(void)
 
int(* end_transaction)(cib_t *cib, bool commit, int call_options)
End and optionally commit this client's CIB transaction. 
 
int(* set_slave_all)(cib_t *cib, int call_options)
 
int(* del_notify_callback)(cib_t *cib, const char *event, void(*callback)(const char *event, xmlNode *msg))
 
#define PCMK__CIB_REQUEST_SCHEMAS
 
#define crm_perror(level, fmt, args...)
Send a system error message to both the log and stderr. 
 
void cib_free_notify(cib_t *cib)
 
#define crm_err(fmt, args...)
 
#define PCMK__CIB_REQUEST_REPLACE
 
int(* set_master)(cib_t *cib, int call_options)
 
#define PCMK__CIB_REQUEST_SYNC_TO_ALL
 
#define PCMK__CIB_REQUEST_SECONDARY
 
#define PCMK__CIB_REQUEST_NOOP
 
void cib_native_callback(cib_t *cib, xmlNode *msg, int call_id, int rc)
 
void(* set_user)(cib_t *cib, const char *user)
Set the user as whom all CIB requests via methods will be executed. 
 
cib_t * cib_new_variant(void)
 
int(* bump_epoch)(cib_t *cib, int call_options)
 
gboolean crm_is_true(const char *s)
 
#define PCMK__CIB_REQUEST_MODIFY
 
int(* remove)(cib_t *cib, const char *section, xmlNode *data, int call_options)
 
int cib_internal_op(cib_t *cib, const char *op, const char *host, const char *section, xmlNode *data, xmlNode **output_data, int call_options, const char *user_name)
 
int(* init_transaction)(cib_t *cib)
Initiate an atomic CIB transaction for this client. 
 
void cib_delete(cib_t *cib)
Free all memory used by CIB connection. 
 
xmlNode * pcmk__xe_create(xmlNode *parent, const char *name)
 
#define pcmk__assert_alloc(nmemb, size)
 
#define PCMK__XE_CIB_TRANSACTION
 
void(* free_func)(void *)
 
int(* client_id)(const cib_t *cib, const char **async_id, const char **sync_id)
Get the given CIB connection's unique client identifier(s) 
 
int(* upgrade)(cib_t *cib, int call_options)
 
#define crm_info(fmt, args...)
 
int(* erase)(cib_t *cib, xmlNode **output_data, int call_options)
 
void remove_cib_op_callback(int call_id, gboolean all_callbacks)
 
#define PCMK__CIB_REQUEST_DELETE