1 /* 2 * Copyright (c) 2012 David Vossel <davidvossel@gmail.com> 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2.1 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with this library; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 * 18 */ 19 20 #ifndef LRMD__H 21 # define LRMD__H 22 23 /** 24 * \file 25 * \brief Local Resource Manager 26 * \ingroup lrmd 27 */ 28 #include <stdbool.h> 29 #include <crm/services.h> 30 31 typedef struct lrmd_s lrmd_t; 32 typedef struct lrmd_key_value_s { 33 char *key; 34 char *value; 35 struct lrmd_key_value_s *next; 36 } lrmd_key_value_t; 37 38 /* This should be bumped every time there is an incompatible change that 39 * prevents older clients from connecting to this version of the server. 40 */ 41 #define LRMD_PROTOCOL_VERSION "1.1" 42 43 /* This is the version that the client version will actually be compared 44 * against. This should be identical to LRMD_PROTOCOL_VERSION. However, we 45 * accidentally bumped LRMD_PROTOCOL_VERSION in 6424a647 (1.1.15) when we didn't 46 * need to, so for now it's different. If we ever have a truly incompatible 47 * bump, we can drop this and compare against LRMD_PROTOCOL_VERSION. 48 */ 49 #define LRMD_MIN_PROTOCOL_VERSION "1.0" 50 51 /* *INDENT-OFF* */ 52 #define DEFAULT_REMOTE_KEY_LOCATION "/etc/pacemaker/authkey" 53 #define ALT_REMOTE_KEY_LOCATION "/etc/corosync/authkey" 54 #define DEFAULT_REMOTE_PORT 3121 55 #define DEFAULT_REMOTE_USERNAME "lrmd" 56 57 #define F_LRMD_OPERATION "lrmd_op" 58 #define F_LRMD_CLIENTNAME "lrmd_clientname" 59 #define F_LRMD_IS_IPC_PROVIDER "lrmd_is_ipc_provider" 60 #define F_LRMD_CLIENTID "lrmd_clientid" 61 #define F_LRMD_PROTOCOL_VERSION "lrmd_protocol_version" 62 #define F_LRMD_REMOTE_MSG_TYPE "lrmd_remote_msg_type" 63 #define F_LRMD_REMOTE_MSG_ID "lrmd_remote_msg_id" 64 #define F_LRMD_CALLBACK_TOKEN "lrmd_async_id" 65 #define F_LRMD_CALLID "lrmd_callid" 66 #define F_LRMD_CANCEL_CALLID "lrmd_cancel_callid" 67 #define F_LRMD_CALLOPTS "lrmd_callopt" 68 #define F_LRMD_CALLDATA "lrmd_calldata" 69 #define F_LRMD_RC "lrmd_rc" 70 #define F_LRMD_EXEC_RC "lrmd_exec_rc" 71 #define F_LRMD_OP_STATUS "lrmd_exec_op_status" 72 #define F_LRMD_TIMEOUT "lrmd_timeout" 73 #define F_LRMD_WATCHDOG "lrmd_watchdog" 74 #define F_LRMD_CLASS "lrmd_class" 75 #define F_LRMD_PROVIDER "lrmd_provider" 76 #define F_LRMD_TYPE "lrmd_type" 77 #define F_LRMD_ORIGIN "lrmd_origin" 78 79 #define F_LRMD_RSC_RUN_TIME "lrmd_run_time" 80 #define F_LRMD_RSC_RCCHANGE_TIME "lrmd_rcchange_time" 81 #define F_LRMD_RSC_EXEC_TIME "lrmd_exec_time" 82 #define F_LRMD_RSC_QUEUE_TIME "lrmd_queue_time" 83 84 #define F_LRMD_RSC_ID "lrmd_rsc_id" 85 #define F_LRMD_RSC_ACTION "lrmd_rsc_action" 86 #define F_LRMD_RSC_USERDATA_STR "lrmd_rsc_userdata_str" 87 #define F_LRMD_RSC_OUTPUT "lrmd_rsc_output" 88 #define F_LRMD_RSC_EXIT_REASON "lrmd_rsc_exit_reason" 89 #define F_LRMD_RSC_START_DELAY "lrmd_rsc_start_delay" 90 #define F_LRMD_RSC_INTERVAL "lrmd_rsc_interval" 91 #define F_LRMD_RSC_METADATA "lrmd_rsc_metadata_res" 92 #define F_LRMD_RSC_DELETED "lrmd_rsc_deleted" 93 #define F_LRMD_RSC "lrmd_rsc" 94 95 #define F_LRMD_ALERT_ID "lrmd_alert_id" 96 #define F_LRMD_ALERT_PATH "lrmd_alert_path" 97 #define F_LRMD_ALERT "lrmd_alert" 98 99 #define LRMD_OP_RSC_CHK_REG "lrmd_rsc_check_register" 100 #define LRMD_OP_RSC_REG "lrmd_rsc_register" 101 #define LRMD_OP_RSC_EXEC "lrmd_rsc_exec" 102 #define LRMD_OP_RSC_CANCEL "lrmd_rsc_cancel" 103 #define LRMD_OP_RSC_UNREG "lrmd_rsc_unregister" 104 #define LRMD_OP_RSC_INFO "lrmd_rsc_info" 105 #define LRMD_OP_RSC_METADATA "lrmd_rsc_metadata" 106 #define LRMD_OP_POKE "lrmd_rsc_poke" 107 #define LRMD_OP_NEW_CLIENT "lrmd_rsc_new_client" 108 #define LRMD_OP_CHECK "lrmd_check" 109 #define LRMD_OP_ALERT_EXEC "lrmd_alert_exec" 110 111 #define LRMD_IPC_OP_NEW "new" 112 #define LRMD_IPC_OP_DESTROY "destroy" 113 #define LRMD_IPC_OP_EVENT "event" 114 #define LRMD_IPC_OP_REQUEST "request" 115 #define LRMD_IPC_OP_RESPONSE "response" 116 #define LRMD_IPC_OP_SHUTDOWN_REQ "shutdown_req" 117 #define LRMD_IPC_OP_SHUTDOWN_ACK "shutdown_ack" 118 #define LRMD_IPC_OP_SHUTDOWN_NACK "shutdown_nack" 119 120 #define F_LRMD_IPC_OP "lrmd_ipc_op" 121 #define F_LRMD_IPC_IPC_SERVER "lrmd_ipc_server" 122 #define F_LRMD_IPC_SESSION "lrmd_ipc_session" 123 #define F_LRMD_IPC_CLIENT "lrmd_ipc_client" 124 #define F_LRMD_IPC_PROXY_NODE "lrmd_ipc_proxy_node" 125 #define F_LRMD_IPC_USER "lrmd_ipc_user" 126 #define F_LRMD_IPC_MSG "lrmd_ipc_msg" 127 #define F_LRMD_IPC_MSG_ID "lrmd_ipc_msg_id" 128 #define F_LRMD_IPC_MSG_FLAGS "lrmd_ipc_msg_flags" 129 130 #define T_LRMD "lrmd" 131 #define T_LRMD_REPLY "lrmd_reply" 132 #define T_LRMD_NOTIFY "lrmd_notify" 133 #define T_LRMD_IPC_PROXY "lrmd_ipc_proxy" 134 /* *INDENT-ON* */ 135 136 /*! 137 * \brief Create a new local lrmd connection 138 */ 139 lrmd_t *lrmd_api_new(void); 140 141 /*! 142 * \brief Create a new remote lrmd connection using tls backend 143 * 144 * \param nodename name of remote node identified with this connection 145 * \param server name of server to connect to 146 * \param port port number to connect to 147 * 148 * \note nodename and server may be the same value. 149 */ 150 lrmd_t *lrmd_remote_api_new(const char *nodename, const char *server, int port); 151 152 /*! 153 * \brief Use after lrmd_poll returns 1 to read and dispatch a message 154 * 155 * \param[in,out] lrmd lrmd connection object 156 * 157 * \return TRUE if connection is still up, FALSE if disconnected 158 */ 159 bool lrmd_dispatch(lrmd_t * lrmd); 160 161 /*! 162 * \brief Poll for a specified timeout period to determine if a message 163 * is ready for dispatch. 164 * \retval 1 msg is ready 165 * \retval 0 timeout occurred 166 * \retval negative error code 167 */ 168 int lrmd_poll(lrmd_t * lrmd, int timeout); 169 170 /*! 171 * \brief Destroy lrmd object 172 */ 173 void lrmd_api_delete(lrmd_t * lrmd); 174 lrmd_key_value_t *lrmd_key_value_add(lrmd_key_value_t * kvp, const char *key, const char *value); 175 176 /* *INDENT-OFF* */ 177 /* Reserved for future use */ 178 enum lrmd_call_options { 179 lrmd_opt_none = 0x00000000, 180 /* lrmd_opt_sync_call = 0x00000001, //Not implemented, patches welcome. */ 181 /*! Only notify the client originating a exec() the results */ 182 lrmd_opt_notify_orig_only = 0x00000002, 183 /*! Drop recurring operations initiated by a client when client disconnects. 184 * This call_option is only valid when registering a resource. When used 185 * remotely with the pacemaker_remote daemon, this option means that recurring 186 * operations will be dropped once all the remote connections disconnect. */ 187 lrmd_opt_drop_recurring = 0x00000003, 188 /*! Send notifications for recurring operations only when the result changes */ 189 lrmd_opt_notify_changes_only = 0x00000004, 190 }; 191 192 enum lrmd_callback_event { 193 lrmd_event_register, 194 lrmd_event_unregister, 195 lrmd_event_exec_complete, 196 lrmd_event_disconnect, 197 lrmd_event_connect, 198 lrmd_event_poke, 199 lrmd_event_new_client, 200 }; 201 202 /* *INDENT-ON* */ 203 204 typedef struct lrmd_event_data_s { 205 /*! Type of event, register, unregister, call_completed... */ 206 enum lrmd_callback_event type; 207 208 /*! The resource this event occurred on. */ 209 const char *rsc_id; 210 /*! The action performed, start, stop, monitor... */ 211 const char *op_type; 212 /*! The userdata string given do exec() api function */ 213 const char *user_data; 214 215 /*! The client api call id associated with this event */ 216 int call_id; 217 /*! The operation's timeout period in ms. */ 218 int timeout; 219 /*! The operation's recurring interval in ms. */ 220 int interval; 221 /*! The operation's start delay value in ms. */ 222 int start_delay; 223 /*! This operation that just completed is on a deleted rsc. */ 224 int rsc_deleted; 225 226 /*! The executed ra return code mapped to OCF */ 227 enum ocf_exitcode rc; 228 /*! The lrmd status returned for exec_complete events */ 229 int op_status; 230 /*! stdout from resource agent operation */ 231 const char *output; 232 /*! Timestamp of when op ran */ 233 unsigned int t_run; 234 /*! Timestamp of last rc change */ 235 unsigned int t_rcchange; 236 /*! Time in length op took to execute */ 237 unsigned int exec_time; 238 /*! Time in length spent in queue */ 239 unsigned int queue_time; 240 241 /*! int connection result. Used for connection and poke events */ 242 int connection_rc; 243 244 /* This is a GHashTable containing the 245 * parameters given to the operation */ 246 void *params; 247 248 /*! client node name associated with this connection 249 * (used to match actions to the proper client when there are multiple) 250 */ 251 const char *remote_nodename; 252 253 /*! exit failure reason string from resource agent operation */ 254 const char *exit_reason; 255 } lrmd_event_data_t; 256 257 lrmd_event_data_t *lrmd_copy_event(lrmd_event_data_t * event); 258 void lrmd_free_event(lrmd_event_data_t * event); 259 260 typedef struct lrmd_rsc_info_s { 261 char *id; 262 char *type; 263 char *class; 264 char *provider; 265 } lrmd_rsc_info_t; 266 267 lrmd_rsc_info_t *lrmd_copy_rsc_info(lrmd_rsc_info_t * rsc_info); 268 void lrmd_free_rsc_info(lrmd_rsc_info_t * rsc_info); 269 270 typedef void (*lrmd_event_callback) (lrmd_event_data_t * event); 271 272 typedef struct lrmd_list_s { 273 const char *val; 274 struct lrmd_list_s *next; 275 } lrmd_list_t; 276 277 void lrmd_list_freeall(lrmd_list_t * head); 278 void lrmd_key_value_freeall(lrmd_key_value_t * head); 279 280 typedef struct lrmd_api_operations_s { 281 /*! 282 * \brief Connect from the lrmd. 283 * 284 * \retval 0, success 285 * \retval negative error code on failure 286 */ 287 int (*connect) (lrmd_t * lrmd, const char *client_name, int *fd); 288 289 /*! 290 * \brief Establish an connection to lrmd, don't block while connecting. 291 * \note this function requires the use of mainloop. 292 * 293 * \note The is returned using the event callback. 294 * \note When this function returns 0, the callback will be invoked 295 * to report the final result of the connect. 296 * \retval 0, connect in progress, wait for event callback 297 * \retval -1, failure. 298 */ 299 int (*connect_async) (lrmd_t * lrmd, const char *client_name, int timeout /*ms */ ); 300 301 /*! 302 * \brief Is connected to lrmd daemon? 303 * 304 * \retval 0, false 305 * \retval 1, true 306 */ 307 int (*is_connected) (lrmd_t * lrmd); 308 309 /*! 310 * \brief Poke lrmd connection to verify it is still capable of serving requests 311 * \note The response comes in the form of a poke event to the callback. 312 * 313 * \retval 0, wait for response in callback 314 * \retval -1, connection failure, callback may not be invoked 315 */ 316 int (*poke_connection) (lrmd_t * lrmd); 317 318 /*! 319 * \brief Disconnect from the lrmd. 320 * 321 * \retval 0, success 322 * \retval negative error code on failure 323 */ 324 int (*disconnect) (lrmd_t * lrmd); 325 326 /*! 327 * \brief Register a resource with the lrmd. 328 * 329 * \note Synchronous, guaranteed to occur in daemon before function returns. 330 * 331 * \retval 0, success 332 * \retval negative error code on failure 333 */ 334 int (*register_rsc) (lrmd_t * lrmd, 335 const char *rsc_id, 336 const char *class, 337 const char *provider, const char *agent, enum lrmd_call_options options); 338 339 /*! 340 * \brief Retrieve registration info for a rsc 341 * 342 * \retval info on success 343 * \retval NULL on failure 344 */ 345 lrmd_rsc_info_t *(*get_rsc_info) (lrmd_t * lrmd, 346 const char *rsc_id, enum lrmd_call_options options); 347 348 /*! 349 * \brief Unregister a resource from the lrmd. 350 * 351 * \note All pending and recurring operations will be cancelled 352 * automatically. 353 * 354 * \note Synchronous, guaranteed to occur in daemon before function returns. 355 * 356 * \retval 0, success 357 * \retval -1, success, but operations are currently executing on the rsc which will 358 * return once they are completed. 359 * \retval negative error code on failure 360 * 361 */ 362 int (*unregister_rsc) (lrmd_t * lrmd, const char *rsc_id, enum lrmd_call_options options); 363 364 /*! 365 * \brief Sets the callback to receive lrmd events on. 366 */ 367 void (*set_callback) (lrmd_t * lrmd, lrmd_event_callback callback); 368 369 /*! 370 * \brief Issue a command on a resource 371 * 372 * \note Asynchronous, command is queued in daemon on function return, but 373 * execution of command is not synced. 374 * 375 * \note Operations on individual resources are guaranteed to occur 376 * in the order the client api calls them in. 377 * 378 * \note Operations between different resources are not guaranteed 379 * to occur in any specific order in relation to one another 380 * regardless of what order the client api is called in. 381 * \retval call_id to track async event result on success 382 * \retval negative error code on failure 383 */ 384 int (*exec) (lrmd_t * lrmd, const char *rsc_id, const char *action, const char *userdata, /* userdata string given back in event notification */ 385 int interval, /* ms */ 386 int timeout, /* ms */ 387 int start_delay, /* ms */ 388 enum lrmd_call_options options, lrmd_key_value_t * params); /* ownership of params is given up to api here */ 389 390 /*! 391 * \brief Cancel a recurring command. 392 * 393 * \note Synchronous, guaranteed to occur in daemon before function returns. 394 * 395 * \note The cancel is completed async from this call. 396 * We can be guaranteed the cancel has completed once 397 * the callback receives an exec_complete event with 398 * the lrmd_op_status signifying that the operation is 399 * cancelled. 400 * \note For each resource, cancel operations and exec operations 401 * are processed in the order they are received. 402 * It is safe to assume that for a single resource, a cancel 403 * will occur in the lrmd before an exec if the client's cancel 404 * api call occurs before the exec api call. 405 * 406 * It is not however safe to assume any operation on one resource will 407 * occur before an operation on another resource regardless of 408 * the order the client api is called in. 409 * 410 * \retval 0, cancel command sent. 411 * \retval negative error code on failure 412 */ 413 int (*cancel) (lrmd_t * lrmd, const char *rsc_id, const char *action, int interval); 414 415 /*! 416 * \brief Get resource metadata for a specified resource agent 417 * 418 * \param[in] lrmd LRMD connection (unused) 419 * \param[in] class Resource agent class 420 * \param[in] provider Resource agent provider 421 * \param[in] agent Resource agent type 422 * \param[out] output Metadata will be stored here (must not be NULL) 423 * \param[in] options Options to use with any LRMD API calls (unused) 424 * 425 * \note Caller is responsible for freeing output. This call is currently 426 * always synchronous (blocking), and always done directly by the 427 * library (not via the LRMD connection). This means that it is based 428 * on the local host environment, even if the lrmd connection is to a 429 * remote node, so (for most resource agent classes) this will fail if 430 * the agent is not installed locally. This also means that, if an 431 * external agent must be executed, it will be executed by the 432 * caller's user, not the lrmd's. 433 * \todo Add a metadata call to the LRMD API and let the server handle this. 434 * 435 * \retval lrmd_ok success 436 * \retval negative error code on failure 437 */ 438 int (*get_metadata) (lrmd_t * lrmd, 439 const char *class, 440 const char *provider, 441 const char *agent, char **output, enum lrmd_call_options options); 442 443 /*! 444 * \brief Retrieve a list of installed resource agents. 445 * 446 * \note if class is not provided, all known agents will be returned 447 * \note list must be freed using lrmd_list_freeall() 448 * 449 * \retval num items in list on success 450 * \retval negative error code on failure 451 */ 452 int (*list_agents) (lrmd_t * lrmd, lrmd_list_t ** agents, const char *class, 453 const char *provider); 454 455 /*! 456 * \brief Retrieve a list of resource agent providers 457 * 458 * \note When the agent is provided, only the agent's provider will be returned 459 * \note When no agent is supplied, all providers will be returned. 460 * \note List must be freed using lrmd_list_freeall() 461 * 462 * \retval num items in list on success 463 * \retval negative error code on failure 464 */ 465 int (*list_ocf_providers) (lrmd_t * lrmd, const char *agent, lrmd_list_t ** providers); 466 467 /*! 468 * \brief Retrieve a list of standards supported by this machine/installation 469 * 470 * \note List must be freed using lrmd_list_freeall() 471 * 472 * \retval num items in list on success 473 * \retval negative error code on failure 474 */ 475 int (*list_standards) (lrmd_t * lrmd, lrmd_list_t ** standards); 476 477 /*! 478 * \brief Execute an alert agent 479 * 480 * \note Asynchronous, command is queued in daemon on function return, but 481 * execution of command is not synced. 482 * 483 * \note Operations on individual alerts are guaranteed to occur 484 * in the order the client api calls them in. 485 * 486 * \note Operations between different alerts are not guaranteed 487 * to occur in any specific order in relation to one another 488 * regardless of what order the client api is called in. 489 * \retval call_id to track async event result on success 490 * \retval negative error code on failure 491 */ 492 int (*exec_alert) (lrmd_t *lrmd, const char *alert_id, 493 const char *alert_path, int timeout, /* ms */ 494 lrmd_key_value_t *params); /* ownership of params is given up to api here */ 495 496 } lrmd_api_operations_t; 497 498 struct lrmd_s { 499 lrmd_api_operations_t *cmds; 500 void *private; 501 }; 502 503 static inline const char * 504 lrmd_event_type2str(enum lrmd_callback_event type) /* */ 505 { 506 switch (type) { 507 case lrmd_event_register: 508 return "register"; 509 case lrmd_event_unregister: 510 return "unregister"; 511 case lrmd_event_exec_complete: 512 return "exec_complete"; 513 case lrmd_event_disconnect: 514 return "disconnect"; 515 case lrmd_event_connect: 516 return "connect"; 517 case lrmd_event_poke: 518 return "poke"; 519 case lrmd_event_new_client: 520 return "new_client"; 521 } 522 return "unknown"; 523 } 524 525 #endif