root/attrd/attrd_common_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 (C) 2015 Andrew Beekhof <andrew@beekhof.net>
   3  *
   4  * This program is free software; you can redistribute it and/or
   5  * modify it under the terms of the GNU Lesser General Public
   6  * License as published by the Free Software Foundation; either
   7  * version 2 of the License, or (at your option) any later version.
   8  *
   9  * This software is distributed in the hope that it will be useful,
  10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12  * General Public License for more details.
  13  *
  14  * You should have received a copy of the GNU Lesser General Public
  15  * License along with this library; if not, write to the Free Software
  16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  17  */
  18 #include <crm_internal.h>
  19 #include <crm/crm.h>
  20 #include <crm/cib/internal.h>
  21 #include <crm/msg_xml.h>
  22 #include <crm/cluster/internal.h>
  23 #include <crm/cluster/election.h>
  24 #include <internal.h>
  25 #include <crm/common/alerts_internal.h>
  26 #include <crm/pengine/rules_internal.h>
  27 #include <crm/lrmd_alerts_internal.h>
  28 
  29 static GListPtr attrd_alert_list = NULL;
  30 
  31 static void
  32 attrd_lrmd_callback(lrmd_event_data_t * op)
     /* [previous][next][first][last][top][bottom][index][help] */
  33 {
  34     CRM_CHECK(op != NULL, return);
  35     switch (op->type) {
  36         case lrmd_event_disconnect:
  37             crm_info("Lost connection to LRMD");
  38             attrd_lrmd_disconnect();
  39             break;
  40         default:
  41             break;
  42     }
  43 }
  44 
  45 static lrmd_t *
  46 attrd_lrmd_connect()
     /* [previous][next][first][last][top][bottom][index][help] */
  47 {
  48     if (the_lrmd == NULL) {
  49         the_lrmd = lrmd_api_new();
  50         the_lrmd->cmds->set_callback(the_lrmd, attrd_lrmd_callback);
  51     }
  52 
  53     if (!the_lrmd->cmds->is_connected(the_lrmd)) {
  54         const unsigned int max_attempts = 10;
  55         int ret = -ENOTCONN;
  56 
  57         for (int fails = 0; fails < max_attempts; ++fails) {
  58             ret = the_lrmd->cmds->connect(the_lrmd, T_ATTRD, NULL);
  59             if (ret == pcmk_ok) {
  60                 break;
  61             }
  62 
  63             crm_debug("Could not connect to LRMD, %d tries remaining",
  64                       (max_attempts - fails));
  65             /* @TODO We don't want to block here with sleep, but we should wait
  66              * some time between connection attempts. We could possibly add a
  67              * timer with a callback, but then we'd likely need an alert queue.
  68              */
  69         }
  70 
  71         if (ret != pcmk_ok) {
  72             attrd_lrmd_disconnect();
  73         }
  74     }
  75 
  76     return the_lrmd;
  77 }
  78 
  79 void
  80 attrd_lrmd_disconnect() {
     /* [previous][next][first][last][top][bottom][index][help] */
  81     if (the_lrmd) {
  82         lrmd_t *conn = the_lrmd;
  83 
  84         the_lrmd = NULL; /* in case we're called recursively */
  85         lrmd_api_delete(conn); /* will disconnect if necessary */
  86     }
  87 }
  88 
  89 static void
  90 config_query_callback(xmlNode * msg, int call_id, int rc, xmlNode * output, void *user_data)
     /* [previous][next][first][last][top][bottom][index][help] */
  91 {
  92     xmlNode *crmalerts = NULL;
  93 
  94     if (rc == -ENXIO) {
  95         crm_debug("Local CIB has no alerts section");
  96         return;
  97     } else if (rc != pcmk_ok) {
  98         crm_notice("Could not query local CIB: %s", pcmk_strerror(rc));
  99         return;
 100     }
 101 
 102     crmalerts = output;
 103     if (crmalerts && !crm_str_eq(crm_element_name(crmalerts),
 104                                  XML_CIB_TAG_ALERTS, TRUE)) {
 105         crmalerts = first_named_child(crmalerts, XML_CIB_TAG_ALERTS);
 106     }
 107     if (!crmalerts) {
 108         crm_notice("CIB query result has no " XML_CIB_TAG_ALERTS " section");
 109         return;
 110     }
 111 
 112     pe_free_alert_list(attrd_alert_list);
 113     attrd_alert_list = pe_unpack_alerts(crmalerts);
 114 }
 115 
 116 #define XPATH_ALERTS \
 117     "/" XML_TAG_CIB "/" XML_CIB_TAG_CONFIGURATION "/" XML_CIB_TAG_ALERTS
 118 
 119 gboolean
 120 attrd_read_options(gpointer user_data)
     /* [previous][next][first][last][top][bottom][index][help] */
 121 {
 122     int call_id;
 123 
 124     if (the_cib) {
 125         call_id = the_cib->cmds->query(the_cib, XPATH_ALERTS, NULL,
 126                                        cib_xpath | cib_scope_local);
 127 
 128         the_cib->cmds->register_callback_full(the_cib, call_id, 120, FALSE,
 129                                               NULL,
 130                                               "config_query_callback",
 131                                               config_query_callback, free);
 132 
 133         crm_trace("Querying the CIB... call %d", call_id);
 134     } else {
 135         crm_err("Could not check for alerts configuration: CIB connection not active");
 136     }
 137     return TRUE;
 138 }
 139 
 140 void
 141 attrd_cib_updated_cb(const char *event, xmlNode * msg)
     /* [previous][next][first][last][top][bottom][index][help] */
 142 {
 143     if (crm_patchset_contains_alert(msg, FALSE)) {
 144         mainloop_set_trigger(attrd_config_read);
 145     }
 146 }
 147 
 148 int
 149 attrd_send_attribute_alert(const char *node, int nodeid,
     /* [previous][next][first][last][top][bottom][index][help] */
 150                            const char *attr, const char *value)
 151 {
 152     if (attrd_alert_list == NULL) {
 153         return pcmk_ok;
 154     }
 155     return lrmd_send_attribute_alert(attrd_lrmd_connect(), attrd_alert_list,
 156                                      node, nodeid, attr, value);
 157 }

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