dhodovsk / source-git / pacemaker

Forked from source-git/pacemaker 3 years ago
Clone

Blame lib/common/alerts.c

rpm-build 3ee90c
/*
rpm-build 3ee90c
 * Copyright 2015-2019 Andrew Beekhof <andrew@beekhof.net>
rpm-build 3ee90c
 *
rpm-build 3ee90c
 * This source code is licensed under the GNU Lesser General Public License
rpm-build 3ee90c
 * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
rpm-build 3ee90c
 */
rpm-build 3ee90c
rpm-build 3ee90c
#include <crm_internal.h>
rpm-build 3ee90c
#include <crm/crm.h>
rpm-build 3ee90c
#include <crm/lrmd.h>
rpm-build 3ee90c
#include <crm/msg_xml.h>
rpm-build 3ee90c
#include <crm/common/alerts_internal.h>
rpm-build 3ee90c
#include <crm/cib/internal.h> /* for F_CIB_UPDATE_RESULT */
rpm-build 3ee90c
rpm-build 3ee90c
/*		
rpm-build 3ee90c
 * to allow script compatibility we can have more than one		
rpm-build 3ee90c
 * set of environment variables		
rpm-build 3ee90c
 */
rpm-build 3ee90c
const char *crm_alert_keys[CRM_ALERT_INTERNAL_KEY_MAX][3] =		
rpm-build 3ee90c
{		
rpm-build 3ee90c
    [CRM_alert_recipient]     = {"CRM_notify_recipient",     "CRM_alert_recipient",     NULL},		
rpm-build 3ee90c
    [CRM_alert_node]          = {"CRM_notify_node",          "CRM_alert_node",          NULL},		
rpm-build 3ee90c
    [CRM_alert_nodeid]        = {"CRM_notify_nodeid",        "CRM_alert_nodeid",        NULL},		
rpm-build 3ee90c
    [CRM_alert_rsc]           = {"CRM_notify_rsc",           "CRM_alert_rsc",           NULL},		
rpm-build 3ee90c
    [CRM_alert_task]          = {"CRM_notify_task",          "CRM_alert_task",          NULL},		
rpm-build 3ee90c
    [CRM_alert_interval]      = {"CRM_notify_interval",      "CRM_alert_interval",      NULL},		
rpm-build 3ee90c
    [CRM_alert_desc]          = {"CRM_notify_desc",          "CRM_alert_desc",          NULL},		
rpm-build 3ee90c
    [CRM_alert_status]        = {"CRM_notify_status",        "CRM_alert_status",        NULL},		
rpm-build 3ee90c
    [CRM_alert_target_rc]     = {"CRM_notify_target_rc",     "CRM_alert_target_rc",     NULL},		
rpm-build 3ee90c
    [CRM_alert_rc]            = {"CRM_notify_rc",            "CRM_alert_rc",            NULL},		
rpm-build 3ee90c
    [CRM_alert_kind]          = {"CRM_notify_kind",          "CRM_alert_kind",          NULL},		
rpm-build 3ee90c
    [CRM_alert_version]       = {"CRM_notify_version",       "CRM_alert_version",       NULL},		
rpm-build 3ee90c
    [CRM_alert_node_sequence] = {"CRM_notify_node_sequence", CRM_ALERT_NODE_SEQUENCE, NULL},		
rpm-build 3ee90c
    [CRM_alert_timestamp]     = {"CRM_notify_timestamp",     "CRM_alert_timestamp",     NULL},
rpm-build 3ee90c
    [CRM_alert_attribute_name]     = {"CRM_notify_attribute_name",     "CRM_alert_attribute_name",     NULL},
rpm-build 3ee90c
    [CRM_alert_attribute_value]     = {"CRM_notify_attribute_value",     "CRM_alert_attribute_value",     NULL},
rpm-build 3ee90c
    [CRM_alert_timestamp_epoch]     = {"CRM_notify_timestamp_epoch",     "CRM_alert_timestamp_epoch",     NULL},
rpm-build 3ee90c
    [CRM_alert_timestamp_usec]     = {"CRM_notify_timestamp_usec",     "CRM_alert_timestamp_usec",     NULL},
rpm-build 3ee90c
    [CRM_alert_exec_time]     = {"CRM_notify_exec_time",     "CRM_alert_exec_time",     NULL}
rpm-build 3ee90c
};
rpm-build 3ee90c
rpm-build 3ee90c
/*!
rpm-build 3ee90c
 * \brief Create a new alert entry structure
rpm-build 3ee90c
 *
rpm-build 3ee90c
 * \param[in] id  ID to use
rpm-build 3ee90c
 * \param[in] path  Path to alert agent executable
rpm-build 3ee90c
 *
rpm-build 3ee90c
 * \return Pointer to newly allocated alert entry
rpm-build 3ee90c
 * \note Non-string fields will be filled in with defaults.
rpm-build 3ee90c
 *       It is the caller's responsibility to free the result,
rpm-build 3ee90c
 *       using crm_free_alert_entry().
rpm-build 3ee90c
 */
