This source file includes following definitions.
- attrd_lrmd_callback
- attrd_lrmd_connect
- attrd_lrmd_disconnect
- config_query_callback
- attrd_read_options
- attrd_send_attribute_alert
1
2
3
4
5
6
7
8
9
10 #include <crm_internal.h>
11 #include <crm/crm.h>
12 #include <crm/cib/internal.h>
13 #include <crm/cluster/internal.h>
14 #include <crm/cluster/election_internal.h>
15 #include <crm/common/alerts_internal.h>
16 #include <crm/common/cib_internal.h>
17 #include <crm/common/xml.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)
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)
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, PCMK__VALUE_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
58
59
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) {
73 if (the_lrmd) {
74 lrmd_t *conn = the_lrmd;
75
76 the_lrmd = NULL;
77 lrmd_api_delete(conn);
78 }
79 }
80
81 static void
82 config_query_callback(xmlNode * msg, int call_id, int rc, xmlNode * output, void *user_data)
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 != NULL) && !pcmk__xe_is(crmalerts, PCMK_XE_ALERTS)) {
96 crmalerts = pcmk__xe_first_child(crmalerts, PCMK_XE_ALERTS, NULL, NULL);
97 }
98 if (!crmalerts) {
99 crm_notice("CIB query result has no " PCMK_XE_ALERTS " section");
100 return;
101 }
102
103 pcmk__free_alerts(attrd_alert_list);
104 attrd_alert_list = pcmk__unpack_alerts(crmalerts);
105 }
106
107 gboolean
108 attrd_read_options(gpointer user_data)
109 {
110 int call_id;
111
112 CRM_CHECK(the_cib != NULL, return TRUE);
113
114 call_id = the_cib->cmds->query(the_cib,
115 pcmk__cib_abs_xpath_for(PCMK_XE_ALERTS),
116 NULL, cib_xpath);
117
118 the_cib->cmds->register_callback_full(the_cib, call_id, 120, FALSE, NULL,
119 "config_query_callback",
120 config_query_callback, free);
121
122 crm_trace("Querying the CIB... call %d", call_id);
123 return TRUE;
124 }
125
126 int
127 attrd_send_attribute_alert(const char *node, const char *node_xml_id,
128 const char *attr, const char *value)
129 {
130 uint32_t nodeid = 0U;
131 pcmk__node_status_t *node_status = NULL;
132
133 if (attrd_alert_list == NULL) {
134 return pcmk_ok;
135 }
136 node_status = pcmk__search_node_caches(0, node, node_xml_id,
137 pcmk__node_search_remote
138 |pcmk__node_search_cluster_member
139 |pcmk__node_search_cluster_cib);
140 if (node_status != NULL) {
141 nodeid = node_status->cluster_layer_id;
142 }
143 return lrmd_send_attribute_alert(attrd_lrmd_connect(), attrd_alert_list,
144 node, nodeid, attr, value);
145 }