root/daemons/fenced/pacemaker-fenced.c

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

DEFINITIONS

This source file includes following definitions.
  1. st_ipc_accept
  2. st_ipc_dispatch
  3. st_ipc_closed
  4. st_ipc_destroy
  5. stonith_peer_callback
  6. stonith_peer_ais_callback
  7. stonith_peer_cs_destroy
  8. do_local_reply
  9. get_stonith_flag
  10. stonith_notify_client
  11. do_stonith_async_timeout_update
  12. fenced_send_notification
  13. fenced_send_config_notification
  14. node_does_watchdog_fencing
  15. stonith_shutdown
  16. stonith_cleanup
  17. stand_alone_cpg_cb
  18. st_peer_update_callback
  19. fencer_metadata
  20. build_arg_context
  21. main

   1 /*
   2  * Copyright 2009-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 <sys/param.h>
  13 #include <stdio.h>
  14 #include <sys/types.h>
  15 #include <sys/stat.h>
  16 #include <unistd.h>
  17 #include <sys/utsname.h>
  18 
  19 #include <stdlib.h>
  20 #include <errno.h>
  21 #include <fcntl.h>
  22 #include <inttypes.h>  // PRIu32, PRIx32
  23 
  24 #include <crm/crm.h>
  25 #include <crm/common/cmdline_internal.h>
  26 #include <crm/common/ipc.h>
  27 #include <crm/common/ipc_internal.h>
  28 #include <crm/common/output_internal.h>
  29 
  30 #include <crm/stonith-ng.h>
  31 #include <crm/fencing/internal.h>
  32 #include <crm/common/xml.h>
  33 #include <crm/common/xml_internal.h>
  34 
  35 #include <crm/common/mainloop.h>
  36 
  37 #include <crm/cib/internal.h>
  38 
  39 #include <pacemaker-fenced.h>
  40 
  41 #define SUMMARY "daemon for executing fencing devices in a Pacemaker cluster"
  42 
  43 char *stonith_our_uname = NULL;
  44 long long stonith_watchdog_timeout_ms = 0;
  45 GList *stonith_watchdog_targets = NULL;
  46 
  47 static GMainLoop *mainloop = NULL;
  48 
  49 gboolean stand_alone = FALSE;
  50 gboolean stonith_shutdown_flag = FALSE;
  51 
  52 static qb_ipcs_service_t *ipcs = NULL;
  53 static pcmk__output_t *out = NULL;
  54 
  55 pcmk__supported_format_t formats[] = {
  56     PCMK__SUPPORTED_FORMAT_NONE,
  57     PCMK__SUPPORTED_FORMAT_TEXT,
  58     PCMK__SUPPORTED_FORMAT_XML,
  59     { NULL, NULL, NULL }
  60 };
  61 
  62 static struct {
  63     bool no_cib_connect;
  64     gchar **log_files;
  65 } options;
  66 
  67 crm_exit_t exit_code = CRM_EX_OK;
  68 
  69 static void stonith_cleanup(void);
  70 
  71 static int32_t
  72 st_ipc_accept(qb_ipcs_connection_t * c, uid_t uid, gid_t gid)
     /* [previous][next][first][last][top][bottom][index][help] */
  73 {
  74     if (stonith_shutdown_flag) {
  75         crm_info("Ignoring new client [%d] during shutdown",
  76                  pcmk__client_pid(c));
  77         return -ECONNREFUSED;
  78     }
  79 
  80     if (pcmk__new_client(c, uid, gid) == NULL) {
  81         return -ENOMEM;
  82     }
  83     return 0;
  84 }
  85 
  86 /* Exit code means? */
  87 static int32_t
  88 st_ipc_dispatch(qb_ipcs_connection_t * qbc, void *data, size_t size)
     /* [previous][next][first][last][top][bottom][index][help] */
  89 {
  90     uint32_t id = 0;
  91     uint32_t flags = 0;
  92     uint32_t call_options = st_opt_none;
  93     xmlNode *request = NULL;
  94     pcmk__client_t *c = pcmk__find_client(qbc);
  95     const char *op = NULL;
  96     int rc = pcmk_rc_ok;
  97 
  98     if (c == NULL) {
  99         crm_info("Invalid client: %p", qbc);
 100         return 0;
 101     }
 102 
 103     request = pcmk__client_data2xml(c, data, &id, &flags);
 104     if (request == NULL) {
 105         pcmk__ipc_send_ack(c, id, flags, PCMK__XE_NACK, NULL, CRM_EX_PROTOCOL);
 106         return 0;
 107     }
 108 
 109 
 110     op = crm_element_value(request, PCMK__XA_CRM_TASK);
 111     if(pcmk__str_eq(op, CRM_OP_RM_NODE_CACHE, pcmk__str_casei)) {
 112         crm_xml_add(request, PCMK__XA_T, PCMK__VALUE_STONITH_NG);
 113         crm_xml_add(request, PCMK__XA_ST_OP, op);
 114         crm_xml_add(request, PCMK__XA_ST_CLIENTID, c->id);
 115         crm_xml_add(request, PCMK__XA_ST_CLIENTNAME, pcmk__client_name(c));
 116         crm_xml_add(request, PCMK__XA_ST_CLIENTNODE, stonith_our_uname);
 117 
 118         pcmk__cluster_send_message(NULL, crm_msg_stonith_ng, request);
 119         free_xml(request);
 120         return 0;
 121     }
 122 
 123     if (c->name == NULL) {
 124         const char *value = crm_element_value(request, PCMK__XA_ST_CLIENTNAME);
 125 
 126         c->name = crm_strdup_printf("%s.%u", pcmk__s(value, "unknown"), c->pid);
 127     }
 128 
 129     rc = pcmk__xe_get_flags(request, PCMK__XA_ST_CALLOPT, &call_options,
 130                             st_opt_none);
 131     if (rc != pcmk_rc_ok) {
 132         crm_warn("Couldn't parse options from IPC request: %s",
 133                  pcmk_rc_str(rc));
 134     }
 135 
 136     crm_trace("Flags %#08" PRIx32 "/%#08x for command %" PRIu32
 137               " from client %s", flags, call_options, id, pcmk__client_name(c));
 138 
 139     if (pcmk_is_set(call_options, st_opt_sync_call)) {
 140         pcmk__assert(pcmk_is_set(flags, crm_ipc_client_response));
 141         CRM_LOG_ASSERT(c->request_id == 0);     /* This means the client has two synchronous events in-flight */
 142         c->request_id = id;     /* Reply only to the last one */
 143     }
 144 
 145     crm_xml_add(request, PCMK__XA_ST_CLIENTID, c->id);
 146     crm_xml_add(request, PCMK__XA_ST_CLIENTNAME, pcmk__client_name(c));
 147     crm_xml_add(request, PCMK__XA_ST_CLIENTNODE, stonith_our_uname);
 148 
 149     crm_log_xml_trace(request, "ipc-received");
 150     stonith_command(c, id, flags, request, NULL);
 151 
 152     free_xml(request);
 153     return 0;
 154 }
 155 
 156 /* Error code means? */
 157 static int32_t
 158 st_ipc_closed(qb_ipcs_connection_t * c)
     /* [previous][next][first][last][top][bottom][index][help] */
 159 {
 160     pcmk__client_t *client = pcmk__find_client(c);
 161 
 162     if (client == NULL) {
 163         return 0;
 164     }
 165 
 166     crm_trace("Connection %p closed", c);
 167     pcmk__free_client(client);
 168 
 169     /* 0 means: yes, go ahead and destroy the connection */
 170     return 0;
 171 }
 172 
 173 static void
 174 st_ipc_destroy(qb_ipcs_connection_t * c)
     /* [previous][next][first][last][top][bottom][index][help] */
 175 {
 176     crm_trace("Connection %p destroyed", c);
 177     st_ipc_closed(c);
 178 }
 179 
 180 static void
 181 stonith_peer_callback(xmlNode * msg, void *private_data)
     /* [previous][next][first][last][top][bottom][index][help] */
 182 {
 183     const char *remote_peer = crm_element_value(msg, PCMK__XA_SRC);
 184     const char *op = crm_element_value(msg, PCMK__XA_ST_OP);
 185 
 186     if (pcmk__str_eq(op, STONITH_OP_POKE, pcmk__str_none)) {
 187         return;
 188     }
 189 
 190     crm_log_xml_trace(msg, "Peer[inbound]");
 191     stonith_command(NULL, 0, 0, msg, remote_peer);
 192 }
 193 
 194 #if SUPPORT_COROSYNC
 195 static void
 196 stonith_peer_ais_callback(cpg_handle_t handle,
     /* [previous][next][first][last][top][bottom][index][help] */
 197                           const struct cpg_name *groupName,
 198                           uint32_t nodeid, uint32_t pid, void *msg, size_t msg_len)
 199 {
 200     uint32_t kind = 0;
 201     xmlNode *xml = NULL;
 202     const char *from = NULL;
 203     char *data = pcmk__cpg_message_data(handle, nodeid, pid, msg, &kind, &from);
 204 
 205     if(data == NULL) {
 206         return;
 207     }
 208     if (kind == crm_class_cluster) {
 209         xml = pcmk__xml_parse(data);
 210         if (xml == NULL) {
 211             crm_err("Invalid XML: '%.120s'", data);
 212             free(data);
 213             return;
 214         }
 215         crm_xml_add(xml, PCMK__XA_SRC, from);
 216         stonith_peer_callback(xml, NULL);
 217     }
 218 
 219     free_xml(xml);
 220     free(data);
 221     return;
 222 }
 223 
 224 static void
 225 stonith_peer_cs_destroy(gpointer user_data)
     /* [previous][next][first][last][top][bottom][index][help] */
 226 {
 227     crm_crit("Lost connection to cluster layer, shutting down");
 228     stonith_shutdown(0);
 229 }
 230 #endif
 231 
 232 void
 233 do_local_reply(const xmlNode *notify_src, pcmk__client_t *client,
     /* [previous][next][first][last][top][bottom][index][help] */
 234                int call_options)
 235 {
 236     /* send callback to originating child */
 237     int local_rc = pcmk_rc_ok;
 238     int rid = 0;
 239     uint32_t ipc_flags = crm_ipc_server_event;
 240 
 241     if (pcmk_is_set(call_options, st_opt_sync_call)) {
 242         CRM_LOG_ASSERT(client->request_id);
 243         rid = client->request_id;
 244         client->request_id = 0;
 245         ipc_flags = crm_ipc_flags_none;
 246     }
 247 
 248     local_rc = pcmk__ipc_send_xml(client, rid, notify_src, ipc_flags);
 249     if (local_rc == pcmk_rc_ok) {
 250         crm_trace("Sent response %d to client %s",
 251                   rid, pcmk__client_name(client));
 252     } else {
 253         crm_warn("%synchronous reply to client %s failed: %s",
 254                  (pcmk_is_set(call_options, st_opt_sync_call)? "S" : "As"),
 255                  pcmk__client_name(client), pcmk_rc_str(local_rc));
 256     }
 257 }
 258 
 259 uint64_t
 260 get_stonith_flag(const char *name)
     /* [previous][next][first][last][top][bottom][index][help] */
 261 {
 262     if (pcmk__str_eq(name, PCMK__VALUE_ST_NOTIFY_FENCE, pcmk__str_none)) {
 263         return st_callback_notify_fence;
 264 
 265     } else if (pcmk__str_eq(name, STONITH_OP_DEVICE_ADD, pcmk__str_casei)) {
 266         return st_callback_device_add;
 267 
 268     } else if (pcmk__str_eq(name, STONITH_OP_DEVICE_DEL, pcmk__str_casei)) {
 269         return st_callback_device_del;
 270 
 271     } else if (pcmk__str_eq(name, PCMK__VALUE_ST_NOTIFY_HISTORY,
 272                             pcmk__str_none)) {
 273         return st_callback_notify_history;
 274 
 275     } else if (pcmk__str_eq(name, PCMK__VALUE_ST_NOTIFY_HISTORY_SYNCED,
 276                             pcmk__str_none)) {
 277         return st_callback_notify_history_synced;
 278 
 279     }
 280     return st_callback_unknown;
 281 }
 282 
 283 static void
 284 stonith_notify_client(gpointer key, gpointer value, gpointer user_data)
     /* [previous][next][first][last][top][bottom][index][help] */
 285 {
 286 
 287     const xmlNode *update_msg = user_data;
 288     pcmk__client_t *client = value;
 289     const char *type = NULL;
 290 
 291     CRM_CHECK(client != NULL, return);
 292     CRM_CHECK(update_msg != NULL, return);
 293 
 294     type = crm_element_value(update_msg, PCMK__XA_SUBT);
 295     CRM_CHECK(type != NULL, crm_log_xml_err(update_msg, "notify"); return);
 296 
 297     if (client->ipcs == NULL) {
 298         crm_trace("Skipping client with NULL channel");
 299         return;
 300     }
 301 
 302     if (pcmk_is_set(client->flags, get_stonith_flag(type))) {
 303         int rc = pcmk__ipc_send_xml(client, 0, update_msg,
 304                                     crm_ipc_server_event);
 305 
 306         if (rc != pcmk_rc_ok) {
 307             crm_warn("%s notification of client %s failed: %s "
 308                      CRM_XS " id=%.8s rc=%d", type, pcmk__client_name(client),
 309                      pcmk_rc_str(rc), client->id, rc);
 310         } else {
 311             crm_trace("Sent %s notification to client %s",
 312                       type, pcmk__client_name(client));
 313         }
 314     }
 315 }
 316 
 317 void
 318 do_stonith_async_timeout_update(const char *client_id, const char *call_id, int timeout)
     /* [previous][next][first][last][top][bottom][index][help] */
 319 {
 320     pcmk__client_t *client = NULL;
 321     xmlNode *notify_data = NULL;
 322 
 323     if (!timeout || !call_id || !client_id) {
 324         return;
 325     }
 326 
 327     client = pcmk__find_client_by_id(client_id);
 328     if (!client) {
 329         return;
 330     }
 331 
 332     notify_data = pcmk__xe_create(NULL, PCMK__XE_ST_ASYNC_TIMEOUT_VALUE);
 333     crm_xml_add(notify_data, PCMK__XA_T, PCMK__VALUE_ST_ASYNC_TIMEOUT_VALUE);
 334     crm_xml_add(notify_data, PCMK__XA_ST_CALLID, call_id);
 335     crm_xml_add_int(notify_data, PCMK__XA_ST_TIMEOUT, timeout);
 336 
 337     crm_trace("timeout update is %d for client %s and call id %s", timeout, client_id, call_id);
 338 
 339     if (client) {
 340         pcmk__ipc_send_xml(client, 0, notify_data, crm_ipc_server_event);
 341     }
 342 
 343     free_xml(notify_data);
 344 }
 345 
 346 /*!
 347  * \internal
 348  * \brief Notify relevant IPC clients of a fencing operation result
 349  *
 350  * \param[in] type     Notification type
 351  * \param[in] result   Result of fencing operation (assume success if NULL)
 352  * \param[in] data     If not NULL, add to notification as call data
 353  */
 354 void
 355 fenced_send_notification(const char *type, const pcmk__action_result_t *result,
     /* [previous][next][first][last][top][bottom][index][help] */
 356                          xmlNode *data)
 357 {
 358     /* TODO: Standardize the contents of data */
 359     xmlNode *update_msg = pcmk__xe_create(NULL, PCMK__XE_NOTIFY);
 360 
 361     CRM_LOG_ASSERT(type != NULL);
 362 
 363     crm_xml_add(update_msg, PCMK__XA_T, PCMK__VALUE_ST_NOTIFY);
 364     crm_xml_add(update_msg, PCMK__XA_SUBT, type);
 365     crm_xml_add(update_msg, PCMK__XA_ST_OP, type);
 366     stonith__xe_set_result(update_msg, result);
 367 
 368     if (data != NULL) {
 369         xmlNode *wrapper = pcmk__xe_create(update_msg, PCMK__XE_ST_CALLDATA);
 370 
 371         pcmk__xml_copy(wrapper, data);
 372     }
 373 
 374     crm_trace("Notifying clients");
 375     pcmk__foreach_ipc_client(stonith_notify_client, update_msg);
 376     free_xml(update_msg);
 377     crm_trace("Notify complete");
 378 }
 379 
 380 /*!
 381  * \internal
 382  * \brief Send notifications for a configuration change to subscribed clients
 383  *
 384  * \param[in] op      Notification type (\c STONITH_OP_DEVICE_ADD,
 385  *                    \c STONITH_OP_DEVICE_DEL, \c STONITH_OP_LEVEL_ADD, or
 386  *                    \c STONITH_OP_LEVEL_DEL)
 387  * \param[in] result  Operation result
 388  * \param[in] desc    Description of what changed (either device ID or string
 389  *                    representation of level
 390  *                    (<tt><target>[<level_index>]</tt>))
 391  */
 392 void
 393 fenced_send_config_notification(const char *op,
     /* [previous][next][first][last][top][bottom][index][help] */
 394                                 const pcmk__action_result_t *result,
 395                                 const char *desc)
 396 {
 397     xmlNode *notify_data = pcmk__xe_create(NULL, op);
 398 
 399     crm_xml_add(notify_data, PCMK__XA_ST_DEVICE_ID, desc);
 400 
 401     fenced_send_notification(op, result, notify_data);
 402     free_xml(notify_data);
 403 }
 404 
 405 /*!
 406  * \internal
 407  * \brief Check whether a node does watchdog-fencing
 408  *
 409  * \param[in] node    Name of node to check
 410  *
 411  * \return TRUE if node found in stonith_watchdog_targets
 412  *         or stonith_watchdog_targets is empty indicating
 413  *         all nodes are doing watchdog-fencing
 414  */
 415 gboolean
 416 node_does_watchdog_fencing(const char *node)
     /* [previous][next][first][last][top][bottom][index][help] */
 417 {
 418     return ((stonith_watchdog_targets == NULL) ||
 419             pcmk__str_in_list(node, stonith_watchdog_targets, pcmk__str_casei));
 420 }
 421 
 422 void
 423 stonith_shutdown(int nsig)
     /* [previous][next][first][last][top][bottom][index][help] */
 424 {
 425     crm_info("Terminating with %d clients", pcmk__ipc_client_count());
 426     stonith_shutdown_flag = TRUE;
 427     if (mainloop != NULL && g_main_loop_is_running(mainloop)) {
 428         g_main_loop_quit(mainloop);
 429     }
 430 }
 431 
 432 static void
 433 stonith_cleanup(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 434 {
 435     fenced_cib_cleanup();
 436     if (ipcs) {
 437         qb_ipcs_destroy(ipcs);
 438     }
 439 
 440     pcmk__cluster_destroy_node_caches();
 441     pcmk__client_cleanup();
 442     free_stonith_remote_op_list();
 443     free_topology_list();
 444     free_device_list();
 445     free_metadata_cache();
 446     fenced_unregister_handlers();
 447 
 448     free(stonith_our_uname);
 449     stonith_our_uname = NULL;
 450 }
 451 
 452 static gboolean
 453 stand_alone_cpg_cb(const gchar *option_name, const gchar *optarg, gpointer data,
     /* [previous][next][first][last][top][bottom][index][help] */
 454                    GError **error)
 455 {
 456     stand_alone = FALSE;
 457     options.no_cib_connect = true;
 458     return TRUE;
 459 }
 460 
 461 struct qb_ipcs_service_handlers ipc_callbacks = {
 462     .connection_accept = st_ipc_accept,
 463     .connection_created = NULL,
 464     .msg_process = st_ipc_dispatch,
 465     .connection_closed = st_ipc_closed,
 466     .connection_destroyed = st_ipc_destroy
 467 };
 468 
 469 /*!
 470  * \internal
 471  * \brief Callback for peer status changes
 472  *
 473  * \param[in] type  What changed
 474  * \param[in] node  What peer had the change
 475  * \param[in] data  Previous value of what changed
 476  */
 477 static void
 478 st_peer_update_callback(enum crm_status_type type, crm_node_t * node, const void *data)
     /* [previous][next][first][last][top][bottom][index][help] */
 479 {
 480     if ((type != crm_status_processes)
 481         && !pcmk_is_set(node->flags, crm_remote_node)) {
 482         /*
 483          * This is a hack until we can send to a nodeid and/or we fix node name lookups
 484          * These messages are ignored in stonith_peer_callback()
 485          */
 486         xmlNode *query = pcmk__xe_create(NULL, PCMK__XE_STONITH_COMMAND);
 487 
 488         crm_xml_add(query, PCMK__XA_T, PCMK__VALUE_STONITH_NG);
 489         crm_xml_add(query, PCMK__XA_ST_OP, STONITH_OP_POKE);
 490 
 491         crm_debug("Broadcasting our uname because of node %u", node->id);
 492         pcmk__cluster_send_message(NULL, crm_msg_stonith_ng, query);
 493 
 494         free_xml(query);
 495     }
 496 }
 497 
 498 /* @COMPAT Deprecated since 2.1.8. Use pcmk_list_fence_attrs() or
 499  * crm_resource --list-options=fencing instead of querying daemon metadata.
 500  */
 501 static int
 502 fencer_metadata(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 503 {
 504     const char *name = "pacemaker-fenced";
 505     const char *desc_short = N_("Instance attributes available for all "
 506                                 "\"stonith\"-class resources");
 507     const char *desc_long = N_("Instance attributes available for all "
 508                                "\"stonith\"-class resources and used by "
 509                                "Pacemaker's fence daemon, formerly known as "
 510                                "stonithd");
 511 
 512     return pcmk__daemon_metadata(out, name, desc_short, desc_long,
 513                                  pcmk__opt_fencing);
 514 }
 515 
 516 static GOptionEntry entries[] = {
 517     { "stand-alone", 's', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &stand_alone,
 518       N_("Deprecated (will be removed in a future release)"), NULL },
 519 
 520     { "stand-alone-w-cpg", 'c', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
 521       stand_alone_cpg_cb, N_("Intended for use in regression testing only"), NULL },
 522 
 523     { "logfile", 'l', G_OPTION_FLAG_NONE, G_OPTION_ARG_FILENAME_ARRAY,
 524       &options.log_files, N_("Send logs to the additional named logfile"), NULL },
 525 
 526     { NULL }
 527 };
 528 
 529 static GOptionContext *
 530 build_arg_context(pcmk__common_args_t *args, GOptionGroup **group)
     /* [previous][next][first][last][top][bottom][index][help] */
 531 {
 532     GOptionContext *context = NULL;
 533 
 534     context = pcmk__build_arg_context(args, "text (default), xml", group, NULL);
 535     pcmk__add_main_args(context, entries);
 536     return context;
 537 }
 538 
 539 int
 540 main(int argc, char **argv)
     /* [previous][next][first][last][top][bottom][index][help] */
 541 {
 542     int rc = pcmk_rc_ok;
 543     pcmk_cluster_t *cluster = NULL;
 544     crm_ipc_t *old_instance = NULL;
 545 
 546     GError *error = NULL;
 547 
 548     GOptionGroup *output_group = NULL;
 549     pcmk__common_args_t *args = pcmk__new_common_args(SUMMARY);
 550     gchar **processed_args = pcmk__cmdline_preproc(argv, "l");
 551     GOptionContext *context = build_arg_context(args, &output_group);
 552 
 553     crm_log_preinit(NULL, argc, argv);
 554 
 555     pcmk__register_formats(output_group, formats);
 556     if (!g_option_context_parse_strv(context, &processed_args, &error)) {
 557         exit_code = CRM_EX_USAGE;
 558         goto done;
 559     }
 560 
 561     rc = pcmk__output_new(&out, args->output_ty, args->output_dest, argv);
 562     if (rc != pcmk_rc_ok) {
 563         exit_code = CRM_EX_ERROR;
 564         g_set_error(&error, PCMK__EXITC_ERROR, exit_code,
 565                     "Error creating output format %s: %s",
 566                     args->output_ty, pcmk_rc_str(rc));
 567         goto done;
 568     }
 569 
 570     if (args->version) {
 571         out->version(out, false);
 572         goto done;
 573     }
 574 
 575     if ((g_strv_length(processed_args) >= 2)
 576         && pcmk__str_eq(processed_args[1], "metadata", pcmk__str_none)) {
 577 
 578         rc = fencer_metadata();
 579         if (rc != pcmk_rc_ok) {
 580             exit_code = CRM_EX_FATAL;
 581             g_set_error(&error, PCMK__EXITC_ERROR, exit_code,
 582                         "Unable to display metadata: %s", pcmk_rc_str(rc));
 583         }
 584         goto done;
 585     }
 586 
 587     // Open additional log files
 588     pcmk__add_logfiles(options.log_files, out);
 589 
 590     crm_log_init(NULL, LOG_INFO + args->verbosity, TRUE,
 591                  (args->verbosity > 0), argc, argv, FALSE);
 592 
 593     crm_notice("Starting Pacemaker fencer");
 594 
 595     old_instance = crm_ipc_new("stonith-ng", 0);
 596     if (old_instance == NULL) {
 597         /* crm_ipc_new() will have already logged an error message with
 598          * crm_err()
 599          */
 600         exit_code = CRM_EX_FATAL;
 601         goto done;
 602     }
 603 
 604     if (pcmk__connect_generic_ipc(old_instance) == pcmk_rc_ok) {
 605         // IPC endpoint already up
 606         crm_ipc_close(old_instance);
 607         crm_ipc_destroy(old_instance);
 608         crm_err("pacemaker-fenced is already active, aborting startup");
 609         goto done;
 610     } else {
 611         // Not up or not authentic, we'll proceed either way
 612         crm_ipc_destroy(old_instance);
 613         old_instance = NULL;
 614     }
 615 
 616     mainloop_add_signal(SIGTERM, stonith_shutdown);
 617 
 618     pcmk__cluster_init_node_caches();
 619 
 620     rc = fenced_scheduler_init();
 621     if (rc != pcmk_rc_ok) {
 622         exit_code = CRM_EX_FATAL;
 623         g_set_error(&error, PCMK__EXITC_ERROR, exit_code,
 624                     "Error initializing scheduler data: %s", pcmk_rc_str(rc));
 625         goto done;
 626     }
 627 
 628     cluster = pcmk_cluster_new();
 629 
 630     if (!stand_alone) {
 631 #if SUPPORT_COROSYNC
 632         if (pcmk_get_cluster_layer() == pcmk_cluster_layer_corosync) {
 633             pcmk_cluster_set_destroy_fn(cluster, stonith_peer_cs_destroy);
 634             pcmk_cpg_set_deliver_fn(cluster, stonith_peer_ais_callback);
 635             pcmk_cpg_set_confchg_fn(cluster, pcmk__cpg_confchg_cb);
 636         }
 637 #endif // SUPPORT_COROSYNC
 638 
 639         pcmk__cluster_set_status_callback(&st_peer_update_callback);
 640 
 641         if (pcmk_cluster_connect(cluster) != pcmk_rc_ok) {
 642             exit_code = CRM_EX_FATAL;
 643             crm_crit("Cannot sign in to the cluster... terminating");
 644             goto done;
 645         }
 646         pcmk__str_update(&stonith_our_uname, cluster->uname);
 647 
 648         if (!options.no_cib_connect) {
 649             setup_cib();
 650         }
 651 
 652     } else {
 653         pcmk__str_update(&stonith_our_uname, "localhost");
 654         crm_warn("Stand-alone mode is deprecated and will be removed "
 655                  "in a future release");
 656     }
 657 
 658     init_device_list();
 659     init_topology_list();
 660 
 661     pcmk__serve_fenced_ipc(&ipcs, &ipc_callbacks);
 662 
 663     // Create the mainloop and run it...
 664     mainloop = g_main_loop_new(NULL, FALSE);
 665     crm_notice("Pacemaker fencer successfully started and accepting connections");
 666     g_main_loop_run(mainloop);
 667 
 668 done:
 669     g_strfreev(processed_args);
 670     pcmk__free_arg_context(context);
 671 
 672     g_strfreev(options.log_files);
 673 
 674     stonith_cleanup();
 675     pcmk_cluster_free(cluster);
 676     fenced_scheduler_cleanup();
 677 
 678     pcmk__output_and_clear_error(&error, out);
 679 
 680     if (out != NULL) {
 681         out->finish(out, exit_code, true, NULL);
 682         pcmk__output_free(out);
 683     }
 684 
 685     pcmk__unregister_formats();
 686     crm_exit(exit_code);
 687 }

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