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-2022 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, NULL);
  62     pcmk__add_main_args(context, extra_prog_entries);
  63     return context;
  64 }
  65 
  66 int
  67 main(int argc, char **argv)
     /* [previous][next][first][last][top][bottom][index][help] */
  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     /* Create the mainloop and run it... */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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 }

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