root/daemons/pacemakerd/pcmkd_messages.c

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

DEFINITIONS

This source file includes following definitions.
  1. pcmk_handle_ping_request
  2. pcmk_handle_shutdown_request
  3. pcmk_ipc_accept
  4. pcmk_ipc_closed
  5. pcmk_ipc_destroy
  6. pcmk_ipc_dispatch

   1 /*
   2  * Copyright 2010-2021 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 #include "pacemakerd.h"
  12 
  13 #include <crm/msg_xml.h>
  14 
  15 #include <errno.h>
  16 #include <stdbool.h>
  17 #include <stdint.h>
  18 #include <string.h>
  19 #include <time.h>
  20 #include <sys/types.h>
  21 
  22 void
  23 pcmk_handle_ping_request(pcmk__client_t *c, xmlNode *msg, uint32_t id)
     /* [previous][next][first][last][top][bottom][index][help] */
  24 {
  25     const char *value = NULL;
  26     xmlNode *ping = NULL;
  27     xmlNode *reply = NULL;
  28     time_t pinged = time(NULL);
  29     const char *from = crm_element_value(msg, F_CRM_SYS_FROM);
  30 
  31     /* Pinged for status */
  32     crm_trace("Pinged from %s.%s",
  33               crm_str(crm_element_value(msg, F_CRM_ORIGIN)),
  34               from?from:"unknown");
  35     ping = create_xml_node(NULL, XML_CRM_TAG_PING);
  36     value = crm_element_value(msg, F_CRM_SYS_TO);
  37     crm_xml_add(ping, XML_PING_ATTR_SYSFROM, value);
  38     crm_xml_add(ping, XML_PING_ATTR_PACEMAKERDSTATE, pacemakerd_state);
  39     crm_xml_add_ll(ping, XML_ATTR_TSTAMP, (long long) pinged);
  40     crm_xml_add(ping, XML_PING_ATTR_STATUS, "ok");
  41     reply = create_reply(msg, ping);
  42     free_xml(ping);
  43     if (reply) {
  44         if (pcmk__ipc_send_xml(c, id, reply, crm_ipc_server_event) !=
  45                 pcmk_rc_ok) {
  46             crm_err("Failed sending ping reply to client %s",
  47                     pcmk__client_name(c));
  48         }
  49         free_xml(reply);
  50     } else {
  51         crm_err("Failed building ping reply for client %s",
  52                 pcmk__client_name(c));
  53     }
  54     /* just proceed state on sbd pinging us */
  55     if (from && strstr(from, "sbd")) {
  56         if (pcmk__str_eq(pacemakerd_state, XML_PING_ATTR_PACEMAKERDSTATE_SHUTDOWNCOMPLETE, pcmk__str_none)) {
  57             if (pcmk__get_sbd_sync_resource_startup()) {
  58                 crm_notice("Shutdown-complete-state passed to SBD.");
  59             }
  60             shutdown_complete_state_reported_to = c->pid;
  61         } else if (pcmk__str_eq(pacemakerd_state, XML_PING_ATTR_PACEMAKERDSTATE_WAITPING, pcmk__str_none)) {
  62             crm_notice("Received startup-trigger from SBD.");
  63             pacemakerd_state = XML_PING_ATTR_PACEMAKERDSTATE_STARTINGDAEMONS;
  64             mainloop_set_trigger(startup_trigger);
  65         }
  66     }
  67 }
  68 
  69 void
  70 pcmk_handle_shutdown_request(pcmk__client_t *c, xmlNode *msg, uint32_t id, uint32_t flags)
     /* [previous][next][first][last][top][bottom][index][help] */
  71 {
  72     xmlNode *shutdown = NULL;
  73     xmlNode *reply = NULL;
  74 
  75     /* Only allow privileged users (i.e. root or hacluster) to shut down
  76      * Pacemaker from the command line (or direct IPC), so that other users
  77      * are forced to go through the CIB and have ACLs applied.
  78      */
  79     bool allowed = pcmk_is_set(c->flags, pcmk__client_privileged);
  80 
  81     shutdown = create_xml_node(NULL, XML_CIB_ATTR_SHUTDOWN);
  82 
  83     if (allowed) {
  84         crm_notice("Shutting down in response to IPC request %s from %s",
  85                    crm_element_value(msg, F_CRM_REFERENCE),
  86                    crm_element_value(msg, F_CRM_ORIGIN));
  87         crm_xml_add_int(shutdown, XML_LRM_ATTR_OPSTATUS, CRM_EX_OK);
  88     } else {
  89         crm_warn("Ignoring shutdown request from unprivileged client %s",
  90                  pcmk__client_name(c));
  91         crm_xml_add_int(shutdown, XML_LRM_ATTR_OPSTATUS, CRM_EX_INSUFFICIENT_PRIV);
  92     }
  93 
  94     reply = create_reply(msg, shutdown);
  95     free_xml(shutdown);
  96     if (reply) {
  97         if (pcmk__ipc_send_xml(c, id, reply, crm_ipc_server_event) != pcmk_rc_ok) {
  98             crm_err("Failed sending shutdown reply to client %s",
  99                     pcmk__client_name(c));
 100         }
 101         free_xml(reply);
 102     } else {
 103         crm_err("Failed building shutdown reply for client %s",
 104                 pcmk__client_name(c));
 105     }
 106 
 107     if (allowed) {
 108         pcmk_shutdown(15);
 109     }
 110 }
 111 
 112 static int32_t
 113 pcmk_ipc_accept(qb_ipcs_connection_t * c, uid_t uid, gid_t gid)
     /* [previous][next][first][last][top][bottom][index][help] */
 114 {
 115     crm_trace("Connection %p", c);
 116     if (pcmk__new_client(c, uid, gid) == NULL) {
 117         return -EIO;
 118     }
 119     return 0;
 120 }
 121 
 122 /* Error code means? */
 123 static int32_t
 124 pcmk_ipc_closed(qb_ipcs_connection_t * c)
     /* [previous][next][first][last][top][bottom][index][help] */
 125 {
 126     pcmk__client_t *client = pcmk__find_client(c);
 127 
 128     if (client == NULL) {
 129         return 0;
 130     }
 131     crm_trace("Connection %p", c);
 132     if (shutdown_complete_state_reported_to == client->pid) {
 133         shutdown_complete_state_reported_client_closed = TRUE;
 134         if (shutdown_trigger) {
 135             mainloop_set_trigger(shutdown_trigger);
 136         }
 137     }
 138     pcmk__free_client(client);
 139     return 0;
 140 }
 141 
 142 static void
 143 pcmk_ipc_destroy(qb_ipcs_connection_t * c)
     /* [previous][next][first][last][top][bottom][index][help] */
 144 {
 145     crm_trace("Connection %p", c);
 146     pcmk_ipc_closed(c);
 147 }
 148 
 149 /* Exit code means? */
 150 static int32_t
 151 pcmk_ipc_dispatch(qb_ipcs_connection_t * qbc, void *data, size_t size)
     /* [previous][next][first][last][top][bottom][index][help] */
 152 {
 153     uint32_t id = 0;
 154     uint32_t flags = 0;
 155     const char *task = NULL;
 156     xmlNode *msg = NULL;
 157     pcmk__client_t *c = pcmk__find_client(qbc);
 158 
 159     CRM_CHECK(c != NULL, return 0);
 160 
 161     msg = pcmk__client_data2xml(c, data, &id, &flags);
 162     if (msg == NULL) {
 163         pcmk__ipc_send_ack(c, id, flags, "ack", CRM_EX_PROTOCOL);
 164         return 0;
 165     }
 166 
 167     task = crm_element_value(msg, F_CRM_TASK);
 168     if (pcmk__str_eq(task, CRM_OP_QUIT, pcmk__str_none)) {
 169         pcmk__ipc_send_ack(c, id, flags, "ack", CRM_EX_INDETERMINATE);
 170         pcmk_handle_shutdown_request(c, msg, id, flags);
 171 
 172     } else if (pcmk__str_eq(task, CRM_OP_RM_NODE_CACHE, pcmk__str_none)) {
 173         crm_trace("Ignoring request from client %s to purge node "
 174                   "because peer cache is not used", pcmk__client_name(c));
 175         pcmk__ipc_send_ack(c, id, flags, "ack", CRM_EX_OK);
 176 
 177     } else if (pcmk__str_eq(task, CRM_OP_PING, pcmk__str_none)) {
 178         pcmk__ipc_send_ack(c, id, flags, "ack", CRM_EX_INDETERMINATE);
 179         pcmk_handle_ping_request(c, msg, id);
 180 
 181     } else {
 182         crm_debug("Unrecognized IPC command '%s' from client %s",
 183                   crm_str(task), pcmk__client_name(c));
 184         pcmk__ipc_send_ack(c, id, flags, "ack", CRM_EX_INVALID_PARAM);
 185     }
 186 
 187     free_xml(msg);
 188     return 0;
 189 }
 190 
 191 struct qb_ipcs_service_handlers mcp_ipc_callbacks = {
 192     .connection_accept = pcmk_ipc_accept,
 193     .connection_created = NULL,
 194     .msg_process = pcmk_ipc_dispatch,
 195     .connection_closed = pcmk_ipc_closed,
 196     .connection_destroyed = pcmk_ipc_destroy
 197 };

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