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

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