This source file includes following definitions.
- scheduler_metadata
- build_arg_context
- main
- pengine_shutdown
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   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 
  50 
  51 
  52 static int
  53 scheduler_metadata(pcmk__output_t *out)
     
  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) {
     
  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)
     
  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     
 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)
     
 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 }