This source file includes following definitions.
- scheduler_metadata
- build_arg_context
- main
- pengine_shutdown
1
2
3
4
5
6
7
8
9
10 #include <crm_internal.h>
11
12 #include <crm/crm.h>
13 #include <stdio.h>
14 #include <stdbool.h>
15
16 #include <stdlib.h>
17 #include <errno.h>
18
19 #include <crm/common/cmdline_internal.h>
20 #include <crm/common/ipc_internal.h>
21 #include <crm/common/mainloop.h>
22 #include <crm/pengine/internal.h>
23 #include <pacemaker-internal.h>
24
25 #include "pacemaker-schedulerd.h"
26
27 #define SUMMARY PCMK__SERVER_SCHEDULERD " - daemon for calculating a " \
28 "Pacemaker cluster's response to events"
29
30 struct {
31 gchar **remainder;
32 } options;
33
34 pcmk__output_t *logger_out = NULL;
35
36 static pcmk__output_t *out = NULL;
37 static GMainLoop *mainloop = NULL;
38 static qb_ipcs_service_t *ipcs = NULL;
39 static crm_exit_t exit_code = CRM_EX_OK;
40
41 pcmk__supported_format_t formats[] = {
42 PCMK__SUPPORTED_FORMAT_NONE,
43 PCMK__SUPPORTED_FORMAT_TEXT,
44 PCMK__SUPPORTED_FORMAT_XML,
45 { NULL, NULL, NULL }
46 };
47
48 void pengine_shutdown(int nsig);
49
50
51
52
53
54
55 static int
56 scheduler_metadata(pcmk__output_t *out)
57 {
58 return pcmk__daemon_metadata(out, PCMK__SERVER_SCHEDULERD,
59 "Pacemaker scheduler options",
60 "Cluster options used by Pacemaker's "
61 "scheduler",
62 pcmk__opt_schedulerd);
63 }
64
65 static GOptionContext *
66 build_arg_context(pcmk__common_args_t *args, GOptionGroup **group) {
67 GOptionContext *context = NULL;
68
69 GOptionEntry extra_prog_entries[] = {
70 { G_OPTION_REMAINING, 0, G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING_ARRAY, &options.remainder,
71 NULL,
72 NULL },
73
74 { NULL }
75 };
76
77 context = pcmk__build_arg_context(args, "text (default), xml", group, NULL);
78 pcmk__add_main_args(context, extra_prog_entries);
79 return context;
80 }
81
82 int
83 main(int argc, char **argv)
84 {
85 GError *error = NULL;
86 int rc = pcmk_rc_ok;
87
88 GOptionGroup *output_group = NULL;
89 pcmk__common_args_t *args = pcmk__new_common_args(SUMMARY);
90 gchar **processed_args = pcmk__cmdline_preproc(argv, NULL);
91 GOptionContext *context = build_arg_context(args, &output_group);
92
93 crm_log_preinit(NULL, argc, argv);
94 mainloop_add_signal(SIGTERM, pengine_shutdown);
95
96 pcmk__register_formats(output_group, formats);
97 if (!g_option_context_parse_strv(context, &processed_args, &error)) {
98 exit_code = CRM_EX_USAGE;
99 goto done;
100 }
101
102 rc = pcmk__output_new(&out, args->output_ty, args->output_dest, argv);
103 if ((rc != pcmk_rc_ok) || (out == NULL)) {
104 exit_code = CRM_EX_FATAL;
105 g_set_error(&error, PCMK__EXITC_ERROR, exit_code, "Error creating output format %s: %s",
106 args->output_ty, pcmk_rc_str(rc));
107 goto done;
108 }
109
110 pe__register_messages(out);
111 pcmk__register_lib_messages(out);
112
113 if (options.remainder) {
114 if (g_strv_length(options.remainder) == 1 &&
115 pcmk__str_eq("metadata", options.remainder[0], pcmk__str_casei)) {
116
117 rc = scheduler_metadata(out);
118 if (rc != pcmk_rc_ok) {
119 exit_code = CRM_EX_FATAL;
120 g_set_error(&error, PCMK__EXITC_ERROR, exit_code,
121 "Unable to display metadata: %s", pcmk_rc_str(rc));
122 }
123
124 } else {
125 exit_code = CRM_EX_USAGE;
126 g_set_error(&error, PCMK__EXITC_ERROR, exit_code,
127 "Unsupported extra command line parameters");
128 }
129 goto done;
130 }
131
132 if (args->version) {
133 out->version(out, false);
134 goto done;
135 }
136
137 pcmk__cli_init_logging(PCMK__SERVER_SCHEDULERD, args->verbosity);
138 crm_log_init(NULL, LOG_INFO, TRUE, FALSE, argc, argv, FALSE);
139 crm_notice("Starting Pacemaker scheduler");
140
141 if (pcmk__daemon_can_write(PCMK_SCHEDULER_INPUT_DIR, NULL) == FALSE) {
142 crm_err("Terminating due to bad permissions on " PCMK_SCHEDULER_INPUT_DIR);
143 exit_code = CRM_EX_FATAL;
144 g_set_error(&error, PCMK__EXITC_ERROR, exit_code,
145 "ERROR: Bad permissions on %s (see logs for details)",
146 PCMK_SCHEDULER_INPUT_DIR);
147 goto done;
148 }
149
150 ipcs = pcmk__serve_schedulerd_ipc(&ipc_callbacks);
151 if (ipcs == NULL) {
152 g_set_error(&error, PCMK__EXITC_ERROR, exit_code,
153 "Exiting fatally because unable to serve "
154 "scheduler server IPC");
155 exit_code = CRM_EX_FATAL;
156 goto done;
157 }
158
159 if (pcmk__log_output_new(&logger_out) != pcmk_rc_ok) {
160 exit_code = CRM_EX_FATAL;
161 goto done;
162 }
163 pe__register_messages(logger_out);
164 pcmk__register_lib_messages(logger_out);
165 pcmk__output_set_log_level(logger_out, LOG_TRACE);
166
167
168 mainloop = g_main_loop_new(NULL, FALSE);
169 crm_notice("Pacemaker scheduler successfully started and accepting connections");
170 g_main_loop_run(mainloop);
171
172 done:
173 g_strfreev(options.remainder);
174 g_strfreev(processed_args);
175 pcmk__free_arg_context(context);
176
177 pcmk__output_and_clear_error(&error, out);
178 pengine_shutdown(0);
179 }
180
181 void
182 pengine_shutdown(int nsig)
183 {
184 if (ipcs != NULL) {
185 crm_trace("Closing IPC server");
186 mainloop_del_ipc_server(ipcs);
187 ipcs = NULL;
188 }
189
190 if (logger_out != NULL) {
191 logger_out->finish(logger_out, exit_code, true, NULL);
192 pcmk__output_free(logger_out);
193 logger_out = NULL;
194 }
195
196 if (out != NULL) {
197 out->finish(out, exit_code, true, NULL);
198 pcmk__output_free(out);
199 out = NULL;
200 }
201
202 pcmk__unregister_formats();
203 crm_exit(exit_code);
204 }