summaryrefslogtreecommitdiffstats
path: root/daemons/schedulerd/pacemaker-schedulerd.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--daemons/schedulerd/pacemaker-schedulerd.c181
1 files changed, 181 insertions, 0 deletions
diff --git a/daemons/schedulerd/pacemaker-schedulerd.c b/daemons/schedulerd/pacemaker-schedulerd.c
new file mode 100644
index 0000000..3f2a3e8
--- /dev/null
+++ b/daemons/schedulerd/pacemaker-schedulerd.c
@@ -0,0 +1,181 @@
+/*
+ * Copyright 2004-2023 the Pacemaker project contributors
+ *
+ * The version control history for this file may have further details.
+ *
+ * This source code is licensed under the GNU General Public License version 2
+ * or later (GPLv2+) WITHOUT ANY WARRANTY.
+ */
+
+#include <crm_internal.h>
+
+#include <crm/crm.h>
+#include <stdio.h>
+#include <stdbool.h>
+
+#include <stdlib.h>
+#include <errno.h>
+
+#include <crm/common/cmdline_internal.h>
+#include <crm/common/ipc_internal.h>
+#include <crm/common/mainloop.h>
+#include <crm/pengine/internal.h>
+#include <pacemaker-internal.h>
+
+#include "pacemaker-schedulerd.h"
+
+#define SUMMARY "pacemaker-schedulerd - daemon for calculating a Pacemaker cluster's response to events"
+
+struct {
+ gchar **remainder;
+} options;
+
+pcmk__output_t *logger_out = NULL;
+pcmk__output_t *out = NULL;
+
+static GMainLoop *mainloop = NULL;
+static qb_ipcs_service_t *ipcs = NULL;
+static crm_exit_t exit_code = CRM_EX_OK;
+
+pcmk__supported_format_t formats[] = {
+ PCMK__SUPPORTED_FORMAT_NONE,
+ PCMK__SUPPORTED_FORMAT_TEXT,
+ PCMK__SUPPORTED_FORMAT_XML,
+ { NULL, NULL, NULL }
+};
+
+void pengine_shutdown(int nsig);
+
+static GOptionContext *
+build_arg_context(pcmk__common_args_t *args, GOptionGroup **group) {
+ GOptionContext *context = NULL;
+
+ GOptionEntry extra_prog_entries[] = {
+ { G_OPTION_REMAINING, 0, G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING_ARRAY, &options.remainder,
+ NULL,
+ NULL },
+
+ { NULL }
+ };
+
+ context = pcmk__build_arg_context(args, "text (default), xml", group,
+ "[metadata]");
+ pcmk__add_main_args(context, extra_prog_entries);
+ return context;
+}
+
+int
+main(int argc, char **argv)
+{
+ GError *error = NULL;
+ int rc = pcmk_rc_ok;
+
+ GOptionGroup *output_group = NULL;
+ pcmk__common_args_t *args = pcmk__new_common_args(SUMMARY);
+ gchar **processed_args = pcmk__cmdline_preproc(argv, NULL);
+ GOptionContext *context = build_arg_context(args, &output_group);
+
+ crm_log_preinit(NULL, argc, argv);
+ mainloop_add_signal(SIGTERM, pengine_shutdown);
+
+ pcmk__register_formats(output_group, formats);
+ if (!g_option_context_parse_strv(context, &processed_args, &error)) {
+ exit_code = CRM_EX_USAGE;
+ goto done;
+ }
+
+ rc = pcmk__output_new(&out, args->output_ty, args->output_dest, argv);
+ if ((rc != pcmk_rc_ok) || (out == NULL)) {
+ exit_code = CRM_EX_FATAL;
+ g_set_error(&error, PCMK__EXITC_ERROR, exit_code, "Error creating output format %s: %s",
+ args->output_ty, pcmk_rc_str(rc));
+ goto done;
+ }
+
+ pe__register_messages(out);
+ pcmk__register_lib_messages(out);
+
+ if (options.remainder) {
+ if (g_strv_length(options.remainder) == 1 &&
+ pcmk__str_eq("metadata", options.remainder[0], pcmk__str_casei)) {
+ pe_metadata(out);
+ goto done;
+ } else {
+ exit_code = CRM_EX_USAGE;
+ g_set_error(&error, PCMK__EXITC_ERROR, exit_code,
+ "Unsupported extra command line parameters");
+ goto done;
+ }
+ }
+
+ if (args->version) {
+ out->version(out, false);
+ goto done;
+ }
+
+ pcmk__cli_init_logging("pacemaker-schedulerd", args->verbosity);
+ crm_log_init(NULL, LOG_INFO, TRUE, FALSE, argc, argv, FALSE);
+ crm_notice("Starting Pacemaker scheduler");
+
+ if (pcmk__daemon_can_write(PE_STATE_DIR, NULL) == FALSE) {
+ crm_err("Terminating due to bad permissions on " PE_STATE_DIR);
+ exit_code = CRM_EX_FATAL;
+ g_set_error(&error, PCMK__EXITC_ERROR, exit_code,
+ "ERROR: Bad permissions on %s (see logs for details)", PE_STATE_DIR);
+ goto done;
+ }
+
+ ipcs = pcmk__serve_schedulerd_ipc(&ipc_callbacks);
+ if (ipcs == NULL) {
+ g_set_error(&error, PCMK__EXITC_ERROR, exit_code,
+ "Failed to create pacemaker-schedulerd server: exiting and inhibiting respawn");
+ exit_code = CRM_EX_FATAL;
+ goto done;
+ }
+
+ if (pcmk__log_output_new(&logger_out) != pcmk_rc_ok) {
+ exit_code = CRM_EX_FATAL;
+ goto done;
+ }
+ pe__register_messages(logger_out);
+ pcmk__register_lib_messages(logger_out);
+ pcmk__output_set_log_level(logger_out, LOG_TRACE);
+
+ /* Create the mainloop and run it... */
+ mainloop = g_main_loop_new(NULL, FALSE);
+ crm_notice("Pacemaker scheduler successfully started and accepting connections");
+ g_main_loop_run(mainloop);
+
+done:
+ g_strfreev(options.remainder);
+ g_strfreev(processed_args);
+ pcmk__free_arg_context(context);
+
+ pcmk__output_and_clear_error(&error, out);
+ pengine_shutdown(0);
+}
+
+void
+pengine_shutdown(int nsig)
+{
+ if (ipcs != NULL) {
+ crm_trace("Closing IPC server");
+ mainloop_del_ipc_server(ipcs);
+ ipcs = NULL;
+ }
+
+ if (logger_out != NULL) {
+ logger_out->finish(logger_out, exit_code, true, NULL);
+ pcmk__output_free(logger_out);
+ logger_out = NULL;
+ }
+
+ if (out != NULL) {
+ out->finish(out, exit_code, true, NULL);
+ pcmk__output_free(out);
+ out = NULL;
+ }
+
+ pcmk__unregister_formats();
+ crm_exit(exit_code);
+}