root/daemons/attrd/attrd_alerts.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. attrd_lrmd_callback
  2. attrd_lrmd_connect
  3. attrd_lrmd_disconnect
  4. config_query_callback
  5. attrd_read_options
  6. attrd_cib_updated_cb
  7. attrd_send_attribute_alert

   1 /*
   2  * Copyright 2015-2021 the Pacemaker project contributors
   3  *
   4  * The version control history for this file may have further details.
   5  *
   6  * This source code is licensed under the GNU General Public License version 2
   7  * or later (GPLv2+) WITHOUT ANY WARRANTY.
   8  */
   9 
  10 #include <crm_internal.h>
  11 #include <crm/crm.h>
  12 #include <crm/cib/internal.h>
  13 #include <crm/msg_xml.h>
  14 #include <crm/cluster/internal.h>
  15 #include <crm/cluster/election_internal.h>
  16 #include <crm/common/alerts_internal.h>
  17 #include <crm/pengine/rules_internal.h>
  18 #include <crm/lrmd_internal.h>
  19 #include "pacemaker-attrd.h"
  20 
  21 static GList *attrd_alert_list = NULL;
  22 
  23 static void
  24 attrd_lrmd_callback(lrmd_event_data_t * op)
     /* [previous][next][first][last][top][bottom][index][help] */
  25 {
  26     CRM_CHECK(op != NULL, return);
  27     switch (op->type) {
  28         case lrmd_event_disconnect:
  29             crm_info("Lost connection to executor");
  30             attrd_lrmd_disconnect();
  31             break;
  32         default:
  33             break;
  34     }
  35 }
  36 
  37 static lrmd_t *
  38 attrd_lrmd_connect(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  39 {
  40     if (the_lrmd == NULL) {
  41         the_lrmd = lrmd_api_new();
  42         the_lrmd->cmds->set_callback(the_lrmd, attrd_lrmd_callback);
  43     }
  44 
  45     if (!the_lrmd->cmds->is_connected(the_lrmd)) {
  46         const unsigned int max_attempts = 10;
  47         int ret = -ENOTCONN;
  48 
  49         for (int fails = 0; fails < max_attempts; ++fails) {
  50             ret = the_lrmd->cmds->connect(the_lrmd, T_ATTRD, NULL);
  51             if (ret == pcmk_ok) {
  52                 break;
  53             }
  54 
  55             crm_debug("Could not connect to executor, %d tries remaining",
  56                       (max_attempts - fails));
  57             /* @TODO We don't want to block here with sleep, but we should wait
  58              * some time between connection attempts. We could possibly add a
  59              * timer with a callback, but then we'd likely need an alert queue.
  60              */
  61         }
  62 
  63         if (ret != pcmk_ok) {
  64             attrd_lrmd_disconnect();
  65         }
  66     }
  67 
  68     return the_lrmd;
  69 }
  70 
  71 void
  72 attrd_lrmd_disconnect(void) {
     /* [previous][next][first][last][top][bottom][index][help] */
  73     if (the_lrmd) {
  74         lrmd_t *conn = the_lrmd;
  75 
  76         the_lrmd = NULL; /* in case we're called recursively */
  77         lrmd_api_delete(conn); /* will disconnect if necessary */
  78     }
  79 }
  80 
  81 static void
  82 config_query_callback(xmlNode * msg, int call_id, int rc, xmlNode * output, void *user_data)
     /* [previous][next][first][last][top][bottom][index][help] */
  83 {
  84     xmlNode *crmalerts = NULL;
  85 
  86     if (rc == -ENXIO) {
  87         crm_debug("Local CIB has no alerts section");
  88         return;
  89     } else if (rc != pcmk_ok) {
  90         crm_notice("Could not query local CIB: %s", pcmk_strerror(rc));
  91         return;
  92     }
  93 
  94     crmalerts = output;
  95     if (crmalerts && !pcmk__str_eq(crm_element_name(crmalerts), XML_CIB_TAG_ALERTS, pcmk__str_none)) {
  96         crmalerts = first_named_child(crmalerts, XML_CIB_TAG_ALERTS);
  97     }
  98     if (!crmalerts) {
  99         crm_notice("CIB query result has no " XML_CIB_TAG_ALERTS " section");
 100         return;
 101     }
 102 
 103     pe_free_alert_list(attrd_alert_list);
 104     attrd_alert_list = pe_unpack_alerts(crmalerts);
 105 }
 106 
 107 #define XPATH_ALERTS \
 108     "/" XML_TAG_CIB "/" XML_CIB_TAG_CONFIGURATION "/" XML_CIB_TAG_ALERTS
 109 
 110 gboolean
 111 attrd_read_options(gpointer user_data)
     /* [previous][next][first][last][top][bottom][index][help] */
 112 {
 113     int call_id;
 114 
 115     CRM_CHECK(the_cib != NULL, return TRUE);
 116 
 117     call_id = the_cib->cmds->query(the_cib, XPATH_ALERTS, NULL,
 118                                    cib_xpath | cib_scope_local);
 119 
 120     the_cib->cmds->register_callback_full(the_cib, call_id, 120, FALSE, NULL,
 121                                           "config_query_callback",
 122                                           config_query_callback, free);
 123 
 124     crm_trace("Querying the CIB... call %d", call_id);
 125     return TRUE;
 126 }
 127 
 128 void
 129 attrd_cib_updated_cb(const char *event, xmlNode * msg)
     /* [previous][next][first][last][top][bottom][index][help] */
 130 {
 131     if (!attrd_shutting_down() && pcmk__alert_in_patchset(msg, false)) {
 132         mainloop_set_trigger(attrd_config_read);
 133     }
 134 }
 135 
 136 int
 137 attrd_send_attribute_alert(const char *node, int nodeid,
     /* [previous][next][first][last][top][bottom][index][help] */
 138                            const char *attr, const char *value)
 139 {
 140     if (attrd_alert_list == NULL) {
 141         return pcmk_ok;
 142     }
 143     return lrmd_send_attribute_alert(attrd_lrmd_connect(), attrd_alert_list,
 144                                      node, nodeid, attr, value);
 145 }

/* [previous][next][first][last][top][bottom][index][help] */