This source file includes following definitions.
- rsc_is_known_on
- order_start_vs_fencing
- order_stop_vs_fencing
- rsc_stonith_ordering
- pcmk__order_vs_fence
- pcmk__order_vs_unfence
- pcmk__fence_guest
- pcmk__node_unfenced
- pcmk__order_restart_vs_unfence
1
2
3
4
5
6
7
8
9
10 #include <crm_internal.h>
11
12 #include <glib.h>
13
14 #include <crm/crm.h>
15 #include <crm/pengine/status.h>
16 #include <pacemaker-internal.h>
17 #include "libpacemaker_private.h"
18
19
20
21
22
23
24
25
26
27
28 static bool
29 rsc_is_known_on(const pe_resource_t *rsc, const pe_node_t *node)
30 {
31 if (pe_hash_table_lookup(rsc->known_on, node->details->id)) {
32 return TRUE;
33
34 } else if ((rsc->variant == pe_native)
35 && pe_rsc_is_anon_clone(rsc->parent)
36 && pe_hash_table_lookup(rsc->parent->known_on, node->details->id)) {
37
38
39
40
41 return TRUE;
42 }
43 return FALSE;
44 }
45
46
47
48
49
50
51
52
53 static void
54 order_start_vs_fencing(pe_resource_t *rsc, pe_action_t *stonith_op)
55 {
56 pe_node_t *target;
57 GList *gIter = NULL;
58
59 CRM_CHECK(stonith_op && stonith_op->node, return);
60 target = stonith_op->node;
61
62 for (gIter = rsc->actions; gIter != NULL; gIter = gIter->next) {
63 pe_action_t *action = (pe_action_t *) gIter->data;
64
65 switch (action->needs) {
66 case rsc_req_nothing:
67
68 break;
69
70 case rsc_req_stonith:
71 order_actions(stonith_op, action, pe_order_optional);
72 break;
73
74 case rsc_req_quorum:
75 if (pcmk__str_eq(action->task, RSC_START, pcmk__str_casei)
76 && pe_hash_table_lookup(rsc->allowed_nodes, target->details->id)
77 && !rsc_is_known_on(rsc, target)) {
78
79
80
81
82
83
84
85
86
87
88 pe_rsc_debug(rsc, "Ordering %s after %s recovery", action->uuid,
89 pe__node_name(target));
90 order_actions(stonith_op, action,
91 pe_order_optional | pe_order_runnable_left);
92 }
93 break;
94 }
95 }
96 }
97
98
99
100
101
102
103
104
105 static void
106 order_stop_vs_fencing(pe_resource_t *rsc, pe_action_t *stonith_op)
107 {
108 GList *gIter = NULL;
109 GList *action_list = NULL;
110 bool order_implicit = false;
111
112 pe_resource_t *top = uber_parent(rsc);
113 pe_action_t *parent_stop = NULL;
114 pe_node_t *target;
115
116 CRM_CHECK(stonith_op && stonith_op->node, return);
117 target = stonith_op->node;
118
119
120 action_list = pe__resource_actions(rsc, target, RSC_STOP, FALSE);
121
122
123
124
125
126
127
128 if (pcmk_is_set(rsc->flags, pe_rsc_needs_fencing)
129 || pe__is_guest_node(target)) {
130
131 order_implicit = true;
132 }
133
134 if (action_list && order_implicit) {
135 parent_stop = find_first_action(top->actions, NULL, RSC_STOP, NULL);
136 }
137
138 for (gIter = action_list; gIter != NULL; gIter = gIter->next) {
139 pe_action_t *action = (pe_action_t *) gIter->data;
140
141
142 pe__set_action_flags(action, pe_action_pseudo|pe_action_runnable);
143
144 if (order_implicit) {
145 pe__set_action_flags(action, pe_action_implied_by_stonith);
146
147
148
149
150
151
152
153
154
155
156
157
158
159 if (!pe_rsc_is_bundled(rsc)) {
160 order_actions(stonith_op, action, pe_order_preserve);
161 }
162 order_actions(stonith_op, parent_stop, pe_order_preserve);
163 }
164
165 if (pcmk_is_set(rsc->flags, pe_rsc_failed)) {
166 crm_notice("Stop of failed resource %s is implicit %s %s is fenced",
167 rsc->id, (order_implicit? "after" : "because"),
168 pe__node_name(target));
169 } else {
170 crm_info("%s is implicit %s %s is fenced",
171 action->uuid, (order_implicit? "after" : "because"),
172 pe__node_name(target));
173 }
174
175 if (pcmk_is_set(rsc->flags, pe_rsc_notify)) {
176 pe__order_notifs_after_fencing(action, rsc, stonith_op);
177 }
178
179 #if 0
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198 crm_info("Moving healthy resource %s off %s before fencing",
199 rsc->id, pe__node_name(node));
200 pcmk__new_ordering(rsc, stop_key(rsc), NULL, NULL,
201 strdup(CRM_OP_FENCE), stonith_op,
202 pe_order_optional, rsc->cluster);
203 #endif
204 }
205
206 g_list_free(action_list);
207
208
209 action_list = pe__resource_actions(rsc, target, RSC_DEMOTE, FALSE);
210
211 for (gIter = action_list; gIter != NULL; gIter = gIter->next) {
212 pe_action_t *action = (pe_action_t *) gIter->data;
213
214 if (!(action->node->details->online) || action->node->details->unclean
215 || pcmk_is_set(rsc->flags, pe_rsc_failed)) {
216
217 if (pcmk_is_set(rsc->flags, pe_rsc_failed)) {
218 pe_rsc_info(rsc,
219 "Demote of failed resource %s is implicit after %s is fenced",
220 rsc->id, pe__node_name(target));
221 } else {
222 pe_rsc_info(rsc, "%s is implicit after %s is fenced",
223 action->uuid, pe__node_name(target));
224 }
225
226
227
228
229 pe__set_action_flags(action, pe_action_pseudo|pe_action_runnable);
230
231 if (pe_rsc_is_bundled(rsc)) {
232
233
234 } else if (order_implicit) {
235 order_actions(stonith_op, action, pe_order_preserve|pe_order_optional);
236 }
237 }
238 }
239
240 g_list_free(action_list);
241 }
242
243
244
245
246
247
248
249
250 static void
251 rsc_stonith_ordering(pe_resource_t *rsc, pe_action_t *stonith_op)
252 {
253 if (rsc->children) {
254 GList *gIter = NULL;
255
256 for (gIter = rsc->children; gIter != NULL; gIter = gIter->next) {
257 pe_resource_t *child_rsc = (pe_resource_t *) gIter->data;
258
259 rsc_stonith_ordering(child_rsc, stonith_op);
260 }
261
262 } else if (!pcmk_is_set(rsc->flags, pe_rsc_managed)) {
263 pe_rsc_trace(rsc,
264 "Skipping fencing constraints for unmanaged resource: %s",
265 rsc->id);
266
267 } else {
268 order_start_vs_fencing(rsc, stonith_op);
269 order_stop_vs_fencing(rsc, stonith_op);
270 }
271 }
272
273
274
275
276
277
278
279
280
281
282
283
284 void
285 pcmk__order_vs_fence(pe_action_t *stonith_op, pe_working_set_t *data_set)
286 {
287 CRM_CHECK(stonith_op && data_set, return);
288 for (GList *r = data_set->resources; r != NULL; r = r->next) {
289 rsc_stonith_ordering((pe_resource_t *) r->data, stonith_op);
290 }
291 }
292
293
294
295
296
297
298
299
300
301
302 void
303 pcmk__order_vs_unfence(const pe_resource_t *rsc, pe_node_t *node,
304 pe_action_t *action, enum pe_ordering order)
305 {
306
307
308
309
310
311
312
313 if ((pcmk_is_set(rsc->flags, pe_rsc_fence_device)
314 && pcmk_is_set(rsc->cluster->flags, pe_flag_enable_unfencing))
315 || pcmk_is_set(rsc->flags, pe_rsc_needs_unfencing)) {
316
317
318
319
320
321 pe_action_t *unfence = pe_fence_op(node, "on", TRUE, NULL, FALSE,
322 node->details->data_set);
323
324 order_actions(unfence, action, order);
325
326 if (!pcmk__node_unfenced(node)) {
327
328 char *reason = crm_strdup_printf("required by %s %s",
329 rsc->id, action->task);
330
331 trigger_unfencing(NULL, node, reason, NULL,
332 node->details->data_set);
333 free(reason);
334 }
335 }
336 }
337
338
339
340
341
342
343
344 void
345 pcmk__fence_guest(pe_node_t *node)
346 {
347 pe_resource_t *container = NULL;
348 pe_action_t *stop = NULL;
349 pe_action_t *stonith_op = NULL;
350
351
352
353
354
355
356
357 const char *fence_action = "off";
358
359 CRM_ASSERT(node != NULL);
360
361
362
363
364 container = node->details->remote_rsc->container;
365 if (container) {
366 stop = find_first_action(container->actions, NULL, CRMD_ACTION_STOP,
367 NULL);
368
369 if (find_first_action(container->actions, NULL, CRMD_ACTION_START,
370 NULL)) {
371 fence_action = "reboot";
372 }
373 }
374
375
376
377
378 stonith_op = pe_fence_op(node, fence_action, FALSE, "guest is unclean",
379 FALSE, node->details->data_set);
380 pe__set_action_flags(stonith_op, pe_action_pseudo|pe_action_runnable);
381
382
383
384
385
386 if ((stop != NULL) && pcmk_is_set(stop->flags, pe_action_pseudo)) {
387 pe_action_t *parent_stonith_op = pe_fence_op(stop->node, NULL, FALSE,
388 NULL, FALSE,
389 node->details->data_set);
390
391 crm_info("Implying guest %s is down (action %d) after %s fencing",
392 pe__node_name(node), stonith_op->id,
393 pe__node_name(stop->node));
394 order_actions(parent_stonith_op, stonith_op,
395 pe_order_runnable_left|pe_order_implies_then);
396
397 } else if (stop) {
398 order_actions(stop, stonith_op,
399 pe_order_runnable_left|pe_order_implies_then);
400 crm_info("Implying guest %s is down (action %d) "
401 "after container %s is stopped (action %d)",
402 pe__node_name(node), stonith_op->id,
403 container->id, stop->id);
404 } else {
405
406
407
408
409
410
411
412 stop = find_first_action(node->details->remote_rsc->actions, NULL,
413 RSC_STOP, NULL);
414
415 if (stop) {
416 order_actions(stop, stonith_op, pe_order_optional);
417 crm_info("Implying guest %s is down (action %d) "
418 "after connection is stopped (action %d)",
419 pe__node_name(node), stonith_op->id, stop->id);
420 } else {
421
422
423
424 crm_info("Implying guest %s is down (action %d) ",
425 pe__node_name(node), stonith_op->id);
426 }
427 }
428
429
430 pcmk__order_vs_fence(stonith_op, node->details->data_set);
431 }
432
433
434
435
436
437
438
439
440
441
442 bool
443 pcmk__node_unfenced(const pe_node_t *node)
444 {
445 const char *unfenced = pe_node_attribute_raw(node, CRM_ATTR_UNFENCED);
446
447 return !pcmk__str_eq(unfenced, "0", pcmk__str_null_matches);
448 }
449
450
451
452
453
454
455
456
457 void
458 pcmk__order_restart_vs_unfence(gpointer data, gpointer user_data)
459 {
460 pe_node_t *node = (pe_node_t *) data;
461 pe_resource_t *rsc = (pe_resource_t *) user_data;
462
463 pe_action_t *unfence = pe_fence_op(node, "on", true, NULL, false,
464 rsc->cluster);
465
466 crm_debug("Ordering any stops of %s before %s, and any starts after",
467 rsc->id, unfence->uuid);
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484 pcmk__new_ordering(rsc, stop_key(rsc), NULL,
485 NULL, strdup(unfence->uuid), unfence,
486 pe_order_optional|pe_order_same_node,
487 rsc->cluster);
488
489 pcmk__new_ordering(NULL, strdup(unfence->uuid), unfence,
490 rsc, start_key(rsc), NULL,
491 pe_order_implies_then_on_node|pe_order_same_node,
492 rsc->cluster);
493 }