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