root/daemons/schedulerd/pacemaker-schedulerd.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. build_arg_context
  2. main
  3. pengine_shutdown

   1 /*
   2  * Copyright 2004-2023 the Pacemaker project contributors
   3  *
   4  * The version control history for this file may have further details.
   5  *
   6  * This source code is licensed under the GNU General Public License version 2
   7  * or later (GPLv2+) WITHOUT ANY WARRANTY.
   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) {
     /* [previous][next][first][last][top][bottom][index][help] */
  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)
     /* [previous][next][first][last][top][bottom][index][help] */
  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     /* Create the mainloop and run it... */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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 }

/* [previous][next][first][last][top][bottom][index][help] */