This source file includes following definitions.
- fenced_scheduler_init
- fenced_set_local_node
- fenced_get_local_node
- fenced_scheduler_cleanup
- local_node_allowed_for
- register_if_fencing_device
- fenced_scheduler_run
1
2
3
4
5
6
7
8
9
10 #include <crm_internal.h>
11
12 #include <stdio.h>
13 #include <errno.h>
14 #include <glib.h>
15
16 #include <crm/pengine/status.h>
17 #include <crm/pengine/internal.h>
18
19 #include <pacemaker-internal.h>
20 #include <pacemaker-fenced.h>
21
22 static pcmk_scheduler_t *scheduler = NULL;
23
24
25
26
27
28
29
30 int
31 fenced_scheduler_init(void)
32 {
33 pcmk__output_t *logger = NULL;
34 int rc = pcmk__log_output_new(&logger);
35
36 if (rc != pcmk_rc_ok) {
37 return rc;
38 }
39
40 scheduler = pe_new_working_set();
41 if (scheduler == NULL) {
42 pcmk__output_free(logger);
43 return ENOMEM;
44 }
45
46 pe__register_messages(logger);
47 pcmk__register_lib_messages(logger);
48 pcmk__output_set_log_level(logger, LOG_TRACE);
49 scheduler->priv->out = logger;
50
51 return pcmk_rc_ok;
52 }
53
54
55
56
57
58
59
60 void
61 fenced_set_local_node(const char *node_name)
62 {
63 pcmk__assert(scheduler != NULL);
64
65 scheduler->priv->local_node_name = pcmk__str_copy(node_name);
66 }
67
68
69
70
71
72
73
74 const char *
75 fenced_get_local_node(void)
76 {
77 if (scheduler == NULL) {
78 return NULL;
79 }
80 return scheduler->priv->local_node_name;
81 }
82
83
84
85
86
87 void
88 fenced_scheduler_cleanup(void)
89 {
90 if (scheduler != NULL) {
91 pcmk__output_t *logger = scheduler->priv->out;
92
93 if (logger != NULL) {
94 logger->finish(logger, CRM_EX_OK, true, NULL);
95 pcmk__output_free(logger);
96 scheduler->priv->out = NULL;
97 }
98 pe_free_working_set(scheduler);
99 scheduler = NULL;
100 }
101 }
102
103
104
105
106
107
108
109
110
111 static pcmk_node_t *
112 local_node_allowed_for(const pcmk_resource_t *rsc)
113 {
114 if ((rsc != NULL) && (scheduler->priv->local_node_name != NULL)) {
115 GHashTableIter iter;
116 pcmk_node_t *node = NULL;
117
118 g_hash_table_iter_init(&iter, rsc->priv->allowed_nodes);
119 while (g_hash_table_iter_next(&iter, NULL, (void **) &node)) {
120 if (pcmk__str_eq(node->priv->name, scheduler->priv->local_node_name,
121 pcmk__str_casei)) {
122 return node;
123 }
124 }
125 }
126 return NULL;
127 }
128
129
130
131
132
133
134
135
136
137 static void
138 register_if_fencing_device(gpointer data, gpointer user_data)
139 {
140 pcmk_resource_t *rsc = data;
141 const char *rsc_id = pcmk__s(rsc->priv->history_id, rsc->id);
142
143 xmlNode *xml = NULL;
144 GHashTableIter hash_iter;
145 pcmk_node_t *node = NULL;
146 const char *name = NULL;
147 const char *value = NULL;
148 const char *agent = NULL;
149 const char *rsc_provides = NULL;
150 stonith_key_value_t *params = NULL;
151
152
153 if (rsc->priv->children != NULL) {
154
155 for (GList *iter = rsc->priv->children;
156 iter != NULL; iter = iter->next) {
157
158 register_if_fencing_device(iter->data, NULL);
159 if (pcmk__is_clone(rsc)) {
160 return;
161 }
162 }
163 return;
164 }
165
166 if (!pcmk_is_set(rsc->flags, pcmk__rsc_fence_device)) {
167 return;
168 }
169
170 if (pe__resource_is_disabled(rsc)) {
171 crm_info("Ignoring fencing device %s because it is disabled", rsc->id);
172 return;
173 }
174
175 if ((stonith_watchdog_timeout_ms <= 0) &&
176 pcmk__str_eq(rsc->id, STONITH_WATCHDOG_ID, pcmk__str_none)) {
177 crm_info("Ignoring fencing device %s "
178 "because watchdog fencing is disabled", rsc->id);
179 return;
180 }
181
182
183 node = local_node_allowed_for(rsc);
184 if (node == NULL) {
185 crm_info("Ignoring fencing device %s "
186 "because local node is not allowed to run it", rsc->id);
187 return;
188 }
189 if (node->assign->score < 0) {
190 crm_info("Ignoring fencing device %s "
191 "because local node has preference %s for it",
192 rsc->id, pcmk_readable_score(node->assign->score));
193 return;
194 }
195
196
197 if (pcmk__is_group(rsc->priv->parent)) {
198 pcmk_node_t *group_node = local_node_allowed_for(rsc->priv->parent);
199
200 if ((group_node != NULL) && (group_node->assign->score < 0)) {
201 crm_info("Ignoring fencing device %s "
202 "because local node has preference %s for its group",
203 rsc->id, pcmk_readable_score(group_node->assign->score));
204 return;
205 }
206 }
207
208 crm_debug("Reloading configuration of fencing device %s", rsc->id);
209
210 agent = crm_element_value(rsc->priv->xml, PCMK_XA_TYPE);
211
212 get_meta_attributes(rsc->priv->meta, rsc, NULL, scheduler);
213 rsc_provides = g_hash_table_lookup(rsc->priv->meta,
214 PCMK_STONITH_PROVIDES);
215
216 g_hash_table_iter_init(&hash_iter, pe_rsc_params(rsc, node, scheduler));
217 while (g_hash_table_iter_next(&hash_iter, (gpointer *) &name,
218 (gpointer *) &value)) {
219 if ((name == NULL) || (value == NULL)) {
220 continue;
221 }
222 params = stonith_key_value_add(params, name, value);
223 }
224
225 xml = create_device_registration_xml(rsc_id, st_namespace_any, agent,
226 params, rsc_provides);
227 stonith_key_value_freeall(params, 1, 1);
228 pcmk__assert(stonith_device_register(xml, TRUE) == pcmk_ok);
229 pcmk__xml_free(xml);
230 }
231
232
233
234
235
236
237
238 void
239 fenced_scheduler_run(xmlNode *cib)
240 {
241 CRM_CHECK((cib != NULL) && (scheduler != NULL), return);
242
243 if (scheduler->priv->now != NULL) {
244 crm_time_free(scheduler->priv->now);
245 scheduler->priv->now = NULL;
246 }
247 pcmk__schedule_actions(cib, pcmk__sched_location_only
248 |pcmk__sched_no_counts, scheduler);
249 g_list_foreach(scheduler->priv->resources, register_if_fencing_device,
250 NULL);
251
252 scheduler->input = NULL;
253 pe_reset_working_set(scheduler);
254 }