16 #include <sys/utsname.h>    27 struct config_root_s {
    39 static struct config_root_s known_paths[] = {
    40     { NULL,                         NULL,                 
"//cib" },
    61     xmlNode *the_cib = NULL;
    65     if (the_cib != NULL) {
    93                          int *_admin_epoch, 
int *_epoch, 
int *_updates)
    95     int add[] = { 0, 0, 0 };
    96     int del[] = { 0, 0, 0 };
   100     *admin_epoch = add[0];
   104     *_admin_epoch = del[0];
   121     for (; lpc < max; lpc++) {
   122         if ((object_type == NULL && known_paths[lpc].
name == NULL)
   124             return known_paths[lpc].path;
   136     for (; lpc < max; lpc++) {
   138             return known_paths[lpc].parent;
   167     xmlNode *cib_root = NULL, *config = NULL;
   185 #if PCMK__RESOURCE_STICKINESS_DEFAULT != 0   202 cib_acl_enabled(xmlNode *xml, 
const char *user)
   207         const char *value = NULL;
   211         value = 
cib_pref(options, 
"enable-acl");
   213         g_hash_table_destroy(options);
   216     crm_trace(
"CIB ACL is %s", 
rc ? 
"enabled" : 
"disabled");
   222                const char *section, xmlNode * req, xmlNode * input,
   223                gboolean manage_counters, gboolean * config_changed,
   224                xmlNode * current_cib, xmlNode ** result_cib, xmlNode ** diff, xmlNode ** output)
   227     gboolean check_schema = TRUE;
   229     xmlNode *scratch = NULL;
   230     xmlNode *local_diff = NULL;
   232     const char *new_version = NULL;
   233     static struct qb_log_callsite *diff_cs = NULL;
   235     bool with_digest = FALSE;
   239               (is_query? 
"read-only " : 
""), op);
   241     CRM_CHECK(output != NULL, 
return -ENOMSG);
   242     CRM_CHECK(result_cib != NULL, 
return -ENOMSG);
   243     CRM_CHECK(config_changed != NULL, 
return -ENOMSG);
   250     *config_changed = FALSE;
   257         xmlNode *cib_ro = current_cib;
   258         xmlNode *cib_filtered = NULL;
   260         if(cib_acl_enabled(cib_ro, user)) {
   262                 if (cib_filtered == NULL) {
   263                     crm_debug(
"Pre-filtered the entire cib");
   266                 cib_ro = cib_filtered;
   271         rc = (*fn) (op, call_options, section, req, input, cib_ro, result_cib, output);
   273         if(output == NULL || *output == NULL) {
   276         } 
else if(cib_filtered == *output) {
   279         } 
else if(*output == current_cib) {
   282         } 
else if(cib_filtered && (*output)->doc == cib_filtered->doc) {
   286         } 
else if((*output)->doc == current_cib->doc) {
   299         scratch = current_cib;
   307         rc = (*fn) (op, call_options, section, req, input, scratch, &scratch, output);
   312         rc = (*fn) (op, call_options, section, req, input, current_cib, &scratch, output);
   315             crm_trace(
"Inferring changes after %s op", op);
   316             xml_track_changes(scratch, user, current_cib, cib_acl_enabled(current_cib, user));
   319         CRM_CHECK(current_cib != scratch, 
return -EINVAL);
   329         crm_trace(
"ACL rejected part or all of the proposed changes");
   341             crm_err(
"Discarding update with feature set '%s' greater than our own '%s'",
   343             rc = -EPROTONOSUPPORT;
   356             crm_err(
"%s went backwards: %d -> %d (Opts: 0x%x)",
   362         } 
else if (old == 
new) {
   366                 crm_err(
"%s went backwards: %d -> %d (Opts: 0x%x)",
   385         local_diff = 
xml_create_patchset(2, current_cib, scratch, (
bool*)config_changed, manage_counters);
   388         static time_t expires = 0;
   389         time_t tm_now = time(NULL);
   391         if (expires < tm_now) {
   392             expires = tm_now + 60;  
   396         local_diff = 
xml_create_patchset(0, current_cib, scratch, (
bool*)config_changed, manage_counters);
   402     if (diff_cs == NULL) {
   403         diff_cs = qb_log_callsite_get(__PRETTY_FUNCTION__, __FILE__, 
"diff-validation", LOG_DEBUG, __LINE__, 
crm_trace_nonlog);
   418         int test_rc, format = 1;
   419         xmlNode * c = 
copy_xml(current_cib);
   429             crm_err(
"v%d patchset error, patch failed to apply: %s (%d)", format, 
pcmk_strerror(test_rc), test_rc);
   439         check_schema = FALSE;
   459             static int minimum_schema = 0;
   462             if (minimum_schema == 0) {
   467             if (current_schema >= minimum_schema) {
   479     crm_trace(
"Perform validation: %s", pcmk__btoa(check_schema));
   484         crm_warn(
"Updated CIB does not validate against %s schema",
   491     *result_cib = scratch;
   492     if(
rc != 
pcmk_ok && cib_acl_enabled(current_cib, user)) {
   494             if (*result_cib == NULL) {
   495                 crm_debug(
"Pre-filtered the entire cib result");
   513 cib_create_op(
int call_id, 
const char *token, 
const char *op, 
const char *
host, 
const char *section,
   514               xmlNode * 
data, 
int call_options, 
const char *user_name)
   532     crm_trace(
"Sending call options: %.8lx, %d", (
long)call_options, call_options);
   548     xmlNode *output = NULL;
   560         crm_trace(
"No callback found for call %d", call_id);
   587         crm_trace(
"Invoking global callback for call %d", call_id);
   590     crm_trace(
"OP callback activated for %d", call_id);
   596     xmlNode *msg = user_data;
   598     const char *
event = NULL;
   601         crm_warn(
"Skipping callback - NULL message");
   608         crm_warn(
"Skipping callback - NULL callback client");
   611     } 
else if (entry->
callback == NULL) {
   612         crm_warn(
"Skipping callback - NULL callback");
   616         crm_trace(
"Skipping callback - event mismatch %p/%s vs. %s", entry, entry->
event, event);
   620     crm_trace(
"Invoking callback for %p/%s event...", entry, event);
   632         "enable-acl", NULL, 
"boolean", NULL,
   634         "Enable Access Control Lists (ACLs) for the CIB",
   638         "cluster-ipc-limit", NULL, 
"integer", NULL,
   640         "Maximum IPC message backlog before disconnecting a cluster daemon",
   641         "Raise this if log has \"Evicting client\" messages for cluster daemon"   642             " PIDs (a good value is the number of resources in the cluster"   643             " multiplied by the number of nodes)."   651                                 "Cluster Information Base manager options",
   652                                 "Cluster options used by Pacemaker's "   653                                     "Cluster Information Base manager",
   673     xmlNode *config = NULL;
   676     if (options == NULL || current_cib == NULL) {
   682     g_hash_table_remove_all(options);
   698 #define XPATH_CONFIG_CHANGE \   699     "//" XML_CIB_TAG_CRMCONFIG " | " \   700     "//" XML_DIFF_CHANGE "[contains(@" XML_DIFF_PATH ",'/" XML_CIB_TAG_CRMCONFIG "/')]"   705     gboolean changed = FALSE;
   710         if (numXpathResults(xpathObj) > 0) {
   720                 const char *section, xmlNode * 
data,
   721                 xmlNode ** output_data, 
int call_options, 
const char *user_name)
   723     int (*delegate) (
cib_t * cib, 
const char *op, 
const char *
host,
   724                      const char *section, xmlNode * 
data,
   725                      xmlNode ** output_data, 
int call_options, 
const char *user_name) =
   728     if(user_name == NULL) {
   729         user_name = getenv(
"CIB_user");
   732     return delegate(cib, op, 
host, section, 
data, output_data, call_options, user_name);
   752     xmlNode *diff = NULL;
   765     if (level > LOG_CRIT) {
   774             crm_debug(
"Update didn't apply: %s (%d) %p",
   778                 crm_trace(
"Masking error, we already have the supplied update");
   793     cib_t *cib_conn = NULL;
   802     if (cib_conn == NULL) {
   820     if (cib_object == NULL) {
 #define pcmk_err_old_data
 
#define CRM_CHECK(expr, failure_action)
 
#define XML_ATTR_UPDATE_ORIG
 
#define pcmk_err_schema_validation
 
const char * get_object_parent(const char *object_type)
 
xmlNode * get_message_xml(xmlNode *msg, const char *field)
 
int cib__signon_query(cib_t **cib, xmlNode **cib_object)
 
#define XML_ATTR_UPDATE_CLIENT
 
const char * pcmk_strerror(int rc)
 
#define XML_CIB_TAG_SECTION_ALL
 
#define XML_ATTR_NUMUPDATES
 
void pe_unpack_nvpairs(xmlNode *top, xmlNode *xml_obj, const char *set_name, GHashTable *node_hash, GHashTable *hash, const char *always_first, gboolean overwrite, crm_time_t *now, crm_time_t *next_change)
Extract nvpair blocks contained by an XML element into a hash table. 
 
gboolean cib_internal_config_changed(xmlNode *diff)
 
#define XPATH_CONFIG_CHANGE
 
const char * pcmk__xe_add_last_written(xmlNode *xe)
 
struct crm_time_s crm_time_t
 
#define XML_CIB_TAG_CONSTRAINTS
 
gboolean cib_version_details(xmlNode *cib, int *admin_epoch, int *epoch, int *updates)
 
#define PCMK__RESOURCE_STICKINESS_DEFAULT
 
int(* signoff)(cib_t *cib)
 
bool xml_acl_filtered_copy(const char *user, xmlNode *acl_source, xmlNode *xml, xmlNode **result)
 
void(* callback)(const char *event, xmlNode *msg)
 
const char * crm_xml_add_int(xmlNode *node, const char *name, int value)
Create an XML attribute with specified name and integer value. 
 
#define XML_ATTR_UPDATE_USER
 
xmlNode * cib_get_generation(cib_t *cib)
 
#define XML_TAG_FENCING_TOPOLOGY
 
void xml_track_changes(xmlNode *xml, const char *user, xmlNode *acl_source, bool enforce_acls)
 
void remove_cib_op_callback(int call_id, gboolean all_callbacks)
 
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value. 
 
#define F_CIB_CALLBACK_TOKEN
 
xmlNode * get_object_root(const char *object_type, xmlNode *the_root)
 
#define XML_NVPAIR_ATTR_NAME
 
int get_schema_version(const char *name)
 
int cib_apply_patch_event(xmlNode *event, xmlNode *input, xmlNode **output, int level)
Apply a CIB update patch to a given CIB. 
 
#define CRM_LOG_ASSERT(expr)
 
#define XML_RSC_ATTR_STICKINESS
 
void copy_in_properties(xmlNode *target, xmlNode *src)
 
void xml_accept_changes(xmlNode *xml)
 
unsigned int crm_trace_nonlog
 
#define XML_CIB_TAG_NVPAIR
 
int crm_element_value_int(const xmlNode *data, const char *name, int *dest)
Retrieve the integer value of an XML attribute. 
 
#define XML_CIB_TAG_NODES
 
xmlNode * get_xpath_object(const char *xpath, xmlNode *xml_obj, int error_level)
 
bool pcmk__valid_positive_number(const char *value)
 
void cib_delete(cib_t *cib)
Free all memory used by CIB connection. 
 
#define XML_ATTR_GENERATION
 
gboolean validate_xml(xmlNode *xml_blob, const char *validation, gboolean to_logs)
 
cib_callback_client_t * cib__lookup_id(int call_id)
 
#define XML_CIB_TAG_PROPSET
 
bool xml_tracking_changes(xmlNode *xml)
 
gboolean cib_read_config(GHashTable *options, xmlNode *current_cib)
 
xmlNode * copy_xml(xmlNode *src_node)
 
const char * get_object_path(const char *object_type)
 
#define XML_CIB_TAG_RESOURCES
 
#define crm_warn(fmt, args...)
 
void pcmk__strip_xml_text(xmlNode *xml)
 
cib_api_operations_t * cmds
 
#define crm_debug(fmt, args...)
 
int cib_process_diff(const char *op, int options, const char *section, xmlNode *req, xmlNode *input, xmlNode *existing_cib, xmlNode **result_cib, xmlNode **answer)
 
void cib_native_callback(cib_t *cib, xmlNode *msg, int call_id, int rc)
 
int xml_apply_patchset(xmlNode *xml, xmlNode *patchset, bool check_version)
 
int(* signon)(cib_t *cib, const char *name, enum cib_conn_type type)
 
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute. 
 
const char * crm_xml_replace(xmlNode *node, const char *name, const char *value)
Replace an XML attribute with specified name and (possibly NULL) value. 
 
int(* cib_op_t)(const char *, int, const char *, xmlNode *, xmlNode *, xmlNode *, xmlNode **, xmlNode **)
 
void pcmk__print_option_metadata(const char *name, const char *desc_short, const char *desc_long, pcmk__cluster_option_t *option_list, int len)
 
void(* callback)(xmlNode *, int, int, xmlNode *, void *)
 
#define crm_trace(fmt, args...)
 
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag. 
 
void(* op_callback)(const xmlNode *msg, int call_id, int rc, xmlNode *output)
 
#define crm_log_xml_debug(xml, text)
 
#define F_CIB_UPDATE_RESULT
 
#define XML_TAG_META_SETS
 
Wrappers for and extensions to libxml2. 
 
void verify_cib_options(GHashTable *options)
 
xmlNode * create_xml_node(xmlNode *parent, const char *name)
 
#define crm_log_xml_warn(xml, text)
 
int(* query)(cib_t *cib, const char *section, xmlNode **output_data, int call_options)
 
#define XML_ATTR_VALIDATION
 
int pcmk_legacy2rc(int legacy_rc)
 
#define CIB_OPTIONS_FIRST
 
xmlNode * createEmptyCib(int cib_epoch)
Create XML for a new (empty) CIB. 
 
gboolean add_message_xml(xmlNode *msg, const char *field, xmlNode *xml)
 
const char * pcmk__cluster_option(GHashTable *options, pcmk__cluster_option_t *option_list, int len, const char *name)
 
void free_xml(xmlNode *child)
 
gboolean cib_diff_version_details(xmlNode *diff, int *admin_epoch, int *epoch, int *updates, int *_admin_epoch, int *_epoch, int *_updates)
 
#define XML_CIB_TAG_GENERATION_TUPPLE
 
const char * xml_latest_schema(void)
 
void patchset_process_digest(xmlNode *patch, xmlNode *source, xmlNode *target, bool with_digest)
 
gboolean crm_is_callsite_active(struct qb_log_callsite *cs, uint8_t level, uint32_t tags)
 
bool xml_patch_versions(xmlNode *patchset, int add[3], int del[3])
 
void xml_log_changes(uint8_t level, const char *function, xmlNode *xml)
 
bool pcmk__valid_boolean(const char *value)
 
xmlNode * cib_create_op(int call_id, const char *token, const char *op, const char *host, const char *section, xmlNode *data, int call_options, const char *user_name)
 
#define pcmk_err_diff_resync
 
GHashTable * pcmk__strkey_table(GDestroyNotify key_destroy_func, GDestroyNotify value_destroy_func)
 
#define crm_err(fmt, args...)
 
xmlXPathObjectPtr xpath_search(xmlNode *xml_top, const char *path)
 
crm_time_t * crm_time_new(const char *string)
 
#define XML_CIB_TAG_CRMCONFIG
 
#define XML_CIB_TAG_RSCCONFIG
 
bool xml_acl_denied(xmlNode *xml)
 
void xml_acl_disable(xmlNode *xml)
 
int compare_version(const char *version1, const char *version2)
 
#define XML_ATTR_GENERATION_ADMIN
 
#define XML_NVPAIR_ATTR_VALUE
 
#define XML_ATTR_CRM_VERSION
 
void save_xml_to_file(xmlNode *xml, const char *desc, const char *filename)
 
#define XML_CIB_TAG_STATUS
 
#define crm_log_xml_trace(xml, text)
 
void pcmk__validate_cluster_options(GHashTable *options, pcmk__cluster_option_t *option_list, int len)
 
gboolean crm_is_true(const char *s)
 
#define XML_CIB_TAG_ALERTS
 
const char * cib_pref(GHashTable *options, const char *name)
 
#define XML_CIB_TAG_CONFIGURATION
 
void xml_log_patchset(uint8_t level, const char *function, xmlNode *xml)
 
void fix_plus_plus_recursive(xmlNode *target)
 
void freeXpathObject(xmlXPathObjectPtr xpathObj)
 
#define XML_CIB_TAG_OPCONFIG
 
int cib_perform_op(const char *op, int call_options, cib_op_t *fn, gboolean is_query, const char *section, xmlNode *req, xmlNode *input, gboolean manage_counters, gboolean *config_changed, xmlNode *current_cib, xmlNode **result_cib, xmlNode **diff, xmlNode **output)
 
xmlNode * xml_create_patchset(int format, xmlNode *source, xmlNode *target, bool *config, bool manage_version)
 
void cib_native_notify(gpointer data, gpointer user_data)
 
void xml_calculate_changes(xmlNode *old_xml, xmlNode *new_xml)
 
bool pcmk_acl_required(const char *user)
Check whether ACLs are required for a given user. 
 
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)
 
void crm_time_free(crm_time_t *dt)