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