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
- crmd_metadata
- 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/msg_xml.h>
18 #include <crm/pengine/rules.h>
19 #include <crm/cluster/internal.h>
20 #include <crm/cluster/election_internal.h>
21 #include <crm/common/ipc_internal.h>
22
23 #include <pacemaker-controld.h>
24
25 static qb_ipcs_service_t *ipcs = NULL;
26
27 static crm_trigger_t *config_read_trigger = NULL;
28
29 #if SUPPORT_COROSYNC
30 extern gboolean crm_connect_corosync(crm_cluster_t * cluster);
31 #endif
32
33 void crm_shutdown(int nsig);
34 static gboolean crm_read_options(gpointer user_data);
35
36
37 void
38 do_ha_control(long long action,
39 enum crmd_fsa_cause cause,
40 enum crmd_fsa_state cur_state,
41 enum crmd_fsa_input current_input, fsa_data_t * msg_data)
42 {
43 gboolean registered = FALSE;
44 static crm_cluster_t *cluster = NULL;
45
46 if (cluster == NULL) {
47 cluster = pcmk_cluster_new();
48 }
49
50 if (action & A_HA_DISCONNECT) {
51 crm_cluster_disconnect(cluster);
52 crm_info("Disconnected from the cluster");
53
54 controld_set_fsa_input_flags(R_HA_DISCONNECTED);
55 }
56
57 if (action & A_HA_CONNECT) {
58 crm_set_status_callback(&peer_update_callback);
59 crm_set_autoreap(FALSE);
60
61 #if SUPPORT_COROSYNC
62 if (is_corosync_cluster()) {
63 registered = crm_connect_corosync(cluster);
64 }
65 #endif
66
67 if (registered) {
68 controld_election_init(cluster->uname);
69 controld_globals.our_nodename = cluster->uname;
70 controld_globals.our_uuid = cluster->uuid;
71 if(cluster->uuid == NULL) {
72 crm_err("Could not obtain local uuid");
73 registered = FALSE;
74 }
75 }
76
77 if (!registered) {
78 controld_set_fsa_input_flags(R_HA_DISCONNECTED);
79 register_fsa_error(C_FSA_INTERNAL, I_ERROR, NULL);
80 return;
81 }
82
83 populate_cib_nodes(node_update_none, __func__);
84 controld_clear_fsa_input_flags(R_HA_DISCONNECTED);
85 crm_info("Connected to the cluster");
86 }
87
88 if (action & ~(A_HA_CONNECT | A_HA_DISCONNECT)) {
89 crm_err("Unexpected action %s in %s", fsa_action2string(action),
90 __func__);
91 }
92 }
93
94
95 void
96 do_shutdown(long long action,
97 enum crmd_fsa_cause cause,
98 enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data)
99 {
100
101 controld_set_fsa_input_flags(R_SHUTDOWN);
102 controld_disconnect_fencer(FALSE);
103 }
104
105
106 void
107 do_shutdown_req(long long action,
108 enum crmd_fsa_cause cause,
109 enum crmd_fsa_state cur_state,
110 enum crmd_fsa_input current_input, fsa_data_t * msg_data)
111 {
112 xmlNode *msg = NULL;
113
114 controld_set_fsa_input_flags(R_SHUTDOWN);
115
116 crm_info("Sending shutdown request to all peers (DC is %s)",
117 pcmk__s(controld_globals.dc_name, "not set"));
118 msg = create_request(CRM_OP_SHUTDOWN_REQ, NULL, NULL, CRM_SYSTEM_CRMD, CRM_SYSTEM_CRMD, NULL);
119
120 if (send_cluster_message(NULL, crm_msg_crmd, msg, TRUE) == FALSE) {
121 register_fsa_error(C_FSA_INTERNAL, I_ERROR, NULL);
122 }
123 free_xml(msg);
124 }
125
126 void
127 crmd_fast_exit(crm_exit_t exit_code)
128 {
129 if (pcmk_is_set(controld_globals.fsa_input_register, R_STAYDOWN)) {
130 crm_warn("Inhibiting respawn "CRM_XS" remapping exit code %d to %d",
131 exit_code, CRM_EX_FATAL);
132 exit_code = CRM_EX_FATAL;
133
134 } else if ((exit_code == CRM_EX_OK)
135 && pcmk_is_set(controld_globals.fsa_input_register,
136 R_IN_RECOVERY)) {
137 crm_err("Could not recover from internal error");
138 exit_code = CRM_EX_ERROR;
139 }
140
141 if (controld_globals.logger_out != NULL) {
142 controld_globals.logger_out->finish(controld_globals.logger_out,
143 exit_code, true, NULL);
144 pcmk__output_free(controld_globals.logger_out);
145 controld_globals.logger_out = NULL;
146 }
147
148 crm_exit(exit_code);
149 }
150
151 crm_exit_t
152 crmd_exit(crm_exit_t exit_code)
153 {
154 GMainLoop *mloop = controld_globals.mainloop;
155
156 static bool in_progress = FALSE;
157
158 if (in_progress && (exit_code == CRM_EX_OK)) {
159 crm_debug("Exit is already in progress");
160 return exit_code;
161
162 } else if(in_progress) {
163 crm_notice("Error during shutdown process, exiting now with status %d (%s)",
164 exit_code, crm_exit_str(exit_code));
165 crm_write_blackbox(SIGTRAP, NULL);
166 crmd_fast_exit(exit_code);
167 }
168
169 in_progress = TRUE;
170 crm_trace("Preparing to exit with status %d (%s)",
171 exit_code, crm_exit_str(exit_code));
172
173
174 controld_set_fsa_input_flags(R_HA_DISCONNECTED);
175
176
177
178 if(ipcs) {
179 crm_trace("Closing IPC server");
180 mainloop_del_ipc_server(ipcs);
181 ipcs = NULL;
182 }
183
184 controld_close_attrd_ipc();
185 controld_shutdown_schedulerd_ipc();
186 controld_disconnect_fencer(TRUE);
187
188 if ((exit_code == CRM_EX_OK) && (controld_globals.mainloop == NULL)) {
189 crm_debug("No mainloop detected");
190 exit_code = CRM_EX_ERROR;
191 }
192
193
194
195
196
197
198
199 if (exit_code != CRM_EX_OK) {
200 crm_notice("Forcing immediate exit with status %d (%s)",
201 exit_code, crm_exit_str(exit_code));
202 crm_write_blackbox(SIGTRAP, NULL);
203 crmd_fast_exit(exit_code);
204 }
205
206
207
208 for (GList *iter = controld_globals.fsa_message_queue; iter != NULL;
209 iter = iter->next) {
210 fsa_data_t *fsa_data = (fsa_data_t *) iter->data;
211
212 crm_info("Dropping %s: [ state=%s cause=%s origin=%s ]",
213 fsa_input2string(fsa_data->fsa_input),
214 fsa_state2string(controld_globals.fsa_state),
215 fsa_cause2string(fsa_data->fsa_cause), fsa_data->origin);
216 delete_fsa_input(fsa_data);
217 }
218
219 controld_clear_fsa_input_flags(R_MEMBERSHIP);
220
221 g_list_free(controld_globals.fsa_message_queue);
222 controld_globals.fsa_message_queue = NULL;
223
224 controld_election_fini();
225
226
227
228
229
230 controld_disconnect_cib_manager();
231
232 verify_stopped(controld_globals.fsa_state, LOG_WARNING);
233 controld_clear_fsa_input_flags(R_LRM_CONNECTED);
234 lrm_state_destroy_all();
235
236 mainloop_destroy_trigger(config_read_trigger);
237 config_read_trigger = NULL;
238
239 controld_destroy_fsa_trigger();
240 controld_destroy_transition_trigger();
241
242 pcmk__client_cleanup();
243 crm_peer_destroy();
244
245 controld_free_fsa_timers();
246 te_cleanup_stonith_history_sync(NULL, TRUE);
247 controld_free_sched_timer();
248
249 free(controld_globals.our_nodename);
250 controld_globals.our_nodename = NULL;
251
252 free(controld_globals.our_uuid);
253 controld_globals.our_uuid = NULL;
254
255 free(controld_globals.dc_name);
256 controld_globals.dc_name = NULL;
257
258 free(controld_globals.dc_version);
259 controld_globals.dc_version = NULL;
260
261 free(controld_globals.cluster_name);
262 controld_globals.cluster_name = NULL;
263
264 free(controld_globals.te_uuid);
265 controld_globals.te_uuid = NULL;
266
267 free_max_generation();
268 controld_destroy_cib_replacements_table();
269 controld_destroy_failed_sync_table();
270 controld_destroy_outside_events_table();
271
272 mainloop_destroy_signal(SIGPIPE);
273 mainloop_destroy_signal(SIGUSR1);
274 mainloop_destroy_signal(SIGTERM);
275 mainloop_destroy_signal(SIGTRAP);
276
277
278 if (mloop) {
279 GMainContext *ctx = g_main_loop_get_context(controld_globals.mainloop);
280
281
282 controld_globals.mainloop = NULL;
283
284
285 mainloop_destroy_signal(SIGCHLD);
286
287 crm_trace("Draining mainloop %d %d", g_main_loop_is_running(mloop), g_main_context_pending(ctx));
288
289 {
290 int lpc = 0;
291
292 while((g_main_context_pending(ctx) && lpc < 10)) {
293 lpc++;
294 crm_trace("Iteration %d", lpc);
295 g_main_context_dispatch(ctx);
296 }
297 }
298
299 crm_trace("Closing mainloop %d %d", g_main_loop_is_running(mloop), g_main_context_pending(ctx));
300 g_main_loop_quit(mloop);
301
302
303 g_main_loop_unref(mloop);
304 } else {
305 mainloop_destroy_signal(SIGCHLD);
306 }
307
308 cib_delete(controld_globals.cib_conn);
309 controld_globals.cib_conn = NULL;
310
311 throttle_fini();
312
313
314 crm_trace("Done preparing for exit with status %d (%s)",
315 exit_code, crm_exit_str(exit_code));
316 return exit_code;
317 }
318
319
320 void
321 do_exit(long long action,
322 enum crmd_fsa_cause cause,
323 enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data)
324 {
325 crm_exit_t exit_code = CRM_EX_OK;
326 int log_level = LOG_INFO;
327 const char *exit_type = "gracefully";
328
329 if (action & A_EXIT_1) {
330 log_level = LOG_ERR;
331 exit_type = "forcefully";
332 exit_code = CRM_EX_ERROR;
333 }
334
335 verify_stopped(cur_state, LOG_ERR);
336 do_crm_log(log_level, "Performing %s - %s exiting the controller",
337 fsa_action2string(action), exit_type);
338
339 crm_info("[%s] stopped (%d)", crm_system_name, exit_code);
340 crmd_exit(exit_code);
341 }
342
343 static void sigpipe_ignore(int nsig) { return; }
344
345
346 void
347 do_startup(long long action,
348 enum crmd_fsa_cause cause,
349 enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data)
350 {
351 crm_debug("Registering Signal Handlers");
352 mainloop_add_signal(SIGTERM, crm_shutdown);
353 mainloop_add_signal(SIGPIPE, sigpipe_ignore);
354
355 config_read_trigger = mainloop_add_trigger(G_PRIORITY_HIGH,
356 crm_read_options, NULL);
357
358 controld_init_fsa_trigger();
359 controld_init_transition_trigger();
360
361 crm_debug("Creating CIB manager and executor objects");
362 controld_globals.cib_conn = cib_new();
363
364 lrm_state_init_local();
365 if (controld_init_fsa_timers() == FALSE) {
366 register_fsa_error(C_FSA_INTERNAL, I_ERROR, NULL);
367 }
368 }
369
370
371 static int32_t
372 accept_controller_client(qb_ipcs_connection_t *c, uid_t uid, gid_t gid)
373 {
374 crm_trace("Accepting new IPC client connection");
375 if (pcmk__new_client(c, uid, gid) == NULL) {
376 return -EIO;
377 }
378 return 0;
379 }
380
381
382 static int32_t
383 dispatch_controller_ipc(qb_ipcs_connection_t * c, void *data, size_t size)
384 {
385 uint32_t id = 0;
386 uint32_t flags = 0;
387 pcmk__client_t *client = pcmk__find_client(c);
388
389 xmlNode *msg = pcmk__client_data2xml(client, data, &id, &flags);
390
391 if (msg == NULL) {
392 pcmk__ipc_send_ack(client, id, flags, "ack", NULL, CRM_EX_PROTOCOL);
393 return 0;
394 }
395 pcmk__ipc_send_ack(client, id, flags, "ack", NULL, CRM_EX_INDETERMINATE);
396
397 CRM_ASSERT(client->user != NULL);
398 pcmk__update_acl_user(msg, F_CRM_USER, client->user);
399
400 crm_xml_add(msg, F_CRM_SYS_FROM, client->id);
401 if (controld_authorize_ipc_message(msg, client, NULL)) {
402 crm_trace("Processing IPC message from client %s",
403 pcmk__client_name(client));
404 route_message(C_IPC_MESSAGE, msg);
405 }
406
407 controld_trigger_fsa();
408 free_xml(msg);
409 return 0;
410 }
411
412 static int32_t
413 ipc_client_disconnected(qb_ipcs_connection_t *c)
414 {
415 pcmk__client_t *client = pcmk__find_client(c);
416
417 if (client) {
418 crm_trace("Disconnecting %sregistered client %s (%p/%p)",
419 (client->userdata? "" : "un"), pcmk__client_name(client),
420 c, client);
421 free(client->userdata);
422 pcmk__free_client(client);
423 controld_trigger_fsa();
424 }
425 return 0;
426 }
427
428 static void
429 ipc_connection_destroyed(qb_ipcs_connection_t *c)
430 {
431 crm_trace("Connection %p", c);
432 ipc_client_disconnected(c);
433 }
434
435
436 void
437 do_stop(long long action,
438 enum crmd_fsa_cause cause,
439 enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data)
440 {
441 crm_trace("Closing IPC server");
442 mainloop_del_ipc_server(ipcs); ipcs = NULL;
443 register_fsa_input(C_FSA_INTERNAL, I_TERMINATE, NULL);
444 }
445
446
447 void
448 do_started(long long action,
449 enum crmd_fsa_cause cause,
450 enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data)
451 {
452 static struct qb_ipcs_service_handlers crmd_callbacks = {
453 .connection_accept = accept_controller_client,
454 .connection_created = NULL,
455 .msg_process = dispatch_controller_ipc,
456 .connection_closed = ipc_client_disconnected,
457 .connection_destroyed = ipc_connection_destroyed
458 };
459
460 if (cur_state != S_STARTING) {
461 crm_err("Start cancelled... %s", fsa_state2string(cur_state));
462 return;
463
464 } else if (!pcmk_is_set(controld_globals.fsa_input_register,
465 R_MEMBERSHIP)) {
466 crm_info("Delaying start, no membership data (%.16llx)", R_MEMBERSHIP);
467
468 crmd_fsa_stall(TRUE);
469 return;
470
471 } else if (!pcmk_is_set(controld_globals.fsa_input_register,
472 R_LRM_CONNECTED)) {
473 crm_info("Delaying start, not connected to executor (%.16llx)", R_LRM_CONNECTED);
474
475 crmd_fsa_stall(TRUE);
476 return;
477
478 } else if (!pcmk_is_set(controld_globals.fsa_input_register,
479 R_CIB_CONNECTED)) {
480 crm_info("Delaying start, CIB not connected (%.16llx)", R_CIB_CONNECTED);
481
482 crmd_fsa_stall(TRUE);
483 return;
484
485 } else if (!pcmk_is_set(controld_globals.fsa_input_register,
486 R_READ_CONFIG)) {
487 crm_info("Delaying start, Config not read (%.16llx)", R_READ_CONFIG);
488
489 crmd_fsa_stall(TRUE);
490 return;
491
492 } else if (!pcmk_is_set(controld_globals.fsa_input_register, R_PEER_DATA)) {
493
494 crm_info("Delaying start, No peer data (%.16llx)", R_PEER_DATA);
495 crmd_fsa_stall(TRUE);
496 return;
497 }
498
499 crm_debug("Init server comms");
500 ipcs = pcmk__serve_controld_ipc(&crmd_callbacks);
501 if (ipcs == NULL) {
502 crm_err("Failed to create IPC server: shutting down and inhibiting respawn");
503 register_fsa_error(C_FSA_INTERNAL, I_ERROR, NULL);
504 } else {
505 crm_notice("Pacemaker controller successfully started and accepting connections");
506 }
507 controld_trigger_fencer_connect();
508
509 controld_clear_fsa_input_flags(R_STARTING);
510 register_fsa_input(msg_data->fsa_cause, I_PENDING, NULL);
511 }
512
513
514 void
515 do_recover(long long action,
516 enum crmd_fsa_cause cause,
517 enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data)
518 {
519 controld_set_fsa_input_flags(R_IN_RECOVERY);
520 crm_warn("Fast-tracking shutdown in response to errors");
521
522 register_fsa_input(C_FSA_INTERNAL, I_TERMINATE, NULL);
523 }
524
525 static pcmk__cluster_option_t controller_options[] = {
526
527
528
529
530
531 {
532 "dc-version", NULL, "string", NULL, PCMK__VALUE_NONE, NULL,
533 N_("Pacemaker version on cluster node elected Designated Controller (DC)"),
534 N_("Includes a hash which identifies the exact changeset the code was "
535 "built from. Used for diagnostic purposes.")
536 },
537 {
538 "cluster-infrastructure", NULL, "string", NULL, "corosync", NULL,
539 N_("The messaging stack on which Pacemaker is currently running"),
540 N_("Used for informational and diagnostic purposes.")
541 },
542 {
543 "cluster-name", NULL, "string", NULL, NULL, NULL,
544 N_("An arbitrary name for the cluster"),
545 N_("This optional value is mostly for users' convenience as desired "
546 "in administration, but may also be used in Pacemaker "
547 "configuration rules via the #cluster-name node attribute, and "
548 "by higher-level tools and resource agents.")
549 },
550 {
551 XML_CONFIG_ATTR_DC_DEADTIME, NULL, "time",
552 NULL, "20s", pcmk__valid_interval_spec,
553 N_("How long to wait for a response from other nodes during start-up"),
554 N_("The optimal value will depend on the speed and load of your network "
555 "and the type of switches used.")
556 },
557 {
558 XML_CONFIG_ATTR_RECHECK, NULL, "time",
559 N_("Zero disables polling, while positive values are an interval in seconds"
560 "(unless other units are specified, for example \"5min\")"),
561 "15min", pcmk__valid_interval_spec,
562 N_("Polling interval to recheck cluster state and evaluate rules "
563 "with date specifications"),
564 N_("Pacemaker is primarily event-driven, and looks ahead to know when to "
565 "recheck cluster state for failure timeouts and most time-based "
566 "rules. However, it will also recheck the cluster after this "
567 "amount of inactivity, to evaluate rules with date specifications "
568 "and serve as a fail-safe for certain types of scheduler bugs.")
569 },
570 {
571 "load-threshold", NULL, "percentage", NULL,
572 "80%", pcmk__valid_percentage,
573 N_("Maximum amount of system load that should be used by cluster nodes"),
574 N_("The cluster will slow down its recovery process when the amount of "
575 "system resources used (currently CPU) approaches this limit"),
576 },
577 {
578 "node-action-limit", NULL, "integer", NULL,
579 "0", pcmk__valid_number,
580 N_("Maximum number of jobs that can be scheduled per node "
581 "(defaults to 2x cores)")
582 },
583 { XML_CONFIG_ATTR_FENCE_REACTION, NULL, "string", NULL, "stop", NULL,
584 N_("How a cluster node should react if notified of its own fencing"),
585 N_("A cluster node may receive notification of its own fencing if fencing "
586 "is misconfigured, or if fabric fencing is in use that doesn't cut "
587 "cluster communication. Allowed values are \"stop\" to attempt to "
588 "immediately stop Pacemaker and stay stopped, or \"panic\" to attempt "
589 "to immediately reboot the local node, falling back to stop on failure.")
590 },
591 {
592 XML_CONFIG_ATTR_ELECTION_FAIL, NULL, "time", NULL,
593 "2min", pcmk__valid_interval_spec,
594 "*** Advanced Use Only ***",
595 N_("Declare an election failed if it is not decided within this much "
596 "time. If you need to adjust this value, it probably indicates "
597 "the presence of a bug.")
598 },
599 {
600 XML_CONFIG_ATTR_FORCE_QUIT, NULL, "time", NULL,
601 "20min", pcmk__valid_interval_spec,
602 "*** Advanced Use Only ***",
603 N_("Exit immediately if shutdown does not complete within this much "
604 "time. If you need to adjust this value, it probably indicates "
605 "the presence of a bug.")
606 },
607 {
608 "join-integration-timeout", "crmd-integration-timeout", "time", NULL,
609 "3min", pcmk__valid_interval_spec,
610 "*** Advanced Use Only ***",
611 N_("If you need to adjust this value, it probably indicates "
612 "the presence of a bug.")
613 },
614 {
615 "join-finalization-timeout", "crmd-finalization-timeout", "time", NULL,
616 "30min", pcmk__valid_interval_spec,
617 "*** Advanced Use Only ***",
618 N_("If you need to adjust this value, it probably indicates "
619 "the presence of a bug.")
620 },
621 {
622 "transition-delay", "crmd-transition-delay", "time", NULL,
623 "0s", pcmk__valid_interval_spec,
624 N_("*** Advanced Use Only *** Enabling this option will slow down "
625 "cluster recovery under all conditions"),
626 N_("Delay cluster recovery for this much time to allow for additional "
627 "events to occur. Useful if your configuration is sensitive to "
628 "the order in which ping updates arrive.")
629 },
630 {
631 "stonith-watchdog-timeout", NULL, "time", NULL,
632 "0", controld_verify_stonith_watchdog_timeout,
633 N_("How long before nodes can be assumed to be safely down when "
634 "watchdog-based self-fencing via SBD is in use"),
635 N_("If this is set to a positive value, lost nodes are assumed to "
636 "self-fence using watchdog-based SBD within this much time. This "
637 "does not require a fencing resource to be explicitly configured, "
638 "though a fence_watchdog resource can be configured, to limit use "
639 "to specific nodes. If this is set to 0 (the default), the cluster "
640 "will never assume watchdog-based self-fencing. If this is set to a "
641 "negative value, the cluster will use twice the local value of the "
642 "`SBD_WATCHDOG_TIMEOUT` environment variable if that is positive, "
643 "or otherwise treat this as 0. WARNING: When used, this timeout "
644 "must be larger than `SBD_WATCHDOG_TIMEOUT` on all nodes that use "
645 "watchdog-based SBD, and Pacemaker will refuse to start on any of "
646 "those nodes where this is not true for the local value or SBD is "
647 "not active. When this is set to a negative value, "
648 "`SBD_WATCHDOG_TIMEOUT` must be set to the same value on all nodes "
649 "that use SBD, otherwise data corruption or loss could occur.")
650 },
651 {
652 "stonith-max-attempts", NULL, "integer", NULL,
653 "10", pcmk__valid_positive_number,
654 N_("How many times fencing can fail before it will no longer be "
655 "immediately re-attempted on a target")
656 },
657
658
659 {
660 "no-quorum-policy", NULL, "select",
661 "stop, freeze, ignore, demote, suicide", "stop", pcmk__valid_quorum,
662 N_("What to do when the cluster does not have quorum"), NULL
663 },
664 {
665 XML_CONFIG_ATTR_SHUTDOWN_LOCK, NULL, "boolean", NULL,
666 "false", pcmk__valid_boolean,
667 N_("Whether to lock resources to a cleanly shut down node"),
668 N_("When true, resources active on a node when it is cleanly shut down "
669 "are kept \"locked\" to that node (not allowed to run elsewhere) "
670 "until they start again on that node after it rejoins (or for at "
671 "most shutdown-lock-limit, if set). Stonith resources and "
672 "Pacemaker Remote connections are never locked. Clone and bundle "
673 "instances and the promoted role of promotable clones are "
674 "currently never locked, though support could be added in a future "
675 "release.")
676 },
677 {
678 XML_CONFIG_ATTR_SHUTDOWN_LOCK_LIMIT, NULL, "time", NULL,
679 "0", pcmk__valid_interval_spec,
680 N_("Do not lock resources to a cleanly shut down node longer than "
681 "this"),
682 N_("If shutdown-lock is true and this is set to a nonzero time "
683 "duration, shutdown locks will expire after this much time has "
684 "passed since the shutdown was initiated, even if the node has not "
685 "rejoined.")
686 },
687 };
688
689 void
690 crmd_metadata(void)
691 {
692 const char *desc_short = "Pacemaker controller options";
693 const char *desc_long = "Cluster options used by Pacemaker's controller";
694
695 gchar *s = pcmk__format_option_metadata("pacemaker-controld", desc_short,
696 desc_long, controller_options,
697 PCMK__NELEM(controller_options));
698 printf("%s", s);
699 g_free(s);
700 }
701
702 static void
703 config_query_callback(xmlNode * msg, int call_id, int rc, xmlNode * output, void *user_data)
704 {
705 const char *value = NULL;
706 GHashTable *config_hash = NULL;
707 crm_time_t *now = crm_time_new(NULL);
708 xmlNode *crmconfig = NULL;
709 xmlNode *alerts = NULL;
710
711 if (rc != pcmk_ok) {
712 fsa_data_t *msg_data = NULL;
713
714 crm_err("Local CIB query resulted in an error: %s", pcmk_strerror(rc));
715 register_fsa_error(C_FSA_INTERNAL, I_ERROR, NULL);
716
717 if (rc == -EACCES || rc == -pcmk_err_schema_validation) {
718 crm_err("The cluster is mis-configured - shutting down and staying down");
719 controld_set_fsa_input_flags(R_STAYDOWN);
720 }
721 goto bail;
722 }
723
724 crmconfig = output;
725 if ((crmconfig) &&
726 (crm_element_name(crmconfig)) &&
727 (strcmp(crm_element_name(crmconfig), XML_CIB_TAG_CRMCONFIG) != 0)) {
728 crmconfig = first_named_child(crmconfig, XML_CIB_TAG_CRMCONFIG);
729 }
730 if (!crmconfig) {
731 fsa_data_t *msg_data = NULL;
732
733 crm_err("Local CIB query for " XML_CIB_TAG_CRMCONFIG " section failed");
734 register_fsa_error(C_FSA_INTERNAL, I_ERROR, NULL);
735 goto bail;
736 }
737
738 crm_debug("Call %d : Parsing CIB options", call_id);
739 config_hash = pcmk__strkey_table(free, free);
740 pe_unpack_nvpairs(crmconfig, crmconfig, XML_CIB_TAG_PROPSET, NULL,
741 config_hash, CIB_OPTIONS_FIRST, FALSE, now, NULL);
742
743
744 pcmk__validate_cluster_options(config_hash, controller_options,
745 PCMK__NELEM(controller_options));
746
747 value = g_hash_table_lookup(config_hash, "no-quorum-policy");
748 if (pcmk__str_eq(value, "suicide", pcmk__str_casei) && pcmk__locate_sbd()) {
749 controld_set_global_flags(controld_no_quorum_suicide);
750 }
751
752 value = g_hash_table_lookup(config_hash, XML_CONFIG_ATTR_SHUTDOWN_LOCK);
753 if (crm_is_true(value)) {
754 controld_set_global_flags(controld_shutdown_lock_enabled);
755 } else {
756 controld_clear_global_flags(controld_shutdown_lock_enabled);
757 }
758
759 value = g_hash_table_lookup(config_hash,
760 XML_CONFIG_ATTR_SHUTDOWN_LOCK_LIMIT);
761 controld_globals.shutdown_lock_limit = crm_parse_interval_spec(value)
762 / 1000;
763
764 value = g_hash_table_lookup(config_hash, "cluster-name");
765 pcmk__str_update(&(controld_globals.cluster_name), value);
766
767
768 controld_configure_election(config_hash);
769 controld_configure_fencing(config_hash);
770 controld_configure_fsa_timers(config_hash);
771 controld_configure_throttle(config_hash);
772
773 alerts = first_named_child(output, XML_CIB_TAG_ALERTS);
774 crmd_unpack_alerts(alerts);
775
776 controld_set_fsa_input_flags(R_READ_CONFIG);
777 controld_trigger_fsa();
778
779 g_hash_table_destroy(config_hash);
780 bail:
781 crm_time_free(now);
782 }
783
784
785
786
787
788
789
790
791 void
792 controld_trigger_config_as(const char *fn, int line)
793 {
794 if (config_read_trigger != NULL) {
795 crm_trace("%s:%d - Triggered config processing", fn, line);
796 mainloop_set_trigger(config_read_trigger);
797 }
798 }
799
800 gboolean
801 crm_read_options(gpointer user_data)
802 {
803 cib_t *cib_conn = controld_globals.cib_conn;
804 int call_id = cib_conn->cmds->query(cib_conn,
805 "//" XML_CIB_TAG_CRMCONFIG
806 " | //" XML_CIB_TAG_ALERTS,
807 NULL, cib_xpath|cib_scope_local);
808
809 fsa_register_cib_callback(call_id, NULL, config_query_callback);
810 crm_trace("Querying the CIB... call %d", call_id);
811 return TRUE;
812 }
813
814
815 void
816 do_read_config(long long action,
817 enum crmd_fsa_cause cause,
818 enum crmd_fsa_state cur_state,
819 enum crmd_fsa_input current_input, fsa_data_t * msg_data)
820 {
821 throttle_init();
822 controld_trigger_config();
823 }
824
825 void
826 crm_shutdown(int nsig)
827 {
828 const char *value = NULL;
829 guint default_period_ms = 0;
830
831 if ((controld_globals.mainloop == NULL)
832 || !g_main_loop_is_running(controld_globals.mainloop)) {
833 crmd_exit(CRM_EX_OK);
834 return;
835 }
836
837 if (pcmk_is_set(controld_globals.fsa_input_register, R_SHUTDOWN)) {
838 crm_err("Escalating shutdown");
839 register_fsa_input_before(C_SHUTDOWN, I_ERROR, NULL);
840 return;
841 }
842
843 controld_set_fsa_input_flags(R_SHUTDOWN);
844 register_fsa_input(C_SHUTDOWN, I_SHUTDOWN, NULL);
845
846
847
848
849
850
851
852 value = pcmk__cluster_option(NULL, controller_options,
853 PCMK__NELEM(controller_options),
854 XML_CONFIG_ATTR_FORCE_QUIT);
855 default_period_ms = crm_parse_interval_spec(value);
856 controld_shutdown_start_countdown(default_period_ms);
857 }