This source file includes following definitions.
- controld_metadata
- 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
50
51
52
53
54 static int
55 controld_metadata(pcmk__output_t *out)
56 {
57 return pcmk__daemon_metadata(out, PCMK__SERVER_CONTROLD,
58 "Pacemaker controller options",
59 "Cluster options used by Pacemaker's "
60 "controller",
61 pcmk__opt_controld);
62 }
63
64 static GOptionContext *
65 build_arg_context(pcmk__common_args_t *args, GOptionGroup **group)
66 {
67 return pcmk__build_arg_context(args, "text (default), xml", group, NULL);
68 }
69
70 int
71 main(int argc, char **argv)
72 {
73 int rc = pcmk_rc_ok;
74 crm_exit_t exit_code = CRM_EX_OK;
75 bool initialize = true;
76
77 crm_ipc_t *old_instance = NULL;
78
79 pcmk__output_t *out = NULL;
80
81 GError *error = NULL;
82
83 GOptionGroup *output_group = NULL;
84 pcmk__common_args_t *args = pcmk__new_common_args(SUMMARY);
85 gchar **processed_args = pcmk__cmdline_preproc(argv, NULL);
86 GOptionContext *context = build_arg_context(args, &output_group);
87
88 crm_log_preinit(NULL, argc, argv);
89
90 pcmk__register_formats(output_group, formats);
91 if (!g_option_context_parse_strv(context, &processed_args, &error)) {
92 exit_code = CRM_EX_USAGE;
93 goto done;
94 }
95
96 rc = pcmk__output_new(&out, args->output_ty, args->output_dest, argv);
97 if (rc != pcmk_rc_ok) {
98 exit_code = CRM_EX_ERROR;
99 g_set_error(&error, PCMK__EXITC_ERROR, exit_code,
100 "Error creating output format %s: %s",
101 args->output_ty, pcmk_rc_str(rc));
102 goto done;
103 }
104
105 if (args->version) {
106 out->version(out, false);
107 initialize = false;
108 goto done;
109 }
110
111 if ((g_strv_length(processed_args) >= 2)
112 && pcmk__str_eq(processed_args[1], "metadata", pcmk__str_none)) {
113
114 initialize = false;
115 rc = controld_metadata(out);
116 if (rc != pcmk_rc_ok) {
117 exit_code = CRM_EX_FATAL;
118 g_set_error(&error, PCMK__EXITC_ERROR, exit_code,
119 "Unable to display metadata: %s", pcmk_rc_str(rc));
120 }
121 goto done;
122 }
123
124 pcmk__cli_init_logging(PCMK__SERVER_CONTROLD, args->verbosity);
125 crm_log_init(NULL, LOG_INFO, TRUE, FALSE, argc, argv, FALSE);
126 crm_notice("Starting Pacemaker controller");
127
128 old_instance = crm_ipc_new(CRM_SYSTEM_CRMD, 0);
129 if (old_instance == NULL) {
130
131 exit_code = CRM_EX_FATAL;
132 goto done;
133 }
134
135 if (pcmk__connect_generic_ipc(old_instance) == pcmk_rc_ok) {
136
137 crm_ipc_close(old_instance);
138 crm_ipc_destroy(old_instance);
139 crm_crit("Aborting start-up because another controller instance is "
140 "already active");
141 initialize = false;
142 goto done;
143
144 } else {
145
146 crm_ipc_destroy(old_instance);
147 old_instance = NULL;
148 }
149
150 if (pcmk__daemon_can_write(PCMK_SCHEDULER_INPUT_DIR, NULL) == FALSE) {
151 exit_code = CRM_EX_FATAL;
152 crm_err("Terminating due to bad permissions on " PCMK_SCHEDULER_INPUT_DIR);
153 g_set_error(&error, PCMK__EXITC_ERROR, exit_code,
154 "Bad permissions on " PCMK_SCHEDULER_INPUT_DIR
155 " (see logs for details)");
156 goto done;
157
158 } else if (pcmk__daemon_can_write(CRM_CONFIG_DIR, NULL) == FALSE) {
159 exit_code = CRM_EX_FATAL;
160 crm_err("Terminating due to bad permissions on " CRM_CONFIG_DIR);
161 g_set_error(&error, PCMK__EXITC_ERROR, exit_code,
162 "Bad permissions on " CRM_CONFIG_DIR
163 " (see logs for details)");
164 goto done;
165 }
166
167 if (pcmk__log_output_new(&(controld_globals.logger_out)) != pcmk_rc_ok) {
168 exit_code = CRM_EX_FATAL;
169 goto done;
170 }
171
172 pcmk__output_set_log_level(controld_globals.logger_out, LOG_TRACE);
173
174 done:
175 g_strfreev(processed_args);
176 pcmk__free_arg_context(context);
177
178 pcmk__output_and_clear_error(&error, out);
179
180 if (out != NULL) {
181 out->finish(out, exit_code, true, NULL);
182 pcmk__output_free(out);
183 }
184 pcmk__unregister_formats();
185
186 if ((exit_code == CRM_EX_OK) && initialize) {
187
188 crmd_init();
189 }
190 crm_exit(exit_code);
191 }
192
193 void
194 crmd_init(void)
195 {
196 crm_exit_t exit_code = CRM_EX_OK;
197 enum crmd_fsa_state state;
198
199 init_dotfile();
200 register_fsa_input(C_STARTUP, I_STARTUP, NULL);
201
202 pcmk__cluster_init_node_caches();
203 state = s_crmd_fsa(C_STARTUP);
204
205 if (state == S_PENDING || state == S_STARTING) {
206
207 crm_trace("Starting %s's mainloop", crm_system_name);
208 controld_globals.mainloop = g_main_loop_new(NULL, FALSE);
209 g_main_loop_run(controld_globals.mainloop);
210 if (pcmk_is_set(controld_globals.fsa_input_register, R_STAYDOWN)) {
211 crm_info("Inhibiting automated respawn");
212 exit_code = CRM_EX_FATAL;
213 }
214
215 } else {
216 crm_err("Startup of %s failed. Current state: %s",
217 crm_system_name, fsa_state2string(state));
218 exit_code = CRM_EX_ERROR;
219 }
220
221 crm_info("%s[%lu] exiting with status %d (%s)",
222 crm_system_name, (unsigned long) getpid(), exit_code,
223 crm_exit_str(exit_code));
224
225 crmd_fast_exit(exit_code);
226 }