rpm-build 3ee90c
crm_alert_entry_t *
rpm-build 3ee90c
crm_alert_entry_new(const char *id, const char *path)
rpm-build 3ee90c
{
rpm-build 3ee90c
    crm_alert_entry_t *entry = calloc(1, sizeof(crm_alert_entry_t));
rpm-build 3ee90c
rpm-build 3ee90c
    CRM_ASSERT(entry && id && path);
rpm-build 3ee90c
    entry->id = strdup(id);
rpm-build 3ee90c
    entry->path = strdup(path);
rpm-build 3ee90c
    entry->timeout = CRM_ALERT_DEFAULT_TIMEOUT_MS;
rpm-build 3ee90c
    entry->flags = crm_alert_default;
rpm-build 3ee90c
    return entry;
rpm-build 3ee90c
}
rpm-build 3ee90c
rpm-build 3ee90c
void
rpm-build 3ee90c
crm_free_alert_entry(crm_alert_entry_t *entry)
rpm-build 3ee90c
{		
rpm-build 3ee90c
    if (entry) {
rpm-build 3ee90c
        free(entry->id);
rpm-build 3ee90c
        free(entry->path);
rpm-build 3ee90c
        free(entry->tstamp_format);
rpm-build 3ee90c
        free(entry->recipient);
rpm-build 3ee90c
rpm-build 3ee90c
        g_strfreev(entry->select_attribute_name);
rpm-build 3ee90c
        if (entry->envvars) {
rpm-build 3ee90c
            g_hash_table_destroy(entry->envvars);
rpm-build 3ee90c
        }
rpm-build 3ee90c
        free(entry);
rpm-build 3ee90c
    }
rpm-build 3ee90c
}		
rpm-build 3ee90c
rpm-build 3ee90c
/*!
rpm-build 3ee90c
 * \internal
rpm-build 3ee90c
 * \brief Duplicate an alert entry
rpm-build 3ee90c
 *
rpm-build 3ee90c
 * \param[in] entry  Alert entry to duplicate
rpm-build 3ee90c
 *
rpm-build 3ee90c
 * \return Duplicate of alert entry
rpm-build 3ee90c
 */
rpm-build 3ee90c
crm_alert_entry_t *
rpm-build 3ee90c
crm_dup_alert_entry(crm_alert_entry_t *entry)
rpm-build 3ee90c
{
rpm-build 3ee90c
    crm_alert_entry_t *new_entry = crm_alert_entry_new(entry->id, entry->path);
rpm-build 3ee90c
rpm-build 3ee90c
    new_entry->timeout = entry->timeout;
rpm-build 3ee90c
    new_entry->flags = entry->flags;
rpm-build 3ee90c
    new_entry->envvars = crm_str_table_dup(entry->envvars);
rpm-build 3ee90c
    if (entry->tstamp_format) {
rpm-build 3ee90c
        new_entry->tstamp_format = strdup(entry->tstamp_format);
rpm-build 3ee90c
    }
rpm-build 3ee90c
    if (entry->recipient) {
rpm-build 3ee90c
        new_entry->recipient = strdup(entry->recipient);
rpm-build 3ee90c
    }
rpm-build 3ee90c
    if (entry->select_attribute_name) {
rpm-build 3ee90c
        new_entry->select_attribute_name = g_strdupv(entry->select_attribute_name);
rpm-build 3ee90c
    }
rpm-build 3ee90c
    return new_entry;
rpm-build 3ee90c
}
rpm-build 3ee90c
rpm-build 3ee90c
void
rpm-build 3ee90c
crm_unset_alert_keys()
rpm-build 3ee90c
{
rpm-build 3ee90c
    const char **key;
rpm-build 3ee90c
    enum crm_alert_keys_e name;
rpm-build 3ee90c
rpm-build 3ee90c
    for(name = 0; name < DIMOF(crm_alert_keys); name++) {
rpm-build 3ee90c
        for(key = crm_alert_keys[name]; *key; key++) {
rpm-build 3ee90c
            crm_trace("Unsetting alert key %s", *key);
rpm-build 3ee90c
            unsetenv(*key);
rpm-build 3ee90c
        }
rpm-build 3ee90c
    }
rpm-build 3ee90c
}
rpm-build 3ee90c
rpm-build 3ee90c
void
rpm-build 3ee90c
crm_insert_alert_key(GHashTable *table, enum crm_alert_keys_e name,
rpm-build 3ee90c
                     const char *value)
