This source file includes following definitions.
- do_ha_control
- do_shutdown
- do_shutdown_req
- crmd_fast_exit
- crmd_exit
- do_exit
- sigpipe_ignore
- do_startup
- accept_controller_client
- dispatch_controller_ipc
- ipc_client_disconnected
- ipc_connection_destroyed
- do_stop
- do_started
- do_recover
- config_query_callback
- controld_trigger_config_as
- crm_read_options
- do_read_config
- crm_shutdown
1
2
3
4
5
6
7
8
9
10 #include <crm_internal.h>
11
12 #include <sys/param.h>
13 #include <sys/types.h>
14 #include <sys/stat.h>
15
16 #include <crm/crm.h>
17 #include <crm/common/xml.h>
18 #include <crm/cluster/internal.h>
19 #include <crm/cluster/election_internal.h>
20 #include <crm/common/ipc_internal.h>
21
22 #include <pacemaker-controld.h>
23
24 static qb_ipcs_service_t *ipcs = NULL;
25
26 static crm_trigger_t *config_read_trigger = NULL;
27
28 #if SUPPORT_COROSYNC
29 extern gboolean crm_connect_corosync(pcmk_cluster_t *cluster);
30 #endif
31
32 static void crm_shutdown(int nsig);
33 static gboolean crm_read_options(gpointer user_data);
34
35
36 void
37 do_ha_control(long long action,
38 enum crmd_fsa_cause cause,
39 enum crmd_fsa_state cur_state,
40 enum crmd_fsa_input current_input, fsa_data_t * msg_data)
41 {
42 gboolean registered = FALSE;
43
44 if (controld_globals.cluster == NULL) {
45 controld_globals.cluster = pcmk_cluster_new();
46 }
47
48 if (action & A_HA_DISCONNECT) {
49 pcmk_cluster_disconnect(controld_globals.cluster);
50 crm_info("Disconnected from the cluster");
51
52 controld_set_fsa_input_flags(R_HA_DISCONNECTED);
53 }
54
55 if (action & A_HA_CONNECT) {
56 pcmk__cluster_set_status_callback(&peer_update_callback);
57 pcmk__cluster_set_autoreap(false);
58
59 #if SUPPORT_COROSYNC
60 if (pcmk_get_cluster_layer() == pcmk_cluster_layer_corosync) {
61 registered = crm_connect_corosync(controld_globals.cluster);
62 }
63 #endif
64
65 if (registered) {
66 pcmk__node_status_t *node = controld_get_local_node_status();
67
68 controld_election_init();
69
70 free(controld_globals.our_uuid);
71 controld_globals.our_uuid =
72 pcmk__str_copy(pcmk__cluster_get_xml_id(node));
73
74 if (controld_globals.our_uuid == NULL) {
75 crm_err("Could not obtain local uuid");
76 registered = FALSE;
77 }
78 }
79
80 if (!registered) {
81 controld_set_fsa_input_flags(R_HA_DISCONNECTED);
82 register_fsa_error(C_FSA_INTERNAL, I_ERROR, NULL);
83 return;
84 }
85
86 populate_cib_nodes(controld_node_update_none, __func__);
87 controld_clear_fsa_input_flags(R_HA_DISCONNECTED);
88 crm_info("Connected to the cluster");
89 }
90
91 if (action & ~(A_HA_CONNECT | A_HA_DISCONNECT)) {
92 crm_err("Unexpected action %s in %s", fsa_action2string(action),
93 __func__);
94 }
95 }
96
97
98 void
99 do_shutdown(long long action,
100 enum crmd_fsa_cause cause,
101 enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data)
102 {
103
104 controld_set_fsa_input_flags(R_SHUTDOWN);
105 controld_disconnect_fencer(FALSE);
106 }
107
108
109 void
110 do_shutdown_req(long long action,
111 enum crmd_fsa_cause cause,
112 enum crmd_fsa_state cur_state,
113 enum crmd_fsa_input current_input, fsa_data_t * msg_data)
114 {
115 xmlNode *msg = NULL;
116
117 controld_set_fsa_input_flags(R_SHUTDOWN);
118
119 crm_info("Sending shutdown request to all peers (DC is %s)",
120 pcmk__s(controld_globals.dc_name, "not set"));
121 msg = pcmk__new_request(pcmk_ipc_controld, CRM_SYSTEM_CRMD, NULL,
122 CRM_SYSTEM_CRMD, CRM_OP_SHUTDOWN_REQ, NULL);
123
124 if (!pcmk__cluster_send_message(NULL, pcmk_ipc_controld, msg)) {
125 register_fsa_error(C_FSA_INTERNAL, I_ERROR, NULL);
126 }
127 pcmk__xml_free(msg);
128 }
129
130 void
131 crmd_fast_exit(crm_exit_t exit_code)
132 {
133 if (pcmk_is_set(controld_globals.fsa_input_register, R_STAYDOWN)) {
134 crm_warn("Inhibiting respawn " QB_XS " remapping exit code %d to %d",
135 exit_code, CRM_EX_FATAL);
136 exit_code = CRM_EX_FATAL;
137
138 } else if ((exit_code == CRM_EX_OK)
139 && pcmk_is_set(controld_globals.fsa_input_register,
140 R_IN_RECOVERY)) {
141 crm_err("Could not recover from internal error");
142 exit_code = CRM_EX_ERROR;
143 }
144
145 if (controld_globals.logger_out != NULL) {
146 controld_globals.logger_out->finish(controld_globals.logger_out,
147 exit_code, true, NULL);
148 pcmk__output_free(controld_globals.logger_out);
149 controld_globals.logger_out = NULL;
150 }
151
152 crm_exit(exit_code);
153 }
154
155 crm_exit_t
156 crmd_exit(crm_exit_t exit_code)
157 {
158 GMainLoop *mloop = controld_globals.mainloop;
159
160 static bool in_progress = FALSE;
161
162 if (in_progress && (exit_code == CRM_EX_OK)) {
163 crm_debug("Exit is already in progress");
164 return exit_code;
165
166 } else if(in_progress) {
167 crm_notice("Error during shutdown process, exiting now with status %d (%s)",
168 exit_code, crm_exit_str(exit_code));
169 crm_write_blackbox(SIGTRAP, NULL);
170 crmd_fast_exit(exit_code);
171 }
172
173 in_progress = TRUE;
174 crm_trace("Preparing to exit with status %d (%s)",
175 exit_code, crm_exit_str(exit_code));
176
177
178 controld_set_fsa_input_flags(R_HA_DISCONNECTED);
179
180
181
182 if(ipcs) {
183 crm_trace("Closing IPC server");
184 mainloop_del_ipc_server(ipcs);
185 ipcs = NULL;
186 }
187
188 controld_close_attrd_ipc();
189 controld_shutdown_schedulerd_ipc();
190 controld_disconnect_fencer(TRUE);
191
192 if ((exit_code == CRM_EX_OK) && (controld_globals.mainloop == NULL)) {
193 crm_debug("No mainloop detected");
194 exit_code = CRM_EX_ERROR;
195 }
196
197
198
199
200
201
202
203 if (exit_code != CRM_EX_OK) {
204 crm_notice("Forcing immediate exit with status %d (%s)",
205 exit_code, crm_exit_str(exit_code));
206 crm_write_blackbox(SIGTRAP, NULL);
207 crmd_fast_exit(exit_code);
208 }
209
210
211
212 for (GList *iter = controld_globals.fsa_message_queue; iter != NULL;
213 iter = iter->next) {
214 fsa_data_t *fsa_data = (fsa_data_t *) iter->data;
215
216 crm_info("Dropping %s: [ state=%s cause=%s origin=%s ]",
217 fsa_input2string(fsa_data->fsa_input),
218 fsa_state2string(controld_globals.fsa_state),
219 fsa_cause2string(fsa_data->fsa_cause), fsa_data->origin);
220 delete_fsa_input(fsa_data);
221 }
222
223 controld_clear_fsa_input_flags(R_MEMBERSHIP);
224
225 g_list_free(controld_globals.fsa_message_queue);
226 controld_globals.fsa_message_queue = NULL;
227
228 controld_free_node_pending_timers();
229 election_reset(controld_globals.cluster);
230
231
232
233
234
235 controld_disconnect_cib_manager();
236
237 verify_stopped(controld_globals.fsa_state, LOG_WARNING);
238 controld_clear_fsa_input_flags(R_LRM_CONNECTED);
239 lrm_state_destroy_all();
240
241 mainloop_destroy_trigger(config_read_trigger);
242 config_read_trigger = NULL;
243
244 controld_destroy_fsa_trigger();
245 controld_destroy_transition_trigger();
246
247 pcmk__client_cleanup();
248 pcmk__cluster_destroy_node_caches();
249
250 controld_free_fsa_timers();
251 te_cleanup_stonith_history_sync(NULL, TRUE);
252 controld_free_sched_timer();
253
254 free(controld_globals.our_uuid);
255 controld_globals.our_uuid = NULL;
256
257 free(controld_globals.dc_name);
258 controld_globals.dc_name = NULL;
259
260 free(controld_globals.dc_version);
261 controld_globals.dc_version = NULL;
262
263 free(controld_globals.cluster_name);
264 controld_globals.cluster_name = NULL;
265
266 free(controld_globals.te_uuid);
267 controld_globals.te_uuid = NULL;
268
269 free_max_generation();
270 controld_destroy_failed_sync_table();
271 controld_destroy_outside_events_table();
272
273 mainloop_destroy_signal(SIGPIPE);
274 mainloop_destroy_signal(SIGUSR1);
275 mainloop_destroy_signal(SIGTERM);
276 mainloop_destroy_signal(SIGTRAP);
277
278
279 if (mloop) {
280 GMainContext *ctx = g_main_loop_get_context(controld_globals.mainloop);
281
282
283 controld_globals.mainloop = NULL;
284
285
286 mainloop_destroy_signal(SIGCHLD);
287
288 crm_trace("Draining mainloop %d %d", g_main_loop_is_running(mloop), g_main_context_pending(ctx));
289
290 {
291 int lpc = 0;
292
293 while((g_main_context_pending(ctx) && lpc < 10)) {
294 lpc++;
295 crm_trace("Iteration %d", lpc);
296 g_main_context_dispatch(ctx);
297 }
298 }
299
300 crm_trace("Closing mainloop %d %d", g_main_loop_is_running(mloop), g_main_context_pending(ctx));
301 g_main_loop_quit(mloop);
302
303
304 g_main_loop_unref(mloop);
305 } else {
306 mainloop_destroy_signal(SIGCHLD);
307 }
308
309 cib_delete(controld_globals.cib_conn);
310 controld_globals.cib_conn = NULL;
311
312 throttle_fini();
313
314 pcmk_cluster_free(controld_globals.cluster);
315 controld_globals.cluster = NULL;
316
317
318 crm_trace("Done preparing for exit with status %d (%s)",
319 exit_code, crm_exit_str(exit_code));
320 return exit_code;
321 }
322
323
324 void
325 do_exit(long long action,
326 enum crmd_fsa_cause cause,
327 enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data)
328 {
329 crm_exit_t exit_code = CRM_EX_OK;
330
331 if (pcmk_is_set(action, A_EXIT_1)) {
332 exit_code = CRM_EX_ERROR;
333 crm_err("Exiting now due to errors");
334 }
335 verify_stopped(cur_state, LOG_ERR);
336 crmd_exit(exit_code);
337 }
338
339 static void sigpipe_ignore(int nsig) { return; }
340
341
342 void
343 do_startup(long long action,
344 enum crmd_fsa_cause cause,
345 enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data)
346 {
347 crm_debug("Registering Signal Handlers");
348 mainloop_add_signal(SIGTERM, crm_shutdown);
349 mainloop_add_signal(SIGPIPE, sigpipe_ignore);
350
351 config_read_trigger = mainloop_add_trigger(G_PRIORITY_HIGH,
352 crm_read_options, NULL);
353
354 controld_init_fsa_trigger();
355 controld_init_transition_trigger();
356
357 crm_debug("Creating CIB manager and executor objects");
358 controld_globals.cib_conn = cib_new();
359
360 lrm_state_init_local();
361 if (controld_init_fsa_timers() == FALSE) {
362 register_fsa_error(C_FSA_INTERNAL, I_ERROR, NULL);
363 }
364 }
365
366
367 static int32_t
368 accept_controller_client(qb_ipcs_connection_t *c, uid_t uid, gid_t gid)
369 {
370 crm_trace("Accepting new IPC client connection");
371 if (pcmk__new_client(c, uid, gid) == NULL) {
372 return -ENOMEM;
373 }
374 return 0;
375 }
376
377
378 static int32_t
379 dispatch_controller_ipc(qb_ipcs_connection_t * c, void *data, size_t size)
380 {
381 int rc = pcmk_rc_ok;
382 uint32_t id = 0;
383 uint32_t flags = 0;
384 pcmk__client_t *client = pcmk__find_client(c);
385 xmlNode *msg = NULL;
386
387 rc = pcmk__ipc_msg_append(&client->buffer, data);
388
389 if (rc == pcmk_rc_ipc_more) {
390
391 return 0;
392
393 } else if (rc == pcmk_rc_ok) {
394
395
396
397 msg = pcmk__client_data2xml(client, &id, &flags);
398 g_byte_array_free(client->buffer, TRUE);
399 client->buffer = NULL;
400
401 } else {
402
403
404
405 crm_err("Error when reading IPC message: %s", pcmk_rc_str(rc));
406
407 if (client->buffer != NULL) {
408 g_byte_array_free(client->buffer, TRUE);
409 client->buffer = NULL;
410 }
411
412 return 0;
413 }
414
415 if (msg == NULL) {
416 pcmk__ipc_send_ack(client, id, flags, PCMK__XE_ACK, NULL,
417 CRM_EX_PROTOCOL);
418 return 0;
419 }
420 pcmk__ipc_send_ack(client, id, flags, PCMK__XE_ACK, NULL,
421 CRM_EX_INDETERMINATE);
422
423 pcmk__assert(client->user != NULL);
424 pcmk__update_acl_user(msg, PCMK__XA_CRM_USER, client->user);
425
426 crm_xml_add(msg, PCMK__XA_CRM_SYS_FROM, client->id);
427 if (controld_authorize_ipc_message(msg, client, NULL)) {
428 crm_trace("Processing IPC message from client %s",
429 pcmk__client_name(client));
430 route_message(C_IPC_MESSAGE, msg);
431 }
432
433 controld_trigger_fsa();
434 pcmk__xml_free(msg);
435 return 0;
436 }
437
438 static int32_t
439 ipc_client_disconnected(qb_ipcs_connection_t *c)
440 {
441 pcmk__client_t *client = pcmk__find_client(c);
442
443 if (client) {
444 crm_trace("Disconnecting %sregistered client %s (%p/%p)",
445 (client->userdata? "" : "un"), pcmk__client_name(client),
446 c, client);
447 free(client->userdata);
448 pcmk__free_client(client);
449 controld_trigger_fsa();
450 }
451 return 0;
452 }
453
454 static void
455 ipc_connection_destroyed(qb_ipcs_connection_t *c)
456 {
457 crm_trace("Connection %p", c);
458 ipc_client_disconnected(c);
459 }
460
461
462 void
463 do_stop(long long action,
464 enum crmd_fsa_cause cause,
465 enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data)
466 {
467 crm_trace("Closing IPC server");
468 mainloop_del_ipc_server(ipcs); ipcs = NULL;
469 register_fsa_input(C_FSA_INTERNAL, I_TERMINATE, NULL);
470 }
471
472
473 void
474 do_started(long long action,
475 enum crmd_fsa_cause cause,
476 enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data)
477 {
478 static struct qb_ipcs_service_handlers crmd_callbacks = {
479 .connection_accept = accept_controller_client,
480 .connection_created = NULL,
481 .msg_process = dispatch_controller_ipc,
482 .connection_closed = ipc_client_disconnected,
483 .connection_destroyed = ipc_connection_destroyed
484 };
485
486 if (cur_state != S_STARTING) {
487 crm_err("Start cancelled... %s", fsa_state2string(cur_state));
488 return;
489
490 } else if (!pcmk_is_set(controld_globals.fsa_input_register,
491 R_MEMBERSHIP)) {
492 crm_info("Delaying start, no membership data (%.16llx)", R_MEMBERSHIP);
493
494 crmd_fsa_stall(TRUE);
495 return;
496
497 } else if (!pcmk_is_set(controld_globals.fsa_input_register,
498 R_LRM_CONNECTED)) {
499 crm_info("Delaying start, not connected to executor (%.16llx)", R_LRM_CONNECTED);
500
501 crmd_fsa_stall(TRUE);
502 return;
503
504 } else if (!pcmk_is_set(controld_globals.fsa_input_register,
505 R_CIB_CONNECTED)) {
506 crm_info("Delaying start, CIB not connected (%.16llx)", R_CIB_CONNECTED);
507
508 crmd_fsa_stall(TRUE);
509 return;
510
511 } else if (!pcmk_is_set(controld_globals.fsa_input_register,
512 R_READ_CONFIG)) {
513 crm_info("Delaying start, Config not read (%.16llx)", R_READ_CONFIG);
514
515 crmd_fsa_stall(TRUE);
516 return;
517
518 } else if (!pcmk_is_set(controld_globals.fsa_input_register, R_PEER_DATA)) {
519
520 crm_info("Delaying start, No peer data (%.16llx)", R_PEER_DATA);
521 crmd_fsa_stall(TRUE);
522 return;
523 }
524
525 crm_debug("Init server comms");
526 ipcs = pcmk__serve_controld_ipc(&crmd_callbacks);
527 if (ipcs == NULL) {
528 crm_err("Failed to create IPC server: shutting down and inhibiting respawn");
529 register_fsa_error(C_FSA_INTERNAL, I_ERROR, NULL);
530 } else {
531 crm_notice("Pacemaker controller successfully started and accepting connections");
532 }
533 controld_set_fsa_input_flags(R_ST_REQUIRED);
534 controld_timer_fencer_connect(GINT_TO_POINTER(TRUE));
535
536 controld_clear_fsa_input_flags(R_STARTING);
537 register_fsa_input(msg_data->fsa_cause, I_PENDING, NULL);
538 }
539
540
541 void
542 do_recover(long long action,
543 enum crmd_fsa_cause cause,
544 enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data)
545 {
546 controld_set_fsa_input_flags(R_IN_RECOVERY);
547 crm_warn("Fast-tracking shutdown in response to errors");
548
549 register_fsa_input(C_FSA_INTERNAL, I_TERMINATE, NULL);
550 }
551
552 static void
553 config_query_callback(xmlNode * msg, int call_id, int rc, xmlNode * output, void *user_data)
554 {
555 const char *value = NULL;
556 GHashTable *config_hash = NULL;
557 crm_time_t *now = crm_time_new(NULL);
558 xmlNode *crmconfig = NULL;
559 xmlNode *alerts = NULL;
560 pcmk_rule_input_t rule_input = {
561 .now = now,
562 };
563
564 if (rc != pcmk_ok) {
565 fsa_data_t *msg_data = NULL;
566
567 crm_err("Local CIB query resulted in an error: %s", pcmk_strerror(rc));
568 register_fsa_error(C_FSA_INTERNAL, I_ERROR, NULL);
569
570 if (rc == -EACCES || rc == -pcmk_err_schema_validation) {
571 crm_err("The cluster is mis-configured - shutting down and staying down");
572 controld_set_fsa_input_flags(R_STAYDOWN);
573 }
574 goto bail;
575 }
576
577 crmconfig = output;
578 if ((crmconfig != NULL) && !pcmk__xe_is(crmconfig, PCMK_XE_CRM_CONFIG)) {
579 crmconfig = pcmk__xe_first_child(crmconfig, PCMK_XE_CRM_CONFIG, NULL,
580 NULL);
581 }
582 if (!crmconfig) {
583 fsa_data_t *msg_data = NULL;
584
585 crm_err("Local CIB query for " PCMK_XE_CRM_CONFIG " section failed");
586 register_fsa_error(C_FSA_INTERNAL, I_ERROR, NULL);
587 goto bail;
588 }
589
590 crm_debug("Call %d : Parsing CIB options", call_id);
591 config_hash = pcmk__strkey_table(free, free);
592 pcmk_unpack_nvpair_blocks(crmconfig, PCMK_XE_CLUSTER_PROPERTY_SET,
593 PCMK_VALUE_CIB_BOOTSTRAP_OPTIONS, &rule_input,
594 config_hash, NULL);
595
596
597 pcmk__validate_cluster_options(config_hash);
598
599
600
601
602
603
604
605
606
607
608
609 value = g_hash_table_lookup(config_hash, PCMK_OPT_STONITH_WATCHDOG_TIMEOUT);
610 controld_verify_stonith_watchdog_timeout(value);
611
612 value = g_hash_table_lookup(config_hash, PCMK_OPT_NO_QUORUM_POLICY);
613 if (pcmk__strcase_any_of(value, PCMK_VALUE_FENCE, PCMK_VALUE_FENCE_LEGACY,
614 NULL)
615 && (pcmk__locate_sbd() != 0)) {
616 controld_set_global_flags(controld_no_quorum_panic);
617 }
618
619 value = g_hash_table_lookup(config_hash, PCMK_OPT_SHUTDOWN_LOCK);
620 if (crm_is_true(value)) {
621 controld_set_global_flags(controld_shutdown_lock_enabled);
622 } else {
623 controld_clear_global_flags(controld_shutdown_lock_enabled);
624 }
625
626 value = g_hash_table_lookup(config_hash, PCMK_OPT_SHUTDOWN_LOCK_LIMIT);
627 pcmk_parse_interval_spec(value, &controld_globals.shutdown_lock_limit);
628 controld_globals.shutdown_lock_limit /= 1000;
629
630 value = g_hash_table_lookup(config_hash, PCMK_OPT_NODE_PENDING_TIMEOUT);
631 pcmk_parse_interval_spec(value, &controld_globals.node_pending_timeout);
632 controld_globals.node_pending_timeout /= 1000;
633
634 value = g_hash_table_lookup(config_hash, PCMK_OPT_CLUSTER_NAME);
635 pcmk__str_update(&(controld_globals.cluster_name), value);
636
637
638 controld_configure_election(config_hash);
639 controld_configure_fencing(config_hash);
640 controld_configure_fsa_timers(config_hash);
641 controld_configure_throttle(config_hash);
642
643 alerts = pcmk__xe_first_child(output, PCMK_XE_ALERTS, NULL, NULL);
644 crmd_unpack_alerts(alerts);
645
646 controld_set_fsa_input_flags(R_READ_CONFIG);
647 controld_trigger_fsa();
648
649 g_hash_table_destroy(config_hash);
650 bail:
651 crm_time_free(now);
652 }
653
654
655
656
657
658
659
660
661 void
662 controld_trigger_config_as(const char *fn, int line)
663 {
664 if (config_read_trigger != NULL) {
665 crm_trace("%s:%d - Triggered config processing", fn, line);
666 mainloop_set_trigger(config_read_trigger);
667 }
668 }
669
670 gboolean
671 crm_read_options(gpointer user_data)
672 {
673 cib_t *cib_conn = controld_globals.cib_conn;
674 int call_id = cib_conn->cmds->query(cib_conn,
675 "//" PCMK_XE_CRM_CONFIG
676 " | //" PCMK_XE_ALERTS,
677 NULL, cib_xpath);
678
679 fsa_register_cib_callback(call_id, NULL, config_query_callback);
680 crm_trace("Querying the CIB... call %d", call_id);
681 return TRUE;
682 }
683
684
685 void
686 do_read_config(long long action,
687 enum crmd_fsa_cause cause,
688 enum crmd_fsa_state cur_state,
689 enum crmd_fsa_input current_input, fsa_data_t * msg_data)
690 {
691 throttle_init();
692 controld_trigger_config();
693 }
694
695 static void
696 crm_shutdown(int nsig)
697 {
698 const char *value = NULL;
699 guint default_period_ms = 0;
700
701 if ((controld_globals.mainloop == NULL)
702 || !g_main_loop_is_running(controld_globals.mainloop)) {
703 crmd_exit(CRM_EX_OK);
704 return;
705 }
706
707 if (pcmk_is_set(controld_globals.fsa_input_register, R_SHUTDOWN)) {
708 crm_err("Escalating shutdown");
709 register_fsa_input_before(C_SHUTDOWN, I_ERROR, NULL);
710 return;
711 }
712
713 controld_set_fsa_input_flags(R_SHUTDOWN);
714 register_fsa_input(C_SHUTDOWN, I_SHUTDOWN, NULL);
715
716
717
718
719
720
721
722 value = pcmk__cluster_option(NULL, PCMK_OPT_SHUTDOWN_ESCALATION);
723 pcmk_parse_interval_spec(value, &default_period_ms);
724 controld_shutdown_start_countdown(default_period_ms);
725 }