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