This source file includes following definitions.
- attrd_lrmd_callback
- attrd_lrmd_connect
- attrd_lrmd_disconnect
- config_query_callback
- attrd_read_options
- attrd_cib_updated_cb
- attrd_send_attribute_alert
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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)
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()
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
66
67
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() {
81 if (the_lrmd) {
82 lrmd_t *conn = the_lrmd;
83
84 the_lrmd = NULL;
85 lrmd_api_delete(conn);
86 }
87 }
88
89 static void
90 config_query_callback(xmlNode * msg, int call_id, int rc, xmlNode * output, void *user_data)
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)
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)
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,
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 }