root/include/crm/common/ipc.h

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

INCLUDED FROM


   1 /*
   2  * Copyright 2004-2025 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 Lesser General Public License
   7  * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
   8  */
   9 
  10 #ifndef PCMK__CRM_COMMON_IPC__H
  11 #define PCMK__CRM_COMMON_IPC__H
  12 
  13 #include <stdint.h>
  14 #include <sys/uio.h>
  15 #include <qb/qbipcc.h>
  16 #include <crm/common/xml.h>
  17 
  18 #ifdef __cplusplus
  19 extern "C" {
  20 #endif
  21 
  22 /**
  23  * \file
  24  * \brief IPC interface to Pacemaker daemons
  25  *
  26  * \ingroup core
  27  */
  28 
  29 /*
  30  * The library supports two methods of creating IPC connections. The older code
  31  * allows connecting to any arbitrary IPC name. The newer code only allows
  32  * connecting to one of the Pacemaker daemons.
  33  *
  34  * As daemons are converted to use the new model, the old functions should be
  35  * considered deprecated for use with those daemons. Once all daemons are
  36  * converted, the old functions should be officially deprecated as public API
  37  * and eventually made internal API.
  38  */
  39 
  40 /*
  41  * Pacemaker daemon IPC
  42  */
  43 
  44 /* @COMPAT This is also used internally for cluster message types, but it's not
  45  * worth the hassle of redefining this public API just to change the name.
  46  */
  47 //! Available IPC interfaces
  48 enum pcmk_ipc_server {
  49     pcmk_ipc_unknown,       //!< Unknown or invalid
  50     pcmk_ipc_attrd,         //!< Attribute manager
  51     pcmk_ipc_based,         //!< CIB manager
  52     pcmk_ipc_controld,      //!< Controller
  53     pcmk_ipc_execd,         //!< Executor
  54     pcmk_ipc_fenced,        //!< Fencer
  55     pcmk_ipc_pacemakerd,    //!< Launcher
  56     pcmk_ipc_schedulerd,    //!< Scheduler
  57 };
  58 
  59 // NOTE: sbd (as of at least 1.5.2) uses this enum
  60 //! Possible event types that an IPC event callback can be called for
  61 enum pcmk_ipc_event {
  62     pcmk_ipc_event_connect,     //!< Result of asynchronous connection attempt
  63 
  64     // NOTE: sbd (as of at least 1.5.2) uses this value
  65     pcmk_ipc_event_disconnect,  //!< Termination of IPC connection
  66 
  67     // NOTE: sbd (as of at least 1.5.2) uses this value
  68     pcmk_ipc_event_reply,       //!< Daemon's reply to client IPC request
  69 
  70     pcmk_ipc_event_notify,      //!< Notification from daemon
  71 };
  72 
  73 //! How IPC replies should be dispatched
  74 enum pcmk_ipc_dispatch {
  75     pcmk_ipc_dispatch_main, //!< Attach IPC to GMainLoop for dispatch
  76     pcmk_ipc_dispatch_poll, //!< Caller will poll and dispatch IPC
  77     pcmk_ipc_dispatch_sync, //!< Sending a command will wait for any reply
  78 };
  79 
  80 // NOTE: sbd (as of at least 1.5.2) uses this
  81 //! Client connection to Pacemaker IPC
  82 typedef struct pcmk_ipc_api_s pcmk_ipc_api_t;
  83 
  84 /*!
  85  * \brief Callback function type for Pacemaker daemon IPC APIs
  86  *
  87  * \param[in,out] api         IPC API connection
  88  * \param[in]     event_type  The type of event that occurred
  89  * \param[in]     status      Event status
  90  * \param[in,out] event_data  Event-specific data
  91  * \param[in,out] user_data   Caller data provided when callback was registered
  92  *
  93  * \note For connection and disconnection events, event_data may be NULL (for
  94  *       local IPC) or the name of the connected node (for remote IPC, for
  95  *       daemons that support that). For reply and notify events, event_data is
  96  *       defined by the specific daemon API.
  97  */
  98 typedef void (*pcmk_ipc_callback_t)(pcmk_ipc_api_t *api,
  99                                     enum pcmk_ipc_event event_type,
 100                                     crm_exit_t status,
 101                                     void *event_data, void *user_data);
 102 
 103 // NOTE: sbd (as of at least 1.5.2) uses this
 104 int pcmk_new_ipc_api(pcmk_ipc_api_t **api, enum pcmk_ipc_server server);
 105 
 106 // NOTE: sbd (as of at least 1.5.2) uses this
 107 void pcmk_free_ipc_api(pcmk_ipc_api_t *api);
 108 
 109 // NOTE: sbd (as of at least 1.5.2) uses this
 110 int pcmk_connect_ipc(pcmk_ipc_api_t *api, enum pcmk_ipc_dispatch dispatch_type);
 111 
 112 void pcmk_disconnect_ipc(pcmk_ipc_api_t *api);
 113 
 114 int pcmk_poll_ipc(const pcmk_ipc_api_t *api, int timeout_ms);
 115 
 116 void pcmk_dispatch_ipc(pcmk_ipc_api_t *api);
 117 
 118 // NOTE: sbd (as of at least 1.5.2) uses this
 119 void pcmk_register_ipc_callback(pcmk_ipc_api_t *api, pcmk_ipc_callback_t cb,
 120                                 void *user_data);
 121 
 122 const char *pcmk_ipc_name(const pcmk_ipc_api_t *api, bool for_log);
 123 
 124 bool pcmk_ipc_is_connected(pcmk_ipc_api_t *api);
 125 
 126 int pcmk_ipc_purge_node(pcmk_ipc_api_t *api, const char *node_name,
 127                         uint32_t nodeid);
 128 
 129 
 130 /*
 131  * Generic IPC API (to eventually be deprecated as public API and made internal)
 132  */
 133 
 134 enum crm_ipc_flags
 135 {
 136     crm_ipc_flags_none              = UINT32_C(0),
 137     //! \deprecated Since 3.0.1
 138     crm_ipc_compressed              = (UINT32_C(1) << 0),
 139     //! _ALL_ replies to proxied connections need to be sent as events
 140     crm_ipc_proxied                 = (UINT32_C(1) << 8),
 141     //! A response is expected in reply
 142     crm_ipc_client_response         = (UINT32_C(1) << 9),
 143 
 144     // These are options for Pacemaker's internal use only (pcmk__ipc_send_*())
 145 
 146     //! Send an Event instead of a Response
 147     crm_ipc_server_event            = (UINT32_C(1) << 16),
 148     //! Free the iovec after sending
 149     crm_ipc_server_free             = (UINT32_C(1) << 17),
 150     //! All replies to proxied connections are sent as events.  This flag
 151     //! preserves whether the events should be treated as an Event or a Response
 152     crm_ipc_proxied_relay_response  = (UINT32_C(1) << 18),
 153     //! This is a multi-part IPC message
 154     crm_ipc_multipart               = (UINT32_C(1) << 19),
 155     //! This is the end of a multi-part IPC message
 156     crm_ipc_multipart_end           = (UINT32_C(1) << 20),
 157 };
 158 
 159 typedef struct crm_ipc_s crm_ipc_t;
 160 
 161 crm_ipc_t *crm_ipc_new(const char *name, size_t max_size);
 162 void crm_ipc_close(crm_ipc_t * client);
 163 void crm_ipc_destroy(crm_ipc_t * client);
 164 void pcmk_free_ipc_event(struct iovec *event);
 165 
 166 int crm_ipc_send(crm_ipc_t *client, const xmlNode *message,
 167                  enum crm_ipc_flags flags, int32_t ms_timeout, xmlNode **reply);
 168 
 169 int crm_ipc_get_fd(crm_ipc_t * client);
 170 bool crm_ipc_connected(crm_ipc_t * client);
 171 int crm_ipc_ready(crm_ipc_t * client);
 172 long crm_ipc_read(crm_ipc_t * client);
 173 const char *crm_ipc_buffer(crm_ipc_t * client);
 174 uint32_t crm_ipc_buffer_flags(crm_ipc_t * client);
 175 const char *crm_ipc_name(crm_ipc_t * client);
 176 unsigned int crm_ipc_default_buffer_size(void);
 177 
 178 /*!
 179  * \brief Check the authenticity of the IPC socket peer process (legacy)
 180  *
 181  * If everything goes well, peer's authenticity is verified by the means
 182  * of comparing against provided referential UID and GID (either satisfies),
 183  * and the result of this check can be deduced from the return value.
 184  * As an exception, detected UID of 0 ("root") satisfies arbitrary
 185  * provided referential daemon's credentials.
 186  *
 187  * \param[in]  sock    IPC related, connected Unix socket to check peer of
 188  * \param[in]  refuid  referential UID to check against
 189  * \param[in]  refgid  referential GID to check against
 190  * \param[out] gotpid  to optionally store obtained PID of the peer
 191  *                     (not available on FreeBSD, special value of 1
 192  *                     used instead, and the caller is required to
 193  *                     special case this value respectively)
 194  * \param[out] gotuid  to optionally store obtained UID of the peer
 195  * \param[out] gotgid  to optionally store obtained GID of the peer
 196  *
 197  * \return 0 if IPC related socket's peer is not authentic given the
 198  *         referential credentials (see above), 1 if it is,
 199  *         negative value on error (generally expressing -errno unless
 200  *         it was zero even on nonhappy path, -pcmk_err_generic is
 201  *         returned then; no message is directly emitted)
 202  *
 203  * \note While this function is tolerant on what constitutes authorized
 204  *       IPC daemon process (its effective user matches UID=0 or \p refuid,
 205  *       or at least its group matches \p refgid), either or both (in case
 206  *       of UID=0) mismatches on the expected credentials of such peer
 207  *       process \e shall be investigated at the caller when value of 1
 208  *       gets returned there, since higher-than-expected privileges in
 209  *       respect to the expected/intended credentials possibly violate
 210  *       the least privilege principle and may pose an additional risk
 211  *       (i.e. such accidental inconsistency shall be eventually fixed).
 212  */
 213 int crm_ipc_is_authentic_process(int sock, uid_t refuid, gid_t refgid,
 214                                  pid_t *gotpid, uid_t *gotuid, gid_t *gotgid);
 215 
 216 #ifdef __cplusplus
 217 }
 218 #endif
 219 
 220 #endif

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