This source file includes following definitions.
- build_arg_context
- main
- crmd_init
1
2
3
4
5
6
7
8
9
10 #include <crm_internal.h>
11
12 #include <sys/param.h>
13 #include <stdio.h>
14 #include <sys/types.h>
15 #include <sys/stat.h>
16 #include <unistd.h>
17
18 #include <stdlib.h>
19 #include <errno.h>
20 #include <fcntl.h>
21
22 #include <crm/crm.h>
23 #include <crm/common/cmdline_internal.h>
24 #include <crm/common/ipc.h>
25 #include <crm/common/output_internal.h>
26 #include <crm/common/xml.h>
27
28 #include <pacemaker-controld.h>
29
30 #define SUMMARY "daemon for coordinating a Pacemaker cluster's response " \
31 "to events"
32
33 _Noreturn void crmd_init(void);
34 extern void init_dotfile(void);
35
36 controld_globals_t controld_globals = {
37
38 .fsa_state = S_STARTING,
39 .fsa_actions = A_NOTHING,
40 };
41
42 static pcmk__supported_format_t formats[] = {
43 PCMK__SUPPORTED_FORMAT_NONE,
44 PCMK__SUPPORTED_FORMAT_TEXT,
45 PCMK__SUPPORTED_FORMAT_XML,
46 { NULL, NULL, NULL }
47 };
48
49 static GOptionContext *
50 build_arg_context(pcmk__common_args_t *args, GOptionGroup **group)
51 {
52 return pcmk__build_arg_context(args, "text (default), xml", group,
53 "[metadata]");
54 }
55
56 int
57 main(int argc, char **argv)
58 {
59 int rc = pcmk_rc_ok;
60 crm_exit_t exit_code = CRM_EX_OK;
61 bool initialize = true;
62
63 crm_ipc_t *old_instance = NULL;
64
65 pcmk__output_t *out = NULL;
66
67 GError *error = NULL;
68
69 GOptionGroup *output_group = NULL;
70 pcmk__common_args_t *args = pcmk__new_common_args(SUMMARY);
71 gchar **processed_args = pcmk__cmdline_preproc(argv, NULL);
72 GOptionContext *context = build_arg_context(args, &output_group);
73
74 crm_log_preinit(NULL, argc, argv);
75
76 pcmk__register_formats(output_group, formats);
77 if (!g_option_context_parse_strv(context, &processed_args, &error)) {
78 exit_code = CRM_EX_USAGE;
79 goto done;
80 }
81
82 rc = pcmk__output_new(&out, args->output_ty, args->output_dest, argv);
83 if (rc != pcmk_rc_ok) {
84 exit_code = CRM_EX_ERROR;
85 g_set_error(&error, PCMK__EXITC_ERROR, exit_code,
86 "Error creating output format %s: %s",
87 args->output_ty, pcmk_rc_str(rc));
88 goto done;
89 }
90
91 if (args->version) {
92 out->version(out, false);
93 initialize = false;
94 goto done;
95 }
96
97 if ((g_strv_length(processed_args) >= 2)
98 && pcmk__str_eq(processed_args[1], "metadata", pcmk__str_none)) {
99 crmd_metadata();
100 initialize = false;
101 goto done;
102 }
103
104 pcmk__cli_init_logging("pacemaker-controld", args->verbosity);
105 crm_log_init(NULL, LOG_INFO, TRUE, FALSE, argc, argv, FALSE);
106 crm_notice("Starting Pacemaker controller");
107
108 old_instance = crm_ipc_new(CRM_SYSTEM_CRMD, 0);
109 if (old_instance == NULL) {
110
111 exit_code = CRM_EX_FATAL;
112 goto done;
113 }
114
115 if (crm_ipc_connect(old_instance)) {
116
117 crm_ipc_close(old_instance);
118 crm_ipc_destroy(old_instance);
119 crm_err("pacemaker-controld is already active, aborting startup");
120 initialize = false;
121 goto done;
122
123 } else {
124
125 crm_ipc_destroy(old_instance);
126 old_instance = NULL;
127 }
128
129 if (pcmk__daemon_can_write(PE_STATE_DIR, NULL) == FALSE) {
130 exit_code = CRM_EX_FATAL;
131 crm_err("Terminating due to bad permissions on " PE_STATE_DIR);
132 g_set_error(&error, PCMK__EXITC_ERROR, exit_code,
133 "Bad permissions on " PE_STATE_DIR
134 " (see logs for details)");
135 goto done;
136
137 } else if (pcmk__daemon_can_write(CRM_CONFIG_DIR, NULL) == FALSE) {
138 exit_code = CRM_EX_FATAL;
139 crm_err("Terminating due to bad permissions on " CRM_CONFIG_DIR);
140 g_set_error(&error, PCMK__EXITC_ERROR, exit_code,
141 "Bad permissions on " CRM_CONFIG_DIR
142 " (see logs for details)");
143 goto done;
144 }
145
146 if (pcmk__log_output_new(&(controld_globals.logger_out)) != pcmk_rc_ok) {
147 exit_code = CRM_EX_FATAL;
148 goto done;
149 }
150
151 pcmk__output_set_log_level(controld_globals.logger_out, LOG_TRACE);
152
153 done:
154 g_strfreev(processed_args);
155 pcmk__free_arg_context(context);
156
157 pcmk__output_and_clear_error(&error, out);
158
159 if (out != NULL) {
160 out->finish(out, exit_code, true, NULL);
161 pcmk__output_free(out);
162 }
163 pcmk__unregister_formats();
164
165 if ((exit_code == CRM_EX_OK) && initialize) {
166
167 crmd_init();
168 }
169 crm_exit(exit_code);
170 }
171
172 void
173 crmd_init(void)
174 {
175 crm_exit_t exit_code = CRM_EX_OK;
176 enum crmd_fsa_state state;
177
178 init_dotfile();
179 register_fsa_input(C_STARTUP, I_STARTUP, NULL);
180
181 crm_peer_init();
182 state = s_crmd_fsa(C_STARTUP);
183
184 if (state == S_PENDING || state == S_STARTING) {
185
186 crm_trace("Starting %s's mainloop", crm_system_name);
187 controld_globals.mainloop = g_main_loop_new(NULL, FALSE);
188 g_main_loop_run(controld_globals.mainloop);
189 if (pcmk_is_set(controld_globals.fsa_input_register, R_STAYDOWN)) {
190 crm_info("Inhibiting automated respawn");
191 exit_code = CRM_EX_FATAL;
192 }
193
194 } else {
195 crm_err("Startup of %s failed. Current state: %s",
196 crm_system_name, fsa_state2string(state));
197 exit_code = CRM_EX_ERROR;
198 }
199
200 crm_info("%s[%lu] exiting with status %d (%s)",
201 crm_system_name, (unsigned long) getpid(), exit_code,
202 crm_exit_str(exit_code));
203
204 crmd_fast_exit(exit_code);
205 }