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