root/daemons/schedulerd/pacemaker-schedulerd.c

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

DEFINITIONS

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

   1 /*
   2  * Copyright 2004-2024 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 PCMK__SERVER_SCHEDULERD " - daemon for calculating a " \
  28                 "Pacemaker cluster's response to events"
  29 
  30 struct {
  31     gchar **remainder;
  32 } options;
  33 
  34 pcmk__output_t *logger_out = NULL;
  35 
  36 static pcmk__output_t *out = NULL;
  37 static GMainLoop *mainloop = NULL;
  38 static qb_ipcs_service_t *ipcs = NULL;
  39 static crm_exit_t exit_code = CRM_EX_OK;
  40 
  41 pcmk__supported_format_t formats[] = {
  42     PCMK__SUPPORTED_FORMAT_NONE,
  43     PCMK__SUPPORTED_FORMAT_TEXT,
  44     PCMK__SUPPORTED_FORMAT_XML,
  45     { NULL, NULL, NULL }
  46 };
  47 
  48 void pengine_shutdown(int nsig);
  49 
  50 /* @COMPAT Deprecated since 2.1.8. Use pcmk_list_cluster_options() or
  51  * crm_attribute --list-options=cluster instead of querying daemon metadata.
  52  *
  53  * NOTE: pcs (as of at least 0.11.8) uses this
  54  */
  55 static int
  56 scheduler_metadata(pcmk__output_t *out)
     /* [previous][next][first][last][top][bottom][index][help] */
  57 {
  58     return pcmk__daemon_metadata(out, PCMK__SERVER_SCHEDULERD,
  59                                  "Pacemaker scheduler options",
  60                                  "Cluster options used by Pacemaker's "
  61                                  "scheduler",
  62                                  pcmk__opt_schedulerd);
  63 }
  64 
  65 static GOptionContext *
  66 build_arg_context(pcmk__common_args_t *args, GOptionGroup **group) {
     /* [previous][next][first][last][top][bottom][index][help] */
  67     GOptionContext *context = NULL;
  68 
  69     GOptionEntry extra_prog_entries[] = {
  70         { G_OPTION_REMAINING, 0, G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING_ARRAY, &options.remainder,
  71           NULL,
  72           NULL },
  73 
  74         { NULL }
  75     };
  76 
  77     context = pcmk__build_arg_context(args, "text (default), xml", group, NULL);
  78     pcmk__add_main_args(context, extra_prog_entries);
  79     return context;
  80 }
  81 
  82 int
  83 main(int argc, char **argv)
     /* [previous][next][first][last][top][bottom][index][help] */
  84 {
  85     GError *error = NULL;
  86     int rc = pcmk_rc_ok;
  87 
  88     GOptionGroup *output_group = NULL;
  89     pcmk__common_args_t *args = pcmk__new_common_args(SUMMARY);
  90     gchar **processed_args = pcmk__cmdline_preproc(argv, NULL);
  91     GOptionContext *context = build_arg_context(args, &output_group);
  92 
  93     crm_log_preinit(NULL, argc, argv);
  94     mainloop_add_signal(SIGTERM, pengine_shutdown);
  95 
  96     pcmk__register_formats(output_group, formats);
  97     if (!g_option_context_parse_strv(context, &processed_args, &error)) {
  98         exit_code = CRM_EX_USAGE;
  99         goto done;
 100     }
 101 
 102     rc = pcmk__output_new(&out, args->output_ty, args->output_dest, argv);
 103     if ((rc != pcmk_rc_ok) || (out == NULL)) {
 104         exit_code = CRM_EX_FATAL;
 105         g_set_error(&error, PCMK__EXITC_ERROR, exit_code, "Error creating output format %s: %s",
 106                     args->output_ty, pcmk_rc_str(rc));
 107         goto done;
 108     }
 109 
 110     pe__register_messages(out);
 111     pcmk__register_lib_messages(out);
 112 
 113     if (options.remainder) {
 114         if (g_strv_length(options.remainder) == 1 &&
 115             pcmk__str_eq("metadata", options.remainder[0], pcmk__str_casei)) {
 116 
 117             rc = scheduler_metadata(out);
 118             if (rc != pcmk_rc_ok) {
 119                 exit_code = CRM_EX_FATAL;
 120                 g_set_error(&error, PCMK__EXITC_ERROR, exit_code,
 121                             "Unable to display metadata: %s", pcmk_rc_str(rc));
 122             }
 123 
 124         } else {
 125             exit_code = CRM_EX_USAGE;
 126             g_set_error(&error, PCMK__EXITC_ERROR, exit_code,
 127                         "Unsupported extra command line parameters");
 128         }
 129         goto done;
 130     }
 131 
 132     if (args->version) {
 133         out->version(out, false);
 134         goto done;
 135     }
 136 
 137     pcmk__cli_init_logging(PCMK__SERVER_SCHEDULERD, args->verbosity);
 138     crm_log_init(NULL, LOG_INFO, TRUE, FALSE, argc, argv, FALSE);
 139     crm_notice("Starting Pacemaker scheduler");
 140 
 141     if (pcmk__daemon_can_write(PCMK_SCHEDULER_INPUT_DIR, NULL) == FALSE) {
 142         crm_err("Terminating due to bad permissions on " PCMK_SCHEDULER_INPUT_DIR);
 143         exit_code = CRM_EX_FATAL;
 144         g_set_error(&error, PCMK__EXITC_ERROR, exit_code,
 145                     "ERROR: Bad permissions on %s (see logs for details)",
 146                     PCMK_SCHEDULER_INPUT_DIR);
 147         goto done;
 148     }
 149 
 150     ipcs = pcmk__serve_schedulerd_ipc(&ipc_callbacks);
 151     if (ipcs == NULL) {
 152         g_set_error(&error, PCMK__EXITC_ERROR, exit_code,
 153                     "Exiting fatally because unable to serve "
 154                     "scheduler server IPC");
 155         exit_code = CRM_EX_FATAL;
 156         goto done;
 157     }
 158 
 159     if (pcmk__log_output_new(&logger_out) != pcmk_rc_ok) {
 160         exit_code = CRM_EX_FATAL;
 161         goto done;
 162     }
 163     pe__register_messages(logger_out);
 164     pcmk__register_lib_messages(logger_out);
 165     pcmk__output_set_log_level(logger_out, LOG_TRACE);
 166 
 167     /* Create the mainloop and run it... */
 168     mainloop = g_main_loop_new(NULL, FALSE);
 169     crm_notice("Pacemaker scheduler successfully started and accepting connections");
 170     g_main_loop_run(mainloop);
 171 
 172 done:
 173     g_strfreev(options.remainder);
 174     g_strfreev(processed_args);
 175     pcmk__free_arg_context(context);
 176 
 177     pcmk__output_and_clear_error(&error, out);
 178     pengine_shutdown(0);
 179 }
 180 
 181 void
 182 pengine_shutdown(int nsig)
     /* [previous][next][first][last][top][bottom][index][help] */
 183 {
 184     if (ipcs != NULL) {
 185         crm_trace("Closing IPC server");
 186         mainloop_del_ipc_server(ipcs);
 187         ipcs = NULL;
 188     }
 189 
 190     if (logger_out != NULL) {
 191         logger_out->finish(logger_out, exit_code, true, NULL);
 192         pcmk__output_free(logger_out);
 193         logger_out = NULL;
 194     }
 195 
 196     if (out != NULL) {
 197         out->finish(out, exit_code, true, NULL);
 198         pcmk__output_free(out);
 199         out = NULL;
 200     }
 201 
 202     pcmk__unregister_formats();
 203     crm_exit(exit_code);
 204 }

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