| /* crm_internal.h */ |
| |
| /* |
| * Copyright (C) 2006 - 2008 |
| * Andrew Beekhof <andrew@beekhof.net> |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU Lesser General Public License as published by |
| * the Free Software Foundation; either version 2 of the License, or |
| * (at your option) any later version. |
| * |
| * This program is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU Lesser General Public License for more details. |
| * |
| * You should have received a copy of the GNU Lesser General Public |
| * License along with this library; if not, write to the Free Software |
| * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
| */ |
| |
| #ifndef CRM_INTERNAL__H |
| # define CRM_INTERNAL__H |
| |
| # include <config.h> |
| # include <portability.h> |
| |
| # include <glib.h> |
| # include <stdbool.h> |
| # include <libxml/tree.h> |
| |
| # include <crm/lrmd.h> |
| # include <crm/common/logging.h> |
| # include <crm/common/ipcs.h> |
| # include <crm/common/internal.h> |
| |
| /* Dynamic loading of libraries */ |
| void *find_library_function(void **handle, const char *lib, const char *fn, int fatal); |
| |
| /* For ACLs */ |
| char *uid2username(uid_t uid); |
| void determine_request_user(const char *user, xmlNode * request, const char *field); |
| const char *crm_acl_get_set_user(xmlNode * request, const char *field, const char *peer_user); |
| |
| # if ENABLE_ACL |
| # include <string.h> |
| static inline gboolean |
| is_privileged(const char *user) |
| { |
| if (user == NULL) { |
| return FALSE; |
| } else if (strcmp(user, CRM_DAEMON_USER) == 0) { |
| return TRUE; |
| } else if (strcmp(user, "root") == 0) { |
| return TRUE; |
| } |
| return FALSE; |
| } |
| # endif |
| |
| /* CLI option processing*/ |
| # ifdef HAVE_GETOPT_H |
| # include <getopt.h> |
| # else |
| # define no_argument 0 |
| # define required_argument 1 |
| # endif |
| |
| # define pcmk_option_default 0x00000 |
| # define pcmk_option_hidden 0x00001 |
| # define pcmk_option_paragraph 0x00002 |
| # define pcmk_option_example 0x00004 |
| |
| struct crm_option { |
| /* Fields from 'struct option' in getopt.h */ |
| /* name of long option */ |
| const char *name; |
| /* |
| * one of no_argument, required_argument, and optional_argument: |
| * whether option takes an argument |
| */ |
| int has_arg; |
| /* if not NULL, set *flag to val when option found */ |
| int *flag; |
| /* if flag not NULL, value to set *flag to; else return value */ |
| int val; |
| |
| /* Custom fields */ |
| const char *desc; |
| long flags; |
| }; |
| |
| void crm_set_options(const char *short_options, const char *usage, struct crm_option *long_options, |
| const char *app_desc); |
| int crm_get_option(int argc, char **argv, int *index); |
| int crm_get_option_long(int argc, char **argv, int *index, const char **longname); |
| int crm_help(char cmd, int exit_code); |
| |
| /* Cluster Option Processing */ |
| typedef struct pe_cluster_option_s { |
| const char *name; |
| const char *alt_name; |
| const char *type; |
| const char *values; |
| const char *default_value; |
| |
| gboolean(*is_valid) (const char *); |
| |
| const char *description_short; |
| const char *description_long; |
| |
| } pe_cluster_option; |
| |
| const char *cluster_option(GHashTable * options, gboolean(*validate) (const char *), |
| const char *name, const char *old_name, const char *def_value); |
| |
| const char *get_cluster_pref(GHashTable * options, pe_cluster_option * option_list, int len, |
| const char *name); |
| |
| void config_metadata(const char *name, const char *version, const char *desc_short, |
| const char *desc_long, pe_cluster_option * option_list, int len); |
| |
| void verify_all_options(GHashTable * options, pe_cluster_option * option_list, int len); |
| gboolean check_time(const char *value); |
| gboolean check_timer(const char *value); |
| gboolean check_boolean(const char *value); |
| gboolean check_number(const char *value); |
| gboolean check_positive_number(const char *value); |
| gboolean check_quorum(const char *value); |
| gboolean check_script(const char *value); |
| gboolean check_utilization(const char *value); |
| long crm_get_sbd_timeout(void); |
| gboolean check_sbd_timeout(const char *value); |
| |
| /* char2score */ |
| extern int node_score_red; |
| extern int node_score_green; |
| extern int node_score_yellow; |
| extern int node_score_infinity; |
| |
| /* Assorted convenience functions */ |
| |
| /*! |
| * \internal |
| * \brief Detect if process per PID and optionally exe path (component) exists |
| * |
| * \param[in] pid PID of process assumed alive, disproving of which to try |
| * \param[in] daemon exe path (component) to possibly match with procfs entry |
| * |
| * \return -1 on invalid PID specification, -2 when the calling process has no |
| * (is refused an) ability to (dis)prove the predicate, |
| * 0 if the negation of the predicate is confirmed (check-through-kill |
| * indicates so, or the subsequent check-through-procfs-match on |
| * \p daemon when provided and procfs available at the standard path), |
| * 1 if it cannot be disproved (reliably [modulo race conditions] |
| * when \p daemon provided, procfs available at the standard path |
| * and the calling process has permissions to access the respective |
| * procfs location, less so otherwise, since mere check-through-kill |
| * is exercised without powers to exclude PID recycled in the interim). |
| * |
| * \note This function cannot be used to verify \e authenticity of the process. |
| */ |
| int crm_pid_active(long pid, const char *daemon); |
| void crm_make_daemon(const char *name, gboolean daemonize, const char *pidfile); |
| |
| /* from operations.c */ |
| char *generate_op_key(const char *rsc_id, const char *op_type, int interval); |
| char *generate_notify_key(const char *rsc_id, const char *notify_type, const char *op_type); |
| char *generate_transition_magic_v202(const char *transition_key, int op_status); |
| char *generate_transition_magic(const char *transition_key, int op_status, int op_rc); |
| char *generate_transition_key(int action, int transition_id, int target_rc, const char *node); |
| void filter_action_parameters(xmlNode *param_set, const char *version); |
| xmlNode *create_operation_update(xmlNode *parent, lrmd_event_data_t *event, |
| const char *caller_version, int target_rc, |
| const char *node, const char *origin, |
| int level); |
| |
| static inline long long |
| crm_clear_bit(const char *function, int line, const char *target, long long word, long long bit) |
| { |
| long long rc = (word & ~bit); |
| |
| if (rc == word) { |
| /* Unchanged */ |
| } else if (target) { |
| crm_trace("Bit 0x%.8llx for %s cleared by %s:%d", bit, target, function, line); |
| } else { |
| crm_trace("Bit 0x%.8llx cleared by %s:%d", bit, function, line); |
| } |
| |
| return rc; |
| } |
| |
| static inline long long |
| crm_set_bit(const char *function, int line, const char *target, long long word, long long bit) |
| { |
| long long rc = (word | bit); |
| |
| if (rc == word) { |
| /* Unchanged */ |
| } else if (target) { |
| crm_trace("Bit 0x%.8llx for %s set by %s:%d", bit, target, function, line); |
| } else { |
| crm_trace("Bit 0x%.8llx set by %s:%d", bit, function, line); |
| } |
| |
| return rc; |
| } |
| |
| # define set_bit(word, bit) word = crm_set_bit(__FUNCTION__, __LINE__, NULL, word, bit) |
| # define clear_bit(word, bit) word = crm_clear_bit(__FUNCTION__, __LINE__, NULL, word, bit) |
| |
| char *generate_hash_key(const char *crm_msg_reference, const char *sys); |
| |
| const char *daemon_option(const char *option); |
| void set_daemon_option(const char *option, const char *value); |
| gboolean daemon_option_enabled(const char *daemon, const char *option); |
| void strip_text_nodes(xmlNode * xml); |
| void pcmk_panic(const char *origin); |
| void sysrq_init(void); |
| pid_t pcmk_locate_sbd(void); |
| long crm_pidfile_inuse(const char *filename, long mypid, const char *daemon); |
| long crm_read_pidfile(const char *filename); |
| |
| # define crm_config_err(fmt...) { crm_config_error = TRUE; crm_err(fmt); } |
| # define crm_config_warn(fmt...) { crm_config_warning = TRUE; crm_warn(fmt); } |
| |
| # define attrd_channel T_ATTRD |
| # define F_ATTRD_KEY "attr_key" |
| # define F_ATTRD_ATTRIBUTE "attr_name" |
| # define F_ATTRD_REGEX "attr_regex" |
| # define F_ATTRD_TASK "task" |
| # define F_ATTRD_VALUE "attr_value" |
| # define F_ATTRD_SET "attr_set" |
| # define F_ATTRD_IS_REMOTE "attr_is_remote" |
| # define F_ATTRD_IS_PRIVATE "attr_is_private" |
| # define F_ATTRD_SECTION "attr_section" |
| # define F_ATTRD_DAMPEN "attr_dampening" |
| # define F_ATTRD_IGNORE_LOCALLY "attr_ignore_locally" |
| # define F_ATTRD_HOST "attr_host" |
| # define F_ATTRD_HOST_ID "attr_host_id" |
| # define F_ATTRD_USER "attr_user" |
| # define F_ATTRD_WRITER "attr_writer" |
| # define F_ATTRD_VERSION "attr_version" |
| # define F_ATTRD_RESOURCE "attr_resource" |
| # define F_ATTRD_OPERATION "attr_clear_operation" |
| # define F_ATTRD_INTERVAL "attr_clear_interval" |
| # define F_ATTRD_IS_FORCE_WRITE "attrd_is_force_write" |
| |
| /* attrd operations */ |
| # define ATTRD_OP_PEER_REMOVE "peer-remove" |
| # define ATTRD_OP_UPDATE "update" |
| # define ATTRD_OP_UPDATE_BOTH "update-both" |
| # define ATTRD_OP_UPDATE_DELAY "update-delay" |
| # define ATTRD_OP_QUERY "query" |
| # define ATTRD_OP_REFRESH "refresh" |
| # define ATTRD_OP_FLUSH "flush" |
| # define ATTRD_OP_SYNC "sync" |
| # define ATTRD_OP_SYNC_RESPONSE "sync-response" |
| # define ATTRD_OP_CLEAR_FAILURE "clear-failure" |
| |
| # define PCMK_ENV_PHYSICAL_HOST "physical_host" |
| |
| |
| # if SUPPORT_COROSYNC |
| # if CS_USES_LIBQB |
| # include <qb/qbipc_common.h> |
| # include <corosync/corotypes.h> |
| typedef struct qb_ipc_request_header cs_ipc_header_request_t; |
| typedef struct qb_ipc_response_header cs_ipc_header_response_t; |
| # else |
| # include <corosync/corodefs.h> |
| # include <corosync/coroipcc.h> |
| # include <corosync/coroipc_types.h> |
| typedef coroipc_request_header_t cs_ipc_header_request_t; |
| typedef coroipc_response_header_t cs_ipc_header_response_t; |
| # endif |
| # else |
| typedef struct { |
| int size __attribute__ ((aligned(8))); |
| int id __attribute__ ((aligned(8))); |
| } __attribute__ ((aligned(8))) cs_ipc_header_request_t; |
| |
| typedef struct { |
| int size __attribute__ ((aligned(8))); |
| int id __attribute__ ((aligned(8))); |
| int error __attribute__ ((aligned(8))); |
| } __attribute__ ((aligned(8))) cs_ipc_header_response_t; |
| |
| # endif |
| |
| void |
| attrd_ipc_server_init(qb_ipcs_service_t **ipcs, struct qb_ipcs_service_handlers *cb); |
| void |
| stonith_ipc_server_init(qb_ipcs_service_t **ipcs, struct qb_ipcs_service_handlers *cb); |
| |
| qb_ipcs_service_t * |
| crmd_ipc_server_init(struct qb_ipcs_service_handlers *cb); |
| |
| void cib_ipc_servers_init(qb_ipcs_service_t **ipcs_ro, |
| qb_ipcs_service_t **ipcs_rw, |
| qb_ipcs_service_t **ipcs_shm, |
| struct qb_ipcs_service_handlers *ro_cb, |
| struct qb_ipcs_service_handlers *rw_cb); |
| |
| void cib_ipc_servers_destroy(qb_ipcs_service_t *ipcs_ro, |
| qb_ipcs_service_t *ipcs_rw, |
| qb_ipcs_service_t *ipcs_shm); |
| |
| static inline void *realloc_safe(void *ptr, size_t size) |
| { |
| void *ret = realloc(ptr, size); |
| |
| if (ret == NULL) { |
| free(ptr); /* make coverity happy */ |
| abort(); |
| } |
| |
| return ret; |
| } |
| |
| const char *crm_xml_add_last_written(xmlNode *xml_node); |
| void crm_xml_dump(xmlNode * data, int options, char **buffer, int *offset, int *max, int depth); |
| void crm_buffer_add_char(char **buffer, int *offset, int *max, char c); |
| |
| gboolean crm_digest_verify(xmlNode *input, const char *expected); |
| |
| /* cross-platform compatibility functions */ |
| char *crm_compat_realpath(const char *path); |
| |
| /* IPC Proxy Backend Shared Functions */ |
| typedef struct remote_proxy_s { |
| char *node_name; |
| char *session_id; |
| |
| gboolean is_local; |
| |
| crm_ipc_t *ipc; |
| mainloop_io_t *source; |
| uint32_t last_request_id; |
| lrmd_t *lrm; |
| |
| } remote_proxy_t; |
| |
| remote_proxy_t *remote_proxy_new( |
| lrmd_t *lrmd, struct ipc_client_callbacks *proxy_callbacks, |
| const char *node_name, const char *session_id, const char *channel); |
| |
| int remote_proxy_check(lrmd_t *lrmd, GHashTable *hash); |
| void remote_proxy_cb(lrmd_t *lrmd, const char *node_name, xmlNode *msg); |
| void remote_proxy_ack_shutdown(lrmd_t *lrmd); |
| void remote_proxy_nack_shutdown(lrmd_t *lrmd); |
| |
| int remote_proxy_dispatch(const char *buffer, ssize_t length, gpointer userdata); |
| void remote_proxy_disconnected(gpointer data); |
| void remote_proxy_free(gpointer data); |
| |
| void remote_proxy_relay_event(remote_proxy_t *proxy, xmlNode *msg); |
| void remote_proxy_relay_response(remote_proxy_t *proxy, xmlNode *msg, int msg_id); |
| |
| #endif /* CRM_INTERNAL__H */ |