diff --git a/include/crm/Makefile.am b/include/crm/Makefile.am index ec2752f433..47fd80966a 100644 --- a/include/crm/Makefile.am +++ b/include/crm/Makefile.am @@ -1,34 +1,32 @@ # # Copyright 2004-2024 the Pacemaker project contributors # # The version control history for this file may have further details. # # This source code is licensed under the GNU General Public License version 2 # or later (GPLv2+) WITHOUT ANY WARRANTY. # MAINTAINERCLEANFILES = Makefile.in headerdir=$(pkgincludedir)/crm header_HEADERS = cib.h \ cib_compat.h \ cluster.h \ crm.h \ crm_compat.h \ lrmd.h \ - lrmd_compat.h \ lrmd_events.h \ msg_xml.h \ msg_xml_compat.h \ services.h \ - services_compat.h \ stonith-ng.h noinst_HEADERS = $(wildcard *_internal.h) SUBDIRS = common \ pengine \ cib \ fencing \ cluster diff --git a/include/crm/lrmd.h b/include/crm/lrmd.h index 9b3f698635..3d9b9c052a 100644 --- a/include/crm/lrmd.h +++ b/include/crm/lrmd.h @@ -1,525 +1,521 @@ /* * Copyright 2012-2024 the Pacemaker project contributors * * The version control history for this file may have further details. * * This source code is licensed under the GNU Lesser General Public License * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY. */ #ifndef PCMK__CRM_LRMD__H # define PCMK__CRM_LRMD__H #include // bool #include // guint, GList #include #include #include #ifdef __cplusplus extern "C" { #endif /** * \file * \brief Resource agent executor * \ingroup lrmd */ typedef struct lrmd_s lrmd_t; typedef struct lrmd_key_value_s { char *key; char *value; struct lrmd_key_value_s *next; } lrmd_key_value_t; /* The major version should be bumped every time there is an incompatible * change that prevents older clients from connecting to this version of * the server. The minor version indicates feature support. * * Protocol Pacemaker Significant changes * -------- --------- ------------------- * 1.2 2.1.8 PCMK__CIB_REQUEST_SCHEMAS */ #define LRMD_PROTOCOL_VERSION "1.2" #define LRMD_SUPPORTS_SCHEMA_XFER(x) (compare_version((x), "1.2") >= 0) /* The major protocol version the client and server both need to support for * the connection to be successful. This should only ever be the major * version - not a complete version number. */ #define LRMD_COMPATIBLE_PROTOCOL "1" /* \deprecated Do not use (will be removed in a future release) * * This is the version that the client version will actually be compared * against. This should be identical to LRMD_PROTOCOL_VERSION. However, we * accidentally bumped LRMD_PROTOCOL_VERSION in 6424a647 (1.1.15) when we didn't * need to, so for now it's different. If we ever have a truly incompatible * bump, we can drop this and compare against LRMD_PROTOCOL_VERSION. */ #define LRMD_MIN_PROTOCOL_VERSION "1.0" /* *INDENT-OFF* */ #define DEFAULT_REMOTE_KEY_LOCATION PACEMAKER_CONFIG_DIR "/authkey" #define ALT_REMOTE_KEY_LOCATION "/etc/corosync/authkey" #define DEFAULT_REMOTE_PORT 3121 #define DEFAULT_REMOTE_USERNAME "lrmd" #define LRMD_OP_RSC_REG "lrmd_rsc_register" #define LRMD_OP_RSC_EXEC "lrmd_rsc_exec" #define LRMD_OP_RSC_CANCEL "lrmd_rsc_cancel" #define LRMD_OP_RSC_UNREG "lrmd_rsc_unregister" #define LRMD_OP_RSC_INFO "lrmd_rsc_info" #define LRMD_OP_RSC_METADATA "lrmd_rsc_metadata" #define LRMD_OP_POKE "lrmd_rsc_poke" #define LRMD_OP_NEW_CLIENT "lrmd_rsc_new_client" #define LRMD_OP_CHECK "lrmd_check" #define LRMD_OP_ALERT_EXEC "lrmd_alert_exec" #define LRMD_OP_GET_RECURRING "lrmd_get_recurring" #define LRMD_IPC_OP_NEW "new" #define LRMD_IPC_OP_DESTROY "destroy" #define LRMD_IPC_OP_EVENT "event" #define LRMD_IPC_OP_REQUEST "request" #define LRMD_IPC_OP_RESPONSE "response" #define LRMD_IPC_OP_SHUTDOWN_REQ "shutdown_req" #define LRMD_IPC_OP_SHUTDOWN_ACK "shutdown_ack" #define LRMD_IPC_OP_SHUTDOWN_NACK "shutdown_nack" /* *INDENT-ON* */ /*! * \brief Create a new connection to the local executor */ lrmd_t *lrmd_api_new(void); /*! * \brief Create a new TLS connection to a remote executor * * \param[in] nodename Name of remote node identified with this connection * \param[in] server Hostname to connect to * \param[in] port Port number to connect to (or 0 to use default) * * \return Newly created executor connection object * \note If only one of \p nodename and \p server is non-NULL, it will be used * for both purposes. If both are NULL, a local IPC connection will be * created instead. */ lrmd_t *lrmd_remote_api_new(const char *nodename, const char *server, int port); /*! * \brief Use after lrmd_poll returns 1 to read and dispatch a message * * \param[in,out] lrmd Executor connection object * * \return TRUE if connection is still up, FALSE if disconnected */ bool lrmd_dispatch(lrmd_t *lrmd); /*! * \brief Check whether a message is available on an executor connection * * \param[in,out] lrmd Executor connection object to check * \param[in] timeout Currently ignored * * \retval 1 Message is ready * \retval 0 Timeout occurred * \retval negative errno Error occurred * * \note This is intended for callers that do not use a main loop. */ int lrmd_poll(lrmd_t *lrmd, int timeout); /*! * \brief Destroy executor connection object * * \param[in,out] lrmd Executor connection object to destroy */ void lrmd_api_delete(lrmd_t *lrmd); lrmd_key_value_t *lrmd_key_value_add(lrmd_key_value_t * kvp, const char *key, const char *value); enum lrmd_call_options { lrmd_opt_none = 0, //! Notify only the client that made the request (rather than all clients) lrmd_opt_notify_orig_only = (1 << 1), /*! * Drop recurring operations initiated by a client when the client * disconnects. This option is only valid when registering a resource. When * used with a connection to a remote executor, recurring operations will be * dropped once all remote connections disconnect. * * @COMPAT This is broken, because these values should be unique bits, and * this value overlaps lrmd_opt_notify_orig_only (0x02). The impact is low * since this value is used only with registration requests and the other * one is used only with execution requests. Regardless, when we can break * API compatibility, this should be changed to (1 << 0) or (1 << 3). */ lrmd_opt_drop_recurring = 0x00000003, //! Send notifications for recurring operations only when the result changes lrmd_opt_notify_changes_only = (1 << 2), }; typedef struct lrmd_rsc_info_s { char *id; char *type; char *standard; char *provider; } lrmd_rsc_info_t; typedef struct lrmd_op_info_s { char *rsc_id; char *action; char *interval_ms_s; char *timeout_ms_s; } lrmd_op_info_t; lrmd_rsc_info_t *lrmd_new_rsc_info(const char *rsc_id, const char *standard, const char *provider, const char *type); lrmd_rsc_info_t *lrmd_copy_rsc_info(lrmd_rsc_info_t * rsc_info); void lrmd_free_rsc_info(lrmd_rsc_info_t * rsc_info); void lrmd_free_op_info(lrmd_op_info_t *op_info); typedef void (*lrmd_event_callback) (lrmd_event_data_t * event); typedef struct lrmd_list_s { const char *val; struct lrmd_list_s *next; } lrmd_list_t; void lrmd_list_freeall(lrmd_list_t * head); void lrmd_key_value_freeall(lrmd_key_value_t * head); typedef struct lrmd_api_operations_s { /*! * \brief Connect to an executor * * \param[in,out] lrmd Executor connection object * \param[in] client_name Arbitrary identifier to pass to server * \param[out] fd If not NULL, where to store file descriptor * for connection's socket * * \return Legacy Pacemaker return code */ int (*connect) (lrmd_t *lrmd, const char *client_name, int *fd); /*! * \brief Initiate an executor connection without blocking * * \param[in,out] lrmd Executor connection object * \param[in] client_name Arbitrary identifier to pass to server * \param[in] timeout Error if not connected within this time * (milliseconds) * * \return Legacy Pacemaker return code (if pcmk_ok, the event callback will * be called later with the result) * \note This function requires a mainloop. */ int (*connect_async) (lrmd_t *lrmd, const char *client_name, int timeout /*ms */ ); /*! * \brief Check whether connection to executor daemon is (still) active * * \param[in,out] lrmd Executor connection object to check * * \return 1 if the executor connection is active, 0 otherwise */ int (*is_connected) (lrmd_t *lrmd); /*! * \brief Poke executor connection to verify it is still active * * \param[in,out] lrmd Executor connection object to check * * \return Legacy Pacemaker return code (if pcmk_ok, the event callback will * be called later with the result) * \note The response comes in the form of a poke event to the callback. * */ int (*poke_connection) (lrmd_t *lrmd); /*! * \brief Disconnect from the executor. * * \param[in,out] lrmd Executor connection object to disconnect * * \return Legacy Pacemaker return code */ int (*disconnect) (lrmd_t *lrmd); /*! * \brief Register a resource with the executor * * \param[in,out] lrmd Executor connection object * \param[in] rsc_id ID of resource to register * \param[in] standard Resource's resource agent standard * \param[in] provider Resource's resource agent provider (or NULL) * \param[in] agent Resource's resource agent name * \param[in] options Group of enum lrmd_call_options flags * * \note Synchronous, guaranteed to occur in daemon before function returns. * * \return Legacy Pacemaker return code */ int (*register_rsc) (lrmd_t *lrmd, const char *rsc_id, const char *standard, const char *provider, const char *agent, enum lrmd_call_options options); /*! * \brief Retrieve a resource's registration information * * \param[in,out] lrmd Executor connection object * \param[in] rsc_id ID of resource to check * \param[in] options Group of enum lrmd_call_options flags * * \return Resource information on success, otherwise NULL */ lrmd_rsc_info_t *(*get_rsc_info) (lrmd_t *lrmd, const char *rsc_id, enum lrmd_call_options options); /*! * \brief Retrieve recurring operations registered for a resource * * \param[in,out] lrmd Executor connection object * \param[in] rsc_id ID of resource to check * \param[in] timeout_ms Error if not completed within this time * \param[in] options Group of enum lrmd_call_options flags * \param[out] output Where to store list of lrmd_op_info_t * * \return Legacy Pacemaker return code */ int (*get_recurring_ops) (lrmd_t *lrmd, const char *rsc_id, int timeout_ms, enum lrmd_call_options options, GList **output); /*! * \brief Unregister a resource from the executor * * \param[in,out] lrmd Executor connection object * \param[in] rsc_id ID of resource to unregister * \param[in] options Group of enum lrmd_call_options flags * * \return Legacy Pacemaker return code (of particular interest, EINPROGRESS * means that operations are in progress for the resource, and the * unregistration will be done when they complete) * \note Pending and recurring operations will be cancelled. * \note Synchronous, guaranteed to occur in daemon before function returns. * */ int (*unregister_rsc) (lrmd_t *lrmd, const char *rsc_id, enum lrmd_call_options options); /*! * \brief Set a callback for executor events * * \param[in,out] lrmd Executor connection object * \param[in] callback Callback to set */ void (*set_callback) (lrmd_t *lrmd, lrmd_event_callback callback); /*! * \brief Request execution of a resource action * * \param[in,out] lrmd Executor connection object * \param[in] rsc_id ID of resource * \param[in] action Name of resource action to execute * \param[in] userdata Arbitrary string to pass to event callback * \param[in] interval_ms If 0, execute action once, otherwise * recurring at this interval (in milliseconds) * \param[in] timeout Error if not complete within this time (in * milliseconds) * \param[in] start_delay Wait this long before execution (in * milliseconds) * \param[in] options Group of enum lrmd_call_options flags * \param[in,out] params Parameters to pass to agent (will be freed) * * \return A call ID for the action on success (in which case the action is * queued in the executor, and the event callback will be called * later with the result), otherwise a negative legacy Pacemaker * return code * \note exec() and cancel() operations on an individual resource are * guaranteed to occur in the order the client API is called. However, * operations on different resources are not guaranteed to occur in * any specific order. */ int (*exec) (lrmd_t *lrmd, const char *rsc_id, const char *action, const char *userdata, guint interval_ms, int timeout, int start_delay, enum lrmd_call_options options, lrmd_key_value_t *params); /*! * \brief Cancel a recurring resource action * * \param[in,out] lrmd Executor connection object * \param[in] rsc_id ID of resource * \param[in] action Name of resource action to cancel * \param[in] interval_ms Action's interval (in milliseconds) * * \return Legacy Pacemaker return code (if pcmk_ok, cancellation is queued * on function return, and the event callback will be called later * with an exec_complete event with an lrmd_op_status signifying * that the operation is cancelled) * * \note exec() and cancel() operations on an individual resource are * guaranteed to occur in the order the client API is called. However, * operations on different resources are not guaranteed to occur in * any specific order. */ int (*cancel) (lrmd_t *lrmd, const char *rsc_id, const char *action, guint interval_ms); /*! * \brief Retrieve resource agent metadata synchronously * * \param[in] lrmd Executor connection (unused) * \param[in] standard Resource agent class * \param[in] provider Resource agent provider * \param[in] agent Resource agent type * \param[out] output Where to store metadata (must not be NULL) * \param[in] options Group of enum lrmd_call_options flags (unused) * * \return Legacy Pacemaker return code * * \note Caller is responsible for freeing output. This call is always * synchronous (blocking), and always done directly by the library * (not via the executor connection). This means that it is based on * the local host environment, even if the executor connection is to a * remote node, so this may fail if the agent is not installed * locally. This also means that, if an external agent must be * executed, it will be executed by the caller's user, not the * executor's. */ int (*get_metadata) (lrmd_t *lrmd, const char *standard, const char *provider, const char *agent, char **output, enum lrmd_call_options options); /*! * \brief Retrieve a list of installed resource agents * * \param[in] lrmd Executor connection (unused) * \param[out] agents Where to store agent list (must not be NULL) * \param[in] standard Resource agent standard to list * \param[in] provider Resource agent provider to list (or NULL) * * \return Number of items in list on success, negative legacy Pacemaker * return code otherwise * * \note if standard is not provided, all known agents will be returned * \note list must be freed using lrmd_list_freeall() */ int (*list_agents) (lrmd_t *lrmd, lrmd_list_t **agents, const char *standard, const char *provider); /*! * \brief Retrieve a list of resource agent providers * * \param[in] lrmd Executor connection (unused) * \param[in] agent If not NULL, list providers for this agent only * \param[out] providers Where to store provider list * * \return Number of items in list on success, negative legacy Pacemaker * return code otherwise * \note The caller is responsible for freeing *providers with * lrmd_list_freeall(). */ int (*list_ocf_providers) (lrmd_t *lrmd, const char *agent, lrmd_list_t **providers); /*! * \brief Retrieve a list of supported standards * * \param[in] lrmd Executor connection (unused) * \param[out] standards Where to store standards list * * \return Number of items in list on success, negative legacy Pacemaker * return code otherwise * \note The caller is responsible for freeing *standards with * lrmd_list_freeall(). */ int (*list_standards) (lrmd_t *lrmd, lrmd_list_t **standards); /*! * \brief Execute an alert agent * * \param[in,out] lrmd Executor connection * \param[in] alert_id Name of alert to execute * \param[in] alert_path Full path to alert executable * \param[in] timeout Error if not complete within this many * milliseconds * \param[in,out] params Parameters to pass to agent (will be freed) * * \return Legacy Pacemaker return code (if pcmk_ok, the alert is queued in * the executor, and the event callback will be called later with * the result) * * \note Operations on individual alerts (by ID) are guaranteed to occur in * the order the client API is called. Operations on different alerts * are not guaranteed to occur in any specific order. */ int (*exec_alert) (lrmd_t *lrmd, const char *alert_id, const char *alert_path, int timeout, lrmd_key_value_t *params); /*! * \brief Retrieve resource agent metadata synchronously with parameters * * \param[in] lrmd Executor connection (unused) * \param[in] standard Resource agent class * \param[in] provider Resource agent provider * \param[in] agent Resource agent type * \param[out] output Where to store metadata (must not be NULL) * \param[in] options Group of enum lrmd_call_options flags (unused) * \param[in,out] params Parameters to pass to agent (will be freed) * * \return Legacy Pacemaker return code * * \note This is identical to the get_metadata() API call, except parameters * will be passed to the resource agent via environment variables. */ int (*get_metadata_params) (lrmd_t *lrmd, const char *standard, const char *provider, const char *agent, char **output, enum lrmd_call_options options, lrmd_key_value_t *params); } lrmd_api_operations_t; struct lrmd_s { lrmd_api_operations_t *cmds; void *lrmd_private; }; static inline const char * lrmd_event_type2str(enum lrmd_callback_event type) { switch (type) { case lrmd_event_register: return "register"; case lrmd_event_unregister: return "unregister"; case lrmd_event_exec_complete: return "exec_complete"; case lrmd_event_disconnect: return "disconnect"; case lrmd_event_connect: return "connect"; case lrmd_event_poke: return "poke"; case lrmd_event_new_client: return "new_client"; } return "unknown"; } -#if !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1) -#include -#endif - #ifdef __cplusplus } #endif #endif diff --git a/include/crm/lrmd_compat.h b/include/crm/lrmd_compat.h deleted file mode 100644 index 98461e0968..0000000000 --- a/include/crm/lrmd_compat.h +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright 2012-2024 the Pacemaker project contributors - * - * The version control history for this file may have further details. - * - * This source code is licensed under the GNU Lesser General Public License - * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY. - */ - -#ifndef PCMK__CRM_LRMD_COMPAT__H -# define PCMK__CRM_LRMD_COMPAT__H - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \file - * \brief Deprecated executor utilities - * \ingroup core - * \deprecated Do not include this header directly. The utilities in this - * header, and the header itself, will be removed in a future - * release. - */ - -//! \deprecated Do not use -#define F_LRMD_OPERATION "lrmd_op" - -//! \deprecated Do not use -#define F_LRMD_CLIENTNAME "lrmd_clientname" - -//! \deprecated Do not use -#define F_LRMD_CALLBACK_TOKEN "lrmd_async_id" - -//! \deprecated Do not use -#define F_LRMD_IS_IPC_PROVIDER "lrmd_is_ipc_provider" - -//! \deprecated Do not use -#define F_LRMD_CLIENTID "lrmd_clientid" - -//! \deprecated Do not use -#define F_LRMD_PROTOCOL_VERSION "lrmd_protocol_version" - -//! \deprecated Do not use -#define F_LRMD_REMOTE_MSG_TYPE "lrmd_remote_msg_type" - -//! \deprecated Do not use -#define F_LRMD_REMOTE_MSG_ID "lrmd_remote_msg_id" - -//! \deprecated Do not use -#define F_LRMD_CALLID "lrmd_callid" - -//! \deprecated Do not use -#define F_LRMD_CALLOPTS "lrmd_callopt" - -//! \deprecated Do not use -#define F_LRMD_CALLDATA "lrmd_calldata" - -//! \deprecated Do not use -#define F_LRMD_RC "lrmd_rc" - -//! \deprecated Do not use -#define F_LRMD_EXEC_RC "lrmd_exec_rc" - -//! \deprecated Do not use -#define F_LRMD_OP_STATUS "lrmd_exec_op_status" - -//! \deprecated Do not use -#define F_LRMD_TIMEOUT "lrmd_timeout" - -//! \deprecated Do not use -#define F_LRMD_WATCHDOG "lrmd_watchdog" - -//! \deprecated Do not use -#define F_LRMD_CLASS "lrmd_class" - -//! \deprecated Do not use -#define F_LRMD_PROVIDER "lrmd_provider" - -//! \deprecated Do not use -#define F_LRMD_TYPE "lrmd_type" - -//! \deprecated Do not use -#define F_LRMD_ORIGIN "lrmd_origin" - -//! \deprecated Do not use -#define F_LRMD_RSC_RUN_TIME "lrmd_run_time" - -//! \deprecated Do not use -#define F_LRMD_RSC_RCCHANGE_TIME "lrmd_rcchange_time" - -//! \deprecated Do not use -#define F_LRMD_RSC_EXEC_TIME "lrmd_exec_time" - -//! \deprecated Do not use -#define F_LRMD_RSC_QUEUE_TIME "lrmd_queue_time" - -//! \deprecated Do not use -#define F_LRMD_RSC_ID "lrmd_rsc_id" - -//! \deprecated Do not use -#define F_LRMD_RSC_ACTION "lrmd_rsc_action" - -//! \deprecated Do not use -#define F_LRMD_RSC_USERDATA_STR "lrmd_rsc_userdata_str" - -//! \deprecated Do not use -#define F_LRMD_RSC_OUTPUT "lrmd_rsc_output" - -//! \deprecated Do not use -#define F_LRMD_RSC_EXIT_REASON "lrmd_rsc_exit_reason" - -//! \deprecated Do not use -#define F_LRMD_RSC_START_DELAY "lrmd_rsc_start_delay" - -//! \deprecated Do not use -#define F_LRMD_RSC_INTERVAL "lrmd_rsc_interval" - -//! \deprecated Do not use -#define F_LRMD_RSC_DELETED "lrmd_rsc_deleted" - -//! \deprecated Do not use -#define F_LRMD_RSC "lrmd_rsc" - -//! \deprecated Do not use -#define F_LRMD_ALERT_ID "lrmd_alert_id" - -//! \deprecated Do not use -#define F_LRMD_ALERT_PATH "lrmd_alert_path" - -//! \deprecated Do not use -#define F_LRMD_ALERT "lrmd_alert" - -//! \deprecated Do not use -#define F_LRMD_IPC_OP "lrmd_ipc_op" - -//! \deprecated Do not use -#define F_LRMD_IPC_IPC_SERVER "lrmd_ipc_server" - -//! \deprecated Do not use -#define F_LRMD_IPC_SESSION "lrmd_ipc_session" - -//! \deprecated Do not use -#define F_LRMD_IPC_CLIENT "lrmd_ipc_client" - -//! \deprecated Do not use -#define F_LRMD_IPC_USER "lrmd_ipc_user" - -//! \deprecated Do not use -#define F_LRMD_IPC_MSG "lrmd_ipc_msg" - -//! \deprecated Do not use -#define F_LRMD_IPC_MSG_ID "lrmd_ipc_msg_id" - -//! \deprecated Do not use -#define F_LRMD_IPC_MSG_FLAGS "lrmd_ipc_msg_flags" - -//! \deprecated Do not use -#define T_LRMD "lrmd" - -//! \deprecated Do not use -#define T_LRMD_REPLY "lrmd_reply" - -//! \deprecated Do not use -#define T_LRMD_NOTIFY "lrmd_notify" - -//! \deprecated Do not use -#define T_LRMD_IPC_PROXY "lrmd_ipc_proxy" - -//! \deprecated Do not use -#define T_LRMD_RSC_OP "lrmd_rsc_op" - -#ifdef __cplusplus -} -#endif - -#endif // PCMK__CRM_LRMD_COMPAT__H diff --git a/include/crm/services.h b/include/crm/services.h index 3e66eb07dd..c14a0c176c 100644 --- a/include/crm/services.h +++ b/include/crm/services.h @@ -1,437 +1,433 @@ /* * Copyright 2010-2024 the Pacemaker project contributors * * The version control history for this file may have further details. * * This source code is licensed under the GNU Lesser General Public License * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY. */ #ifndef PCMK__CRM_SERVICES__H # define PCMK__CRM_SERVICES__H # include # include # include # include # include # include # include // OCF_ROOT_DIR # include # include #ifdef __cplusplus extern "C" { #endif // NOTE: booth (as of at least 1.1) checks for the existence of this header /*! * \file * \brief Services API * \ingroup core */ /* TODO: Autodetect these two ?*/ # ifndef SYSTEMCTL # define SYSTEMCTL "/bin/systemctl" # endif /* This is the string passed in the OCF_EXIT_REASON_PREFIX environment variable. * The stderr output that occurs after this prefix is encountered is considered * the exit reason for a completed operation. */ #define PCMK_OCF_REASON_PREFIX "ocf-exit-reason:" // Agent version to use if agent doesn't specify one #define PCMK_DEFAULT_AGENT_VERSION "0.1" enum lsb_exitcode { PCMK_LSB_OK = 0, // NOTE: booth (as of at least 1.1) uses this value PCMK_LSB_UNKNOWN_ERROR = 1, PCMK_LSB_INVALID_PARAM = 2, PCMK_LSB_UNIMPLEMENT_FEATURE = 3, PCMK_LSB_INSUFFICIENT_PRIV = 4, PCMK_LSB_NOT_INSTALLED = 5, PCMK_LSB_NOT_CONFIGURED = 6, PCMK_LSB_NOT_RUNNING = 7, }; // LSB uses different return codes for status actions enum lsb_status_exitcode { PCMK_LSB_STATUS_OK = 0, PCMK_LSB_STATUS_VAR_PID = 1, PCMK_LSB_STATUS_VAR_LOCK = 2, PCMK_LSB_STATUS_NOT_RUNNING = 3, PCMK_LSB_STATUS_UNKNOWN = 4, /* custom codes should be in the 150-199 range reserved for application use */ PCMK_LSB_STATUS_NOT_INSTALLED = 150, PCMK_LSB_STATUS_INSUFFICIENT_PRIV = 151, }; //!@{ //! \deprecated Do not use enum nagios_exitcode { NAGIOS_STATE_OK = 0, NAGIOS_STATE_WARNING = 1, NAGIOS_STATE_CRITICAL = 2, NAGIOS_STATE_UNKNOWN = 3, /* This is a custom Pacemaker value (not a nagios convention), used as an * intermediate value between the services library and the executor, so the * executor can map it to the corresponding OCF code. */ NAGIOS_INSUFFICIENT_PRIV = 100, #if !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1) NAGIOS_STATE_DEPENDENT = 4, NAGIOS_NOT_INSTALLED = 101, #endif }; //!@} enum svc_action_flags { /* On timeout, only kill pid, do not kill entire pid group */ SVC_ACTION_LEAVE_GROUP = 0x01, SVC_ACTION_NON_BLOCKED = 0x02, }; typedef struct svc_action_private_s svc_action_private_t; /*! * \brief Object for executing external actions * * \note This object should never be instantiated directly, but instead created * using one of the constructor functions (resources_action_create() for * resource agents, services_alert_create() for alert agents, or * services_action_create_generic() for generic executables). Similarly, * do not use sizeof() on this struct. */ /* * NOTE: Internally, services__create_resource_action() is preferable to * resources_action_create(). */ typedef struct svc_action_s { /*! Operation key (__) for resource actions, * XML ID for alert actions, or NULL for generic actions */ char *id; //! XML ID of resource being executed for resource actions, otherwise NULL char *rsc; //! Name of action being executed for resource actions, otherwise NULL char *action; //! Action interval for recurring resource actions, otherwise 0 guint interval_ms; //! Resource standard for resource actions, otherwise NULL char *standard; //! Resource provider for resource actions that require it, otherwise NULL char *provider; //! Resource agent name for resource actions, otherwise NULL char *agent; int timeout; //!< Action timeout (in milliseconds) /*! A hash table of name/value pairs to use as parameters for resource and * alert actions, otherwise NULL. These will be used to set environment * variables for non-fencing resource agents and alert agents, and to send * stdin to fence agents. */ GHashTable *params; int rc; //!< Exit status of action (set by library upon completion) //!@{ //! This field should be treated as internal to Pacemaker int pid; // Process ID of child int cancel; // Whether this is a cancellation of a recurring action //!@} int status; //!< Execution status (enum pcmk_exec_status set by library) /*! Action counter (set by library for resource actions, or by caller * otherwise) */ int sequence; //!@{ //! This field should be treated as internal to Pacemaker int expected_rc; // Unused int synchronous; // Whether execution should be synchronous (blocking) //!@} enum svc_action_flags flags; //!< Flag group of enum svc_action_flags char *stderr_data; //!< Action stderr (set by library) char *stdout_data; //!< Action stdout (set by library) void *cb_data; //!< For caller's use (not used by library) //! This field should be treated as internal to Pacemaker svc_action_private_t *opaque; } svc_action_t; /*! * \brief Get a list of files or directories in a given path * * \param[in] root Full path to a directory to read * \param[in] files Return list of files if TRUE or directories if FALSE * \param[in] executable If TRUE and files is TRUE, only return executable files * * \return List of what was found as char * items. * \note The caller is responsibile for freeing the result with * g_list_free_full(list, free). */ GList *get_directory_list(const char *root, gboolean files, gboolean executable); /*! * \brief Get a list of providers * * \param[in] standard List providers of this resource agent standard * * \return List of providers as char * list items (or NULL if standard does not * support providers) * \note The caller is responsible for freeing the result using * g_list_free_full(list, free). */ GList *resources_list_providers(const char *standard); /*! * \brief Get a list of resource agents * * \param[in] standard List agents of this standard (or NULL for all) * \param[in] provider List agents of this provider (or NULL for all) * * \return List of resource agents as char * items. * \note The caller is responsible for freeing the result using * g_list_free_full(list, free). */ GList *resources_list_agents(const char *standard, const char *provider); /*! * Get list of available standards * * \return List of resource standards as char * items. * \note The caller is responsible for freeing the result using * g_list_free_full(list, free). */ GList *resources_list_standards(void); /*! * \brief Check whether a resource agent exists on the local host * * \param[in] standard Resource agent standard of agent to check * \param[in] provider Provider of agent to check (or NULL) * \param[in] agent Name of agent to check * * \return TRUE if agent exists locally, otherwise FALSE */ gboolean resources_agent_exists(const char *standard, const char *provider, const char *agent); /*! * \brief Create a new resource action * * \param[in] name Name of resource that action is for * \param[in] standard Resource agent standard * \param[in] provider Resource agent provider * \param[in] agent Resource agent name * \param[in] action Name of action to create * \param[in] interval_ms How often to repeat action (if 0, execute once) * \param[in] timeout Error if not complete within this time (ms) * \param[in,out] params Action parameters * \param[in] flags Group of enum svc_action_flags * * \return Newly allocated action * \note This function assumes ownership of (and may free) \p params. * \note The caller is responsible for freeing the return value using * services_action_free(). */ svc_action_t *resources_action_create(const char *name, const char *standard, const char *provider, const char *agent, const char *action, guint interval_ms, int timeout, GHashTable *params, enum svc_action_flags flags); /*! * \brief Reschedule a recurring action for immediate execution * * \param[in] name Name of resource that action is for * \param[in] action Action's name * \param[in] interval_ms Action's interval (in milliseconds) * * \return TRUE on success, otherwise FALSE */ gboolean services_action_kick(const char *name, const char *action, guint interval_ms); const char *resources_find_service_class(const char *agent); /*! * \brief Request execution of an arbitrary command * * This API has useful infrastructure in place to be able to run a command * in the background and get notified via a callback when the command finishes. * * \param[in] exec Full path to command executable * \param[in] args NULL-terminated list of arguments to pass to command * * \return Newly allocated action object */ svc_action_t *services_action_create_generic(const char *exec, const char *args[]); void services_action_cleanup(svc_action_t *op); void services_action_free(svc_action_t *op); int services_action_user(svc_action_t *op, const char *user); gboolean services_action_sync(svc_action_t *op); /*! * \brief Run an action asynchronously, with callback after process is forked * * \param[in,out] op Action to run * \param[in] action_callback Function to call when action completes * (if NULL, any previously set callback will * continue to be used) * \param[in] action_fork_callback Function to call after child process is * forked for action (if NULL, any * previously set callback will continue to * be used) * * \retval TRUE if the caller should not free or otherwise use \p op again, * because one of these conditions is true: * * * \p op is NULL. * * The action was successfully initiated, in which case * \p action_fork_callback has been called, but \p action_callback has * not (it will be called when the action completes). * * The action's ID matched an existing recurring action. The existing * action has taken over the callback and callback data from \p op * and has been re-initiated asynchronously, and \p op has been freed. * * Another action for the same resource is in flight, and \p op will * be blocked until it completes. * * The action could not be initiated, and is either non-recurring or * being cancelled. \p action_fork_callback has not been called, but * \p action_callback has, and \p op has been freed. * * \retval FALSE if \op is still valid, because the action cannot be initiated, * and is a recurring action that is not being cancelled. * \p action_fork_callback has not been called, but \p action_callback * has, and a timer has been set for the next invocation of \p op. */ gboolean services_action_async_fork_notify(svc_action_t *op, void (*action_callback) (svc_action_t *), void (*action_fork_callback) (svc_action_t *)); /*! * \brief Request asynchronous execution of an action * * \param[in,out] op Action to execute * \param[in] action_callback Function to call when the action completes * (if NULL, any previously set callback will * continue to be used) * * \retval TRUE if the caller should not free or otherwise use \p op again, * because one of these conditions is true: * * * \p op is NULL. * * The action was successfully initiated, in which case * \p action_callback has not been called (it will be called when the * action completes). * * The action's ID matched an existing recurring action. The existing * action has taken over the callback and callback data from \p op * and has been re-initiated asynchronously, and \p op has been freed. * * Another action for the same resource is in flight, and \p op will * be blocked until it completes. * * The action could not be initiated, and is either non-recurring or * being cancelled. \p action_callback has been called, and \p op has * been freed. * * \retval FALSE if \op is still valid, because the action cannot be initiated, * and is a recurring action that is not being cancelled. * \p action_callback has been called, and a timer has been set for the * next invocation of \p op. */ gboolean services_action_async(svc_action_t *op, void (*action_callback) (svc_action_t *)); gboolean services_action_cancel(const char *name, const char *action, guint interval_ms); /* functions for alert agents */ svc_action_t *services_alert_create(const char *id, const char *exec, int timeout, GHashTable *params, int sequence, void *cb_data); gboolean services_alert_async(svc_action_t *action, void (*cb)(svc_action_t *op)); enum ocf_exitcode services_result2ocf(const char *standard, const char *action, int exit_status); static inline const char *services_ocf_exitcode_str(enum ocf_exitcode code) { switch (code) { case PCMK_OCF_OK: return "ok"; case PCMK_OCF_UNKNOWN_ERROR: return "error"; case PCMK_OCF_INVALID_PARAM: return "invalid parameter"; case PCMK_OCF_UNIMPLEMENT_FEATURE: return "unimplemented feature"; case PCMK_OCF_INSUFFICIENT_PRIV: return "insufficient privileges"; case PCMK_OCF_NOT_INSTALLED: return "not installed"; case PCMK_OCF_NOT_CONFIGURED: return "not configured"; case PCMK_OCF_NOT_RUNNING: return "not running"; case PCMK_OCF_RUNNING_PROMOTED: return "promoted"; case PCMK_OCF_FAILED_PROMOTED: return "promoted (failed)"; case PCMK_OCF_DEGRADED: return "OCF_DEGRADED"; case PCMK_OCF_DEGRADED_PROMOTED: return "promoted (degraded)"; #if !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1) case PCMK_OCF_NOT_SUPPORTED: return "not supported (DEPRECATED STATUS)"; case PCMK_OCF_CANCELLED: return "cancelled (DEPRECATED STATUS)"; case PCMK_OCF_OTHER_ERROR: return "other error (DEPRECATED STATUS)"; case PCMK_OCF_SIGNAL: return "interrupted by signal (DEPRECATED STATUS)"; case PCMK_OCF_PENDING: return "pending (DEPRECATED STATUS)"; case PCMK_OCF_TIMEOUT: return "timeout (DEPRECATED STATUS)"; #endif default: return "unknown"; } } -#if !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1) -#include -#endif - # ifdef __cplusplus } # endif #endif /* __PCMK_SERVICES__ */ diff --git a/include/crm/services_compat.h b/include/crm/services_compat.h deleted file mode 100644 index 456d35195b..0000000000 --- a/include/crm/services_compat.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 2010-2023 the Pacemaker project contributors - * - * The version control history for this file may have further details. - * - * This source code is licensed under the GNU Lesser General Public License - * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY. - */ - -#ifndef PCMK__CRM_SERVICES_COMPAT__H -# define PCMK__CRM_SERVICES_COMPAT__H - -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/*! - * \file - * \brief Deprecated services API - * \ingroup core - * \deprecated Do not include this header directly. The service APIs in this - * header, and the header itself, will be removed in a future - * release. - */ - -# ifndef LSB_ROOT_DIR - //! \deprecated Do not use -# define LSB_ROOT_DIR "/etc/init.d" -# endif - -//! \deprecated Use enum pcmk_exec_status instead -enum op_status { - PCMK_LRM_OP_UNKNOWN = PCMK_EXEC_UNKNOWN, - PCMK_LRM_OP_PENDING = PCMK_EXEC_PENDING, - PCMK_LRM_OP_DONE = PCMK_EXEC_DONE, - PCMK_LRM_OP_CANCELLED = PCMK_EXEC_CANCELLED, - PCMK_LRM_OP_TIMEOUT = PCMK_EXEC_TIMEOUT, - PCMK_LRM_OP_NOTSUPPORTED = PCMK_EXEC_NOT_SUPPORTED, - PCMK_LRM_OP_ERROR = PCMK_EXEC_ERROR, - PCMK_LRM_OP_ERROR_HARD = PCMK_EXEC_ERROR_HARD, - PCMK_LRM_OP_ERROR_FATAL = PCMK_EXEC_ERROR_FATAL, - PCMK_LRM_OP_NOT_INSTALLED = PCMK_EXEC_NOT_INSTALLED, - PCMK_LRM_OP_NOT_CONNECTED = PCMK_EXEC_NOT_CONNECTED, - PCMK_LRM_OP_INVALID = PCMK_EXEC_INVALID, -}; - -//! \deprecated Use resources_action_create() instead -svc_action_t *services_action_create(const char *name, const char *action, - guint interval_ms, int timeout); - -//! \deprecated Use resources_list_agents() instead -GList *services_list(void); - -//! \deprecated Use pcmk_exec_status_str() instead -static inline const char * -services_lrm_status_str(enum op_status status) -{ - return pcmk_exec_status_str((enum pcmk_exec_status) status); -} - -//! \deprecated Use services_result2ocf() instead -static inline enum ocf_exitcode -services_get_ocf_exitcode(const char *action, int lsb_exitcode) -{ - /* For non-status actions, LSB and OCF share error code meaning <= 7 */ - if ((action != NULL) && (strcmp(action, PCMK_ACTION_STATUS) != 0) - && (strcmp(action, PCMK_ACTION_MONITOR) != 0)) { - if ((lsb_exitcode < 0) || (lsb_exitcode > PCMK_LSB_NOT_RUNNING)) { - return PCMK_OCF_UNKNOWN_ERROR; - } - return (enum ocf_exitcode)lsb_exitcode; - } - - /* status has different return codes */ - switch (lsb_exitcode) { - case PCMK_LSB_STATUS_OK: - return PCMK_OCF_OK; - case PCMK_LSB_STATUS_NOT_INSTALLED: - return PCMK_OCF_NOT_INSTALLED; - case PCMK_LSB_STATUS_INSUFFICIENT_PRIV: - return PCMK_OCF_INSUFFICIENT_PRIV; - case PCMK_LSB_STATUS_VAR_PID: - case PCMK_LSB_STATUS_VAR_LOCK: - case PCMK_LSB_STATUS_NOT_RUNNING: - return PCMK_OCF_NOT_RUNNING; - } - return PCMK_OCF_UNKNOWN_ERROR; -} - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/lib/services/services_lsb.c b/lib/services/services_lsb.c index 83587f2f7b..a9a2832514 100644 --- a/lib/services/services_lsb.c +++ b/lib/services/services_lsb.c @@ -1,345 +1,323 @@ /* * Copyright 2010-2024 the Pacemaker project contributors * * The version control history for this file may have further details. * * This source code is licensed under the GNU Lesser General Public License * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY. */ #include #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #include #include #include #include #include #include #include "services_private.h" #include "services_lsb.h" // @TODO Use XML string constants and maybe a real XML object #define lsb_metadata_template \ "\n" \ "<" PCMK_XE_RESOURCE_AGENT " " \ PCMK_XA_NAME "='%s' " \ PCMK_XA_VERSION "='" PCMK_DEFAULT_AGENT_VERSION "'>\n" \ " <" PCMK_XE_VERSION ">1.1\n" \ " <" PCMK_XE_LONGDESC " " PCMK_XA_LANG "='" PCMK__VALUE_EN "'>\n" \ "%s" \ " \n" \ " <" PCMK_XE_SHORTDESC " " PCMK_XA_LANG "='" PCMK__VALUE_EN "'>" \ "%s" \ "\n" \ " <" PCMK_XE_PARAMETERS "/>\n" \ " <" PCMK_XE_ACTIONS ">\n" \ " <" PCMK_XE_ACTION " " PCMK_XA_NAME "='" PCMK_ACTION_META_DATA "'" \ " " PCMK_META_TIMEOUT "='5s' />\n" \ " <" PCMK_XE_ACTION " " PCMK_XA_NAME "='" PCMK_ACTION_START "'" \ " " PCMK_META_TIMEOUT "='15s' />\n" \ " <" PCMK_XE_ACTION " " PCMK_XA_NAME "='" PCMK_ACTION_STOP "'" \ " " PCMK_META_TIMEOUT "='15s' />\n" \ " <" PCMK_XE_ACTION " " PCMK_XA_NAME "='" PCMK_ACTION_STATUS "'" \ " " PCMK_META_TIMEOUT "='15s' />\n" \ " <" PCMK_XE_ACTION " " PCMK_XA_NAME "='restart'" \ " " PCMK_META_TIMEOUT "='15s' />\n" \ " <" PCMK_XE_ACTION " " PCMK_XA_NAME "='force-reload'" \ " " PCMK_META_TIMEOUT "='15s' />\n" \ " <" PCMK_XE_ACTION " " PCMK_XA_NAME "='" PCMK_ACTION_MONITOR "'" \ " " PCMK_META_TIMEOUT "='15s'" \ " " PCMK_META_INTERVAL "='15s' />\n" \ " \n" \ " <" PCMK_XE_SPECIAL " " PCMK_XA_TAG "='LSB'>\n" \ " %s\n" \ " %s\n" \ " %s\n" \ " %s\n" \ " %s\n" \ " %s\n" \ " %s\n" \ " \n" \ "\n" /* See "Comment Conventions for Init Scripts" in the LSB core specification at: * http://refspecs.linuxfoundation.org/lsb.shtml */ #define LSB_INITSCRIPT_INFOBEGIN_TAG "### BEGIN INIT INFO" #define LSB_INITSCRIPT_INFOEND_TAG "### END INIT INFO" #define PROVIDES "# Provides:" #define REQUIRED_START "# Required-Start:" #define REQUIRED_STOP "# Required-Stop:" #define SHOULD_START "# Should-Start:" #define SHOULD_STOP "# Should-Stop:" #define DEFAULT_START "# Default-Start:" #define DEFAULT_STOP "# Default-Stop:" #define SHORT_DESC "# Short-Description:" #define DESCRIPTION "# Description:" /*! * \internal * \brief Grab an LSB header value * * \param[in] line Line read from LSB init script * \param[in,out] value If not set, will be set to XML-safe copy of value * \param[in] prefix Set value if line starts with this pattern * * \return TRUE if value was set, FALSE otherwise */ static inline gboolean lsb_meta_helper_get_value(const char *line, gchar **value, const char *prefix) { /* @TODO Perhaps update later to use pcmk__xml_needs_escape(). Involves many * extra variables in the caller. */ if ((*value == NULL) && pcmk__starts_with(line, prefix)) { *value = pcmk__xml_escape(line + strlen(prefix), pcmk__xml_escape_text); return TRUE; } return FALSE; } int services__get_lsb_metadata(const char *type, char **output) { char ra_pathname[PATH_MAX] = { 0, }; FILE *fp = NULL; char buffer[1024] = { 0, }; gchar *provides = NULL; gchar *required_start = NULL; gchar *required_stop = NULL; gchar *should_start = NULL; gchar *should_stop = NULL; gchar *default_start = NULL; gchar *default_stop = NULL; gchar *short_desc = NULL; gchar *long_desc = NULL; bool in_header = FALSE; if (type[0] == '/') { snprintf(ra_pathname, sizeof(ra_pathname), "%s", type); } else { snprintf(ra_pathname, sizeof(ra_pathname), "%s/%s", PCMK__LSB_INIT_DIR, type); } crm_trace("Looking into %s", ra_pathname); fp = fopen(ra_pathname, "r"); if (fp == NULL) { return -errno; } /* Enter into the LSB-compliant comment block */ while (fgets(buffer, sizeof(buffer), fp)) { // Ignore lines up to and including the block delimiter if (pcmk__starts_with(buffer, LSB_INITSCRIPT_INFOBEGIN_TAG)) { in_header = TRUE; continue; } if (!in_header) { continue; } /* Assume each of the following eight arguments contain one line */ if (lsb_meta_helper_get_value(buffer, &provides, PROVIDES)) { continue; } if (lsb_meta_helper_get_value(buffer, &required_start, REQUIRED_START)) { continue; } if (lsb_meta_helper_get_value(buffer, &required_stop, REQUIRED_STOP)) { continue; } if (lsb_meta_helper_get_value(buffer, &should_start, SHOULD_START)) { continue; } if (lsb_meta_helper_get_value(buffer, &should_stop, SHOULD_STOP)) { continue; } if (lsb_meta_helper_get_value(buffer, &default_start, DEFAULT_START)) { continue; } if (lsb_meta_helper_get_value(buffer, &default_stop, DEFAULT_STOP)) { continue; } if (lsb_meta_helper_get_value(buffer, &short_desc, SHORT_DESC)) { continue; } /* Long description may cross multiple lines */ if ((long_desc == NULL) // Haven't already found long description && pcmk__starts_with(buffer, DESCRIPTION)) { bool processed_line = TRUE; GString *desc = g_string_sized_new(2048); // Get remainder of description line itself g_string_append(desc, buffer + sizeof(DESCRIPTION) - 1); // Read any continuation lines of the description buffer[0] = '\0'; while (fgets(buffer, sizeof(buffer), fp)) { if (pcmk__starts_with(buffer, "# ") || pcmk__starts_with(buffer, "#\t")) { /* '#' followed by a tab or more than one space indicates a * continuation of the long description. */ g_string_append(desc, buffer + 1); } else { /* This line is not part of the long description, * so continue with normal processing. */ processed_line = FALSE; break; } } // Make long description safe to use in XML long_desc = pcmk__xml_escape(desc->str, pcmk__xml_escape_text); g_string_free(desc, TRUE); if (processed_line) { // We grabbed the line into the long description continue; } } // Stop if we leave the header block if (pcmk__starts_with(buffer, LSB_INITSCRIPT_INFOEND_TAG)) { break; } if (buffer[0] != '#') { break; } } fclose(fp); *output = crm_strdup_printf(lsb_metadata_template, type, pcmk__s(long_desc, type), pcmk__s(short_desc, type), pcmk__s(provides, ""), pcmk__s(required_start, ""), pcmk__s(required_stop, ""), pcmk__s(should_start, ""), pcmk__s(should_stop, ""), pcmk__s(default_start, ""), pcmk__s(default_stop, "")); g_free(long_desc); g_free(short_desc); g_free(provides); g_free(required_start); g_free(required_stop); g_free(should_start); g_free(should_stop); g_free(default_start); g_free(default_stop); return pcmk_ok; } GList * services__list_lsb_agents(void) { return services_os_get_directory_list(PCMK__LSB_INIT_DIR, TRUE, TRUE); } bool services__lsb_agent_exists(const char *agent) { bool rc = FALSE; struct stat st; char *path = pcmk__full_path(agent, PCMK__LSB_INIT_DIR); rc = (stat(path, &st) == 0); free(path); return rc; } /*! * \internal * \brief Prepare an LSB action * * \param[in,out] op Action to prepare * * \return Standard Pacemaker return code */ int services__lsb_prepare(svc_action_t *op) { op->opaque->exec = pcmk__full_path(op->agent, PCMK__LSB_INIT_DIR); op->opaque->args[0] = strdup(op->opaque->exec); op->opaque->args[1] = strdup(op->action); if ((op->opaque->args[0] == NULL) || (op->opaque->args[1] == NULL)) { return ENOMEM; } return pcmk_rc_ok; } /*! * \internal * \brief Map an LSB result to a standard OCF result * * \param[in] action Action that result is for * \param[in] exit_status LSB agent exit status * * \return Standard OCF result */ enum ocf_exitcode services__lsb2ocf(const char *action, int exit_status) { // For non-status actions, LSB and OCF share error codes <= 7 if (!pcmk__str_any_of(action, PCMK_ACTION_STATUS, PCMK_ACTION_MONITOR, NULL)) { if ((exit_status < 0) || (exit_status > PCMK_LSB_NOT_RUNNING)) { return PCMK_OCF_UNKNOWN_ERROR; } return (enum ocf_exitcode) exit_status; } // LSB status actions have their own codes switch (exit_status) { case PCMK_LSB_STATUS_OK: return PCMK_OCF_OK; case PCMK_LSB_STATUS_NOT_INSTALLED: return PCMK_OCF_NOT_INSTALLED; case PCMK_LSB_STATUS_INSUFFICIENT_PRIV: return PCMK_OCF_INSUFFICIENT_PRIV; case PCMK_LSB_STATUS_VAR_PID: case PCMK_LSB_STATUS_VAR_LOCK: case PCMK_LSB_STATUS_NOT_RUNNING: return PCMK_OCF_NOT_RUNNING; default: return PCMK_OCF_UNKNOWN_ERROR; } } - -// Deprecated functions kept only for backward API compatibility -// LCOV_EXCL_START - -#include - -svc_action_t * -services_action_create(const char *name, const char *action, - guint interval_ms, int timeout) -{ - return resources_action_create(name, PCMK_RESOURCE_CLASS_LSB, NULL, name, - action, interval_ms, timeout, NULL, 0); -} - -GList * -services_list(void) -{ - return resources_list_agents(PCMK_RESOURCE_CLASS_LSB, NULL); -} - -// LCOV_EXCL_STOP -// End deprecated API