rpm-build 3ee90c
{
rpm-build 3ee90c
    for (const char **key = crm_alert_keys[name]; *key; key++) {
rpm-build 3ee90c
        crm_trace("Inserting alert key %s = '%s'", *key, value);
rpm-build 3ee90c
        if (value) {
rpm-build 3ee90c
            g_hash_table_insert(table, strdup(*key), strdup(value));
rpm-build 3ee90c
        } else {
rpm-build 3ee90c
            g_hash_table_remove(table, *key);
rpm-build 3ee90c
        }
rpm-build 3ee90c
    }
rpm-build 3ee90c
}
rpm-build 3ee90c
rpm-build 3ee90c
void
rpm-build 3ee90c
crm_insert_alert_key_int(GHashTable *table, enum crm_alert_keys_e name,
rpm-build 3ee90c
                         int value)
rpm-build 3ee90c
{
rpm-build 3ee90c
    for (const char **key = crm_alert_keys[name]; *key; key++) {
rpm-build 3ee90c
        crm_trace("Inserting alert key %s = %d", *key, value);
rpm-build 3ee90c
        g_hash_table_insert(table, strdup(*key), crm_itoa(value));
rpm-build 3ee90c
    }
rpm-build 3ee90c
}
rpm-build 3ee90c
rpm-build 3ee90c
static void
rpm-build 3ee90c
set_envvar(gpointer key, gpointer value, gpointer user_data)
rpm-build 3ee90c
{
rpm-build 3ee90c
    gboolean always_unset = GPOINTER_TO_INT(user_data);
rpm-build 3ee90c
rpm-build 3ee90c
    crm_trace("%s environment variable %s='%s'",
rpm-build 3ee90c
              (value? "Setting" : "Unsetting"),
rpm-build 3ee90c
              (char*)key, (value? (char*)value : ""));
rpm-build 3ee90c
    if (value && !always_unset) {
rpm-build 3ee90c
        setenv(key, value, 1);
rpm-build 3ee90c
    } else {
rpm-build 3ee90c
        unsetenv(key);
rpm-build 3ee90c
    }
rpm-build 3ee90c
}
rpm-build 3ee90c
rpm-build 3ee90c
void
rpm-build 3ee90c
crm_set_envvar_list(crm_alert_entry_t *entry)
rpm-build 3ee90c
{
rpm-build 3ee90c
    if (entry->envvars) {
rpm-build 3ee90c
        g_hash_table_foreach(entry->envvars, set_envvar, GINT_TO_POINTER(FALSE));
rpm-build 3ee90c
    }
rpm-build 3ee90c
}
rpm-build 3ee90c
rpm-build 3ee90c
/*
rpm-build 3ee90c
 * \note We have no way of restoring a previous value if one was set.
rpm-build 3ee90c
 */
rpm-build 3ee90c
void
rpm-build 3ee90c
crm_unset_envvar_list(crm_alert_entry_t *entry)
rpm-build 3ee90c
{
rpm-build 3ee90c
    if (entry->envvars) {
rpm-build 3ee90c
        g_hash_table_foreach(entry->envvars, set_envvar, GINT_TO_POINTER(TRUE));
rpm-build 3ee90c
    }
rpm-build 3ee90c
}
rpm-build 3ee90c
rpm-build 3ee90c
#define XPATH_PATCHSET1_DIFF "//" F_CIB_UPDATE_RESULT "//" XML_TAG_DIFF_ADDED
rpm-build 3ee90c
rpm-build 3ee90c
#define XPATH_PATCHSET1_CRMCONFIG XPATH_PATCHSET1_DIFF "//" XML_CIB_TAG_CRMCONFIG
rpm-build 3ee90c
#define XPATH_PATCHSET1_ALERTS    XPATH_PATCHSET1_DIFF "//" XML_CIB_TAG_ALERTS
rpm-build 3ee90c
rpm-build 3ee90c
#define XPATH_PATCHSET1_EITHER \
rpm-build 3ee90c
    XPATH_PATCHSET1_CRMCONFIG " | " XPATH_PATCHSET1_ALERTS
