root/daemons/controld/pacemaker-controld.c

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

DEFINITIONS

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

   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 <sys/param.h>
  13 #include <stdio.h>
  14 #include <sys/types.h>
  15 #include <sys/stat.h>
  16 #include <unistd.h>
  17 
  18 #include <stdlib.h>
  19 #include <errno.h>
  20 #include <fcntl.h>
  21 
  22 #include <crm/crm.h>
  23 #include <crm/common/cmdline_internal.h>
  24 #include <crm/common/ipc.h>
  25 #include <crm/common/output_internal.h>
  26 #include <crm/common/xml.h>
  27 
  28 #include <pacemaker-controld.h>
  29 
  30 #define SUMMARY "daemon for coordinating a Pacemaker cluster's response "   \
  31                 "to events"
  32 
  33 _Noreturn void crmd_init(void);
  34 extern void init_dotfile(void);
  35 
  36 controld_globals_t controld_globals = {
  37     // Automatic initialization to 0, false, or NULL is fine for most members
  38     .fsa_state = S_STARTING,
  39     .fsa_actions = A_NOTHING,
  40 };
  41 
  42 static pcmk__supported_format_t formats[] = {
  43     PCMK__SUPPORTED_FORMAT_NONE,
  44     PCMK__SUPPORTED_FORMAT_TEXT,
  45     PCMK__SUPPORTED_FORMAT_XML,
  46     { NULL, NULL, NULL }
  47 };
  48 
  49 static GOptionContext *
  50 build_arg_context(pcmk__common_args_t *args, GOptionGroup **group)
     /* [previous][next][first][last][top][bottom][index][help] */
  51 {
  52     return pcmk__build_arg_context(args, "text (default), xml", group,
  53                                    "[metadata]");
  54 }
  55 
  56 int
  57 main(int argc, char **argv)
     /* [previous][next][first][last][top][bottom][index][help] */
  58 {
  59     int rc = pcmk_rc_ok;
  60     crm_exit_t exit_code = CRM_EX_OK;
  61     bool initialize = true;
  62 
  63     crm_ipc_t *old_instance = NULL;
  64 
  65     pcmk__output_t *out = NULL;
  66 
  67     GError *error = NULL;
  68 
  69     GOptionGroup *output_group = NULL;
  70     pcmk__common_args_t *args = pcmk__new_common_args(SUMMARY);
  71     gchar **processed_args = pcmk__cmdline_preproc(argv, NULL);
  72     GOptionContext *context = build_arg_context(args, &output_group);
  73 
  74     crm_log_preinit(NULL, argc, argv);
  75 
  76     pcmk__register_formats(output_group, formats);
  77     if (!g_option_context_parse_strv(context, &processed_args, &error)) {
  78         exit_code = CRM_EX_USAGE;
  79         goto done;
  80     }
  81 
  82     rc = pcmk__output_new(&out, args->output_ty, args->output_dest, argv);
  83     if (rc != pcmk_rc_ok) {
  84         exit_code = CRM_EX_ERROR;
  85         g_set_error(&error, PCMK__EXITC_ERROR, exit_code,
  86                     "Error creating output format %s: %s",
  87                     args->output_ty, pcmk_rc_str(rc));
  88         goto done;
  89     }
  90 
  91     if (args->version) {
  92         out->version(out, false);
  93         initialize = false;
  94         goto done;
  95     }
  96 
  97     if ((g_strv_length(processed_args) >= 2)
  98         && pcmk__str_eq(processed_args[1], "metadata", pcmk__str_none)) {
  99         crmd_metadata();
 100         initialize = false;
 101         goto done;
 102     }
 103 
 104     pcmk__cli_init_logging("pacemaker-controld", args->verbosity);
 105     crm_log_init(NULL, LOG_INFO, TRUE, FALSE, argc, argv, FALSE);
 106     crm_notice("Starting Pacemaker controller");
 107 
 108     old_instance = crm_ipc_new(CRM_SYSTEM_CRMD, 0);
 109     if (old_instance == NULL) {
 110         /* crm_ipc_new will have already printed an error message with crm_err. */
 111         exit_code = CRM_EX_FATAL;
 112         goto done;
 113     }
 114 
 115     if (crm_ipc_connect(old_instance)) {
 116         /* IPC end-point already up */
 117         crm_ipc_close(old_instance);
 118         crm_ipc_destroy(old_instance);
 119         crm_err("pacemaker-controld is already active, aborting startup");
 120         initialize = false;
 121         goto done;
 122 
 123     } else {
 124         /* not up or not authentic, we'll proceed either way */
 125         crm_ipc_destroy(old_instance);
 126         old_instance = NULL;
 127     }
 128 
 129     if (pcmk__daemon_can_write(PE_STATE_DIR, NULL) == FALSE) {
 130         exit_code = CRM_EX_FATAL;
 131         crm_err("Terminating due to bad permissions on " PE_STATE_DIR);
 132         g_set_error(&error, PCMK__EXITC_ERROR, exit_code,
 133                     "Bad permissions on " PE_STATE_DIR
 134                     " (see logs for details)");
 135         goto done;
 136 
 137     } else if (pcmk__daemon_can_write(CRM_CONFIG_DIR, NULL) == FALSE) {
 138         exit_code = CRM_EX_FATAL;
 139         crm_err("Terminating due to bad permissions on " CRM_CONFIG_DIR);
 140         g_set_error(&error, PCMK__EXITC_ERROR, exit_code,
 141                     "Bad permissions on " CRM_CONFIG_DIR
 142                     " (see logs for details)");
 143         goto done;
 144     }
 145 
 146     if (pcmk__log_output_new(&(controld_globals.logger_out)) != pcmk_rc_ok) {
 147         exit_code = CRM_EX_FATAL;
 148         goto done;
 149     }
 150 
 151     pcmk__output_set_log_level(controld_globals.logger_out, LOG_TRACE);
 152 
 153 done:
 154     g_strfreev(processed_args);
 155     pcmk__free_arg_context(context);
 156 
 157     pcmk__output_and_clear_error(&error, out);
 158 
 159     if (out != NULL) {
 160         out->finish(out, exit_code, true, NULL);
 161         pcmk__output_free(out);
 162     }
 163     pcmk__unregister_formats();
 164 
 165     if ((exit_code == CRM_EX_OK) && initialize) {
 166         // Does not return
 167         crmd_init();
 168     }
 169     crm_exit(exit_code);
 170 }
 171 
 172 void
 173 crmd_init(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 174 {
 175     crm_exit_t exit_code = CRM_EX_OK;
 176     enum crmd_fsa_state state;
 177 
 178     init_dotfile();
 179     register_fsa_input(C_STARTUP, I_STARTUP, NULL);
 180 
 181     crm_peer_init();
 182     state = s_crmd_fsa(C_STARTUP);
 183 
 184     if (state == S_PENDING || state == S_STARTING) {
 185         /* Create the mainloop and run it... */
 186         crm_trace("Starting %s's mainloop", crm_system_name);
 187         controld_globals.mainloop = g_main_loop_new(NULL, FALSE);
 188         g_main_loop_run(controld_globals.mainloop);
 189         if (pcmk_is_set(controld_globals.fsa_input_register, R_STAYDOWN)) {
 190             crm_info("Inhibiting automated respawn");
 191             exit_code = CRM_EX_FATAL;
 192         }
 193 
 194     } else {
 195         crm_err("Startup of %s failed.  Current state: %s",
 196                 crm_system_name, fsa_state2string(state));
 197         exit_code = CRM_EX_ERROR;
 198     }
 199 
 200     crm_info("%s[%lu] exiting with status %d (%s)",
 201              crm_system_name, (unsigned long) getpid(), exit_code,
 202              crm_exit_str(exit_code));
 203 
 204     crmd_fast_exit(exit_code);
 205 }

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