rpm-build 3ee90c
rpm-build 3ee90c
#define XPATH_CONFIG "/" XML_TAG_CIB "/" XML_CIB_TAG_CONFIGURATION
rpm-build 3ee90c
rpm-build 3ee90c
#define XPATH_CRMCONFIG XPATH_CONFIG "/" XML_CIB_TAG_CRMCONFIG "/"
rpm-build 3ee90c
#define XPATH_ALERTS    XPATH_CONFIG "/" XML_CIB_TAG_ALERTS
rpm-build 3ee90c
rpm-build 3ee90c
/*!
rpm-build 3ee90c
 * \internal
rpm-build 3ee90c
 * \brief Check whether a CIB update affects alerts
rpm-build 3ee90c
 *
rpm-build 3ee90c
 * \param[in] msg     XML containing CIB update
rpm-build 3ee90c
 * \param[in] config  Whether to check for crmconfig change as well
rpm-build 3ee90c
 *
rpm-build 3ee90c
 * \return TRUE if update affects alerts, FALSE otherwise
rpm-build 3ee90c
 */
rpm-build 3ee90c
bool
rpm-build 3ee90c
crm_patchset_contains_alert(xmlNode *msg, bool config)
rpm-build 3ee90c
{
rpm-build 3ee90c
    int rc = -1;
rpm-build 3ee90c
    int format= 1;
rpm-build 3ee90c
    xmlNode *patchset = get_message_xml(msg, F_CIB_UPDATE_RESULT);
rpm-build 3ee90c
    xmlNode *change = NULL;
rpm-build 3ee90c
    xmlXPathObject *xpathObj = NULL;
rpm-build 3ee90c
rpm-build 3ee90c
    CRM_CHECK(msg != NULL, return FALSE);
rpm-build 3ee90c
rpm-build 3ee90c
    crm_element_value_int(msg, F_CIB_RC, &rc);
rpm-build 3ee90c
    if (rc < pcmk_ok) {
rpm-build 3ee90c
        crm_trace("Ignore failed CIB update: %s (%d)", pcmk_strerror(rc), rc);
rpm-build 3ee90c
        return FALSE;
rpm-build 3ee90c
    }
rpm-build 3ee90c
rpm-build 3ee90c
    crm_element_value_int(patchset, "format", &format);
rpm-build 3ee90c
    if (format == 1) {
rpm-build 3ee90c
        const char *diff = (config? XPATH_PATCHSET1_EITHER : XPATH_PATCHSET1_ALERTS);
rpm-build 3ee90c
rpm-build 3ee90c
        if ((xpathObj = xpath_search(msg, diff)) != NULL) {
rpm-build 3ee90c
            freeXpathObject(xpathObj);
rpm-build 3ee90c
            return TRUE;
rpm-build 3ee90c
        }
rpm-build 3ee90c
    } else if (format == 2) {
rpm-build 3ee90c
        for (change = __xml_first_child(patchset); change != NULL; change = __xml_next(change)) {
rpm-build 3ee90c
            const char *xpath = crm_element_value(change, XML_DIFF_PATH);
rpm-build 3ee90c
rpm-build 3ee90c
            if (xpath == NULL) {
rpm-build 3ee90c
                continue;
rpm-build 3ee90c
            }
rpm-build 3ee90c
rpm-build 3ee90c
            if ((!config || !strstr(xpath, XPATH_CRMCONFIG))
rpm-build 3ee90c
                && !strstr(xpath, XPATH_ALERTS)) {
rpm-build 3ee90c
rpm-build 3ee90c
                /* this is not a change to an existing section ... */
rpm-build 3ee90c
rpm-build 3ee90c
                xmlNode *section = NULL;
rpm-build 3ee90c
                const char *name = NULL;
rpm-build 3ee90c
rpm-build 3ee90c
                if ((strcmp(xpath, XPATH_CONFIG) != 0) ||
rpm-build 3ee90c
                    ((section = __xml_first_child(change)) == NULL) ||
rpm-build 3ee90c
                    ((name = crm_element_name(section)) == NULL) ||
rpm-build 3ee90c
                    (strcmp(name, XML_CIB_TAG_ALERTS) != 0)) {
rpm-build 3ee90c
rpm-build 3ee90c
                    /* ... nor is it a newly added alerts section */
rpm-build 3ee90c
                    continue;
rpm-build 3ee90c
                }
rpm-build 3ee90c
            }
rpm-build 3ee90c
rpm-build 3ee90c
            return TRUE;
rpm-build 3ee90c
        }
rpm-build 3ee90c
rpm-build 3ee90c
    } else {
rpm-build 3ee90c
        crm_warn("Unknown patch format: %d", format);
rpm-build 3ee90c
    }
rpm-build 3ee90c
    return FALSE;
rpm-build 3ee90c
}