Page MenuHomeClusterLabs Projects

No OneTemporary

This file is larger than 256 KB, so syntax highlighting was skipped.
diff --git a/include/Makefile.am b/include/Makefile.am
index 48b15a65fb..97688a80e1 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -1,26 +1,28 @@
#
-# Copyright (C) 2004-2009 Andrew Beekhof
+# Copyright 2003-2019 the Pacemaker project contributors
+#
+# The version control history for this file may have further details.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
MAINTAINERCLEANFILES = Makefile.in config.h.in
noinst_HEADERS = portability.h config.h crm_internal.h pacemaker-internal.h
pkginclude_HEADERS = crm_config.h
SUBDIRS = crm pcmki
.PHONY: $(ARCHIVE_VERSION)
diff --git a/include/crm/Makefile.am b/include/crm/Makefile.am
index 44db3ccc15..3f5f4bf4ce 100644
--- a/include/crm/Makefile.am
+++ b/include/crm/Makefile.am
@@ -1,26 +1,28 @@
#
-# Copyright (C) 2004 Andrew Beekhof <andrew@beekhof.net>
+# Copyright 2004-2018 the Pacemaker project contributors
+#
+# The version control history for this file may have further details.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
MAINTAINERCLEANFILES = Makefile.in
headerdir=$(pkgincludedir)/crm
header_HEADERS = attrd.h cib.h cluster.h compatibility.h crm.h \
lrmd.h msg_xml.h services.h stonith-ng.h \
transition.h
SUBDIRS = common pengine cib fencing cluster
diff --git a/include/crm/attrd.h b/include/crm/attrd.h
index ac4932c640..5ec1948670 100644
--- a/include/crm/attrd.h
+++ b/include/crm/attrd.h
@@ -1,45 +1,47 @@
/*
- * Copyright (C) 2004 Andrew Beekhof <andrew@beekhof.net>
+ * Copyright 2004-2018 the Pacemaker project contributors
+ *
+ * The version control history for this file may have further details.
*
* 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 software 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
* 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_ATTRD__H
# define CRM_ATTRD__H
#ifdef __cplusplus
extern "C" {
#endif
# include <crm/common/ipc.h>
/* attribute options for clients to use with these functions */
#define attrd_opt_none 0x000
#define attrd_opt_remote 0x001
#define attrd_opt_private 0x002
const char *attrd_get_target(const char *name);
int attrd_update_delegate(crm_ipc_t * ipc, char command, const char *host,
const char *name, const char *value, const char *section,
const char *set, const char *dampen, const char *user_name, int options);
int attrd_clear_delegate(crm_ipc_t *ipc, const char *host, const char *resource,
const char *operation, const char *interval_spec,
const char *user_name, int options);
#ifdef __cplusplus
}
#endif
#endif
diff --git a/include/crm/cib.h b/include/crm/cib.h
index a0faa91ed0..86195aad1e 100644
--- a/include/crm/cib.h
+++ b/include/crm/cib.h
@@ -1,184 +1,186 @@
/*
- * Copyright 2004-2019 Andrew Beekhof <andrew@beekhof.net>
+ * Copyright 2004-2019 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 CIB__H
# define CIB__H
#ifdef __cplusplus
extern "C" {
#endif
/**
* \file
* \brief Cluster Configuration
* \ingroup cib
*/
# include <glib.h> // gboolean, GList
# include <libxml/tree.h> // xmlNode
# include <crm/common/ipc.h>
# include <crm/common/xml.h>
# define CIB_FEATURE_SET "2.0"
/* use compare_version() for doing comparisons */
enum cib_variant {
cib_undefined,
cib_native,
cib_file,
cib_remote,
cib_database,
};
enum cib_state {
cib_connected_command,
cib_connected_query,
cib_disconnected
};
enum cib_conn_type {
cib_command,
cib_query,
cib_no_connection,
cib_command_nonblocking,
};
/* *INDENT-OFF* */
enum cib_call_options {
cib_none = 0x00000000,
cib_verbose = 0x00000001, /* prefer stderr to logs */
cib_xpath = 0x00000002,
cib_multiple = 0x00000004,
cib_can_create = 0x00000008,
cib_discard_reply = 0x00000010,
cib_no_children = 0x00000020,
cib_xpath_address = 0x00000040,
cib_mixed_update = 0x00000080,
cib_scope_local = 0x00000100,
cib_dryrun = 0x00000200,
cib_sync_call = 0x00001000,
cib_no_mtime = 0x00002000,
cib_zero_copy = 0x00004000,
cib_inhibit_notify = 0x00010000,
cib_quorum_override = 0x00100000,
cib_inhibit_bcast = 0x01000000, /* TODO: Remove */
cib_force_diff = 0x10000000
};
#define T_CIB_DIFF_NOTIFY "cib_diff_notify"
/* *INDENT-ON* */
typedef struct cib_s cib_t;
typedef struct cib_api_operations_s {
int (*signon) (cib_t * cib, const char *name, enum cib_conn_type type);
int (*signon_raw) (cib_t * cib, const char *name, enum cib_conn_type type, int *event_fd);
int (*signoff) (cib_t * cib);
int (*free) (cib_t * cib);
int (*set_op_callback) (cib_t * cib, void (*callback) (const xmlNode * msg, int callid,
int rc, xmlNode * output));
int (*add_notify_callback) (cib_t * cib, const char *event,
void (*callback) (const char *event, xmlNode * msg));
int (*del_notify_callback) (cib_t * cib, const char *event,
void (*callback) (const char *event, xmlNode * msg));
int (*set_connection_dnotify) (cib_t * cib, void (*dnotify) (gpointer user_data));
int (*inputfd) (cib_t * cib);
int (*noop) (cib_t * cib, int call_options);
int (*ping) (cib_t * cib, xmlNode ** output_data, int call_options);
int (*query) (cib_t * cib, const char *section, xmlNode ** output_data, int call_options);
int (*query_from) (cib_t * cib, const char *host, const char *section,
xmlNode ** output_data, int call_options);
int (*is_master) (cib_t * cib);
int (*set_master) (cib_t * cib, int call_options);
int (*set_slave) (cib_t * cib, int call_options);
int (*set_slave_all) (cib_t * cib, int call_options);
int (*sync) (cib_t * cib, const char *section, int call_options);
int (*sync_from) (cib_t * cib, const char *host, const char *section, int call_options);
int (*upgrade) (cib_t * cib, int call_options);
int (*bump_epoch) (cib_t * cib, int call_options);
int (*create) (cib_t * cib, const char *section, xmlNode * data, int call_options);
int (*modify) (cib_t * cib, const char *section, xmlNode * data, int call_options);
int (*update) (cib_t * cib, const char *section, xmlNode * data, int call_options);
int (*replace) (cib_t * cib, const char *section, xmlNode * data, int call_options);
int (*remove) (cib_t * cib, const char *section, xmlNode * data, int call_options);
int (*erase) (cib_t * cib, xmlNode ** output_data, int call_options);
int (*delete_absolute) (cib_t * cib, const char *section, xmlNode * data, int call_options);
int (*quit) (cib_t * cib, int call_options);
int (*register_notification) (cib_t * cib, const char *callback, int enabled);
gboolean(*register_callback) (cib_t * cib, int call_id, int timeout, gboolean only_success,
void *user_data, const char *callback_name,
void (*callback) (xmlNode *, int, int, xmlNode *, void *));
gboolean (*register_callback_full)(cib_t *cib, int call_id, int timeout,
gboolean only_success, void *user_data,
const char *callback_name,
void (*callback)(xmlNode *, int, int,
xmlNode *, void *),
void (*free_func)(void *));
} cib_api_operations_t;
struct cib_s {
enum cib_state state;
enum cib_conn_type type;
enum cib_variant variant;
int call_id;
int call_timeout;
void *variant_opaque;
void *delegate_fn;
GList *notify_list;
void (*op_callback) (const xmlNode * msg, int call_id, int rc, xmlNode * output);
cib_api_operations_t *cmds;
};
/* Core functions */
cib_t *cib_new(void);
cib_t *cib_native_new(void);
cib_t *cib_file_new(const char *filename);
cib_t *cib_remote_new(const char *server, const char *user, const char *passwd, int port,
gboolean encrypted);
cib_t *cib_new_no_shadow(void);
char *get_shadow_file(const char *name);
cib_t *cib_shadow_new(const char *name);
void cib_free_callbacks(cib_t *cib);
void cib_delete(cib_t * cib);
void cib_dump_pending_callbacks(void);
int num_cib_op_callbacks(void);
void remove_cib_op_callback(int call_id, gboolean all_callbacks);
# include <crm/cib/util.h>
# define CIB_LIBRARY "libcib.so.27"
#ifdef __cplusplus
}
#endif
#endif
diff --git a/include/crm/cib/Makefile.am b/include/crm/cib/Makefile.am
index 9966f7fc7e..cfb00721cb 100644
--- a/include/crm/cib/Makefile.am
+++ b/include/crm/cib/Makefile.am
@@ -1,23 +1,25 @@
#
-# Copyright (C) 2004 Andrew Beekhof <andrew@beekhof.net>
+# Copyright 2012 the Pacemaker project contributors
+#
+# The version control history for this file may have further details.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
MAINTAINERCLEANFILES = Makefile.in
headerdir=$(pkgincludedir)/crm/cib
noinst_HEADERS = internal.h
header_HEADERS = util.h
diff --git a/include/crm/cib/internal.h b/include/crm/cib/internal.h
index 510fb83530..e537daa358 100644
--- a/include/crm/cib/internal.h
+++ b/include/crm/cib/internal.h
@@ -1,205 +1,207 @@
/*
- * Copyright 2004-2018 Andrew Beekhof <andrew@beekhof.net>
+ * Copyright 2004-2018 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 CIB_INTERNAL__H
# define CIB_INTERNAL__H
# include <crm/cib.h>
# include <crm/common/ipcs.h>
# define CIB_OP_SLAVE "cib_slave"
# define CIB_OP_SLAVEALL "cib_slave_all"
# define CIB_OP_MASTER "cib_master"
# define CIB_OP_SYNC "cib_sync"
# define CIB_OP_SYNC_ONE "cib_sync_one"
# define CIB_OP_ISMASTER "cib_ismaster"
# define CIB_OP_BUMP "cib_bump"
# define CIB_OP_QUERY "cib_query"
# define CIB_OP_CREATE "cib_create"
# define CIB_OP_MODIFY "cib_modify"
# define CIB_OP_DELETE "cib_delete"
# define CIB_OP_ERASE "cib_erase"
# define CIB_OP_REPLACE "cib_replace"
# define CIB_OP_APPLY_DIFF "cib_apply_diff"
# define CIB_OP_UPGRADE "cib_upgrade"
# define CIB_OP_DELETE_ALT "cib_delete_alt"
# define F_CIB_CLIENTID "cib_clientid"
# define F_CIB_CALLOPTS "cib_callopt"
# define F_CIB_CALLID "cib_callid"
# define F_CIB_CALLDATA "cib_calldata"
# define F_CIB_OPERATION "cib_op"
# define F_CIB_ISREPLY "cib_isreplyto"
# define F_CIB_SECTION "cib_section"
# define F_CIB_HOST "cib_host"
# define F_CIB_RC "cib_rc"
# define F_CIB_UPGRADE_RC "cib_upgrade_rc"
# define F_CIB_DELEGATED "cib_delegated_from"
# define F_CIB_OBJID "cib_object"
# define F_CIB_OBJTYPE "cib_object_type"
# define F_CIB_EXISTING "cib_existing_object"
# define F_CIB_SEENCOUNT "cib_seen"
# define F_CIB_TIMEOUT "cib_timeout"
# define F_CIB_UPDATE "cib_update"
# define F_CIB_CALLBACK_TOKEN "cib_async_id"
# define F_CIB_GLOBAL_UPDATE "cib_update"
# define F_CIB_UPDATE_RESULT "cib_update_result"
# define F_CIB_CLIENTNAME "cib_clientname"
# define F_CIB_NOTIFY_TYPE "cib_notify_type"
# define F_CIB_NOTIFY_ACTIVATE "cib_notify_activate"
# define F_CIB_UPDATE_DIFF "cib_update_diff"
# define F_CIB_USER "cib_user"
# define F_CIB_LOCAL_NOTIFY_ID "cib_local_notify_id"
# define F_CIB_PING_ID "cib_ping_id"
# define F_CIB_SCHEMA_MAX "cib_schema_max"
# define T_CIB "cib"
# define T_CIB_NOTIFY "cib_notify"
/* notify sub-types */
# define T_CIB_PRE_NOTIFY "cib_pre_notify"
# define T_CIB_POST_NOTIFY "cib_post_notify"
# define T_CIB_UPDATE_CONFIRM "cib_update_confirmation"
# define T_CIB_REPLACE_NOTIFY "cib_refresh_notify"
# define CIB_CHANNEL_RO "cib_ro"
# define CIB_CHANNEL_RW "cib_rw"
# define CIB_CHANNEL_SHM "cib_shm"
gboolean cib_diff_version_details(xmlNode * diff, int *admin_epoch, int *epoch, int *updates,
int *_admin_epoch, int *_epoch, int *_updates);
gboolean cib_read_config(GHashTable * options, xmlNode * current_cib);
void verify_cib_options(GHashTable * options);
gboolean cib_internal_config_changed(xmlNode * diff);
extern GHashTable *cib_op_callback_table;
typedef struct cib_notify_client_s {
const char *event;
const char *obj_id; /* implement one day */
const char *obj_type; /* implement one day */
void (*callback) (const char *event, xmlNode * msg);
} cib_notify_client_t;
typedef struct cib_callback_client_s {
void (*callback) (xmlNode *, int, int, xmlNode *, void *);
const char *id;
void *user_data;
gboolean only_success;
struct timer_rec_s *timer;
void (*free_func)(void *);
} cib_callback_client_t;
struct timer_rec_s {
int call_id;
int timeout;
guint ref;
cib_t *cib;
};
typedef int (*cib_op_t) (const char *, int, const char *, xmlNode *,
xmlNode *, xmlNode *, xmlNode **, xmlNode **);
cib_t *cib_new_variant(void);
int cib_perform_op(const char *op, int call_options, cib_op_t * fn, gboolean is_query,
const char *section, xmlNode * req, xmlNode * input,
gboolean manage_counters, gboolean * config_changed,
xmlNode * current_cib, xmlNode ** result_cib, xmlNode ** diff,
xmlNode ** output);
xmlNode *cib_create_op(int call_id, const char *token, const char *op, const char *host,
const char *section, xmlNode * data, int call_options,
const char *user_name);
void cib_native_callback(cib_t * cib, xmlNode * msg, int call_id, int rc);
void cib_native_notify(gpointer data, gpointer user_data);
int cib_native_register_notification(cib_t * cib, const char *callback, int enabled);
gboolean cib_client_register_callback(cib_t * cib, int call_id, int timeout, gboolean only_success,
void *user_data, const char *callback_name,
void (*callback) (xmlNode *, int, int, xmlNode *, void *));
gboolean cib_client_register_callback_full(cib_t *cib, int call_id,
int timeout, gboolean only_success,
void *user_data,
const char *callback_name,
void (*callback)(xmlNode *, int, int,
xmlNode *, void *),
void (*free_func)(void *));
int cib_process_query(const char *op, int options, const char *section, xmlNode * req,
xmlNode * input, xmlNode * existing_cib, xmlNode ** result_cib,
xmlNode ** answer);
int cib_process_erase(const char *op, int options, const char *section, xmlNode * req,
xmlNode * input, xmlNode * existing_cib, xmlNode ** result_cib,
xmlNode ** answer);
int cib_process_bump(const char *op, int options, const char *section, xmlNode * req,
xmlNode * input, xmlNode * existing_cib, xmlNode ** result_cib,
xmlNode ** answer);
int cib_process_replace(const char *op, int options, const char *section, xmlNode * req,
xmlNode * input, xmlNode * existing_cib, xmlNode ** result_cib,
xmlNode ** answer);
int cib_process_create(const char *op, int options, const char *section, xmlNode * req,
xmlNode * input, xmlNode * existing_cib, xmlNode ** result_cib,
xmlNode ** answer);
int cib_process_modify(const char *op, int options, const char *section, xmlNode * req,
xmlNode * input, xmlNode * existing_cib, xmlNode ** result_cib,
xmlNode ** answer);
int cib_process_delete(const char *op, int options, const char *section, xmlNode * req,
xmlNode * input, xmlNode * existing_cib, xmlNode ** result_cib,
xmlNode ** answer);
int cib_process_diff(const char *op, int options, const char *section, xmlNode * req,
xmlNode * input, xmlNode * existing_cib, xmlNode ** result_cib,
xmlNode ** answer);
int cib_process_upgrade(const char *op, int options, const char *section, xmlNode * req,
xmlNode * input, xmlNode * existing_cib, xmlNode ** result_cib,
xmlNode ** answer);
/*!
* \internal
* \brief Core function to manipulate with/query CIB/XML per xpath + arguments
* \param[in] op, the operation to be performed:
* <tt>CIB_OP_{CREATE,DELETE,MODIFY,QUERY,REPLACE}</tt>
* \param[in] options, ORed flags per relevant \c cib_call_options enumeration:
* <tt>cib_{multiple,no_children,xpath_address}</tt>
* \param[in] section, xpath defining place of interest in
* <tt>{existing,result}_cib</tt>
* \param[in] req, UNUSED
* \param[in] input, the input operand for
* <tt>CIB_OP_{CREATE,MODIFY,REPLACE}</tt>
* \param[in] existing_cib, the input operand (CIB) for \c CIB_OP_QUERY
* \param[inout] result_cib, the operand and result for
* <tt>CIB_OP_{CREATE,DELETE,MODIFY,REPLACE}</tt>
* \param[out] answer, the result for \c CIB_OP_QUERY, structured per \c options
*
* \retval \c pcmk_ok (0) for success, different value for failure
*/
int cib_process_xpath(const char *op, int options, const char *section, xmlNode * req,
xmlNode * input, xmlNode * existing_cib, xmlNode ** result_cib,
xmlNode ** answer);
gboolean cib_config_changed(xmlNode * last, xmlNode * next, xmlNode ** diff);
gboolean update_results(xmlNode * failed, xmlNode * target, const char *operation, int return_code);
int cib_update_counter(xmlNode * xml_obj, const char *field, gboolean reset);
int cib_internal_op(cib_t * cib, const char *op, const char *host,
const char *section, xmlNode * data,
xmlNode ** output_data, int call_options, const char *user_name);
int cib_file_read_and_verify(const char *filename, const char *sigfile,
xmlNode **root);
int cib_file_write_with_digest(xmlNode *cib_root, const char *cib_dirname,
const char *cib_filename);
#endif
diff --git a/include/crm/cib/util.h b/include/crm/cib/util.h
index f7d70c7c8c..21420ff9be 100644
--- a/include/crm/cib/util.h
+++ b/include/crm/cib/util.h
@@ -1,71 +1,73 @@
/*
- * Copyright 2004-2019 Andrew Beekhof <andrew@beekhof.net>
+ * Copyright 2004-2019 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 CIB_UTIL__H
# define CIB_UTIL__H
#include <glib.h> // gboolean
#include <crm/cib.h> // cib_t
#include <libxml/tree.h> // xmlNode
#ifdef __cplusplus
extern "C" {
#endif
/* Utility functions */
const char *get_object_path(const char *object_type);
const char *get_object_parent(const char *object_type);
xmlNode *get_object_root(const char *object_type, xmlNode * the_root);
xmlNode *create_cib_fragment_adv(xmlNode * update, const char *section, const char *source);
xmlNode *createEmptyCib(int admin_epoch);
gboolean verifyCibXml(xmlNode * cib);
gboolean cib_version_details(xmlNode * cib, int *admin_epoch, int *epoch, int *updates);
int update_attr_delegate(cib_t * the_cib, int call_options,
const char *section, const char *node_uuid,
const char *set_type, const char *set_name,
const char *attr_id, const char *attr_name,
const char *attr_value, gboolean to_console,
const char *user_name, const char *node_type);
int find_nvpair_attr_delegate(cib_t * the_cib, const char *attr,
const char *section, const char *node_uuid,
const char *set_type, const char *set_name,
const char *attr_id, const char *attr_name,
gboolean to_console, char **value, const char *user_name);
int read_attr_delegate(cib_t * the_cib,
const char *section, const char *node_uuid,
const char *set_type, const char *set_name,
const char *attr_id, const char *attr_name,
char **attr_value, gboolean to_console, const char *user_name);
int delete_attr_delegate(cib_t * the_cib, int options,
const char *section, const char *node_uuid,
const char *set_type, const char *set_name,
const char *attr_id, const char *attr_name,
const char *attr_value, gboolean to_console, const char *user_name);
int query_node_uuid(cib_t * the_cib, const char *uname, char **uuid, int *is_remote_node);
int query_node_uname(cib_t * the_cib, const char *uuid, char **uname);
int set_standby(cib_t * the_cib, const char *uuid, const char *scope, const char *standby_value);
xmlNode *cib_get_generation(cib_t * cib);
void cib_metadata(void);
const char *cib_pref(GHashTable * options, const char *name);
int cib_apply_patch_event(xmlNode * event, xmlNode * input, xmlNode ** output, int level);
#ifdef __cplusplus
}
#endif
#endif
diff --git a/include/crm/cluster.h b/include/crm/cluster.h
index d87091a3c8..99a59c44df 100644
--- a/include/crm/cluster.h
+++ b/include/crm/cluster.h
@@ -1,209 +1,211 @@
/*
- * Copyright 2004-2018 Andrew Beekhof <andrew@beekhof.net>
+ * Copyright 2004-2018 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 CRM_COMMON_CLUSTER__H
# define CRM_COMMON_CLUSTER__H
#ifdef __cplusplus
extern "C" {
#endif
# include <crm/common/xml.h>
# include <crm/common/util.h>
# if SUPPORT_COROSYNC
# include <corosync/cpg.h>
# endif
extern gboolean crm_have_quorum;
extern GHashTable *crm_peer_cache;
extern GHashTable *crm_remote_peer_cache;
extern unsigned long long crm_peer_seq;
/* *INDENT-OFF* */
#define CRM_NODE_LOST "lost"
#define CRM_NODE_MEMBER "member"
enum crm_join_phase
{
crm_join_nack = -1,
crm_join_none = 0,
crm_join_welcomed = 1,
crm_join_integrated = 2,
crm_join_finalized = 3,
crm_join_confirmed = 4,
};
enum crm_node_flags
{
/* node is not a cluster node and should not be considered for cluster membership */
crm_remote_node = 0x0001,
/* node's cache entry is dirty */
crm_node_dirty = 0x0010,
};
/* *INDENT-ON* */
typedef struct crm_peer_node_s {
char *uname; // Node name as known to cluster
char *uuid; // Node UUID to ensure uniqueness
char *state; // @TODO change to enum
uint64_t flags; // Bitmask of crm_node_flags
uint64_t last_seen; // Only needed by cluster nodes
uint32_t processes; // @TODO most not needed, merge into flags
// Currently only needed by corosync stack
uint32_t id; // Node ID
time_t when_lost; // When CPG membership was last lost
// Only used by controller
enum crm_join_phase join;
char *expected;
} crm_node_t;
void crm_peer_init(void);
void crm_peer_destroy(void);
typedef struct crm_cluster_s {
char *uuid;
char *uname;
uint32_t nodeid;
void (*destroy) (gpointer);
# if SUPPORT_COROSYNC
struct cpg_name group;
cpg_callbacks_t cpg;
cpg_handle_t cpg_handle;
# endif
} crm_cluster_t;
gboolean crm_cluster_connect(crm_cluster_t * cluster);
void crm_cluster_disconnect(crm_cluster_t * cluster);
/* *INDENT-OFF* */
enum crm_ais_msg_class {
crm_class_cluster = 0,
};
enum crm_ais_msg_types {
crm_msg_none = 0,
crm_msg_ais = 1,
crm_msg_lrmd = 2,
crm_msg_cib = 3,
crm_msg_crmd = 4,
crm_msg_attrd = 5,
crm_msg_stonithd = 6,
crm_msg_te = 7,
crm_msg_pe = 8,
crm_msg_stonith_ng = 9,
};
/* used with crm_get_peer_full */
enum crm_get_peer_flags {
CRM_GET_PEER_CLUSTER = 0x0001,
CRM_GET_PEER_REMOTE = 0x0002,
CRM_GET_PEER_ANY = CRM_GET_PEER_CLUSTER|CRM_GET_PEER_REMOTE,
};
/* *INDENT-ON* */
gboolean send_cluster_message(crm_node_t * node, enum crm_ais_msg_types service,
xmlNode * data, gboolean ordered);
int crm_remote_peer_cache_size(void);
/* Initialize and refresh the remote peer cache from a cib config */
void crm_remote_peer_cache_refresh(xmlNode *cib);
crm_node_t *crm_remote_peer_get(const char *node_name);
void crm_remote_peer_cache_remove(const char *node_name);
/* allows filtering of remote and cluster nodes using crm_get_peer_flags */
crm_node_t *crm_get_peer_full(unsigned int id, const char *uname, int flags);
/* only searches cluster nodes */
crm_node_t *crm_get_peer(unsigned int id, const char *uname);
guint crm_active_peers(void);
gboolean crm_is_peer_active(const crm_node_t * node);
guint reap_crm_member(uint32_t id, const char *name);
int crm_terminate_member(int nodeid, const char *uname, void *unused);
int crm_terminate_member_no_mainloop(int nodeid, const char *uname, int *connection);
# if SUPPORT_COROSYNC
uint32_t get_local_nodeid(cpg_handle_t handle);
gboolean cluster_connect_cpg(crm_cluster_t *cluster);
void cluster_disconnect_cpg(crm_cluster_t * cluster);
void pcmk_cpg_membership(cpg_handle_t handle,
const struct cpg_name *groupName,
const struct cpg_address *member_list, size_t member_list_entries,
const struct cpg_address *left_list, size_t left_list_entries,
const struct cpg_address *joined_list, size_t joined_list_entries);
gboolean crm_is_corosync_peer_active(const crm_node_t * node);
gboolean send_cluster_text(enum crm_ais_msg_class msg_class, const char *data,
gboolean local, crm_node_t * node,
enum crm_ais_msg_types dest);
char *pcmk_message_common_cs(cpg_handle_t handle, uint32_t nodeid, uint32_t pid, void *msg,
uint32_t *kind, const char **from);
# endif
const char *crm_peer_uuid(crm_node_t *node);
const char *crm_peer_uname(const char *uuid);
void set_uuid(xmlNode *xml, const char *attr, crm_node_t *node);
enum crm_status_type {
crm_status_uname,
crm_status_nstate,
crm_status_processes,
};
enum crm_ais_msg_types text2msg_type(const char *text);
void crm_set_status_callback(void (*dispatch) (enum crm_status_type, crm_node_t *, const void *));
void crm_set_autoreap(gboolean autoreap);
/* *INDENT-OFF* */
enum cluster_type_e
{
pcmk_cluster_unknown = 0x0001,
pcmk_cluster_invalid = 0x0002,
// 0x0004 was heartbeat
// 0x0010 was corosync 1 with plugin
pcmk_cluster_corosync = 0x0020,
// 0x0040 was corosync 1 with CMAN
};
/* *INDENT-ON* */
enum cluster_type_e get_cluster_type(void);
const char *name_for_cluster_type(enum cluster_type_e type);
gboolean is_corosync_cluster(void);
const char *get_local_node_name(void);
char *get_node_name(uint32_t nodeid);
static inline const char *
crm_join_phase_str(enum crm_join_phase phase)
{
switch (phase) {
case crm_join_nack: return "nack";
case crm_join_none: return "none";
case crm_join_welcomed: return "welcomed";
case crm_join_integrated: return "integrated";
case crm_join_finalized: return "finalized";
case crm_join_confirmed: return "confirmed";
}
return "invalid";
}
#ifdef __cplusplus
}
#endif
#endif
diff --git a/include/crm/cluster/Makefile.am b/include/crm/cluster/Makefile.am
index bc4b39808d..cd51a6f354 100644
--- a/include/crm/cluster/Makefile.am
+++ b/include/crm/cluster/Makefile.am
@@ -1,23 +1,25 @@
#
-# Copyright (C) 2004 Andrew Beekhof
+# Copyright 2012-2017 the Pacemaker project contributors
+#
+# The version control history for this file may have further details.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
MAINTAINERCLEANFILES = Makefile.in
headerdir=$(pkgincludedir)/crm/cluster
noinst_HEADERS = internal.h election.h
header_HEADERS =
diff --git a/include/crm/cluster/election.h b/include/crm/cluster/election.h
index 0facc85c30..1dcc66c2f8 100644
--- a/include/crm/cluster/election.h
+++ b/include/crm/cluster/election.h
@@ -1,85 +1,87 @@
/*
- * Copyright 2009-2019 Andrew Beekhof <andrew@beekhof.net>
+ * Copyright 2009-2019 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 CRM_COMMON_ELECTION__H
# define CRM_COMMON_ELECTION__H
#ifdef __cplusplus
extern "C" {
#endif
/**
* \file
* \brief Functions for conducting elections
*
* An election is useful for a daemon that runs on all nodes but needs any one
* instance to perform a special role.
*
* Elections are closely tied to the cluster peer cache. Peers in the cache that
* are active members are eligible to vote. Elections are named for logging
* purposes, but only one election may exist at any time, so typically an
* election would be created at daemon start-up and freed at shutdown.
*
* Pacemaker's election procedure has been heavily adapted from the
* Invitation Algorithm variant of the Garcia-Molina Bully Algorithm:
*
* https://en.wikipedia.org/wiki/Bully_algorithm
*
* Elections are conducted via cluster messages. There are two types of
* messages: a "vote" is a declaration of the voting node's candidacy, and is
* always broadcast; a "no-vote" is a concession by the responding node, and is
* always a reply to the preferred node's vote. (These correspond to "invite"
* and "accept" in the traditional algorithm.)
*
* A vote together with any no-vote replies to it is considered an election
* round. Rounds are numbered with a simple counter unique to each node
* (this would be the group number in the traditional algorithm). Concurrent
* election rounds are possible.
*
* An election round is started when any node broadcasts a vote. When a node
* receives another node's vote, it compares itself against the sending node
* according to certain metrics, and either starts a new round (if it prefers
* itself) or replies to the other node with a no-vote (if it prefers that
* node).
*
* If a node receives no-votes from all other active nodes, it declares itself
* the winner. The library API does not notify other nodes of this; callers
* must implement that if desired.
*
* \ingroup core
*/
typedef struct election_s election_t;
/*! Possible election states */
enum election_result {
election_start = 0, /*! new election needed */
election_in_progress, /*! election started but not all peers have voted */
election_lost, /*! local node lost most recent election */
election_won, /*! local node won most recent election */
election_error, /*! election message or election object invalid */
};
void election_fini(election_t *e);
void election_reset(election_t *e);
election_t *election_init(const char *name, const char *uname, guint period_ms, GSourceFunc cb);
void election_timeout_set_period(election_t *e, guint period_ms);
void election_timeout_stop(election_t *e);
void election_vote(election_t *e);
bool election_check(election_t *e);
void election_remove(election_t *e, const char *uname);
enum election_result election_state(election_t *e);
enum election_result election_count_vote(election_t *e, xmlNode *vote, bool can_win);
void election_clear_dampening(election_t *e);
#ifdef __cplusplus
}
#endif
#endif
diff --git a/include/crm/cluster/internal.h b/include/crm/cluster/internal.h
index 12bf41ab02..73abc99d6e 100644
--- a/include/crm/cluster/internal.h
+++ b/include/crm/cluster/internal.h
@@ -1,335 +1,337 @@
/*
- * Copyright 2004-2018 Andrew Beekhof <andrew@beekhof.net>
+ * Copyright 2004-2018 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 CRM_CLUSTER_INTERNAL__H
# define CRM_CLUSTER_INTERNAL__H
# include <crm/cluster.h>
typedef struct crm_ais_host_s AIS_Host;
typedef struct crm_ais_msg_s AIS_Message;
struct crm_ais_host_s {
uint32_t id;
uint32_t pid;
gboolean local;
enum crm_ais_msg_types type;
uint32_t size;
char uname[MAX_NAME];
} __attribute__ ((packed));
struct crm_ais_msg_s {
cs_ipc_header_response_t header __attribute__ ((aligned(8)));
uint32_t id;
gboolean is_compressed;
AIS_Host host;
AIS_Host sender;
uint32_t size;
uint32_t compressed_size;
/* 584 bytes */
char data[0];
} __attribute__ ((packed));
/* *INDENT-OFF* */
enum crm_proc_flag {
crm_proc_none = 0x00000001,
// Cluster layers
crm_proc_cpg = 0x04000000,
// Daemons
crm_proc_execd = 0x00000010,
crm_proc_based = 0x00000100,
crm_proc_controld = 0x00000200,
crm_proc_attrd = 0x00001000,
crm_proc_schedulerd = 0x00010000,
crm_proc_fenced = 0x00100000,
};
/* *INDENT-ON* */
/*!
* \internal
* \brief Return the process bit corresponding to the current cluster stack
*
* \return Process flag if detectable, otherwise 0
*/
static inline uint32_t
crm_get_cluster_proc()
{
switch (get_cluster_type()) {
case pcmk_cluster_corosync:
return crm_proc_cpg;
default:
break;
}
return crm_proc_none;
}
static inline const char *
peer2text(enum crm_proc_flag proc)
{
const char *text = "unknown";
switch (proc) {
case crm_proc_none:
text = "none";
break;
case crm_proc_based:
text = "pacemaker-based";
break;
case crm_proc_controld:
text = "pacemaker-controld";
break;
case crm_proc_schedulerd:
text = "pacemaker-schedulerd";
break;
case crm_proc_execd:
text = "pacemaker-execd";
break;
case crm_proc_attrd:
text = "pacemaker-attrd";
break;
case crm_proc_fenced:
text = "pacemaker-fenced";
break;
case crm_proc_cpg:
text = "corosync-cpg";
break;
}
return text;
}
static inline const char *
ais_dest(const AIS_Host *host)
{
if (host->local) {
return "local";
} else if (host->size > 0) {
return host->uname;
} else {
return "<all>";
}
}
# define ais_data_len(msg) (msg->is_compressed?msg->compressed_size:msg->size)
/*
typedef enum {
CS_OK = 1,
CS_ERR_LIBRARY = 2,
CS_ERR_VERSION = 3,
CS_ERR_INIT = 4,
CS_ERR_TIMEOUT = 5,
CS_ERR_TRY_AGAIN = 6,
CS_ERR_INVALID_PARAM = 7,
CS_ERR_NO_MEMORY = 8,
CS_ERR_BAD_HANDLE = 9,
CS_ERR_BUSY = 10,
CS_ERR_ACCESS = 11,
CS_ERR_NOT_EXIST = 12,
CS_ERR_NAME_TOO_LONG = 13,
CS_ERR_EXIST = 14,
CS_ERR_NO_SPACE = 15,
CS_ERR_INTERRUPT = 16,
CS_ERR_NAME_NOT_FOUND = 17,
CS_ERR_NO_RESOURCES = 18,
CS_ERR_NOT_SUPPORTED = 19,
CS_ERR_BAD_OPERATION = 20,
CS_ERR_FAILED_OPERATION = 21,
CS_ERR_MESSAGE_ERROR = 22,
CS_ERR_QUEUE_FULL = 23,
CS_ERR_QUEUE_NOT_AVAILABLE = 24,
CS_ERR_BAD_FLAGS = 25,
CS_ERR_TOO_BIG = 26,
CS_ERR_NO_SECTIONS = 27,
CS_ERR_CONTEXT_NOT_FOUND = 28,
CS_ERR_TOO_MANY_GROUPS = 30,
CS_ERR_SECURITY = 100
} cs_error_t;
*/
static inline const char *
ais_error2text(int error)
{
const char *text = "unknown";
# if SUPPORT_COROSYNC
switch (error) {
case CS_OK:
text = "OK";
break;
case CS_ERR_LIBRARY:
text = "Library error";
break;
case CS_ERR_VERSION:
text = "Version error";
break;
case CS_ERR_INIT:
text = "Initialization error";
break;
case CS_ERR_TIMEOUT:
text = "Timeout";
break;
case CS_ERR_TRY_AGAIN:
text = "Try again";
break;
case CS_ERR_INVALID_PARAM:
text = "Invalid parameter";
break;
case CS_ERR_NO_MEMORY:
text = "No memory";
break;
case CS_ERR_BAD_HANDLE:
text = "Bad handle";
break;
case CS_ERR_BUSY:
text = "Busy";
break;
case CS_ERR_ACCESS:
text = "Access error";
break;
case CS_ERR_NOT_EXIST:
text = "Doesn't exist";
break;
case CS_ERR_NAME_TOO_LONG:
text = "Name too long";
break;
case CS_ERR_EXIST:
text = "Exists";
break;
case CS_ERR_NO_SPACE:
text = "No space";
break;
case CS_ERR_INTERRUPT:
text = "Interrupt";
break;
case CS_ERR_NAME_NOT_FOUND:
text = "Name not found";
break;
case CS_ERR_NO_RESOURCES:
text = "No resources";
break;
case CS_ERR_NOT_SUPPORTED:
text = "Not supported";
break;
case CS_ERR_BAD_OPERATION:
text = "Bad operation";
break;
case CS_ERR_FAILED_OPERATION:
text = "Failed operation";
break;
case CS_ERR_MESSAGE_ERROR:
text = "Message error";
break;
case CS_ERR_QUEUE_FULL:
text = "Queue full";
break;
case CS_ERR_QUEUE_NOT_AVAILABLE:
text = "Queue not available";
break;
case CS_ERR_BAD_FLAGS:
text = "Bad flags";
break;
case CS_ERR_TOO_BIG:
text = "Too big";
break;
case CS_ERR_NO_SECTIONS:
text = "No sections";
break;
}
# endif
return text;
}
static inline const char *
msg_type2text(enum crm_ais_msg_types type)
{
const char *text = "unknown";
switch (type) {
case crm_msg_none:
text = "unknown";
break;
case crm_msg_ais:
text = "ais";
break;
case crm_msg_cib:
text = "cib";
break;
case crm_msg_crmd:
text = "crmd";
break;
case crm_msg_pe:
text = "pengine";
break;
case crm_msg_te:
text = "tengine";
break;
case crm_msg_lrmd:
text = "lrmd";
break;
case crm_msg_attrd:
text = "attrd";
break;
case crm_msg_stonithd:
text = "stonithd";
break;
case crm_msg_stonith_ng:
text = "stonith-ng";
break;
}
return text;
}
gboolean check_message_sanity(const AIS_Message * msg, const char *data);
# if SUPPORT_COROSYNC
gboolean send_cpg_iov(struct iovec * iov);
char *get_corosync_uuid(crm_node_t *peer);
char *corosync_node_name(uint64_t /*cmap_handle_t */ cmap_handle, uint32_t nodeid);
char *corosync_cluster_name(void);
int corosync_cmap_has_config(const char *prefix);
gboolean corosync_initialize_nodelist(void *cluster, gboolean force_member, xmlNode * xml_parent);
gboolean send_cluster_message_cs(xmlNode * msg, gboolean local,
crm_node_t * node, enum crm_ais_msg_types dest);
enum cluster_type_e find_corosync_variant(void);
void terminate_cs_connection(crm_cluster_t * cluster);
gboolean init_cs_connection(crm_cluster_t * cluster);
gboolean init_cs_connection_once(crm_cluster_t * cluster);
# endif
crm_node_t *crm_update_peer_proc(const char *source, crm_node_t * peer,
uint32_t flag, const char *status);
crm_node_t *crm_update_peer_state(const char *source, crm_node_t * node,
const char *state, int membership);
void crm_update_peer_uname(crm_node_t *node, const char *uname);
void crm_update_peer_expected(const char *source, crm_node_t * node, const char *expected);
void crm_reap_unseen_nodes(uint64_t ring_id);
gboolean cluster_connect_quorum(gboolean(*dispatch) (unsigned long long, gboolean),
void (*destroy) (gpointer));
gboolean node_name_is_valid(const char *key, const char *name);
crm_node_t * crm_find_peer_full(unsigned int id, const char *uname, int flags);
crm_node_t * crm_find_peer(unsigned int id, const char *uname);
void crm_peer_caches_refresh(xmlNode *cib);
crm_node_t *crm_find_known_peer_full(unsigned int id, const char *uname, int flags);
#endif
diff --git a/include/crm/common/Makefile.am b/include/crm/common/Makefile.am
index 40a01e3963..7400152984 100644
--- a/include/crm/common/Makefile.am
+++ b/include/crm/common/Makefile.am
@@ -1,15 +1,17 @@
#
-# Copyright 2004-2019 Andrew Beekhof <andrew@beekhof.net>
+# Copyright 2004-2019 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/common
header_HEADERS = xml.h ipc.h util.h iso8601.h mainloop.h logging.h results.h \
nvpair.h
noinst_HEADERS = cib_secrets.h ipcs.h internal.h alerts_internal.h \
iso8601_internal.h remote_internal.h xml_internal.h
diff --git a/include/crm/common/alerts_internal.h b/include/crm/common/alerts_internal.h
index 6d37800954..2cd2e638e7 100644
--- a/include/crm/common/alerts_internal.h
+++ b/include/crm/common/alerts_internal.h
@@ -1,97 +1,99 @@
/*
- * Copyright 2015-2019 Andrew Beekhof <andrew@beekhof.net>
+ * Copyright 2015-2019 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 ALERT_INTERNAL_H
#define ALERT_INTERNAL_H
#include <glib.h>
#include <stdbool.h>
/* Default-Timeout to use before killing a alerts script (in milliseconds) */
# define CRM_ALERT_DEFAULT_TIMEOUT_MS (30000)
/* Default-Format-String used to pass timestamps to the alerts scripts */
# define CRM_ALERT_DEFAULT_TSTAMP_FORMAT "%H:%M:%S.%06N"
enum crm_alert_flags {
crm_alert_none = 0x0000,
crm_alert_node = 0x0001,
crm_alert_fencing = 0x0002,
crm_alert_resource = 0x0004,
crm_alert_attribute = 0x0008,
crm_alert_default = crm_alert_node|crm_alert_fencing|crm_alert_resource
};
typedef struct {
char *id;
char *path;
char *tstamp_format;
char *recipient;
char **select_attribute_name;
GHashTable *envvars;
int timeout;
uint32_t flags;
} crm_alert_entry_t;
enum crm_alert_keys_e {
CRM_alert_recipient = 0,
CRM_alert_node,
CRM_alert_nodeid,
CRM_alert_rsc,
CRM_alert_task,
CRM_alert_interval,
CRM_alert_desc,
CRM_alert_status,
CRM_alert_target_rc,
CRM_alert_rc,
CRM_alert_kind,
CRM_alert_version,
CRM_alert_node_sequence,
CRM_alert_timestamp,
CRM_alert_attribute_name,
CRM_alert_attribute_value,
CRM_alert_timestamp_epoch,
CRM_alert_timestamp_usec,
CRM_alert_exec_time,
CRM_alert_select_kind,
CRM_alert_select_attribute_name
};
#define CRM_ALERT_INTERNAL_KEY_MAX 19
#define CRM_ALERT_NODE_SEQUENCE "CRM_alert_node_sequence"
extern const char *crm_alert_keys[CRM_ALERT_INTERNAL_KEY_MAX][3];
crm_alert_entry_t *crm_dup_alert_entry(crm_alert_entry_t *entry);
crm_alert_entry_t *crm_alert_entry_new(const char *id, const char *path);
void crm_free_alert_entry(crm_alert_entry_t *entry);
void crm_insert_alert_key(GHashTable *table, enum crm_alert_keys_e name,
const char *value);
void crm_insert_alert_key_int(GHashTable *table, enum crm_alert_keys_e name,
int value);
void crm_unset_alert_keys(void);
void crm_set_envvar_list(crm_alert_entry_t *entry);
void crm_unset_envvar_list(crm_alert_entry_t *entry);
bool crm_patchset_contains_alert(xmlNode *msg, bool config);
static inline const char *
crm_alert_flag2text(enum crm_alert_flags flag)
{
switch (flag) {
case crm_alert_node:
return "node";
case crm_alert_fencing:
return "fencing";
case crm_alert_resource:
return "resource";
case crm_alert_attribute:
return "attribute";
default:
return "unknown";
}
}
#endif
diff --git a/include/crm/common/cib_secrets.h b/include/crm/common/cib_secrets.h
index b5cf41eb94..d6fcb13aac 100644
--- a/include/crm/common/cib_secrets.h
+++ b/include/crm/common/cib_secrets.h
@@ -1,25 +1,26 @@
/*
- * Copyright 2011-2018 SUSE, Attachmate
- * Author: Dejan Muhamedagic <dejan@suse.de>
+ * Copyright 2011-2018 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.
*/
#ifndef CIB_SECRETS__H
#define CIB_SECRETS__H
#ifdef __cplusplus
extern "C" {
#endif
/*
* load parameters from an ini file (cib_secrets.c)
*/
int replace_secret_params(const char *rsc_id, GHashTable *params);
#ifdef __cplusplus
}
#endif
#endif
diff --git a/include/crm/common/internal.h b/include/crm/common/internal.h
index c9ee488755..e59c7bf3d6 100644
--- a/include/crm/common/internal.h
+++ b/include/crm/common/internal.h
@@ -1,151 +1,153 @@
/*
- * Copyright 2015-2018 Andrew Beekhof <andrew@beekhof.net>
+ * Copyright 2015-2018 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 CRM_COMMON_INTERNAL__H
#define CRM_COMMON_INTERNAL__H
#include <glib.h> /* for gboolean */
#include <dirent.h> /* for struct dirent */
#include <unistd.h> /* for getpid() */
#include <sys/types.h> /* for uid_t and gid_t */
#include <crm/common/logging.h>
/* internal I/O utilities (from io.c) */
char *generate_series_filename(const char *directory, const char *series, int sequence,
gboolean bzip);
int get_last_sequence(const char *directory, const char *series);
void write_last_sequence(const char *directory, const char *series, int sequence, int max);
int crm_chown_last_sequence(const char *directory, const char *series, uid_t uid, gid_t gid);
bool pcmk__daemon_can_write(const char *dir, const char *file);
void crm_sync_directory(const char *name);
char *crm_read_contents(const char *filename);
int crm_write_sync(int fd, const char *contents);
int crm_set_nonblocking(int fd);
const char *crm_get_tmpdir(void);
/* internal procfs utilities (from procfs.c) */
int crm_procfs_process_info(struct dirent *entry, char *name, int *pid);
int crm_procfs_pid_of(const char *name);
unsigned int crm_procfs_num_cores(void);
/* internal XML schema functions (from xml.c) */
void crm_schema_init(void);
void crm_schema_cleanup(void);
/* internal functions related to process IDs (from pid.c) */
int crm_pid_active(long pid, const char *daemon);
long crm_pidfile_inuse(const char *filename, long mypid, const char *daemon);
long crm_read_pidfile(const char *filename);
int crm_lock_pidfile(const char *filename, const char *name);
/* interal functions related to resource operations (from operations.c) */
char *generate_op_key(const char *rsc_id, const char *op_type,
guint interval_ms);
char *generate_notify_key(const char *rsc_id, const char *notify_type,
const char *op_type);
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);
// miscellaneous utilities (from utils.c)
const char *pcmk_message_name(const char *name);
/* internal generic string functions (from strings.c) */
long long crm_int_helper(const char *text, char **end_text);
guint crm_parse_ms(const char *text);
bool crm_starts_with(const char *str, const char *prefix);
gboolean crm_ends_with(const char *s, const char *match);
gboolean crm_ends_with_ext(const char *s, const char *match);
char *add_list_element(char *list, const char *value);
bool crm_compress_string(const char *data, int length, int max, char **result,
unsigned int *result_len);
gint crm_alpha_sort(gconstpointer a, gconstpointer b);
static inline char *
crm_concat(const char *prefix, const char *suffix, char join)
{
CRM_ASSERT(prefix && suffix);
return crm_strdup_printf("%s%c%s", prefix, join, suffix);
}
static inline int
crm_strlen_zero(const char *s)
{
return !s || *s == '\0';
}
static inline char *
crm_getpid_s()
{
return crm_strdup_printf("%lu", (unsigned long) getpid());
}
/* convenience functions for failure-related node attributes */
#define CRM_FAIL_COUNT_PREFIX "fail-count"
#define CRM_LAST_FAILURE_PREFIX "last-failure"
/*!
* \internal
* \brief Generate a failure-related node attribute name for a resource
*
* \param[in] prefix Start of attribute name
* \param[in] rsc_id Resource name
* \param[in] op Operation name
* \param[in] interval_ms Operation interval
*
* \return Newly allocated string with attribute name
*
* \note Failure attributes are named like PREFIX-RSC#OP_INTERVAL (for example,
* "fail-count-myrsc#monitor_30000"). The '#' is used because it is not
* a valid character in a resource ID, to reliably distinguish where the
* operation name begins. The '_' is used simply to be more comparable to
* action labels like "myrsc_monitor_30000".
*/
static inline char *
crm_fail_attr_name(const char *prefix, const char *rsc_id, const char *op,
guint interval_ms)
{
CRM_CHECK(prefix && rsc_id && op, return NULL);
return crm_strdup_printf("%s-%s#%s_%u", prefix, rsc_id, op, interval_ms);
}
static inline char *
crm_failcount_name(const char *rsc_id, const char *op, guint interval_ms)
{
return crm_fail_attr_name(CRM_FAIL_COUNT_PREFIX, rsc_id, op, interval_ms);
}
static inline char *
crm_lastfailure_name(const char *rsc_id, const char *op, guint interval_ms)
{
return crm_fail_attr_name(CRM_LAST_FAILURE_PREFIX, rsc_id, op, interval_ms);
}
#endif /* CRM_COMMON_INTERNAL__H */
diff --git a/include/crm/common/ipc.h b/include/crm/common/ipc.h
index 1270cbeeb4..84a3a71f4b 100644
--- a/include/crm/common/ipc.h
+++ b/include/crm/common/ipc.h
@@ -1,84 +1,86 @@
/*
- * Copyright 2013-2018 Andrew Beekhof <andrew@beekhof.net>
+ * Copyright 2004-2018 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 CRM_COMMON_IPC__H
# define CRM_COMMON_IPC__H
#ifdef __cplusplus
extern "C" {
#endif
/**
* \file
* \brief Wrappers for and extensions to libqb IPC
* \ingroup core
*/
#include <sys/uio.h>
#include <qb/qbipcc.h>
#include <crm/common/xml.h>
/* clplumbing based IPC */
# define create_reply(request, xml_response_data) create_reply_adv(request, xml_response_data, __FUNCTION__);
xmlNode *create_reply_adv(xmlNode * request, xmlNode * xml_response_data, const char *origin);
# define create_request(task, xml_data, host_to, sys_to, sys_from, uuid_from) create_request_adv(task, xml_data, host_to, sys_to, sys_from, uuid_from, __FUNCTION__)
xmlNode *create_request_adv(const char *task, xmlNode * xml_data, const char *host_to,
const char *sys_to, const char *sys_from, const char *uuid_from,
const char *origin);
/* *INDENT-OFF* */
enum crm_ipc_flags
{
crm_ipc_flags_none = 0x00000000,
crm_ipc_compressed = 0x00000001, /* Message has been compressed */
crm_ipc_proxied = 0x00000100, /* _ALL_ replies to proxied connections need to be sent as events */
crm_ipc_client_response = 0x00000200, /* A Response is expected in reply */
/* These options are just options for crm_ipcs_sendv() */
crm_ipc_server_event = 0x00010000, /* Send an Event instead of a Response */
crm_ipc_server_free = 0x00020000, /* Free the iovec after sending */
crm_ipc_proxied_relay_response = 0x00040000, /* all replies to proxied connections are sent as events, this flag preserves whether the event should be treated as an actual event, or a response.*/
crm_ipc_server_info = 0x00100000, /* Log failures as LOG_INFO */
crm_ipc_server_error = 0x00200000, /* Log failures as LOG_ERR */
};
/* *INDENT-ON* */
typedef struct crm_ipc_s crm_ipc_t;
crm_ipc_t *crm_ipc_new(const char *name, size_t max_size);
bool crm_ipc_connect(crm_ipc_t * client);
void crm_ipc_close(crm_ipc_t * client);
void crm_ipc_destroy(crm_ipc_t * client);
void pcmk_free_ipc_event(struct iovec *event);
int crm_ipc_send(crm_ipc_t * client, xmlNode * message, enum crm_ipc_flags flags,
int32_t ms_timeout, xmlNode ** reply);
int crm_ipc_get_fd(crm_ipc_t * client);
bool crm_ipc_connected(crm_ipc_t * client);
int crm_ipc_ready(crm_ipc_t * client);
long crm_ipc_read(crm_ipc_t * client);
const char *crm_ipc_buffer(crm_ipc_t * client);
uint32_t crm_ipc_buffer_flags(crm_ipc_t * client);
const char *crm_ipc_name(crm_ipc_t * client);
unsigned int crm_ipc_default_buffer_size(void);
/* Utils */
xmlNode *create_hello_message(const char *uuid, const char *client_name,
const char *major_version, const char *minor_version);
#ifdef __cplusplus
}
#endif
#endif
diff --git a/include/crm/common/ipcs.h b/include/crm/common/ipcs.h
index a10765960b..c4462007d8 100644
--- a/include/crm/common/ipcs.h
+++ b/include/crm/common/ipcs.h
@@ -1,126 +1,128 @@
/*
- * Copyright 2013-2018 Andrew Beekhof <andrew@beekhof.net>
+ * Copyright 2013-2018 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 CRM_COMMON_IPCS__H
# define CRM_COMMON_IPCS__H
#ifdef __cplusplus
extern "C" {
#endif
# include <stdbool.h>
# include <qb/qbipcs.h>
# ifdef HAVE_GNUTLS_GNUTLS_H
# undef KEYFILE
# include <gnutls/gnutls.h>
# endif
# include <crm/common/ipc.h>
# include <crm/common/mainloop.h>
typedef struct crm_client_s crm_client_t;
enum client_type {
CRM_CLIENT_IPC = 1,
CRM_CLIENT_TCP = 2,
# ifdef HAVE_GNUTLS_GNUTLS_H
CRM_CLIENT_TLS = 3,
# endif
};
struct crm_remote_s {
/* Shared */
char *buffer;
size_t buffer_size;
size_t buffer_offset;
int auth_timeout;
int tcp_socket;
mainloop_io_t *source;
/* CIB-only */
bool authenticated;
char *token;
/* TLS only */
# ifdef HAVE_GNUTLS_GNUTLS_H
gnutls_session_t *tls_session;
bool tls_handshake_complete;
# endif
};
enum crm_client_flags
{
crm_client_flag_ipc_proxied = 0x00001, /* ipc_proxy code only */
crm_client_flag_ipc_privileged = 0x00002, /* root or cluster user */
};
struct crm_client_s {
uint pid;
uid_t uid;
gid_t gid;
char *id;
char *name;
char *user;
/* Provided for server use (not used by library) */
/* @TODO merge options, flags, and kind (reserving lower bits for server) */
long long options;
int request_id;
uint32_t flags;
void *userdata;
int event_timer;
GQueue *event_queue;
/* Depending on the value of kind, only some of the following
* will be populated/valid
*/
enum client_type kind;
qb_ipcs_connection_t *ipcs; /* IPC */
struct crm_remote_s *remote; /* TCP/TLS */
unsigned int queue_backlog; /* IPC queue length after last flush */
unsigned int queue_max; /* Evict client whose queue grows this big */
};
extern GHashTable *client_connections;
void crm_client_init(void);
void crm_client_cleanup(void);
crm_client_t *crm_client_get(qb_ipcs_connection_t * c);
crm_client_t *crm_client_get_by_id(const char *id);
const char *crm_client_name(crm_client_t * c);
const char *crm_client_type_text(enum client_type client_type);
crm_client_t *crm_client_alloc(void *key);
crm_client_t *crm_client_new(qb_ipcs_connection_t * c, uid_t uid, gid_t gid);
void crm_client_destroy(crm_client_t * c);
void crm_client_disconnect_all(qb_ipcs_service_t *s);
bool crm_set_client_queue_max(crm_client_t *client, const char *qmax);
void crm_ipcs_send_ack(crm_client_t * c, uint32_t request, uint32_t flags,
const char *tag, const char *function, int line);
/* when max_send_size is 0, default ipc buffer size is used */
ssize_t crm_ipc_prepare(uint32_t request, xmlNode * message, struct iovec ** result, uint32_t max_send_size);
ssize_t crm_ipcs_send(crm_client_t * c, uint32_t request, xmlNode * message, enum crm_ipc_flags flags);
ssize_t crm_ipcs_sendv(crm_client_t * c, struct iovec *iov, enum crm_ipc_flags flags);
xmlNode *crm_ipcs_recv(crm_client_t * c, void *data, size_t size, uint32_t * id, uint32_t * flags);
int crm_ipcs_client_pid(qb_ipcs_connection_t * c);
#ifdef __cplusplus
}
#endif
#endif
diff --git a/include/crm/common/iso8601_internal.h b/include/crm/common/iso8601_internal.h
index d7ceee8e34..f26827e744 100644
--- a/include/crm/common/iso8601_internal.h
+++ b/include/crm/common/iso8601_internal.h
@@ -1,47 +1,49 @@
/*
- * Copyright (C) 2015 Andrew Beekhof <andrew@beekhof.net>
+ * Copyright 2015-2017 the Pacemaker project contributors
+ *
+ * The version control history for this file may have further details.
*
* 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 software 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
* 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_COMMON_ISO8601_INTERNAL
# define CRM_COMMON_ISO8601_INTERNAL
#include <time.h>
#include <sys/time.h>
#include <ctype.h>
#include <crm/common/iso8601.h>
typedef struct crm_time_us crm_time_hr_t;
crm_time_hr_t *crm_time_hr_convert(crm_time_hr_t *target, crm_time_t *dt);
void crm_time_set_hr_dt(crm_time_t *target, crm_time_hr_t *hr_dt);
crm_time_hr_t *crm_time_timeval_hr_convert(crm_time_hr_t *target,
struct timeval *tv);
crm_time_hr_t *crm_time_hr_new(const char *date_time);
void crm_time_hr_free(crm_time_hr_t * hr_dt);
char *crm_time_format_hr(const char *format, crm_time_hr_t * hr_dt);
crm_time_t *parse_date(const char *date_str); /* in iso8601.c global but
not in header */
struct crm_time_us {
int years;
int months; /* Only for durations */
int days;
int seconds;
int offset; /* Seconds */
bool duration;
int useconds;
};
#endif
diff --git a/include/crm/common/logging.h b/include/crm/common/logging.h
index c6a103f548..5a744021f2 100644
--- a/include/crm/common/logging.h
+++ b/include/crm/common/logging.h
@@ -1,281 +1,283 @@
/*
- * Copyright (C) 2004 Andrew Beekhof <andrew@beekhof.net>
+ * Copyright 2004-2018 the Pacemaker project contributors
+ *
+ * The version control history for this file may have further details.
*
* 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 software 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
* 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
*/
#ifdef __cplusplus
extern "C" {
#endif
/**
* \file
* \brief Wrappers for and extensions to libqb logging
* \ingroup core
*/
#ifndef CRM_LOGGING__H
# define CRM_LOGGING__H
# include <qb/qblog.h>
# ifndef LOG_TRACE
# define LOG_TRACE LOG_DEBUG+1
# endif
/* "Extended information" logging support */
#ifdef QB_XS
# define CRM_XS QB_XS
# define crm_extended_logging(t, e) qb_log_ctl((t), QB_LOG_CONF_EXTENDED, (e))
#else
# define CRM_XS "|"
/* A caller might want to check the return value, so we can't define this as a
* no-op, and we can't simply define it to be 0 because gcc will then complain
* when the value isn't checked.
*/
static inline int
crm_extended_logging(int t, int e)
{
return 0;
}
#endif
extern unsigned int crm_log_level;
extern gboolean crm_config_error;
extern gboolean crm_config_warning;
extern unsigned int crm_trace_nonlog;
enum xml_log_options
{
xml_log_option_filtered = 0x0001,
xml_log_option_formatted = 0x0002,
xml_log_option_text = 0x0004, /* add this option to dump text into xml */
xml_log_option_diff_plus = 0x0010,
xml_log_option_diff_minus = 0x0020,
xml_log_option_diff_short = 0x0040,
xml_log_option_diff_all = 0x0100,
xml_log_option_dirty_add = 0x1000,
xml_log_option_open = 0x2000,
xml_log_option_children = 0x4000,
xml_log_option_close = 0x8000,
};
void crm_enable_blackbox(int nsig);
void crm_disable_blackbox(int nsig);
void crm_write_blackbox(int nsig, struct qb_log_callsite *callsite);
void crm_update_callsites(void);
void crm_log_deinit(void);
gboolean crm_log_cli_init(const char *entity);
void crm_log_preinit(const char *entity, int argc, char **argv);
gboolean crm_log_init(const char *entity, uint8_t level, gboolean daemon,
gboolean to_stderr, int argc, char **argv, gboolean quiet);
void crm_log_args(int argc, char **argv);
void crm_log_output_fn(const char *file, const char *function, int line, int level,
const char *prefix, const char *output);
# define crm_log_output(level, prefix, output) crm_log_output_fn(__FILE__, __FUNCTION__, __LINE__, level, prefix, output)
gboolean crm_add_logfile(const char *filename);
void crm_bump_log_level(int argc, char **argv);
void crm_enable_stderr(int enable);
gboolean crm_is_callsite_active(struct qb_log_callsite *cs, uint8_t level, uint32_t tags);
void log_data_element(int log_level, const char *file, const char *function, int line,
const char *prefix, xmlNode * data, int depth, gboolean formatted);
/* returns the old value */
unsigned int set_crm_log_level(unsigned int level);
unsigned int get_crm_log_level(void);
/*
* Throughout the macros below, note the leading, pre-comma, space in the
* various ' , ##args' occurrences to aid portability across versions of 'gcc'.
* http://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html#Variadic-Macros
*/
#if defined(__clang__)
# define CRM_TRACE_INIT_DATA(name)
# else
# include <assert.h> // required by QB_LOG_INIT_DATA() macro
# define CRM_TRACE_INIT_DATA(name) QB_LOG_INIT_DATA(name)
#endif
/*!
* \brief Log a message
*
* \param[in] level Severity at which to log the message
* \param[in] fmt printf-style format string for message
* \param[in] args Any arguments needed by format string
*/
# define do_crm_log(level, fmt, args...) \
qb_log_from_external_source(__func__, __FILE__, fmt, level, __LINE__, 0 , ##args)
/*!
* \brief Log a message that is likely to be filtered out
*
* \param[in] level Severity at which to log the message
* \param[in] fmt printf-style format string for message
* \param[in] args Any arguments needed by format string
*/
# define do_crm_log_unlikely(level, fmt, args...) do { \
static struct qb_log_callsite *trace_cs = NULL; \
if(trace_cs == NULL) { \
trace_cs = qb_log_callsite_get(__func__, __FILE__, fmt, level, __LINE__, 0); \
} \
if (crm_is_callsite_active(trace_cs, level, 0)) { \
qb_log_from_external_source( \
__func__, __FILE__, fmt, level, __LINE__, 0 , ##args); \
} \
} while(0)
# define CRM_LOG_ASSERT(expr) do { \
if(__unlikely((expr) == FALSE)) { \
static struct qb_log_callsite *core_cs = NULL; \
if(core_cs == NULL) { \
core_cs = qb_log_callsite_get(__func__, __FILE__, "log-assert", LOG_TRACE, __LINE__, 0); \
} \
crm_abort(__FILE__, __FUNCTION__, __LINE__, #expr, \
core_cs?core_cs->targets:FALSE, TRUE); \
} \
} while(0)
/* 'failure_action' MUST NOT be 'continue' as it will apply to the
* macro's do-while loop
*/
# define CRM_CHECK(expr, failure_action) do { \
if(__unlikely((expr) == FALSE)) { \
static struct qb_log_callsite *core_cs = NULL; \
if(core_cs == NULL) { \
core_cs = qb_log_callsite_get(__func__, __FILE__, "check-assert", LOG_TRACE, __LINE__, 0); \
} \
crm_abort(__FILE__, __FUNCTION__, __LINE__, #expr, \
core_cs?core_cs->targets:FALSE, TRUE); \
failure_action; \
} \
} while(0)
# define do_crm_log_xml(level, text, xml) do { \
static struct qb_log_callsite *xml_cs = NULL; \
if(xml_cs == NULL) { \
xml_cs = qb_log_callsite_get(__func__, __FILE__, "xml-blob", level, __LINE__, 0); \
} \
if (crm_is_callsite_active(xml_cs, level, 0)) { \
log_data_element(level, __FILE__, __FUNCTION__, __LINE__, text, xml, 1, xml_log_option_formatted); \
} \
} while(0)
/*!
* \brief Log a message as if it came from a different code location
*
* \param[in] level Severity at which to log the message
* \param[in] file Source file name to use instead of __FILE__
* \param[in] function Source function name to use instead of __func__
* \param[in] line Source line number to use instead of __line__
* \param[in] fmt printf-style format string for message
* \param[in] args Any arguments needed by format string
*/
# define do_crm_log_alias(level, file, function, line, fmt, args...) do { \
if(level > 0) { \
qb_log_from_external_source(function, file, fmt, level, line, 0 , ##args); \
} else { \
printf(fmt "\n" , ##args); \
} \
} while(0)
/*!
* \brief Log a message using constant severity
*
* \param[in] level Severity at which to log the message
* \param[in] fmt printf-style format string for message
* \param[in] args Any arguments needed by format string
*
* \note level and fmt /MUST/ be constants else compilation may fail
*/
# define do_crm_log_always(level, fmt, args...) qb_log(level, fmt , ##args)
/*!
* \brief Log a system error message
*
* \param[in] level Severity at which to log the message
* \param[in] fmt printf-style format string for message
* \param[in] args Any arguments needed by format string
*
* \note Because crm_perror() adds the system error message and error number
* onto the end of fmt, that information will become extended information
* if CRM_XS is used inside fmt and will not show up in syslog.
*/
# define crm_perror(level, fmt, args...) do { \
const char *err = strerror(errno); \
/* cast to int makes coverity happy when level == 0 */ \
if (level <= (int)crm_log_level) { \
fprintf(stderr, fmt ": %s (%d)\n" , ##args, err, errno); \
} \
do_crm_log(level, fmt ": %s (%d)" , ##args, err, errno); \
} while(0)
# define crm_log_tag(level, tag, fmt, args...) do { \
static struct qb_log_callsite *trace_tag_cs = NULL; \
int converted_tag = g_quark_try_string(tag); \
if(trace_tag_cs == NULL) { \
trace_tag_cs = qb_log_callsite_get(__func__, __FILE__, fmt, level, __LINE__, converted_tag); \
} \
if (crm_is_callsite_active(trace_tag_cs, level, converted_tag)) { \
qb_log_from_external_source(__func__, __FILE__, fmt, level, \
__LINE__, converted_tag , ##args); \
} \
} while(0)
# define crm_crit(fmt, args...) qb_logt(LOG_CRIT, 0, fmt , ##args)
# define crm_err(fmt, args...) qb_logt(LOG_ERR, 0, fmt , ##args)
# define crm_warn(fmt, args...) qb_logt(LOG_WARNING, 0, fmt , ##args)
# define crm_notice(fmt, args...) qb_logt(LOG_NOTICE, 0, fmt , ##args)
# define crm_info(fmt, args...) qb_logt(LOG_INFO, 0, fmt , ##args)
# define crm_debug(fmt, args...) do_crm_log_unlikely(LOG_DEBUG, fmt , ##args)
# define crm_trace(fmt, args...) do_crm_log_unlikely(LOG_TRACE, fmt , ##args)
# define crm_log_xml_crit(xml, text) do_crm_log_xml(LOG_CRIT, text, xml)
# define crm_log_xml_err(xml, text) do_crm_log_xml(LOG_ERR, text, xml)
# define crm_log_xml_warn(xml, text) do_crm_log_xml(LOG_WARNING, text, xml)
# define crm_log_xml_notice(xml, text) do_crm_log_xml(LOG_NOTICE, text, xml)
# define crm_log_xml_info(xml, text) do_crm_log_xml(LOG_INFO, text, xml)
# define crm_log_xml_debug(xml, text) do_crm_log_xml(LOG_DEBUG, text, xml)
# define crm_log_xml_trace(xml, text) do_crm_log_xml(LOG_TRACE, text, xml)
# define crm_log_xml_explicit(xml, text) do { \
static struct qb_log_callsite *digest_cs = NULL; \
digest_cs = qb_log_callsite_get( \
__func__, __FILE__, text, LOG_TRACE, __LINE__, \
crm_trace_nonlog); \
if (digest_cs && digest_cs->targets) { \
do_crm_log_xml(LOG_TRACE, text, xml); \
} \
} while(0)
# define crm_str(x) (const char*)(x?x:"<null>")
#ifdef __cplusplus
}
#endif
#endif
diff --git a/include/crm/common/mainloop.h b/include/crm/common/mainloop.h
index 2ddf089d9c..c7b43ca532 100644
--- a/include/crm/common/mainloop.h
+++ b/include/crm/common/mainloop.h
@@ -1,127 +1,129 @@
/*
- * Copyright 2009-2018 Andrew Beekhof <andrew@beekhof.net>
+ * Copyright 2009-2018 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 CRM_COMMON_MAINLOOP__H
# define CRM_COMMON_MAINLOOP__H
#ifdef __cplusplus
extern "C" {
#endif
/**
* \file
* \brief Wrappers for and extensions to glib mainloop
* \ingroup core
*/
# include <glib.h>
enum mainloop_child_flags {
/* don't kill pid group on timeout, only kill the pid */
mainloop_leave_pid_group = 0x01,
};
typedef struct trigger_s crm_trigger_t;
typedef struct mainloop_io_s mainloop_io_t;
typedef struct mainloop_child_s mainloop_child_t;
typedef struct mainloop_timer_s mainloop_timer_t;
void mainloop_cleanup(void);
crm_trigger_t *mainloop_add_trigger(int priority, int (*dispatch) (gpointer user_data),
gpointer userdata);
void mainloop_set_trigger(crm_trigger_t * source);
void mainloop_trigger_complete(crm_trigger_t * trig);
gboolean mainloop_destroy_trigger(crm_trigger_t * source);
gboolean crm_signal(int sig, void (*dispatch) (int sig));
gboolean mainloop_add_signal(int sig, void (*dispatch) (int sig));
gboolean mainloop_destroy_signal(int sig);
bool mainloop_timer_running(mainloop_timer_t *t);
void mainloop_timer_start(mainloop_timer_t *t);
void mainloop_timer_stop(mainloop_timer_t *t);
guint mainloop_timer_set_period(mainloop_timer_t *t, guint period_ms);
mainloop_timer_t *mainloop_timer_add(const char *name, guint period_ms, bool repeat, GSourceFunc cb, void *userdata);
void mainloop_timer_del(mainloop_timer_t *t);
# include <crm/common/ipc.h>
# include <qb/qbipcs.h>
struct ipc_client_callbacks {
int (*dispatch) (const char *buffer, ssize_t length, gpointer userdata);
void (*destroy) (gpointer);
};
qb_ipcs_service_t *mainloop_add_ipc_server(const char *name, enum qb_ipc_type type,
struct qb_ipcs_service_handlers *callbacks);
void mainloop_del_ipc_server(qb_ipcs_service_t * server);
mainloop_io_t *mainloop_add_ipc_client(const char *name, int priority, size_t max_size,
void *userdata, struct ipc_client_callbacks *callbacks);
void mainloop_del_ipc_client(mainloop_io_t * client);
crm_ipc_t *mainloop_get_ipc_client(mainloop_io_t * client);
struct mainloop_fd_callbacks {
int (*dispatch) (gpointer userdata);
void (*destroy) (gpointer userdata);
};
mainloop_io_t *mainloop_add_fd(const char *name, int priority, int fd, void *userdata,
struct mainloop_fd_callbacks *callbacks);
void mainloop_del_fd(mainloop_io_t * client);
/*
* Create a new tracked process
* To track a process group, use -pid
*/
void mainloop_child_add(pid_t pid,
int timeout,
const char *desc,
void *userdata,
void (*callback) (mainloop_child_t * p, pid_t pid, int core, int signo, int exitcode));
void mainloop_child_add_with_flags(pid_t pid,
int timeout,
const char *desc,
void *userdata,
enum mainloop_child_flags,
void (*callback) (mainloop_child_t * p, pid_t pid, int core, int signo, int exitcode));
void *mainloop_child_userdata(mainloop_child_t * child);
int mainloop_child_timeout(mainloop_child_t * child);
const char *mainloop_child_name(mainloop_child_t * child);
pid_t mainloop_child_pid(mainloop_child_t * child);
void mainloop_clear_child_userdata(mainloop_child_t * child);
gboolean mainloop_child_kill(pid_t pid);
void pcmk_drain_main_loop(GMainLoop *mloop, guint timer_ms,
bool (*check)(guint));
# define G_PRIORITY_MEDIUM (G_PRIORITY_HIGH/2)
#ifdef __cplusplus
}
#endif
#endif
diff --git a/include/crm/common/nvpair.h b/include/crm/common/nvpair.h
index 20520dd64e..0a49e6b056 100644
--- a/include/crm/common/nvpair.h
+++ b/include/crm/common/nvpair.h
@@ -1,97 +1,99 @@
/*
- * Copyright 2004-2019 Andrew Beekhof <andrew@beekhof.net>
+ * Copyright 2004-2019 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 CRM_COMMON_NVPAIR__H
# define CRM_COMMON_NVPAIR__H
# ifdef __cplusplus
extern "C" {
# endif
/**
* \file
* \brief Functionality for manipulating name/value pairs
* \ingroup core
*/
# include <sys/time.h> // struct timeval
# include <glib.h> // gpointer, gboolean, guint
# include <libxml/tree.h> // xmlNode
# include <crm/crm.h>
typedef struct pcmk_nvpair_s {
char *name;
char *value;
} pcmk_nvpair_t;
GSList *pcmk_prepend_nvpair(GSList *nvpairs, const char *name, const char *value);
void pcmk_free_nvpairs(GSList *nvpairs);
GSList *pcmk_sort_nvpairs(GSList *list);
GSList *pcmk_xml_attrs2nvpairs(xmlNode *xml);
void pcmk_nvpairs2xml_attrs(GSList *list, xmlNode *xml);
xmlNode *crm_create_nvpair_xml(xmlNode *parent, const char *id,
const char *name, const char *value);
void hash2nvpair(gpointer key, gpointer value, gpointer user_data);
void hash2field(gpointer key, gpointer value, gpointer user_data);
void hash2metafield(gpointer key, gpointer value, gpointer user_data);
void hash2smartfield(gpointer key, gpointer value, gpointer user_data);
GHashTable *xml2list(xmlNode *parent);
const char *crm_xml_add(xmlNode *node, const char *name, const char *value);
const char *crm_xml_replace(xmlNode *node, const char *name, const char *value);
const char *crm_xml_add_int(xmlNode *node, const char *name, int value);
const char *crm_xml_add_ms(xmlNode *node, const char *name, guint ms);
const char *crm_element_value(const xmlNode *data, const char *name);
int crm_element_value_int(const xmlNode *data, const char *name, int *dest);
int crm_element_value_ms(const xmlNode *data, const char *name, guint *dest);
int crm_element_value_timeval(const xmlNode *data, const char *name_sec,
const char *name_usec, struct timeval *dest);
char *crm_element_value_copy(const xmlNode *data, const char *name);
/*!
* \brief Copy an element from one XML object to another
*
* \param[in] obj1 Source XML
* \param[in,out] obj2 Destination XML
* \param[in] element Name of element to copy
*
* \return Pointer to copied value (from source)
*/
static inline const char *
crm_copy_xml_element(xmlNode *obj1, xmlNode *obj2, const char *element)
{
const char *value = crm_element_value(obj1, element);
crm_xml_add(obj2, element, value);
return value;
}
/*!
* \brief Add a boolean attribute to an XML object
*
* Add an attribute with the value \c XML_BOOLEAN_TRUE or \c XML_BOOLEAN_FALSE
* as appropriate to an XML object.
*
* \param[in,out] node XML object to add attribute to
* \param[in] name Name of attribute to add
* \param[in] value Boolean whose value will be tested
*
* \return Pointer to newly created XML attribute's content, or \c NULL on error
*/
static inline const char *
crm_xml_add_boolean(xmlNode *node, const char *name, gboolean value)
{
return crm_xml_add(node, name, (value? "true" : "false"));
}
# ifdef __cplusplus
}
# endif
#endif // CRM_COMMON_NVPAIR__H
diff --git a/include/crm/common/remote_internal.h b/include/crm/common/remote_internal.h
index 2f76ea07cf..a909218726 100644
--- a/include/crm/common/remote_internal.h
+++ b/include/crm/common/remote_internal.h
@@ -1,48 +1,50 @@
/*
- * Copyright 2008-2018 Andrew Beekhof <andrew@beekhof.net>
+ * Copyright 2008-2018 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__REMOTE__H
# define PCMK__REMOTE__H
// internal functions from remote.c
typedef struct crm_remote_s crm_remote_t;
int crm_remote_send(crm_remote_t *remote, xmlNode *msg);
int crm_remote_ready(crm_remote_t *remote, int total_timeout /*ms */ );
gboolean crm_remote_recv(crm_remote_t *remote, int total_timeout /*ms */,
int *disconnected);
xmlNode *crm_remote_parse_buffer(crm_remote_t *remote);
int crm_remote_tcp_connect(const char *host, int port);
int crm_remote_tcp_connect_async(const char *host, int port,
int timeout /*ms */,
int *timer_id, void *userdata,
void (*callback) (void *userdata, int sock));
int crm_remote_accept(int ssock);
void crm_sockaddr2str(void *sa, char *s);
# ifdef HAVE_GNUTLS_GNUTLS_H
# include <gnutls/gnutls.h>
gnutls_session_t *pcmk__new_tls_session(int csock, unsigned int conn_type,
gnutls_credentials_type_t cred_type,
void *credentials);
int pcmk__init_tls_dh(gnutls_dh_params_t *dh_params);
int pcmk__read_handshake_data(crm_client_t *client);
/*!
* \internal
* \brief Initiate the client handshake after establishing the tcp socket
*
* \return 0 on success, negative number on failure
* \note This function will block until the entire handshake is complete or
* until the timeout period is reached.
*/
int crm_initiate_client_tls_handshake(crm_remote_t *remote, int timeout_ms);
# endif // HAVE_GNUTLS_GNUTLS_H
#endif // PCMK__REMOTE__H
diff --git a/include/crm/common/results.h b/include/crm/common/results.h
index 0d29cd747a..0fb2ee2043 100644
--- a/include/crm/common/results.h
+++ b/include/crm/common/results.h
@@ -1,142 +1,144 @@
/*
- * Copyright 2012-2018 Andrew Beekhof <andrew@beekhof.net>
+ * Copyright 2012-2019 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 CRM_RESULTS__H
# define CRM_RESULTS__H
#ifdef __cplusplus
extern "C" {
#endif
/*!
* \file
* \brief Function and executable result codes
* \ingroup core
*/
# define CRM_ASSERT(expr) do { \
if(__unlikely((expr) == FALSE)) { \
crm_abort(__FILE__, __FUNCTION__, __LINE__, #expr, TRUE, FALSE); \
abort(); /* Redundant but it makes static analyzers happy */ \
} \
} while(0)
/*
* Function return codes
*
* For system error codes, see:
* - /usr/include/asm-generic/errno.h
* - /usr/include/asm-generic/errno-base.h
*/
# define pcmk_ok 0
# define PCMK_ERROR_OFFSET 190 /* Replacements on non-linux systems, see include/portability.h */
# define PCMK_CUSTOM_OFFSET 200 /* Purely custom codes */
# define pcmk_err_generic 201
# define pcmk_err_no_quorum 202
# define pcmk_err_schema_validation 203
# define pcmk_err_transform_failed 204
# define pcmk_err_old_data 205
# define pcmk_err_diff_failed 206
# define pcmk_err_diff_resync 207
# define pcmk_err_cib_modified 208
# define pcmk_err_cib_backup 209
# define pcmk_err_cib_save 210
# define pcmk_err_schema_unchanged 211
# define pcmk_err_cib_corrupt 212
# define pcmk_err_multiple 213
# define pcmk_err_node_unknown 214
# define pcmk_err_already 215
# define pcmk_err_bad_nvpair 216
/*
* Exit status codes
*
* We want well-specified (i.e. OS-invariant) exit status codes for our daemons
* and applications so they can be relied on by callers. (Function return codes
* and errno's do not make good exit statuses.)
*
* The only hard rule is that exit statuses must be between 0 and 255; all else
* is convention. Universally, 0 is success, and 1 is generic error (excluding
* OSes we don't support -- for example, OpenVMS considers 1 success!).
*
* For init scripts, the LSB gives meaning to 0-7, and sets aside 150-199 for
* application use. OCF adds 8-9 and 189-199.
*
* sysexits.h was an attempt to give additional meanings, but never really
* caught on. It uses 0 and 64-78.
*
* Bash reserves 2 ("incorrect builtin usage") and 126-255 (126 is "command
* found but not executable", 127 is "command not found", 128 + n is
* "interrupted by signal n").
*
* tldp.org recommends 64-113 for application use.
*
* We try to overlap with the above conventions when practical.
*/
typedef enum crm_exit_e {
// Common convention
CRM_EX_OK = 0,
CRM_EX_ERROR = 1,
// LSB + OCF
CRM_EX_INVALID_PARAM = 2,
CRM_EX_UNIMPLEMENT_FEATURE = 3,
CRM_EX_INSUFFICIENT_PRIV = 4,
CRM_EX_NOT_INSTALLED = 5,
CRM_EX_NOT_CONFIGURED = 6,
CRM_EX_NOT_RUNNING = 7,
// sysexits.h
CRM_EX_USAGE = 64, // command line usage error
CRM_EX_DATAERR = 65, // user-supplied data incorrect
CRM_EX_NOINPUT = 66, // input file not available
CRM_EX_NOUSER = 67, // user does not exist
CRM_EX_NOHOST = 68, // host unknown
CRM_EX_UNAVAILABLE = 69, // needed service unavailable
CRM_EX_SOFTWARE = 70, // internal software bug
CRM_EX_OSERR = 71, // external (OS/environmental) problem
CRM_EX_OSFILE = 72, // system file not usable
CRM_EX_CANTCREAT = 73, // file couldn't be created
CRM_EX_IOERR = 74, // file I/O error
CRM_EX_TEMPFAIL = 75, // try again
CRM_EX_PROTOCOL = 76, // protocol violated
CRM_EX_NOPERM = 77, // non-file permission issue
CRM_EX_CONFIG = 78, // misconfiguration
// Custom
CRM_EX_FATAL = 100, // do not respawn
CRM_EX_PANIC = 101, // panic the local host
CRM_EX_DISCONNECT = 102, // lost connection to something
CRM_EX_OLD = 103, // update older than existing config
CRM_EX_DIGEST = 104, // digest comparison failed
CRM_EX_NOSUCH = 105, // requested item does not exist
CRM_EX_QUORUM = 106, // local partition does not have quorum
CRM_EX_UNSAFE = 107, // requires --force or new conditions
CRM_EX_EXISTS = 108, // requested item already exists
CRM_EX_MULTIPLE = 109, // requested item has multiple matches
CRM_EX_EXPIRED = 110, // requested item has expired
CRM_EX_NOT_YET_IN_EFFECT = 111, // requested item is not in effect
CRM_EX_INDETERMINATE = 112, // could not determine status
// Other
CRM_EX_TIMEOUT = 124, // convention from timeout(1)
CRM_EX_MAX = 255, // ensure crm_exit_t can hold this
} crm_exit_t;
const char *pcmk_strerror(int rc);
const char *pcmk_errorname(int rc);
const char *bz2_strerror(int rc);
crm_exit_t crm_errno2exit(int rc);
const char *crm_exit_name(crm_exit_t exit_code);
const char *crm_exit_str(crm_exit_t exit_code);
crm_exit_t crm_exit(crm_exit_t rc);
#ifdef __cplusplus
}
#endif
#endif
diff --git a/include/crm/common/util.h b/include/crm/common/util.h
index eae8a9846c..41d39994a7 100644
--- a/include/crm/common/util.h
+++ b/include/crm/common/util.h
@@ -1,197 +1,199 @@
/*
- * Copyright 2004-2018 Andrew Beekhof <andrew@beekhof.net>
+ * Copyright 2004-2019 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 CRM_COMMON_UTIL__H
# define CRM_COMMON_UTIL__H
#ifdef __cplusplus
extern "C" {
#endif
/**
* \file
* \brief Utility functions
* \ingroup core
*/
# include <sys/types.h>
# include <stdlib.h>
# include <stdbool.h>
# include <stdint.h> // uint32_t
# include <limits.h>
# include <signal.h>
# include <glib.h>
# include <libxml/tree.h>
# include <crm/lrmd.h>
# include <crm/common/results.h>
# define ONLINESTATUS "online" // Status of an online client
# define OFFLINESTATUS "offline" // Status of an offline client
/* public Pacemaker Remote functions (from remote.c) */
int crm_default_remote_port(void);
/* public string functions (from strings.c) */
char *crm_itoa_stack(int an_int, char *buf, size_t len);
gboolean crm_is_true(const char *s);
int crm_str_to_boolean(const char *s, int *ret);
long long crm_parse_ll(const char *text, const char *default_text);
int crm_parse_int(const char *text, const char *default_text);
char * crm_strip_trailing_newline(char *str);
gboolean crm_str_eq(const char *a, const char *b, gboolean use_case);
gboolean safe_str_neq(const char *a, const char *b);
gboolean crm_strcase_equal(gconstpointer a, gconstpointer b);
guint crm_strcase_hash(gconstpointer v);
guint g_str_hash_traditional(gconstpointer v);
char *crm_strdup_printf(char const *format, ...) __attribute__ ((__format__ (__printf__, 1, 2)));
int pcmk_scan_nvpair(const char *input, char **name, char **value);
# define safe_str_eq(a, b) crm_str_eq(a, b, FALSE)
# define crm_str_hash g_str_hash_traditional
static inline char *
crm_itoa(int an_int)
{
return crm_strdup_printf("%d", an_int);
}
/*!
* \brief Create hash table with dynamically allocated string keys/values
*
* \return Newly allocated hash table
* \note It is the caller's responsibility to free the result, using
* g_hash_table_destroy().
*/
static inline GHashTable *
crm_str_table_new()
{
return g_hash_table_new_full(crm_str_hash, g_str_equal, free, free);
}
/*!
* \brief Create hash table with case-insensitive dynamically allocated string keys/values
*
* \return Newly allocated hash table
* \note It is the caller's responsibility to free the result, using
* g_hash_table_destroy().
*/
static inline GHashTable *
crm_strcase_table_new()
{
return g_hash_table_new_full(crm_strcase_hash, crm_strcase_equal, free, free);
}
GHashTable *crm_str_table_dup(GHashTable *old_table);
# define crm_atoi(text, default_text) crm_parse_int(text, default_text)
/* public I/O functions (from io.c) */
void crm_build_path(const char *path_c, mode_t mode);
long long crm_get_msec(const char *input);
guint crm_parse_interval_spec(const char *input);
int char2score(const char *score);
char *score2char(int score);
char *score2char_stack(int score, char *buf, size_t len);
// deprecated
#define crm_get_interval crm_parse_interval_spec
/* public operation functions (from operations.c) */
gboolean parse_op_key(const char *key, char **rsc_id, char **op_type,
guint *interval_ms);
gboolean decode_transition_key(const char *key, char **uuid, int *action,
int *transition_id, int *target_rc);
gboolean decode_transition_magic(const char *magic, char **uuid,
int *transition_id, int *action_id,
int *op_status, int *op_rc, int *target_rc);
int rsc_op_expected_rc(lrmd_event_data_t *event);
gboolean did_rsc_op_fail(lrmd_event_data_t *event, int target_rc);
bool crm_op_needs_metadata(const char *rsc_class, const char *op);
xmlNode *crm_create_op_xml(xmlNode *parent, const char *prefix,
const char *task, const char *interval_spec,
const char *timeout);
#define CRM_DEFAULT_OP_TIMEOUT_S "20s"
// Public resource agent functions (from agents.c)
// Capabilities supported by a resource agent standard
enum pcmk_ra_caps {
pcmk_ra_cap_none = 0x000,
pcmk_ra_cap_provider = 0x001, // Requires provider
pcmk_ra_cap_status = 0x002, // Supports status instead of monitor
pcmk_ra_cap_params = 0x004, // Supports parameters
pcmk_ra_cap_unique = 0x008, // Supports unique clones
pcmk_ra_cap_promotable = 0x010, // Supports promotable clones
};
uint32_t pcmk_get_ra_caps(const char *standard);
char *crm_generate_ra_key(const char *standard, const char *provider,
const char *type);
int crm_parse_agent_spec(const char *spec, char **standard, char **provider,
char **type);
bool crm_provider_required(const char *standard); // deprecated
int compare_version(const char *version1, const char *version2);
/* coverity[+kill] */
void crm_abort(const char *file, const char *function, int line,
const char *condition, gboolean do_core, gboolean do_fork);
static inline gboolean
is_not_set(long long word, long long bit)
{
return ((word & bit) == 0);
}
static inline gboolean
is_set(long long word, long long bit)
{
return ((word & bit) == bit);
}
static inline gboolean
is_set_any(long long word, long long bit)
{
return ((word & bit) != 0);
}
static inline guint
crm_hash_table_size(GHashTable * hashtable)
{
if (hashtable == NULL) {
return 0;
}
return g_hash_table_size(hashtable);
}
char *crm_meta_name(const char *field);
const char *crm_meta_value(GHashTable * hash, const char *field);
char *crm_md5sum(const char *buffer);
char *crm_generate_uuid(void);
bool crm_is_daemon_name(const char *name);
int crm_user_lookup(const char *name, uid_t * uid, gid_t * gid);
#ifdef HAVE_GNUTLS_GNUTLS_H
void crm_gnutls_global_init(void);
#endif
bool pcmk_acl_required(const char *user);
char *pcmk_hostname(void);
#ifdef __cplusplus
}
#endif
#endif
diff --git a/include/crm/common/xml.h b/include/crm/common/xml.h
index 9695798909..dc9bf57247 100644
--- a/include/crm/common/xml.h
+++ b/include/crm/common/xml.h
@@ -1,317 +1,319 @@
/*
- * Copyright 2004-2019 Andrew Beekhof <andrew@beekhof.net>
+ * Copyright 2004-2019 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 CRM_COMMON_XML__H
# define CRM_COMMON_XML__H
#ifdef __cplusplus
extern "C" {
#endif
/**
* \file
* \brief Wrappers for and extensions to libxml2
* \ingroup core
*/
# include <stdio.h>
# include <sys/types.h>
# include <unistd.h>
# include <stdlib.h>
# include <errno.h>
# include <fcntl.h>
# include <libxml/tree.h>
# include <libxml/xpath.h>
# include <crm/crm.h>
# include <crm/common/nvpair.h>
/* Define compression parameters for IPC messages
*
* Compression costs a LOT, so we don't want to do it unless we're hitting
* message limits. Currently, we use 128KB as the threshold, because higher
* values don't play well with the heartbeat stack. With an earlier limit of
* 10KB, compressing 184 of 1071 messages accounted for 23% of the total CPU
* used by the cib.
*/
# define CRM_BZ2_BLOCKS 4
# define CRM_BZ2_WORK 20
# define CRM_BZ2_THRESHOLD 128 * 1024
# define XML_PARANOIA_CHECKS 0
gboolean add_message_xml(xmlNode * msg, const char *field, xmlNode * xml);
xmlNode *get_message_xml(xmlNode * msg, const char *field);
xmlDoc *getDocPtr(xmlNode * node);
/*
* Replacement function for xmlCopyPropList which at the very least,
* doesn't work the way *I* would expect it to.
*
* Copy all the attributes/properties from src into target.
*
* Not recursive, does not return anything.
*
*/
void copy_in_properties(xmlNode * target, xmlNode * src);
void expand_plus_plus(xmlNode * target, const char *name, const char *value);
void fix_plus_plus_recursive(xmlNode * target);
/*
* Create a node named "name" as a child of "parent"
* If parent is NULL, creates an unconnected node.
*
* Returns the created node
*
*/
xmlNode *create_xml_node(xmlNode * parent, const char *name);
/*
*
*/
void purge_diff_markers(xmlNode * a_node);
/*
* Returns a deep copy of src_node
*
*/
xmlNode *copy_xml(xmlNode * src_node);
/*
* Add a copy of xml_node to new_parent
*/
xmlNode *add_node_copy(xmlNode * new_parent, xmlNode * xml_node);
int add_node_nocopy(xmlNode * parent, const char *name, xmlNode * child);
/*
* XML I/O Functions
*
* Whitespace between tags is discarded.
*/
xmlNode *filename2xml(const char *filename);
xmlNode *stdin2xml(void);
xmlNode *string2xml(const char *input);
int write_xml_fd(xmlNode * xml_node, const char *filename, int fd, gboolean compress);
int write_xml_file(xmlNode * xml_node, const char *filename, gboolean compress);
char *dump_xml_formatted(xmlNode * msg);
/* Also dump the text node with xml_log_option_text enabled */
char *dump_xml_formatted_with_text(xmlNode * msg);
char *dump_xml_unformatted(xmlNode * msg);
/*
* Diff related Functions
*/
xmlNode *diff_xml_object(xmlNode * left, xmlNode * right, gboolean suppress);
xmlNode *subtract_xml_object(xmlNode * parent, xmlNode * left, xmlNode * right,
gboolean full, gboolean * changed, const char *marker);
gboolean can_prune_leaf(xmlNode * xml_node);
gboolean apply_xml_diff(xmlNode *old_xml, xmlNode *diff, xmlNode **new_xml);
/*
* Searching & Modifying
*/
xmlNode *find_xml_node(xmlNode * cib, const char *node_path, gboolean must_find);
xmlNode *find_entity(xmlNode * parent, const char *node_name, const char *id);
void xml_remove_prop(xmlNode * obj, const char *name);
gboolean replace_xml_child(xmlNode * parent, xmlNode * child, xmlNode * update,
gboolean delete_only);
gboolean update_xml_child(xmlNode * child, xmlNode * to_update);
int find_xml_children(xmlNode ** children, xmlNode * root,
const char *tag, const char *field, const char *value,
gboolean search_matches);
xmlNode *get_xpath_object(const char *xpath, xmlNode * xml_obj, int error_level);
xmlNode *get_xpath_object_relative(const char *xpath, xmlNode * xml_obj, int error_level);
static inline const char *
crm_element_name(const xmlNode *xml)
{
return xml? (const char *)(xml->name) : NULL;
}
gboolean xml_has_children(const xmlNode * root);
char *calculate_on_disk_digest(xmlNode * local_cib);
char *calculate_operation_digest(xmlNode * local_cib, const char *version);
char *calculate_xml_versioned_digest(xmlNode * input, gboolean sort, gboolean do_filter,
const char *version);
/* schema-related functions (from schemas.c) */
gboolean validate_xml(xmlNode * xml_blob, const char *validation, gboolean to_logs);
gboolean validate_xml_verbose(xmlNode * xml_blob);
/*!
* \brief Update CIB XML to most recent schema version
*
* "Update" means either actively employ XSLT-based transformation(s)
* (if intermediate product to transform valid per its declared schema version,
* transformation available, proceeded successfully with a result valid per
* expectated newer schema version), or just try to bump the marked validating
* schema until all gradually rising schema versions attested or the first
* such attempt subsequently fails to validate. Which of the two styles will
* be used depends on \p transform parameter (positive/negative, respectively).
*
* \param[in,out] xml_blob XML tree representing CIB, may be swapped with
* an "updated" one
* \param[out] best The highest configuration version (per its index
* in the global schemas table) it was possible to
* reach during the update steps while ensuring
* the validity of the result; if no validation
* success was observed against possibly multiple
* schemas, the value is less or equal the result
* of \c get_schema_version applied on the input
* \p xml_blob value (unless that function maps it
* to -1, then 0 would be used instead)
* \param[in] max When \p transform is positive, this allows to
* set upper boundary schema (per its index in the
* global schemas table) beyond which it's forbidden
* to update by the means of XSLT transformation
* \param[in] transform Whether to employ XSLT-based transformation so
* as to allow overcoming possible incompatibilities
* between major schema versions (see above)
* \param[in] to_logs If true, output notable progress info to
* internal log streams; if false, to stderr
*
* \return \c pcmk_ok if no non-recoverable error encountered (up to
* caller to evaluate if the update satisfies the requirements
* per returned \p best value), negative value carrying the reason
* otherwise
*/
int update_validation(xmlNode **xml_blob, int *best, int max,
gboolean transform, gboolean to_logs);
int get_schema_version(const char *name);
const char *get_schema_name(int version);
const char *xml_latest_schema(void);
gboolean cli_config_update(xmlNode ** xml, int *best_version, gboolean to_logs);
void crm_xml_init(void);
void crm_xml_cleanup(void);
static inline xmlNode *
__xml_first_child(const xmlNode *parent)
{
xmlNode *child = parent? parent->children : NULL;
while (child && (child->type == XML_TEXT_NODE)) {
child = child->next;
}
return child;
}
static inline xmlNode *
__xml_next(const xmlNode *child)
{
xmlNode *next = child? child->next : NULL;
while (next && (next->type == XML_TEXT_NODE)) {
next = next->next;
}
return next;
}
static inline xmlNode *
__xml_first_child_element(const xmlNode *parent)
{
xmlNode *child = parent? parent->children : NULL;
while (child && (child->type != XML_ELEMENT_NODE)) {
child = child->next;
}
return child;
}
static inline xmlNode *
__xml_next_element(const xmlNode *child)
{
xmlNode *next = child? child->next : NULL;
while (next && (next->type != XML_ELEMENT_NODE)) {
next = next->next;
}
return next;
}
void free_xml(xmlNode * child);
xmlNode *first_named_child(const xmlNode *parent, const char *name);
xmlNode *crm_next_same_xml(const xmlNode *sibling);
xmlNode *sorted_xml(xmlNode * input, xmlNode * parent, gboolean recursive);
xmlXPathObjectPtr xpath_search(xmlNode * xml_top, const char *path);
void crm_foreach_xpath_result(xmlNode *xml, const char *xpath,
void (*helper)(xmlNode*, void*), void *user_data);
xmlNode *expand_idref(xmlNode * input, xmlNode * top);
void freeXpathObject(xmlXPathObjectPtr xpathObj);
xmlNode *getXpathResult(xmlXPathObjectPtr xpathObj, int index);
void dedupXpathResults(xmlXPathObjectPtr xpathObj);
static inline int numXpathResults(xmlXPathObjectPtr xpathObj)
{
if(xpathObj == NULL || xpathObj->nodesetval == NULL) {
return 0;
}
return xpathObj->nodesetval->nodeNr;
}
bool xml_acl_enabled(xmlNode *xml);
void xml_acl_disable(xmlNode *xml);
bool xml_acl_denied(xmlNode *xml); /* Part or all of a change was rejected */
bool xml_acl_filtered_copy(const char *user, xmlNode* acl_source, xmlNode *xml, xmlNode ** result);
bool xml_tracking_changes(xmlNode * xml);
bool xml_document_dirty(xmlNode *xml);
void xml_track_changes(xmlNode * xml, const char *user, xmlNode *acl_source, bool enforce_acls);
void xml_calculate_changes(xmlNode *old_xml, xmlNode *new_xml);
void xml_calculate_significant_changes(xmlNode *old_xml, xmlNode *new_xml);
void xml_accept_changes(xmlNode * xml);
void xml_log_changes(uint8_t level, const char *function, xmlNode *xml);
void xml_log_patchset(uint8_t level, const char *function, xmlNode *xml);
bool xml_patch_versions(xmlNode *patchset, int add[3], int del[3]);
xmlNode *xml_create_patchset(
int format, xmlNode *source, xmlNode *target, bool *config, bool manage_version);
int xml_apply_patchset(xmlNode *xml, xmlNode *patchset, bool check_version);
void patchset_process_digest(xmlNode *patch, xmlNode *source, xmlNode *target, bool with_digest);
void save_xml_to_file(xmlNode * xml, const char *desc, const char *filename);
char *xml_get_path(xmlNode *xml);
char * crm_xml_escape(const char *text);
void crm_xml_sanitize_id(char *id);
void crm_xml_set_id(xmlNode *xml, const char *format, ...)
__attribute__ ((__format__ (__printf__, 2, 3)));
/*!
* \brief xmlNode destructor which can be used in glib collections
*/
void crm_destroy_xml(gpointer data);
#ifdef __cplusplus
}
#endif
#endif
diff --git a/include/crm/common/xml_internal.h b/include/crm/common/xml_internal.h
index 95a83ba636..e8da84a8ca 100644
--- a/include/crm/common/xml_internal.h
+++ b/include/crm/common/xml_internal.h
@@ -1,134 +1,136 @@
/*
- * Copyright 2017 Jan Pokorny <jpokorny@redhat.com>
+ * Copyright 2017-2018 the Pacemaker project contributors
+ *
+ * The version control history for this file may have further details.
*
* 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 software 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
* 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_COMMON_XML_INTERNAL__H
# define CRM_COMMON_XML_INTERNAL__H
/*
* Internal-only wrappers for and extensions to libxml2 (libxslt)
*/
# include <stdlib.h>
# include <stdio.h>
# include <string.h>
# include <crm/crm.h> /* transitively imports qblog.h */
/*!
* \brief Base for directing lib{xml2,xslt} log into standard libqb backend
*
* This macro implements the core of what can be needed for directing
* libxml2 or libxslt error messaging into standard, preconfigured
* libqb-backed log stream.
*
* It's a bit unfortunate that libxml2 (and more sparsely, also libxslt)
* emits a single message by chunks (location is emitted separatedly from
* the message itself), so we have to take the effort to combine these
* chunks back to single message. Whether to do this or not is driven
* with \p dechunk toggle.
*
* The form of a macro was chosen for implicit deriving of __FILE__, etc.
* and also because static dechunking buffer should be differentiated per
* library (here we assume different functions referring to this macro
* will not ever be using both at once), preferably also per-library
* context of use to avoid clashes altogether.
*
* Note that we cannot use qb_logt, because callsite data have to be known
* at the moment of compilation, which it is not always the case -- xml_log
* (and unfortunately there's no clear explanation of the fail to compile).
*
* Also note that there's no explicit guard against said libraries producing
* never-newline-terminated chunks (which would just keep consuming memory),
* as it's quite improbable. Termination of the program in between the
* same-message chunks will raise a flag with valgrind and the likes, though.
*
* And lastly, regarding how dechunking combines with other non-message
* parameters -- for \p priority, most important running specification
* wins (possibly elevated to LOG_ERR in case of nonconformance with the
* newline-termination "protocol"), \p dechunk is expected to always be
* on once it was at the start, and the rest (\p postemit and \p prefix)
* are picked directly from the last chunk entry finalizing the message
* (also reasonable to always have it the same with all related entries).
*
* \param[in] priority Syslog priority for the message to be logged
* \param[in] dechunk Whether to dechunk new-line terminated message
* \param[in] postemit Code to be executed once message is sent out
* \param[in] prefix How to prefix the message or NULL for raw passing
* \param[in] fmt Format string as with printf-like functions
* \param[in] ap Variable argument list to supplement \p fmt format string
*/
#define CRM_XML_LOG_BASE(priority, dechunk, postemit, prefix, fmt, ap) \
do { \
if (!(dechunk) && (prefix) == NULL) { /* quick pass */ \
qb_log_from_external_source_va(__FUNCTION__, __FILE__, (fmt), \
(priority), __LINE__, 0, (ap)); \
(void) (postemit); \
} else { \
int CXLB_len = 0; \
char *CXLB_buf = NULL; \
static int CXLB_buffer_len = 0; \
static char *CXLB_buffer = NULL; \
static uint8_t CXLB_priority = 0; \
\
CXLB_len = vasprintf(&CXLB_buf, (fmt), (ap)); \
\
if (CXLB_len <= 0 || CXLB_buf[CXLB_len - 1] == '\n' || !(dechunk)) { \
if (CXLB_len < 0) { \
CXLB_buf = (char *) "LOG CORRUPTION HAZARD"; /*we don't modify*/\
CXLB_priority = QB_MIN(CXLB_priority, LOG_ERR); \
} else if (CXLB_len > 0 /* && (dechunk) */ \
&& CXLB_buf[CXLB_len - 1] == '\n') { \
CXLB_buf[CXLB_len - 1] = '\0'; \
} \
if (CXLB_buffer) { \
qb_log_from_external_source(__FUNCTION__, __FILE__, "%s%s%s", \
CXLB_priority, __LINE__, 0, \
(prefix) != NULL ? (prefix) : "", \
CXLB_buffer, CXLB_buf); \
free(CXLB_buffer); \
} else { \
qb_log_from_external_source(__FUNCTION__, __FILE__, "%s%s", \
(priority), __LINE__, 0, \
(prefix) != NULL ? (prefix) : "", \
CXLB_buf); \
} \
if (CXLB_len < 0) { \
CXLB_buf = NULL; /* restore temporary override */ \
} \
CXLB_buffer = NULL; \
CXLB_buffer_len = 0; \
(void) (postemit); \
\
} else if (CXLB_buffer == NULL) { \
CXLB_buffer_len = CXLB_len; \
CXLB_buffer = CXLB_buf; \
CXLB_buf = NULL; \
CXLB_priority = (priority); /* remember as a running severest */ \
\
} else { \
CXLB_buffer = realloc(CXLB_buffer, 1 + CXLB_buffer_len + CXLB_len); \
memcpy(CXLB_buffer + CXLB_buffer_len, CXLB_buf, CXLB_len); \
CXLB_buffer_len += CXLB_len; \
CXLB_buffer[CXLB_buffer_len] = '\0'; \
CXLB_priority = QB_MIN(CXLB_priority, (priority)); /* severest? */ \
} \
free(CXLB_buf); \
} \
} while (0)
#endif
diff --git a/include/crm/crm.h b/include/crm/crm.h
index 50d9a5c1bb..5f323e829c 100644
--- a/include/crm/crm.h
+++ b/include/crm/crm.h
@@ -1,207 +1,209 @@
/*
- * Copyright 2004-2018 Andrew Beekhof <andrew@beekhof.net>
+ * Copyright 2004-2018 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 CRM__H
# define CRM__H
#ifdef __cplusplus
extern "C" {
#endif
/**
* \file
* \brief A dumping ground
* \ingroup core
*/
# include <crm_config.h>
# include <stdlib.h>
# include <glib.h>
# include <stdbool.h>
# include <string.h>
# include <libxml/tree.h>
# define CRM_FEATURE_SET "3.1.0"
# define EOS '\0'
# define DIMOF(a) ((int) (sizeof(a)/sizeof(a[0])) )
# ifndef MAX_NAME
# define MAX_NAME 256
# endif
# ifndef __GNUC__
# define __builtin_expect(expr, result) (expr)
# endif
/* Some handy macros used by the Linux kernel */
# define __likely(expr) __builtin_expect(expr, 1)
# define __unlikely(expr) __builtin_expect(expr, 0)
# define CRM_META "CRM_meta"
extern char *crm_system_name;
/* *INDENT-OFF* */
// Used for some internal IPC timeouts (maybe should be configurable option)
# define MAX_IPC_DELAY 120
// How we represent "infinite" scores
# define CRM_SCORE_INFINITY 1000000
# define CRM_INFINITY_S "INFINITY"
# define CRM_PLUS_INFINITY_S "+" CRM_INFINITY_S
# define CRM_MINUS_INFINITY_S "-" CRM_INFINITY_S
/* @COMPAT API < 2.0.0 Deprecated "infinity" aliases
*
* INFINITY might be defined elsewhere (e.g. math.h), so undefine it first.
* This, of course, complicates any attempt to use the other definition in any
* code that includes this header.
*/
# undef INFINITY
# define INFINITY_S "INFINITY"
# define MINUS_INFINITY_S "-INFINITY"
# define INFINITY 1000000
/* Sub-systems */
# define CRM_SYSTEM_DC "dc"
# define CRM_SYSTEM_DCIB "dcib"
/* The master CIB */
# define CRM_SYSTEM_CIB "cib"
# define CRM_SYSTEM_CRMD "crmd"
# define CRM_SYSTEM_LRMD "lrmd"
# define CRM_SYSTEM_PENGINE "pengine"
# define CRM_SYSTEM_TENGINE "tengine"
# define CRM_SYSTEM_STONITHD "stonithd"
# define CRM_SYSTEM_MCP "pacemakerd"
// Names of internally generated node attributes
# define CRM_ATTR_UNAME "#uname"
# define CRM_ATTR_ID "#id"
# define CRM_ATTR_KIND "#kind"
# define CRM_ATTR_ROLE "#role"
# define CRM_ATTR_IS_DC "#is_dc"
# define CRM_ATTR_CLUSTER_NAME "#cluster-name"
# define CRM_ATTR_SITE_NAME "#site-name"
# define CRM_ATTR_UNFENCED "#node-unfenced"
# define CRM_ATTR_DIGESTS_ALL "#digests-all"
# define CRM_ATTR_DIGESTS_SECURE "#digests-secure"
# define CRM_ATTR_RA_VERSION "#ra-version"
# define CRM_ATTR_PROTOCOL "#attrd-protocol"
/* Valid operations */
# define CRM_OP_NOOP "noop"
# define CRM_OP_JOIN_ANNOUNCE "join_announce"
# define CRM_OP_JOIN_OFFER "join_offer"
# define CRM_OP_JOIN_REQUEST "join_request"
# define CRM_OP_JOIN_ACKNAK "join_ack_nack"
# define CRM_OP_JOIN_CONFIRM "join_confirm"
# define CRM_OP_PING "ping"
# define CRM_OP_NODE_INFO "node-info"
# define CRM_OP_THROTTLE "throttle"
# define CRM_OP_VOTE "vote"
# define CRM_OP_NOVOTE "no-vote"
# define CRM_OP_HELLO "hello"
# define CRM_OP_PECALC "pe_calc"
# define CRM_OP_QUIT "quit"
# define CRM_OP_LOCAL_SHUTDOWN "start_shutdown"
# define CRM_OP_SHUTDOWN_REQ "req_shutdown"
# define CRM_OP_SHUTDOWN "do_shutdown"
# define CRM_OP_FENCE "stonith"
# define CRM_OP_REGISTER "register"
# define CRM_OP_IPC_FWD "ipc_fwd"
# define CRM_OP_INVOKE_LRM "lrm_invoke"
# define CRM_OP_LRM_REFRESH "lrm_refresh" /* Deprecated */
# define CRM_OP_LRM_QUERY "lrm_query"
# define CRM_OP_LRM_DELETE "lrm_delete"
# define CRM_OP_LRM_FAIL "lrm_fail"
# define CRM_OP_PROBED "probe_complete"
# define CRM_OP_REPROBE "probe_again"
# define CRM_OP_CLEAR_FAILCOUNT "clear_failcount"
# define CRM_OP_REMOTE_STATE "remote_state"
# define CRM_OP_RELAXED_SET "one-or-more"
# define CRM_OP_RELAXED_CLONE "clone-one-or-more"
# define CRM_OP_RM_NODE_CACHE "rm_node_cache"
# define CRM_OP_MAINTENANCE_NODES "maintenance_nodes"
/* Possible cluster membership states */
# define CRMD_JOINSTATE_DOWN "down"
# define CRMD_JOINSTATE_PENDING "pending"
# define CRMD_JOINSTATE_MEMBER "member"
# define CRMD_JOINSTATE_NACK "banned"
# define CRMD_ACTION_DELETE "delete"
# define CRMD_ACTION_CANCEL "cancel"
# define CRMD_ACTION_RELOAD "reload"
# define CRMD_ACTION_MIGRATE "migrate_to"
# define CRMD_ACTION_MIGRATED "migrate_from"
# define CRMD_ACTION_START "start"
# define CRMD_ACTION_STARTED "running"
# define CRMD_ACTION_STOP "stop"
# define CRMD_ACTION_STOPPED "stopped"
# define CRMD_ACTION_PROMOTE "promote"
# define CRMD_ACTION_PROMOTED "promoted"
# define CRMD_ACTION_DEMOTE "demote"
# define CRMD_ACTION_DEMOTED "demoted"
# define CRMD_ACTION_NOTIFY "notify"
# define CRMD_ACTION_NOTIFIED "notified"
# define CRMD_ACTION_STATUS "monitor"
# define CRMD_ACTION_METADATA "meta-data"
# define CRMD_METADATA_CALL_TIMEOUT 30000
/* short names */
# define RSC_DELETE CRMD_ACTION_DELETE
# define RSC_CANCEL CRMD_ACTION_CANCEL
# define RSC_MIGRATE CRMD_ACTION_MIGRATE
# define RSC_MIGRATED CRMD_ACTION_MIGRATED
# define RSC_START CRMD_ACTION_START
# define RSC_STARTED CRMD_ACTION_STARTED
# define RSC_STOP CRMD_ACTION_STOP
# define RSC_STOPPED CRMD_ACTION_STOPPED
# define RSC_PROMOTE CRMD_ACTION_PROMOTE
# define RSC_PROMOTED CRMD_ACTION_PROMOTED
# define RSC_DEMOTE CRMD_ACTION_DEMOTE
# define RSC_DEMOTED CRMD_ACTION_DEMOTED
# define RSC_NOTIFY CRMD_ACTION_NOTIFY
# define RSC_NOTIFIED CRMD_ACTION_NOTIFIED
# define RSC_STATUS CRMD_ACTION_STATUS
# define RSC_METADATA CRMD_ACTION_METADATA
/* *INDENT-ON* */
typedef GList *GListPtr;
# include <crm/common/logging.h>
# include <crm/common/util.h>
static inline const char *
crm_action_str(const char *task, guint interval_ms) {
if(safe_str_eq(task, RSC_STATUS) && !interval_ms) {
return "probe";
}
return task;
}
#ifdef __cplusplus
}
#endif
#endif
diff --git a/include/crm/fencing/Makefile.am b/include/crm/fencing/Makefile.am
index 57a787b663..1271dbd1df 100644
--- a/include/crm/fencing/Makefile.am
+++ b/include/crm/fencing/Makefile.am
@@ -1,20 +1,22 @@
#
-# Copyright (C) 2004 Andrew Beekhof <andrew@beekhof.net>
+# Copyright 2012-2016 the Pacemaker project contributors
+#
+# The version control history for this file may have further details.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
MAINTAINERCLEANFILES = Makefile.in
noinst_HEADERS = internal.h
diff --git a/include/crm/fencing/internal.h b/include/crm/fencing/internal.h
index 0a090f28fa..e88a155384 100644
--- a/include/crm/fencing/internal.h
+++ b/include/crm/fencing/internal.h
@@ -1,144 +1,146 @@
/*
- * Copyright 2011-2018 Andrew Beekhof <andrew@beekhof.net>
+ * Copyright 2011-2018 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 STONITH_NG_INTERNAL__H
# define STONITH_NG_INTERNAL__H
# include <crm/common/ipc.h>
# include <crm/common/xml.h>
struct stonith_action_s;
typedef struct stonith_action_s stonith_action_t;
stonith_action_t *stonith_action_create(const char *agent,
const char *_action,
const char *victim,
uint32_t victim_nodeid,
int timeout,
GHashTable * device_args, GHashTable * port_map);
void stonith__destroy_action(stonith_action_t *action);
void stonith__action_result(stonith_action_t *action, int *rc, char **output,
char **error_output);
GPid
stonith_action_execute_async(stonith_action_t * action,
void *userdata,
void (*done) (GPid pid, int rc, const char *output,
gpointer user_data));
int stonith__execute(stonith_action_t *action);
xmlNode *create_level_registration_xml(const char *node, const char *pattern,
const char *attr, const char *value,
int level,
stonith_key_value_t *device_list);
xmlNode *create_device_registration_xml(const char *id,
enum stonith_namespace namespace,
const char *agent,
stonith_key_value_t *params,
const char *rsc_provides);
# define ST_LEVEL_MAX 10
# define F_STONITH_CLIENTID "st_clientid"
# define F_STONITH_CALLOPTS "st_callopt"
# define F_STONITH_CALLID "st_callid"
# define F_STONITH_CALLDATA "st_calldata"
# define F_STONITH_OPERATION "st_op"
# define F_STONITH_TARGET "st_target"
# define F_STONITH_REMOTE_OP_ID "st_remote_op"
# define F_STONITH_RC "st_rc"
/*! Timeout period per a device execution */
# define F_STONITH_TIMEOUT "st_timeout"
# define F_STONITH_TOLERANCE "st_tolerance"
/*! Action specific timeout period returned in query of fencing devices. */
# define F_STONITH_ACTION_TIMEOUT "st_action_timeout"
/*! Host in query result is not allowed to run this action */
# define F_STONITH_ACTION_DISALLOWED "st_action_disallowed"
/*! Maximum of random fencing delay for a device */
# define F_STONITH_DELAY_MAX "st_delay_max"
/*! Base delay used for a fencing delay */
# define F_STONITH_DELAY_BASE "st_delay_base"
/*! Has this device been verified using a monitor type
* operation (monitor, list, status) */
# define F_STONITH_DEVICE_VERIFIED "st_monitor_verified"
/*! device is required for this action */
# define F_STONITH_DEVICE_REQUIRED "st_required"
/*! number of available devices in query result */
# define F_STONITH_AVAILABLE_DEVICES "st-available-devices"
# define F_STONITH_CALLBACK_TOKEN "st_async_id"
# define F_STONITH_CLIENTNAME "st_clientname"
# define F_STONITH_CLIENTNODE "st_clientnode"
# define F_STONITH_NOTIFY_ACTIVATE "st_notify_activate"
# define F_STONITH_NOTIFY_DEACTIVATE "st_notify_deactivate"
# define F_STONITH_DELEGATE "st_delegate"
/*! The node initiating the stonith operation. If an operation
* is relayed, this is the last node the operation lands on. When
* in standalone mode, origin is the client's id that originated the
* operation. */
# define F_STONITH_ORIGIN "st_origin"
# define F_STONITH_HISTORY_LIST "st_history"
# define F_STONITH_DATE "st_date"
# define F_STONITH_STATE "st_state"
# define F_STONITH_ACTIVE "st_active"
# define F_STONITH_DIFFERENTIAL "st_differential"
# define F_STONITH_DEVICE "st_device_id"
# define F_STONITH_ACTION "st_device_action"
# define F_STONITH_MODE "st_mode"
# define T_STONITH_NG "stonith-ng"
# define T_STONITH_REPLY "st-reply"
/*! For async operations, an event from the server containing
* the total amount of time the server is allowing for the operation
* to take place is returned to the client. */
# define T_STONITH_TIMEOUT_VALUE "st-async-timeout-value"
# define T_STONITH_NOTIFY "st_notify"
# define STONITH_ATTR_HOSTARG "pcmk_host_argument"
# define STONITH_ATTR_HOSTMAP "pcmk_host_map"
# define STONITH_ATTR_HOSTLIST "pcmk_host_list"
# define STONITH_ATTR_HOSTCHECK "pcmk_host_check"
# define STONITH_ATTR_DELAY_MAX "pcmk_delay_max"
# define STONITH_ATTR_DELAY_BASE "pcmk_delay_base"
# define STONITH_ATTR_ACTION_LIMIT "pcmk_action_limit"
# define STONITH_ATTR_ACTION_OP "action"
# define STONITH_OP_EXEC "st_execute"
# define STONITH_OP_TIMEOUT_UPDATE "st_timeout_update"
# define STONITH_OP_QUERY "st_query"
# define STONITH_OP_FENCE "st_fence"
# define STONITH_OP_RELAY "st_relay"
# define STONITH_OP_DEVICE_ADD "st_device_register"
# define STONITH_OP_DEVICE_DEL "st_device_remove"
# define STONITH_OP_FENCE_HISTORY "st_fence_history"
# define STONITH_OP_LEVEL_ADD "st_level_add"
# define STONITH_OP_LEVEL_DEL "st_level_remove"
# define STONITH_WATCHDOG_AGENT "#watchdog"
# ifdef HAVE_STONITH_STONITH_H
// utilities from st_lha.c
int stonith__list_lha_agents(stonith_key_value_t **devices);
int stonith__lha_metadata(const char *agent, int timeout, char **output);
bool stonith__agent_is_lha(const char *agent);
int stonith__lha_validate(stonith_t *st, int call_options, const char *target,
const char *agent, GHashTable *params,
int timeout, char **output, char **error_output);
# endif
// utilities from st_rhcs.c
int stonith__list_rhcs_agents(stonith_key_value_t **devices);
int stonith__rhcs_metadata(const char *agent, int timeout, char **output);
bool stonith__agent_is_rhcs(const char *agent);
int stonith__rhcs_validate(stonith_t *st, int call_options, const char *target,
const char *agent, GHashTable *params,
int timeout, char **output, char **error_output);
#endif
diff --git a/include/crm/lrmd.h b/include/crm/lrmd.h
index 7a8a829eb7..87023565ff 100644
--- a/include/crm/lrmd.h
+++ b/include/crm/lrmd.h
@@ -1,561 +1,563 @@
/*
- * Copyright 2012-2018 David Vossel <davidvossel@gmail.com>
+ * Copyright 2012-2018 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 LRMD__H
# define LRMD__H
#ifdef __cplusplus
extern "C" {
#endif
/**
* \file
* \brief Resource agent executor
* \ingroup lrmd
*/
#include <stdbool.h>
#include <crm_config.h>
#include <crm/services.h>
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;
/* This should be bumped every time there is an incompatible change that
* prevents older clients from connecting to this version of the server.
*/
#define LRMD_PROTOCOL_VERSION "1.1"
/* 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 F_LRMD_OPERATION "lrmd_op"
#define F_LRMD_CLIENTNAME "lrmd_clientname"
#define F_LRMD_IS_IPC_PROVIDER "lrmd_is_ipc_provider"
#define F_LRMD_CLIENTID "lrmd_clientid"
#define F_LRMD_PROTOCOL_VERSION "lrmd_protocol_version"
#define F_LRMD_REMOTE_MSG_TYPE "lrmd_remote_msg_type"
#define F_LRMD_REMOTE_MSG_ID "lrmd_remote_msg_id"
#define F_LRMD_CALLBACK_TOKEN "lrmd_async_id"
#define F_LRMD_CALLID "lrmd_callid"
#define F_LRMD_CALLOPTS "lrmd_callopt"
#define F_LRMD_CALLDATA "lrmd_calldata"
#define F_LRMD_RC "lrmd_rc"
#define F_LRMD_EXEC_RC "lrmd_exec_rc"
#define F_LRMD_OP_STATUS "lrmd_exec_op_status"
#define F_LRMD_TIMEOUT "lrmd_timeout"
#define F_LRMD_WATCHDOG "lrmd_watchdog"
#define F_LRMD_CLASS "lrmd_class"
#define F_LRMD_PROVIDER "lrmd_provider"
#define F_LRMD_TYPE "lrmd_type"
#define F_LRMD_ORIGIN "lrmd_origin"
#define F_LRMD_RSC_RUN_TIME "lrmd_run_time"
#define F_LRMD_RSC_RCCHANGE_TIME "lrmd_rcchange_time"
#define F_LRMD_RSC_EXEC_TIME "lrmd_exec_time"
#define F_LRMD_RSC_QUEUE_TIME "lrmd_queue_time"
#define F_LRMD_RSC_ID "lrmd_rsc_id"
#define F_LRMD_RSC_ACTION "lrmd_rsc_action"
#define F_LRMD_RSC_USERDATA_STR "lrmd_rsc_userdata_str"
#define F_LRMD_RSC_OUTPUT "lrmd_rsc_output"
#define F_LRMD_RSC_EXIT_REASON "lrmd_rsc_exit_reason"
#define F_LRMD_RSC_START_DELAY "lrmd_rsc_start_delay"
#define F_LRMD_RSC_INTERVAL "lrmd_rsc_interval"
#define F_LRMD_RSC_DELETED "lrmd_rsc_deleted"
#define F_LRMD_RSC "lrmd_rsc"
#define F_LRMD_ALERT_ID "lrmd_alert_id"
#define F_LRMD_ALERT_PATH "lrmd_alert_path"
#define F_LRMD_ALERT "lrmd_alert"
#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"
#define F_LRMD_IPC_OP "lrmd_ipc_op"
#define F_LRMD_IPC_IPC_SERVER "lrmd_ipc_server"
#define F_LRMD_IPC_SESSION "lrmd_ipc_session"
#define F_LRMD_IPC_CLIENT "lrmd_ipc_client"
#define F_LRMD_IPC_USER "lrmd_ipc_user"
#define F_LRMD_IPC_MSG "lrmd_ipc_msg"
#define F_LRMD_IPC_MSG_ID "lrmd_ipc_msg_id"
#define F_LRMD_IPC_MSG_FLAGS "lrmd_ipc_msg_flags"
#define T_LRMD "lrmd"
#define T_LRMD_REPLY "lrmd_reply"
#define T_LRMD_NOTIFY "lrmd_notify"
#define T_LRMD_IPC_PROXY "lrmd_ipc_proxy"
#define T_LRMD_RSC_OP "lrmd_rsc_op"
/* *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 nodename name of remote node identified with this connection
* \param server name of server to connect to
* \param port port number to connect to
*
* \note nodename and server may be the same value.
*/
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 Poll for a specified timeout period to determine if a message
* is ready for dispatch.
* \retval 1 msg is ready
* \retval 0 timeout occurred
* \retval negative error code
*/
int lrmd_poll(lrmd_t * lrmd, int timeout);
/*!
* \brief Destroy executor connection object
*/
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);
/* *INDENT-OFF* */
/* Reserved for future use */
enum lrmd_call_options {
lrmd_opt_none = 0x00000000,
/* lrmd_opt_sync_call = 0x00000001, //Not implemented, patches welcome. */
/*! Only notify the client originating a exec() the results */
lrmd_opt_notify_orig_only = 0x00000002,
/*! Drop recurring operations initiated by a client when client disconnects.
* This call_option is only valid when registering a resource. When used
* remotely with the pacemaker_remote daemon, this option means that recurring
* operations will be dropped once all the remote connections disconnect. */
lrmd_opt_drop_recurring = 0x00000003,
/*! Send notifications for recurring operations only when the result changes */
lrmd_opt_notify_changes_only = 0x00000004,
};
enum lrmd_callback_event {
lrmd_event_register,
lrmd_event_unregister,
lrmd_event_exec_complete,
lrmd_event_disconnect,
lrmd_event_connect,
lrmd_event_poke,
lrmd_event_new_client,
};
/* *INDENT-ON* */
typedef struct lrmd_event_data_s {
/*! Type of event, register, unregister, call_completed... */
enum lrmd_callback_event type;
/*! The resource this event occurred on. */
const char *rsc_id;
/*! The action performed, start, stop, monitor... */
const char *op_type;
/*! The userdata string given do exec() api function */
const char *user_data;
/*! The client api call id associated with this event */
int call_id;
/*! The operation's timeout period in ms. */
int timeout;
/*! The operation's recurring interval in ms. */
guint interval_ms;
/*! The operation's start delay value in ms. */
int start_delay;
/*! This operation that just completed is on a deleted rsc. */
int rsc_deleted;
/*! The executed ra return code mapped to OCF */
enum ocf_exitcode rc;
/*! The executor status returned for exec_complete events */
int op_status;
/*! stdout from resource agent operation */
const char *output;
/*! Timestamp of when op ran */
unsigned int t_run;
/*! Timestamp of last rc change */
unsigned int t_rcchange;
/*! Time in length op took to execute */
unsigned int exec_time;
/*! Time in length spent in queue */
unsigned int queue_time;
/*! int connection result. Used for connection and poke events */
int connection_rc;
/* This is a GHashTable containing the
* parameters given to the operation */
void *params;
/*! client node name associated with this connection
* (used to match actions to the proper client when there are multiple)
*/
const char *remote_nodename;
/*! exit failure reason string from resource agent operation */
const char *exit_reason;
} lrmd_event_data_t;
lrmd_event_data_t *lrmd_copy_event(lrmd_event_data_t * event);
void lrmd_free_event(lrmd_event_data_t * event);
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
*
* \retval 0, success
* \retval negative error code on failure
*/
int (*connect) (lrmd_t * lrmd, const char *client_name, int *fd);
/*!
* \brief Initiate an executor connection without blocking
* \note this function requires the use of mainloop.
*
* \note The is returned using the event callback.
* \note When this function returns 0, the callback will be invoked
* to report the final result of the connect.
* \retval 0, connect in progress, wait for event callback
* \retval -1, failure.
*/
int (*connect_async) (lrmd_t * lrmd, const char *client_name, int timeout /*ms */ );
/*!
* \brief Is connected to lrmd daemon?
*
* \retval 0, false
* \retval 1, true
*/
int (*is_connected) (lrmd_t * lrmd);
/*!
* \brief Poke executor connection to verify it is still capable of serving requests
* \note The response comes in the form of a poke event to the callback.
*
* \retval 0, wait for response in callback
* \retval -1, connection failure, callback may not be invoked
*/
int (*poke_connection) (lrmd_t * lrmd);
/*!
* \brief Disconnect from the executor.
*
* \retval 0, success
* \retval negative error code on failure
*/
int (*disconnect) (lrmd_t * lrmd);
/*!
* \brief Register a resource with the executor.
*
* \note Synchronous, guaranteed to occur in daemon before function returns.
*
* \retval 0, success
* \retval negative error code on failure
*/
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 registration info for a rsc
*
* \retval info on success
* \retval NULL on failure
*/
lrmd_rsc_info_t *(*get_rsc_info) (lrmd_t * lrmd,
const char *rsc_id, enum lrmd_call_options options);
/*!
* \brief Retrieve registered recurring operations
*
* \return pcmk_ok on success, -errno otherwise
*/
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.
*
* \note All pending and recurring operations will be cancelled
* automatically.
*
* \note Synchronous, guaranteed to occur in daemon before function returns.
*
* \retval 0, success
* \retval -1, success, but operations are currently executing on the rsc which will
* return once they are completed.
* \retval negative error code on failure
*
*/
int (*unregister_rsc) (lrmd_t * lrmd, const char *rsc_id, enum lrmd_call_options options);
/*!
* \brief Set a callback for executor events
*/
void (*set_callback) (lrmd_t * lrmd, lrmd_event_callback callback);
/*!
* \brief Issue a command on a resource
*
* \note Asynchronous, command is queued in daemon on function return, but
* execution of command is not synced.
*
* \note Operations on individual resources are guaranteed to occur
* in the order the client api calls them in.
*
* \note Operations between different resources are not guaranteed
* to occur in any specific order in relation to one another
* regardless of what order the client api is called in.
* \retval call_id to track async event result on success
* \retval negative error code on failure
*/
int (*exec) (lrmd_t * lrmd, const char *rsc_id, const char *action, const char *userdata, /* userdata string given back in event notification */
guint interval_ms,
int timeout, /* ms */
int start_delay, /* ms */
enum lrmd_call_options options, lrmd_key_value_t * params); /* ownership of params is given up to api here */
/*!
* \brief Cancel a recurring command.
*
* \note Synchronous, guaranteed to occur in daemon before function returns.
*
* \note The cancel is completed async from this call.
* We can be guaranteed the cancel has completed once
* the callback receives an exec_complete event with
* the lrmd_op_status signifying that the operation is
* cancelled.
* \note For each resource, cancel operations and exec operations
* are processed in the order they are received.
* It is safe to assume that for a single resource, a cancel
* will occur in the executor before an exec if the client's cancel
* api call occurs before the exec api call.
*
* It is not however safe to assume any operation on one resource will
* occur before an operation on another resource regardless of
* the order the client api is called in.
*
* \retval 0, cancel command sent.
* \retval negative error code on failure
*/
int (*cancel) (lrmd_t *lrmd, const char *rsc_id, const char *action,
guint interval_ms);
/*!
* \brief Get resource metadata for a specified resource agent
*
* \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 Metadata will be stored here (must not be NULL)
* \param[in] options Options to use with any executor API calls (unused)
*
* \note Caller is responsible for freeing output. This call is currently
* 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 (for most resource agent classes) this will 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.
* \todo Add a metadata call to the executor API and let the server handle this.
*
* \retval lrmd_ok success
* \retval negative error code on failure
*/
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.
*
* \note if standard is not provided, all known agents will be returned
* \note list must be freed using lrmd_list_freeall()
*
* \retval num items in list on success
* \retval negative error code on failure
*/
int (*list_agents) (lrmd_t * lrmd, lrmd_list_t ** agents,
const char *standard, const char *provider);
/*!
* \brief Retrieve a list of resource agent providers
*
* \note When the agent is provided, only the agent's provider will be returned
* \note When no agent is supplied, all providers will be returned.
* \note List must be freed using lrmd_list_freeall()
*
* \retval num items in list on success
* \retval negative error code on failure
*/
int (*list_ocf_providers) (lrmd_t * lrmd, const char *agent, lrmd_list_t ** providers);
/*!
* \brief Retrieve a list of standards supported by this machine/installation
*
* \note List must be freed using lrmd_list_freeall()
*
* \retval num items in list on success
* \retval negative error code on failure
*/
int (*list_standards) (lrmd_t * lrmd, lrmd_list_t ** standards);
/*!
* \brief Execute an alert agent
*
* \note Asynchronous, command is queued in daemon on function return, but
* execution of command is not synced.
*
* \note Operations on individual alerts are guaranteed to occur
* in the order the client api calls them in.
*
* \note Operations between different alerts are not guaranteed
* to occur in any specific order in relation to one another
* regardless of what order the client api is called in.
* \retval call_id to track async event result on success
* \retval negative error code on failure
*/
int (*exec_alert) (lrmd_t *lrmd, const char *alert_id,
const char *alert_path, int timeout, /* ms */
lrmd_key_value_t *params); /* ownership of params is given up to api here */
/*!
* \brief Get resource metadata for a resource agent, passing 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 Metadata will be stored here (must not be NULL)
* \param[in] options Options to use with any executor API calls (unused)
* \param[in] params Parameters to pass to agent via environment
*
* \note This is identical to the get_metadata() API call, except parameters
* will be passed to the resource agent via environment variables.
* \note The API will handle freeing params.
*
* \return lrmd_ok on success, negative error code on failure
*/
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";
}
#ifdef __cplusplus
}
#endif
#endif
diff --git a/include/crm/lrmd_alerts_internal.h b/include/crm/lrmd_alerts_internal.h
index 43c00b1d70..a381789270 100644
--- a/include/crm/lrmd_alerts_internal.h
+++ b/include/crm/lrmd_alerts_internal.h
@@ -1,36 +1,38 @@
/*
- * Copyright (C) 2015 Andrew Beekhof <andrew@beekhof.net>
+ * Copyright 2015-2017 the Pacemaker project contributors
+ *
+ * The version control history for this file may have further details.
*
* 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 software 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
* 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 LRMD_ALERT_INTERNAL_H
#define LRMD_ALERT_INTERNAL_H
#include <glib.h>
#include <crm/lrmd.h>
int lrmd_send_attribute_alert(lrmd_t *lrmd, GList *alert_list,
const char *node, uint32_t nodeid,
const char *attr_name, const char *attr_value);
int lrmd_send_node_alert(lrmd_t *lrmd, GList *alert_list,
const char *node, uint32_t nodeid, const char *state);
int lrmd_send_fencing_alert(lrmd_t *lrmd, GList *alert_list,
const char *target, const char *task,
const char *desc, int op_rc);
int lrmd_send_resource_alert(lrmd_t *lrmd, GList *alert_list,
const char *node, lrmd_event_data_t *op);
#endif
diff --git a/include/crm/msg_xml.h b/include/crm/msg_xml.h
index 25ea471e80..2a355ec5f7 100644
--- a/include/crm/msg_xml.h
+++ b/include/crm/msg_xml.h
@@ -1,419 +1,421 @@
/*
- * Copyright 2004-2018 Andrew Beekhof <andrew@beekhof.net>
+ * Copyright 2004-2018 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 XML_TAGS__H
# define XML_TAGS__H
#ifdef __cplusplus
extern "C" {
#endif
# ifndef F_ORIG
# define F_ORIG "src"
# endif
# ifndef F_SEQ
# define F_SEQ "seq"
# endif
# ifndef F_SUBTYPE
# define F_SUBTYPE "subt"
# endif
# ifndef F_TYPE
# define F_TYPE "t"
# endif
# ifndef F_CLIENTNAME
# define F_CLIENTNAME "cn"
# endif
# ifndef F_XML_TAGNAME
# define F_XML_TAGNAME "__name__"
# endif
# ifndef T_CRM
# define T_CRM "crmd"
# endif
# ifndef T_ATTRD
# define T_ATTRD "attrd"
# endif
# define CIB_OPTIONS_FIRST "cib-bootstrap-options"
# define F_CRM_DATA "crm_xml"
# define F_CRM_TASK "crm_task"
# define F_CRM_HOST_TO "crm_host_to"
# define F_CRM_MSG_TYPE F_SUBTYPE
# define F_CRM_SYS_TO "crm_sys_to"
# define F_CRM_SYS_FROM "crm_sys_from"
# define F_CRM_HOST_FROM F_ORIG
# define F_CRM_REFERENCE XML_ATTR_REFERENCE
# define F_CRM_VERSION XML_ATTR_VERSION
# define F_CRM_ORIGIN "origin"
# define F_CRM_USER "crm_user"
# define F_CRM_JOIN_ID "join_id"
# define F_CRM_DC_LEAVING "dc-leaving"
# define F_CRM_ELECTION_ID "election-id"
# define F_CRM_ELECTION_AGE_S "election-age-sec"
# define F_CRM_ELECTION_AGE_US "election-age-nano-sec"
# define F_CRM_ELECTION_OWNER "election-owner"
# define F_CRM_TGRAPH "crm-tgraph-file"
# define F_CRM_TGRAPH_INPUT "crm-tgraph-in"
# define F_CRM_THROTTLE_MODE "crm-limit-mode"
# define F_CRM_THROTTLE_MAX "crm-limit-max"
/*---- Common tags/attrs */
# define XML_DIFF_MARKER "__crm_diff_marker__"
# define XML_TAG_CIB "cib"
# define XML_TAG_FAILED "failed"
# define XML_ATTR_CRM_VERSION "crm_feature_set"
# define XML_ATTR_DIGEST "digest"
# define XML_ATTR_VALIDATION "validate-with"
# define XML_ATTR_RA_VERSION "ra-version"
# define XML_ATTR_QUORUM_PANIC "no-quorum-panic"
# define XML_ATTR_HAVE_QUORUM "have-quorum"
# define XML_ATTR_HAVE_WATCHDOG "have-watchdog"
# define XML_ATTR_GENERATION "epoch"
# define XML_ATTR_GENERATION_ADMIN "admin_epoch"
# define XML_ATTR_NUMUPDATES "num_updates"
# define XML_ATTR_TIMEOUT "timeout"
# define XML_ATTR_ORIGIN "crm-debug-origin"
# define XML_ATTR_TSTAMP "crm-timestamp"
# define XML_CIB_ATTR_WRITTEN "cib-last-written"
# define XML_ATTR_VERSION "version"
# define XML_ATTR_DESC "description"
# define XML_ATTR_ID "id"
# define XML_ATTR_IDREF "id-ref"
# define XML_ATTR_ID_LONG "long-id"
# define XML_ATTR_TYPE "type"
# define XML_ATTR_VERBOSE "verbose"
# define XML_ATTR_OP "op"
# define XML_ATTR_DC_UUID "dc-uuid"
# define XML_ATTR_UPDATE_ORIG "update-origin"
# define XML_ATTR_UPDATE_CLIENT "update-client"
# define XML_ATTR_UPDATE_USER "update-user"
# define XML_BOOLEAN_TRUE "true"
# define XML_BOOLEAN_FALSE "false"
# define XML_BOOLEAN_YES XML_BOOLEAN_TRUE
# define XML_BOOLEAN_NO XML_BOOLEAN_FALSE
# define XML_TAG_OPTIONS "options"
/*---- top level tags/attrs */
# define XML_ATTR_REQUEST "request"
# define XML_ATTR_RESPONSE "response"
# define XML_ATTR_UNAME "uname"
# define XML_ATTR_UUID "id"
# define XML_ATTR_REFERENCE "reference"
# define XML_CRM_TAG_PING "ping_response"
# define XML_PING_ATTR_STATUS "result"
# define XML_PING_ATTR_SYSFROM "crm_subsystem"
# define XML_PING_ATTR_CRMDSTATE "crmd_state"
# define XML_TAG_FRAGMENT "cib_fragment"
# define XML_FAIL_TAG_CIB "failed_update"
# define XML_FAILCIB_ATTR_ID "id"
# define XML_FAILCIB_ATTR_OBJTYPE "object_type"
# define XML_FAILCIB_ATTR_OP "operation"
# define XML_FAILCIB_ATTR_REASON "reason"
/*---- CIB specific tags/attrs */
# define XML_CIB_TAG_SECTION_ALL "all"
# define XML_CIB_TAG_CONFIGURATION "configuration"
# define XML_CIB_TAG_STATUS "status"
# define XML_CIB_TAG_RESOURCES "resources"
# define XML_CIB_TAG_NODES "nodes"
# define XML_CIB_TAG_DOMAINS "domains"
# define XML_CIB_TAG_CONSTRAINTS "constraints"
# define XML_CIB_TAG_CRMCONFIG "crm_config"
# define XML_CIB_TAG_OPCONFIG "op_defaults"
# define XML_CIB_TAG_RSCCONFIG "rsc_defaults"
# define XML_CIB_TAG_ACLS "acls"
# define XML_CIB_TAG_ALERTS "alerts"
# define XML_CIB_TAG_ALERT "alert"
# define XML_CIB_TAG_ALERT_RECIPIENT "recipient"
# define XML_CIB_TAG_ALERT_SELECT "select"
# define XML_CIB_TAG_ALERT_ATTRIBUTES "select_attributes"
# define XML_CIB_TAG_ALERT_FENCING "select_fencing"
# define XML_CIB_TAG_ALERT_NODES "select_nodes"
# define XML_CIB_TAG_ALERT_RESOURCES "select_resources"
# define XML_CIB_TAG_ALERT_ATTR "attribute"
# define XML_CIB_TAG_STATE "node_state"
# define XML_CIB_TAG_NODE "node"
# define XML_CIB_TAG_NVPAIR "nvpair"
# define XML_CIB_TAG_PROPSET "cluster_property_set"
# define XML_TAG_ATTR_SETS "instance_attributes"
# define XML_TAG_META_SETS "meta_attributes"
# define XML_TAG_ATTRS "attributes"
# define XML_TAG_RSC_VER_ATTRS "rsc_versioned_attrs"
# define XML_TAG_OP_VER_ATTRS "op_versioned_attrs"
# define XML_TAG_OP_VER_META "op_versioned_meta"
# define XML_TAG_PARAMS "parameters"
# define XML_TAG_PARAM "param"
# define XML_TAG_UTILIZATION "utilization"
# define XML_TAG_RESOURCE_REF "resource_ref"
# define XML_CIB_TAG_RESOURCE "primitive"
# define XML_CIB_TAG_GROUP "group"
# define XML_CIB_TAG_INCARNATION "clone"
# define XML_CIB_TAG_MASTER "master" // deprecated since 2.0.0
# define XML_CIB_TAG_CONTAINER "bundle"
# define XML_CIB_TAG_RSC_TEMPLATE "template"
# define XML_RSC_ATTR_TARGET "container-attribute-target"
# define XML_RSC_ATTR_RESTART "restart-type"
# define XML_RSC_ATTR_ORDERED "ordered"
# define XML_RSC_ATTR_INTERLEAVE "interleave"
# define XML_RSC_ATTR_INCARNATION "clone"
# define XML_RSC_ATTR_INCARNATION_MAX "clone-max"
# define XML_RSC_ATTR_INCARNATION_MIN "clone-min"
# define XML_RSC_ATTR_INCARNATION_NODEMAX "clone-node-max"
# define XML_RSC_ATTR_PROMOTABLE "promotable"
# define XML_RSC_ATTR_PROMOTED_MAX "promoted-max"
# define XML_RSC_ATTR_PROMOTED_NODEMAX "promoted-node-max"
# define XML_RSC_ATTR_MASTER_MAX "master-max" // deprecated since 2.0.0
# define XML_RSC_ATTR_MASTER_NODEMAX "master-node-max" // deprecated since 2.0.0
# define XML_RSC_ATTR_MANAGED "is-managed"
# define XML_RSC_ATTR_TARGET_ROLE "target-role"
# define XML_RSC_ATTR_UNIQUE "globally-unique"
# define XML_RSC_ATTR_NOTIFY "notify"
# define XML_RSC_ATTR_STICKINESS "resource-stickiness"
# define XML_RSC_ATTR_FAIL_STICKINESS "migration-threshold"
# define XML_RSC_ATTR_FAIL_TIMEOUT "failure-timeout"
# define XML_RSC_ATTR_MULTIPLE "multiple-active"
# define XML_RSC_ATTR_REQUIRES "requires"
# define XML_RSC_ATTR_PROVIDES "provides"
# define XML_RSC_ATTR_CONTAINER "container"
# define XML_RSC_ATTR_INTERNAL_RSC "internal_rsc"
# define XML_RSC_ATTR_MAINTENANCE "maintenance"
# define XML_RSC_ATTR_REMOTE_NODE "remote-node"
# define XML_RSC_ATTR_CLEAR_OP "clear_failure_op"
# define XML_RSC_ATTR_CLEAR_INTERVAL "clear_failure_interval"
# define XML_RSC_ATTR_REMOTE_RA_ADDR "addr"
# define XML_RSC_ATTR_REMOTE_RA_SERVER "server"
# define XML_RSC_ATTR_REMOTE_RA_PORT "port"
# define XML_REMOTE_ATTR_RECONNECT_INTERVAL "reconnect_interval"
# define XML_OP_ATTR_ON_FAIL "on-fail"
# define XML_OP_ATTR_START_DELAY "start-delay"
# define XML_OP_ATTR_ALLOW_MIGRATE "allow-migrate"
# define XML_OP_ATTR_ORIGIN "interval-origin"
# define XML_OP_ATTR_PENDING "record-pending"
# define XML_OP_ATTR_DIGESTS_ALL "digests-all"
# define XML_OP_ATTR_DIGESTS_SECURE "digests-secure"
# define XML_CIB_TAG_LRM "lrm"
# define XML_LRM_TAG_RESOURCES "lrm_resources"
# define XML_LRM_TAG_RESOURCE "lrm_resource"
# define XML_LRM_TAG_RSC_OP "lrm_rsc_op"
# define XML_AGENT_ATTR_CLASS "class"
# define XML_AGENT_ATTR_PROVIDER "provider"
# define XML_CIB_ATTR_REPLACE "replace"
# define XML_CIB_ATTR_SOURCE "source"
# define XML_CIB_ATTR_PRIORITY "priority"
# define XML_CIB_ATTR_SOURCE "source"
# define XML_NODE_JOIN_STATE "join"
# define XML_NODE_EXPECTED "expected"
# define XML_NODE_IN_CLUSTER "in_ccm"
# define XML_NODE_IS_PEER "crmd"
# define XML_NODE_IS_REMOTE "remote_node"
# define XML_NODE_IS_FENCED "node_fenced"
# define XML_NODE_IS_MAINTENANCE "node_in_maintenance"
# define XML_CIB_ATTR_SHUTDOWN "shutdown"
/* Aside from being an old name for the executor, LRM is a misnomer here because
* the controller and scheduler use these to track actions, which are not always
* executor operations.
*/
// XML attribute that takes interval specification (user-facing configuration)
# define XML_LRM_ATTR_INTERVAL "interval"
// XML attribute that takes interval in milliseconds (daemon APIs)
// (identical value as above, but different constant allows clearer code intent)
# define XML_LRM_ATTR_INTERVAL_MS XML_LRM_ATTR_INTERVAL
# define XML_LRM_ATTR_TASK "operation"
# define XML_LRM_ATTR_TASK_KEY "operation_key"
# define XML_LRM_ATTR_TARGET "on_node"
# define XML_LRM_ATTR_TARGET_UUID "on_node_uuid"
/*! Actions to be executed on Pacemaker Remote nodes are routed through the
* controller on the cluster node hosting the remote connection. That cluster
* node is considered the router node for the action.
*/
# define XML_LRM_ATTR_ROUTER_NODE "router_node"
# define XML_LRM_ATTR_RSCID "rsc-id"
# define XML_LRM_ATTR_OPSTATUS "op-status"
# define XML_LRM_ATTR_RC "rc-code"
# define XML_LRM_ATTR_CALLID "call-id"
# define XML_LRM_ATTR_OP_DIGEST "op-digest"
# define XML_LRM_ATTR_OP_RESTART "op-force-restart"
# define XML_LRM_ATTR_OP_SECURE "op-secure-params"
# define XML_LRM_ATTR_RESTART_DIGEST "op-restart-digest"
# define XML_LRM_ATTR_SECURE_DIGEST "op-secure-digest"
# define XML_LRM_ATTR_EXIT_REASON "exit-reason"
# define XML_RSC_OP_LAST_CHANGE "last-rc-change"
# define XML_RSC_OP_LAST_RUN "last-run"
# define XML_RSC_OP_T_EXEC "exec-time"
# define XML_RSC_OP_T_QUEUE "queue-time"
# define XML_LRM_ATTR_MIGRATE_SOURCE "migrate_source"
# define XML_LRM_ATTR_MIGRATE_TARGET "migrate_target"
# define XML_TAG_GRAPH "transition_graph"
# define XML_GRAPH_TAG_RSC_OP "rsc_op"
# define XML_GRAPH_TAG_PSEUDO_EVENT "pseudo_event"
# define XML_GRAPH_TAG_CRM_EVENT "crm_event"
# define XML_GRAPH_TAG_DOWNED "downed"
# define XML_GRAPH_TAG_MAINTENANCE "maintenance"
# define XML_TAG_RULE "rule"
# define XML_RULE_ATTR_SCORE "score"
# define XML_RULE_ATTR_SCORE_ATTRIBUTE "score-attribute"
# define XML_RULE_ATTR_ROLE "role"
# define XML_RULE_ATTR_BOOLEAN_OP "boolean-op"
# define XML_TAG_EXPRESSION "expression"
# define XML_EXPR_ATTR_ATTRIBUTE "attribute"
# define XML_EXPR_ATTR_OPERATION "operation"
# define XML_EXPR_ATTR_VALUE "value"
# define XML_EXPR_ATTR_TYPE "type"
# define XML_EXPR_ATTR_VALUE_SOURCE "value-source"
# define XML_CONS_TAG_RSC_DEPEND "rsc_colocation"
# define XML_CONS_TAG_RSC_ORDER "rsc_order"
# define XML_CONS_TAG_RSC_LOCATION "rsc_location"
# define XML_CONS_TAG_RSC_TICKET "rsc_ticket"
# define XML_CONS_TAG_RSC_SET "resource_set"
# define XML_CONS_ATTR_SYMMETRICAL "symmetrical"
# define XML_LOCATION_ATTR_DISCOVERY "resource-discovery"
# define XML_COLOC_ATTR_SOURCE "rsc"
# define XML_COLOC_ATTR_SOURCE_ROLE "rsc-role"
# define XML_COLOC_ATTR_TARGET "with-rsc"
# define XML_COLOC_ATTR_TARGET_ROLE "with-rsc-role"
# define XML_COLOC_ATTR_NODE_ATTR "node-attribute"
# define XML_COLOC_ATTR_SOURCE_INSTANCE "rsc-instance"
# define XML_COLOC_ATTR_TARGET_INSTANCE "with-rsc-instance"
# define XML_LOC_ATTR_SOURCE "rsc"
# define XML_LOC_ATTR_SOURCE_PATTERN "rsc-pattern"
# define XML_ORDER_ATTR_FIRST "first"
# define XML_ORDER_ATTR_THEN "then"
# define XML_ORDER_ATTR_FIRST_ACTION "first-action"
# define XML_ORDER_ATTR_THEN_ACTION "then-action"
# define XML_ORDER_ATTR_FIRST_INSTANCE "first-instance"
# define XML_ORDER_ATTR_THEN_INSTANCE "then-instance"
# define XML_ORDER_ATTR_KIND "kind"
# define XML_TICKET_ATTR_TICKET "ticket"
# define XML_TICKET_ATTR_LOSS_POLICY "loss-policy"
# define XML_NVPAIR_ATTR_NAME "name"
# define XML_NVPAIR_ATTR_VALUE "value"
# define XML_NODE_ATTR_RSC_DISCOVERY "resource-discovery-enabled"
# define XML_CONFIG_ATTR_DC_DEADTIME "dc-deadtime"
# define XML_CONFIG_ATTR_ELECTION_FAIL "election-timeout"
# define XML_CONFIG_ATTR_FORCE_QUIT "shutdown-escalation"
# define XML_CONFIG_ATTR_RECHECK "cluster-recheck-interval"
# define XML_ALERT_ATTR_PATH "path"
# define XML_ALERT_ATTR_TIMEOUT "timeout"
# define XML_ALERT_ATTR_TSTAMP_FORMAT "timestamp-format"
# define XML_ALERT_ATTR_REC_VALUE "value"
# define XML_CIB_TAG_GENERATION_TUPPLE "generation_tuple"
# define XML_ATTR_TRANSITION_MAGIC "transition-magic"
# define XML_ATTR_TRANSITION_KEY "transition-key"
# define XML_ATTR_TE_NOWAIT "op_no_wait"
# define XML_ATTR_TE_TARGET_RC "op_target_rc"
# define XML_TAG_TRANSIENT_NODEATTRS "transient_attributes"
# define XML_TAG_DIFF_ADDED "diff-added"
# define XML_TAG_DIFF_REMOVED "diff-removed"
# define XML_ACL_TAG_USER "acl_target"
# define XML_ACL_TAG_USERv1 "acl_user"
# define XML_ACL_TAG_GROUP "acl_group"
# define XML_ACL_TAG_ROLE "acl_role"
# define XML_ACL_TAG_PERMISSION "acl_permission"
# define XML_ACL_TAG_ROLE_REF "role"
# define XML_ACL_TAG_ROLE_REFv1 "role_ref"
# define XML_ACL_ATTR_KIND "kind"
# define XML_ACL_TAG_READ "read"
# define XML_ACL_TAG_WRITE "write"
# define XML_ACL_TAG_DENY "deny"
# define XML_ACL_ATTR_REF "reference"
# define XML_ACL_ATTR_REFv1 "ref"
# define XML_ACL_ATTR_TAG "object-type"
# define XML_ACL_ATTR_TAGv1 "tag"
# define XML_ACL_ATTR_XPATH "xpath"
# define XML_ACL_ATTR_ATTRIBUTE "attribute"
# define XML_CIB_TAG_TICKETS "tickets"
# define XML_CIB_TAG_TICKET_STATE "ticket_state"
# define XML_CIB_TAG_TAGS "tags"
# define XML_CIB_TAG_TAG "tag"
# define XML_CIB_TAG_OBJ_REF "obj_ref"
# define XML_TAG_FENCING_TOPOLOGY "fencing-topology"
# define XML_TAG_FENCING_LEVEL "fencing-level"
# define XML_ATTR_STONITH_INDEX "index"
# define XML_ATTR_STONITH_TARGET "target"
# define XML_ATTR_STONITH_TARGET_VALUE "target-value"
# define XML_ATTR_STONITH_TARGET_PATTERN "target-pattern"
# define XML_ATTR_STONITH_TARGET_ATTRIBUTE "target-attribute"
# define XML_ATTR_STONITH_DEVICES "devices"
# define XML_TAG_DIFF "diff"
# define XML_DIFF_VERSION "version"
# define XML_DIFF_VSOURCE "source"
# define XML_DIFF_VTARGET "target"
# define XML_DIFF_CHANGE "change"
# define XML_DIFF_LIST "change-list"
# define XML_DIFF_ATTR "change-attr"
# define XML_DIFF_RESULT "change-result"
# define XML_DIFF_OP "operation"
# define XML_DIFF_PATH "path"
# define XML_DIFF_POSITION "position"
# include <crm/common/xml.h>
# define ID(x) crm_element_value(x, XML_ATTR_ID)
# define TYPE(x) crm_element_name(x)
#ifdef __cplusplus
}
#endif
#endif
diff --git a/include/crm/pengine/Makefile.am b/include/crm/pengine/Makefile.am
index f41f88782a..ac18d001b3 100644
--- a/include/crm/pengine/Makefile.am
+++ b/include/crm/pengine/Makefile.am
@@ -1,23 +1,25 @@
#
-# Copyright (C) 2004 Andrew Beekhof
+# Copyright 2006-2017 the Pacemaker project contributors
+#
+# The version control history for this file may have further details.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
MAINTAINERCLEANFILES = Makefile.in
headerdir=$(pkgincludedir)/crm/pengine
noinst_HEADERS = internal.h rules_internal.h
header_HEADERS = common.h complex.h remote.h rules.h status.h
diff --git a/include/crm/pengine/common.h b/include/crm/pengine/common.h
index d8f412402f..d21724f0a6 100644
--- a/include/crm/pengine/common.h
+++ b/include/crm/pengine/common.h
@@ -1,148 +1,150 @@
/*
- * Copyright (C) 2004 Andrew Beekhof <andrew@beekhof.net>
+ * Copyright 2004-2018 the Pacemaker project contributors
+ *
+ * The version control history for this file may have further details.
*
* 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 software 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
* 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 PE_COMMON__H
# define PE_COMMON__H
#ifdef __cplusplus
extern "C" {
#endif
# include <glib.h>
extern gboolean was_processing_error;
extern gboolean was_processing_warning;
/* order is significant here
* items listed in order of accending severeness
* more severe actions take precedent over lower ones
*/
enum action_fail_response {
action_fail_ignore,
action_fail_recover,
action_fail_migrate, /* recover by moving it somewhere else */
action_fail_block,
action_fail_stop,
action_fail_standby,
action_fail_fence,
action_fail_restart_container,
/* This is reserved for internal use for baremetal remote node connection
* resources. This fail action means
* 1. If stonith is enabled, fence the baremetal remote node
* 2. stonith not enabled, attempt to recover the connection resources
*
* This response value gives us control of saying types of
* connection resource failures result in fencing the remote node.
* Example: recurring monitors failure should result in fencing.
*/
action_fail_reset_remote,
};
/* the "done" action must be the "pre" action +1 */
enum action_tasks {
no_action,
monitor_rsc,
stop_rsc,
stopped_rsc,
start_rsc,
started_rsc,
action_notify,
action_notified,
action_promote,
action_promoted,
action_demote,
action_demoted,
shutdown_crm,
stonith_node
};
enum rsc_recovery_type {
recovery_stop_start,
recovery_stop_only,
recovery_block
};
enum rsc_start_requirement {
rsc_req_nothing, /* Allowed by custom_action() */
rsc_req_quorum, /* Enforced by custom_action() */
rsc_req_stonith /* Enforced by native_start_constraints() */
};
enum rsc_role_e {
RSC_ROLE_UNKNOWN,
RSC_ROLE_STOPPED,
RSC_ROLE_STARTED,
RSC_ROLE_SLAVE,
RSC_ROLE_MASTER,
};
# define RSC_ROLE_MAX RSC_ROLE_MASTER+1
# define RSC_ROLE_UNKNOWN_S "Unknown"
# define RSC_ROLE_STOPPED_S "Stopped"
# define RSC_ROLE_STARTED_S "Started"
# define RSC_ROLE_SLAVE_S "Slave"
# define RSC_ROLE_MASTER_S "Master"
enum pe_print_options {
pe_print_log = 0x0001,
pe_print_html = 0x0002,
pe_print_ncurses = 0x0004,
pe_print_printf = 0x0008,
pe_print_dev = 0x0010,
pe_print_details = 0x0020,
pe_print_max_details = 0x0040,
pe_print_rsconly = 0x0080,
pe_print_ops = 0x0100,
pe_print_suppres_nl = 0x0200,
pe_print_xml = 0x0400,
pe_print_brief = 0x0800,
pe_print_pending = 0x1000,
pe_print_clone_details = 0x2000,
pe_print_clone_active = 0x4000, // Print clone instances only if active
pe_print_implicit = 0x8000, // Print implicitly created resources
};
const char *task2text(enum action_tasks task);
enum action_tasks text2task(const char *task);
enum rsc_role_e text2role(const char *role);
const char *role2text(enum rsc_role_e role);
const char *fail2text(enum action_fail_response fail);
const char *pe_pref(GHashTable * options, const char *name);
void calculate_active_ops(GList * sorted_op_list, int *start_index, int *stop_index);
static inline const char *
recovery2text(enum rsc_recovery_type type)
{
switch (type) {
case recovery_stop_only:
return "shutting it down";
case recovery_stop_start:
return "attempting recovery";
case recovery_block:
return "waiting for an administrator";
}
return "Unknown";
}
#ifdef __cplusplus
}
#endif
#endif
diff --git a/include/crm/pengine/internal.h b/include/crm/pengine/internal.h
index c9e57641ed..93835dc522 100644
--- a/include/crm/pengine/internal.h
+++ b/include/crm/pengine/internal.h
@@ -1,353 +1,355 @@
/*
- * Copyright 2004-2019 Andrew Beekhof <andrew@beekhof.net>
+ * Copyright 2004-2019 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 PE_INTERNAL__H
# define PE_INTERNAL__H
# include <string.h>
# include <crm/pengine/status.h>
# include <crm/pengine/remote.h>
# define pe_rsc_info(rsc, fmt, args...) crm_log_tag(LOG_INFO, rsc ? rsc->id : "<NULL>", fmt, ##args)
# define pe_rsc_debug(rsc, fmt, args...) crm_log_tag(LOG_DEBUG, rsc ? rsc->id : "<NULL>", fmt, ##args)
# define pe_rsc_trace(rsc, fmt, args...) crm_log_tag(LOG_TRACE, rsc ? rsc->id : "<NULL>", fmt, ##args)
# define pe_err(fmt...) { was_processing_error = TRUE; crm_config_error = TRUE; crm_err(fmt); }
# define pe_warn(fmt...) { was_processing_warning = TRUE; crm_config_warning = TRUE; crm_warn(fmt); }
# define pe_proc_err(fmt...) { was_processing_error = TRUE; crm_err(fmt); }
# define pe_proc_warn(fmt...) { was_processing_warning = TRUE; crm_warn(fmt); }
# define pe_set_action_bit(action, bit) action->flags = crm_set_bit(__FUNCTION__, __LINE__, action->uuid, action->flags, bit)
# define pe_clear_action_bit(action, bit) action->flags = crm_clear_bit(__FUNCTION__, __LINE__, action->uuid, action->flags, bit)
typedef struct pe__location_constraint_s {
char *id; // Constraint XML ID
pe_resource_t *rsc_lh; // Resource being located
enum rsc_role_e role_filter; // Role to locate
enum pe_discover_e discover_mode; // Resource discovery
GListPtr node_list_rh; // List of pe_node_t*
} pe__location_t;
typedef struct pe__order_constraint_s {
int id;
enum pe_ordering type;
void *lh_opaque;
resource_t *lh_rsc;
action_t *lh_action;
char *lh_action_task;
void *rh_opaque;
resource_t *rh_rsc;
action_t *rh_action;
char *rh_action_task;
} pe__ordering_t;
typedef struct notify_data_s {
GSList *keys; // Environment variable name/value pairs
const char *action;
action_t *pre;
action_t *post;
action_t *pre_done;
action_t *post_done;
GListPtr active; /* notify_entry_t* */
GListPtr inactive; /* notify_entry_t* */
GListPtr start; /* notify_entry_t* */
GListPtr stop; /* notify_entry_t* */
GListPtr demote; /* notify_entry_t* */
GListPtr promote; /* notify_entry_t* */
GListPtr master; /* notify_entry_t* */
GListPtr slave; /* notify_entry_t* */
GHashTable *allowed_nodes;
} notify_data_t;
bool pe_can_fence(pe_working_set_t *data_set, node_t *node);
int merge_weights(int w1, int w2);
void add_hash_param(GHashTable * hash, const char *name, const char *value);
char *native_parameter(resource_t * rsc, node_t * node, gboolean create, const char *name,
pe_working_set_t * data_set);
pe_node_t *native_location(const pe_resource_t *rsc, GList **list, int current);
void pe_metadata(void);
void verify_pe_options(GHashTable * options);
void common_update_score(resource_t * rsc, const char *id, int score);
void native_add_running(resource_t * rsc, node_t * node, pe_working_set_t * data_set);
gboolean native_unpack(resource_t * rsc, pe_working_set_t * data_set);
gboolean group_unpack(resource_t * rsc, pe_working_set_t * data_set);
gboolean clone_unpack(resource_t * rsc, pe_working_set_t * data_set);
gboolean container_unpack(resource_t * rsc, pe_working_set_t * data_set);
resource_t *native_find_rsc(resource_t *rsc, const char *id, const node_t *node,
int flags);
gboolean native_active(resource_t * rsc, gboolean all);
gboolean group_active(resource_t * rsc, gboolean all);
gboolean clone_active(resource_t * rsc, gboolean all);
gboolean container_active(resource_t * rsc, gboolean all);
void native_print(resource_t * rsc, const char *pre_text, long options, void *print_data);
void group_print(resource_t * rsc, const char *pre_text, long options, void *print_data);
void clone_print(resource_t * rsc, const char *pre_text, long options, void *print_data);
void container_print(resource_t * rsc, const char *pre_text, long options, void *print_data);
void native_free(resource_t * rsc);
void group_free(resource_t * rsc);
void clone_free(resource_t * rsc);
void container_free(resource_t * rsc);
enum rsc_role_e native_resource_state(const resource_t * rsc, gboolean current);
enum rsc_role_e group_resource_state(const resource_t * rsc, gboolean current);
enum rsc_role_e clone_resource_state(const resource_t * rsc, gboolean current);
enum rsc_role_e container_resource_state(const resource_t * rsc, gboolean current);
gboolean common_unpack(xmlNode * xml_obj, resource_t ** rsc, resource_t * parent,
pe_working_set_t * data_set);
void common_free(resource_t * rsc);
extern node_t *node_copy(const node_t *this_node);
extern time_t get_effective_time(pe_working_set_t * data_set);
/* Failure handling utilities (from failcounts.c) */
// bit flags for fail count handling options
enum pe_fc_flags_e {
pe_fc_default = 0x00,
pe_fc_effective = 0x01, // don't count expired failures
pe_fc_fillers = 0x02, // if container, include filler failures in count
};
int pe_get_failcount(node_t *node, resource_t *rsc, time_t *last_failure,
uint32_t flags, xmlNode *xml_op,
pe_working_set_t *data_set);
pe_action_t *pe__clear_failcount(pe_resource_t *rsc, pe_node_t *node,
const char *reason,
pe_working_set_t *data_set);
/* Functions for finding/counting a resource's active nodes */
pe_node_t *pe__find_active_on(const pe_resource_t *rsc,
unsigned int *count_all,
unsigned int *count_clean);
pe_node_t *pe__find_active_requires(const pe_resource_t *rsc,
unsigned int *count);
static inline pe_node_t *
pe__current_node(const pe_resource_t *rsc)
{
return pe__find_active_on(rsc, NULL, NULL);
}
/* Binary like operators for lists of nodes */
extern void node_list_exclude(GHashTable * list, GListPtr list2, gboolean merge_scores);
extern GListPtr node_list_dup(GListPtr list, gboolean reset, gboolean filter);
extern GHashTable *node_hash_from_list(GListPtr list);
static inline gpointer
pe_hash_table_lookup(GHashTable * hash, gconstpointer key)
{
if (hash) {
return g_hash_table_lookup(hash, key);
}
return NULL;
}
extern action_t *get_pseudo_op(const char *name, pe_working_set_t * data_set);
extern gboolean order_actions(action_t * lh_action, action_t * rh_action, enum pe_ordering order);
GHashTable *node_hash_dup(GHashTable * hash);
/* Printing functions for debug */
extern void print_node(const char *pre_text, node_t * node, gboolean details);
extern void print_resource(int log_level, const char *pre_text, resource_t * rsc, gboolean details);
extern void dump_node_scores_worker(int level, const char *file, const char *function, int line,
resource_t * rsc, const char *comment, GHashTable * nodes);
extern void dump_node_capacity(int level, const char *comment, node_t * node);
extern void dump_rsc_utilization(int level, const char *comment, resource_t * rsc, node_t * node);
# define dump_node_scores(level, rsc, text, nodes) do { \
dump_node_scores_worker(level, __FILE__, __FUNCTION__, __LINE__, rsc, text, nodes); \
} while(0)
/* Sorting functions */
extern gint sort_rsc_priority(gconstpointer a, gconstpointer b);
extern gint sort_rsc_index(gconstpointer a, gconstpointer b);
extern xmlNode *find_rsc_op_entry(resource_t * rsc, const char *key);
extern action_t *custom_action(resource_t * rsc, char *key, const char *task, node_t * on_node,
gboolean optional, gboolean foo, pe_working_set_t * data_set);
# define delete_key(rsc) generate_op_key(rsc->id, CRMD_ACTION_DELETE, 0)
# define delete_action(rsc, node, optional) custom_action( \
rsc, delete_key(rsc), CRMD_ACTION_DELETE, node, \
optional, TRUE, data_set);
# define stopped_key(rsc) generate_op_key(rsc->id, CRMD_ACTION_STOPPED, 0)
# define stopped_action(rsc, node, optional) custom_action( \
rsc, stopped_key(rsc), CRMD_ACTION_STOPPED, node, \
optional, TRUE, data_set);
# define stop_key(rsc) generate_op_key(rsc->id, CRMD_ACTION_STOP, 0)
# define stop_action(rsc, node, optional) custom_action( \
rsc, stop_key(rsc), CRMD_ACTION_STOP, node, \
optional, TRUE, data_set);
# define reload_key(rsc) generate_op_key(rsc->id, CRMD_ACTION_RELOAD, 0)
# define start_key(rsc) generate_op_key(rsc->id, CRMD_ACTION_START, 0)
# define start_action(rsc, node, optional) custom_action( \
rsc, start_key(rsc), CRMD_ACTION_START, node, \
optional, TRUE, data_set)
# define started_key(rsc) generate_op_key(rsc->id, CRMD_ACTION_STARTED, 0)
# define started_action(rsc, node, optional) custom_action( \
rsc, started_key(rsc), CRMD_ACTION_STARTED, node, \
optional, TRUE, data_set)
# define promote_key(rsc) generate_op_key(rsc->id, CRMD_ACTION_PROMOTE, 0)
# define promote_action(rsc, node, optional) custom_action( \
rsc, promote_key(rsc), CRMD_ACTION_PROMOTE, node, \
optional, TRUE, data_set)
# define promoted_key(rsc) generate_op_key(rsc->id, CRMD_ACTION_PROMOTED, 0)
# define promoted_action(rsc, node, optional) custom_action( \
rsc, promoted_key(rsc), CRMD_ACTION_PROMOTED, node, \
optional, TRUE, data_set)
# define demote_key(rsc) generate_op_key(rsc->id, CRMD_ACTION_DEMOTE, 0)
# define demote_action(rsc, node, optional) custom_action( \
rsc, demote_key(rsc), CRMD_ACTION_DEMOTE, node, \
optional, TRUE, data_set)
# define demoted_key(rsc) generate_op_key(rsc->id, CRMD_ACTION_DEMOTED, 0)
# define demoted_action(rsc, node, optional) custom_action( \
rsc, demoted_key(rsc), CRMD_ACTION_DEMOTED, node, \
optional, TRUE, data_set)
extern int pe_get_configured_timeout(resource_t *rsc, const char *action,
pe_working_set_t *data_set);
extern action_t *find_first_action(GListPtr input, const char *uuid, const char *task,
node_t * on_node);
extern enum action_tasks get_complex_task(resource_t * rsc, const char *name,
gboolean allow_non_atomic);
extern GListPtr find_actions(GListPtr input, const char *key, const node_t *on_node);
extern GListPtr find_actions_exact(GListPtr input, const char *key, node_t * on_node);
extern GListPtr find_recurring_actions(GListPtr input, node_t * not_on_node);
extern void pe_free_action(action_t * action);
extern void resource_location(resource_t * rsc, node_t * node, int score, const char *tag,
pe_working_set_t * data_set);
extern gint sort_op_by_callid(gconstpointer a, gconstpointer b);
extern gboolean get_target_role(resource_t * rsc, enum rsc_role_e *role);
extern resource_t *find_clone_instance(resource_t * rsc, const char *sub_id,
pe_working_set_t * data_set);
extern void destroy_ticket(gpointer data);
extern ticket_t *ticket_new(const char *ticket_id, pe_working_set_t * data_set);
// Resources for manipulating resource names
const char *pe_base_name_end(const char *id);
char *clone_strip(const char *last_rsc_id);
char *clone_zero(const char *last_rsc_id);
static inline bool
pe_base_name_eq(resource_t *rsc, const char *id)
{
if (id && rsc && rsc->id) {
// Number of characters in rsc->id before any clone suffix
size_t base_len = pe_base_name_end(rsc->id) - rsc->id + 1;
return (strlen(id) == base_len) && !strncmp(id, rsc->id, base_len);
}
return FALSE;
}
int get_target_rc(xmlNode * xml_op);
gint sort_node_uname(gconstpointer a, gconstpointer b);
bool is_set_recursive(resource_t * rsc, long long flag, bool any);
enum rsc_digest_cmp_val {
/*! Digests are the same */
RSC_DIGEST_MATCH = 0,
/*! Params that require a restart changed */
RSC_DIGEST_RESTART,
/*! Some parameter changed. */
RSC_DIGEST_ALL,
/*! rsc op didn't have a digest associated with it, so
* it is unknown if parameters changed or not. */
RSC_DIGEST_UNKNOWN,
};
typedef struct op_digest_cache_s {
enum rsc_digest_cmp_val rc;
xmlNode *params_all;
xmlNode *params_secure;
xmlNode *params_restart;
char *digest_all_calc;
char *digest_secure_calc;
char *digest_restart_calc;
} op_digest_cache_t;
op_digest_cache_t *rsc_action_digest_cmp(resource_t * rsc, xmlNode * xml_op, node_t * node,
pe_working_set_t * data_set);
action_t *pe_fence_op(node_t * node, const char *op, bool optional, const char *reason, pe_working_set_t * data_set);
void trigger_unfencing(
resource_t * rsc, node_t *node, const char *reason, action_t *dependency, pe_working_set_t * data_set);
void pe_action_set_reason(pe_action_t *action, const char *reason, bool overwrite);
void pe_action_set_flag_reason(const char *function, long line, pe_action_t *action, pe_action_t *reason, const char *text, enum pe_action_flags flags, bool overwrite);
#define pe_action_required(action, reason, text) pe_action_set_flag_reason(__FUNCTION__, __LINE__, action, reason, text, pe_action_optional, FALSE)
#define pe_action_implies(action, reason, flag) pe_action_set_flag_reason(__FUNCTION__, __LINE__, action, reason, NULL, flag, FALSE)
void set_bit_recursive(resource_t * rsc, unsigned long long flag);
void clear_bit_recursive(resource_t * rsc, unsigned long long flag);
gboolean add_tag_ref(GHashTable * tags, const char * tag_name, const char * obj_ref);
void print_rscs_brief(GListPtr rsc_list, const char * pre_text, long options,
void * print_data, gboolean print_all);
void pe_fence_node(pe_working_set_t * data_set, node_t * node, const char *reason);
node_t *pe_create_node(const char *id, const char *uname, const char *type,
const char *score, pe_working_set_t * data_set);
bool remote_id_conflict(const char *remote_name, pe_working_set_t *data);
void common_print(resource_t * rsc, const char *pre_text, const char *name, node_t *node, long options, void *print_data);
resource_t *find_container_child(const resource_t *bundle, const node_t *node);
bool container_fix_remote_addr(resource_t *rsc);
const char *container_fix_remote_addr_in(resource_t *rsc, xmlNode *xml, const char *field);
const char *pe_node_attribute_calculated(const pe_node_t *node,
const char *name,
const resource_t *rsc);
const char *pe_node_attribute_raw(pe_node_t *node, const char *name);
bool pe__is_universal_clone(pe_resource_t *rsc,
pe_working_set_t *data_set);
void pe__add_param_check(xmlNode *rsc_op, pe_resource_t *rsc, pe_node_t *node,
enum pe_check_parameters, pe_working_set_t *data_set);
void pe__foreach_param_check(pe_working_set_t *data_set,
void (*cb)(pe_resource_t*, pe_node_t*, xmlNode*,
enum pe_check_parameters,
pe_working_set_t*));
void pe__free_param_checks(pe_working_set_t *data_set);
#endif
diff --git a/include/crm/pengine/remote.h b/include/crm/pengine/remote.h
index 12a6026c9e..66bfc23525 100644
--- a/include/crm/pengine/remote.h
+++ b/include/crm/pengine/remote.h
@@ -1,36 +1,38 @@
/*
- * Copyright 2013-2019 Andrew Beekhof <andrew@beekhof.net>
+ * Copyright 2013-2019 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 PE_REMOTE__H
# define PE_REMOTE__H
#ifdef __cplusplus
extern "C" {
#endif
#include <glib.h> // gboolean
#include <libxml/tree.h> // xmlNode
#include <crm/pengine/status.h>
gboolean xml_contains_remote_node(xmlNode *xml);
gboolean is_baremetal_remote_node(node_t *node);
gboolean is_container_remote_node(node_t *node);
gboolean is_remote_node(node_t *node);
gboolean is_rsc_baremetal_remote_node(resource_t *rsc, pe_working_set_t * data_set);
resource_t * rsc_contains_remote_node(pe_working_set_t * data_set, resource_t *rsc);
void pe_foreach_guest_node(const pe_working_set_t *data_set, const node_t *host,
void (*helper)(const node_t*, void*), void *user_data);
xmlNode *pe_create_remote_xml(xmlNode *parent, const char *uname,
const char *container_id, const char *migrateable,
const char *is_managed, const char *start_timeout,
const char *server, const char *port);
#ifdef __cplusplus
}
#endif
#endif
diff --git a/include/crm/pengine/rules.h b/include/crm/pengine/rules.h
index 1ef85bfa9e..c0d0fc47e0 100644
--- a/include/crm/pengine/rules.h
+++ b/include/crm/pengine/rules.h
@@ -1,91 +1,93 @@
/*
- * Copyright (C) 2004 Andrew Beekhof <andrew@beekhof.net>
+ * Copyright 2004-2018 the Pacemaker project contributors
+ *
+ * The version control history for this file may have further details.
*
* 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 software 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
* 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 PENGINE_RULES__H
# define PENGINE_RULES__H
#ifdef __cplusplus
extern "C" {
#endif
# include <glib.h>
# include <regex.h>
# include <crm/crm.h>
# include <crm/common/iso8601.h>
# include <crm/pengine/common.h>
enum expression_type {
not_expr,
nested_rule,
attr_expr,
loc_expr,
role_expr,
time_expr,
version_expr
};
typedef struct pe_re_match_data {
char *string;
int nregs;
regmatch_t *pmatch;
} pe_re_match_data_t;
typedef struct pe_match_data {
pe_re_match_data_t *re;
GHashTable *params;
GHashTable *meta;
} pe_match_data_t;
enum expression_type find_expression_type(xmlNode * expr);
gboolean test_ruleset(xmlNode * ruleset, GHashTable * node_hash, crm_time_t * now);
gboolean test_rule(xmlNode * rule, GHashTable * node_hash, enum rsc_role_e role, crm_time_t * now);
gboolean pe_test_rule_re(xmlNode * rule, GHashTable * node_hash, enum rsc_role_e role, crm_time_t * now,
pe_re_match_data_t * re_match_data);
gboolean pe_test_rule_full(xmlNode * rule, GHashTable * node_hash, enum rsc_role_e role, crm_time_t * now,
pe_match_data_t * match_data);
gboolean test_expression(xmlNode * expr, GHashTable * node_hash,
enum rsc_role_e role, crm_time_t * now);
gboolean pe_test_expression_re(xmlNode * expr, GHashTable * node_hash,
enum rsc_role_e role, crm_time_t * now, pe_re_match_data_t * re_match_data);
gboolean pe_test_expression_full(xmlNode * expr, GHashTable * node_hash,
enum rsc_role_e role, crm_time_t * now, pe_match_data_t * match_data);
void unpack_instance_attributes(xmlNode * top, xmlNode * xml_obj, const char *set_name,
GHashTable * node_hash, GHashTable * hash,
const char *always_first, gboolean overwrite, crm_time_t * now);
#ifdef ENABLE_VERSIONED_ATTRS
void pe_unpack_versioned_attributes(xmlNode * top, xmlNode * xml_obj, const char *set_name,
GHashTable * node_hash, xmlNode * hash, crm_time_t * now);
GHashTable *pe_unpack_versioned_parameters(xmlNode *versioned_params, const char *ra_version);
#endif
char *pe_expand_re_matches(const char *string, pe_re_match_data_t * match_data);
#ifdef __cplusplus
}
#endif
#endif
diff --git a/include/crm/pengine/rules_internal.h b/include/crm/pengine/rules_internal.h
index 4adc9204b3..71086e89fe 100644
--- a/include/crm/pengine/rules_internal.h
+++ b/include/crm/pengine/rules_internal.h
@@ -1,38 +1,40 @@
/*
- * Copyright (C) 2015-2017 Andrew Beekhof <andrew@beekhof.net>
+ * Copyright 2015-2019 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 RULES_INTERNAL_H
#define RULES_INTERNAL_H
#include <glib.h>
#include <libxml/tree.h>
#include <crm/common/iso8601.h>
#include <crm/pengine/common.h>
#include <crm/pengine/rules.h>
typedef enum {
pe_date_before_range,
pe_date_within_range,
pe_date_after_range,
pe_date_result_undetermined,
pe_date_op_satisfied,
pe_date_op_unsatisfied
} pe_eval_date_result_t;
GListPtr pe_unpack_alerts(xmlNode *alerts);
void pe_free_alert_list(GListPtr alert_list);
crm_time_t *pe_parse_xml_duration(crm_time_t * start, xmlNode * duration_spec);
pe_eval_date_result_t pe_eval_date_expression(xmlNode * time_expr, crm_time_t * now);
gboolean pe_test_date_expression(xmlNode * time_expr, crm_time_t * now);
gboolean pe_cron_range_satisfied(crm_time_t * now, xmlNode * cron_spec);
gboolean pe_test_attr_expression(xmlNode * expr, GHashTable * hash, crm_time_t * now);
gboolean pe_test_attr_expression_full(xmlNode * expr, GHashTable * hash, crm_time_t * now, pe_match_data_t * match_data);
gboolean pe_test_role_expression(xmlNode * expr, enum rsc_role_e role, crm_time_t * now);
#endif
diff --git a/include/crm/services.h b/include/crm/services.h
index 55da965c1c..013f0b8519 100644
--- a/include/crm/services.h
+++ b/include/crm/services.h
@@ -1,415 +1,417 @@
/*
- * Copyright 2010-2018 Andrew Beekhof <andrew@beekhof.net>
+ * Copyright 2010-2019 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_SERVICES__
# define __PCMK_SERVICES__
#ifdef __cplusplus
extern "C" {
#endif
/**
* \file
* \brief Services API
* \ingroup core
*/
# include <glib.h>
# include <stdio.h>
# include <string.h>
# include <stdbool.h>
# include <sys/types.h>
# ifndef OCF_ROOT_DIR
# define OCF_ROOT_DIR "/usr/lib/ocf"
# endif
# ifndef LSB_ROOT_DIR
# define LSB_ROOT_DIR "/etc/init.d"
# endif
/* TODO: Autodetect these two ?*/
# ifndef SYSTEMCTL
# define SYSTEMCTL "/bin/systemctl"
# endif
/* Known resource classes */
#define PCMK_RESOURCE_CLASS_OCF "ocf"
#define PCMK_RESOURCE_CLASS_SERVICE "service"
#define PCMK_RESOURCE_CLASS_LSB "lsb"
#define PCMK_RESOURCE_CLASS_SYSTEMD "systemd"
#define PCMK_RESOURCE_CLASS_UPSTART "upstart"
#define PCMK_RESOURCE_CLASS_NAGIOS "nagios"
#define PCMK_RESOURCE_CLASS_STONITH "stonith"
/* 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,
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,
};
/* The return codes for the status operation are not the same for other
* operatios - go figure
*/
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,
};
/* Uniform exit codes
* Everything is mapped to its OCF equivalent so that Pacemaker only deals with one set of codes
*/
enum ocf_exitcode {
PCMK_OCF_OK = 0,
PCMK_OCF_UNKNOWN_ERROR = 1,
PCMK_OCF_INVALID_PARAM = 2,
PCMK_OCF_UNIMPLEMENT_FEATURE = 3,
PCMK_OCF_INSUFFICIENT_PRIV = 4,
PCMK_OCF_NOT_INSTALLED = 5,
PCMK_OCF_NOT_CONFIGURED = 6,
PCMK_OCF_NOT_RUNNING = 7, /* End of overlap with LSB */
PCMK_OCF_RUNNING_MASTER = 8,
PCMK_OCF_FAILED_MASTER = 9,
/* 150-199 reserved for application use */
PCMK_OCF_CONNECTION_DIED = 189, /* Operation failure implied by disconnection of the LRM API to a local or remote node */
PCMK_OCF_DEGRADED = 190, /* Active resource that is no longer 100% functional */
PCMK_OCF_DEGRADED_MASTER = 191, /* Promoted resource that is no longer 100% functional */
PCMK_OCF_EXEC_ERROR = 192, /* Generic problem invoking the agent */
PCMK_OCF_UNKNOWN = 193, /* State of the service is unknown - used for recording in-flight operations */
PCMK_OCF_SIGNAL = 194,
PCMK_OCF_NOT_SUPPORTED = 195,
PCMK_OCF_PENDING = 196,
PCMK_OCF_CANCELLED = 197,
PCMK_OCF_TIMEOUT = 198,
PCMK_OCF_OTHER_ERROR = 199, /* Keep the same codes as PCMK_LSB */
};
enum op_status {
PCMK_LRM_OP_UNKNOWN = -2,
PCMK_LRM_OP_PENDING = -1,
PCMK_LRM_OP_DONE,
PCMK_LRM_OP_CANCELLED,
PCMK_LRM_OP_TIMEOUT,
PCMK_LRM_OP_NOTSUPPORTED,
PCMK_LRM_OP_ERROR,
PCMK_LRM_OP_ERROR_HARD,
PCMK_LRM_OP_ERROR_FATAL,
PCMK_LRM_OP_NOT_INSTALLED,
};
enum nagios_exitcode {
NAGIOS_STATE_OK = 0,
NAGIOS_STATE_WARNING = 1,
NAGIOS_STATE_CRITICAL = 2,
NAGIOS_STATE_UNKNOWN = 3,
NAGIOS_STATE_DEPENDENT = 4,
NAGIOS_INSUFFICIENT_PRIV = 100,
NAGIOS_NOT_INSTALLED = 101,
};
enum svc_action_flags {
/* On timeout, only kill pid, do not kill entire pid group */
SVC_ACTION_LEAVE_GROUP = 0x01,
};
typedef struct svc_action_private_s svc_action_private_t;
typedef struct svc_action_s {
char *id;
char *rsc;
char *action;
guint interval_ms;
char *standard;
char *provider;
char *agent;
int timeout;
GHashTable *params; /* used by OCF agents and alert agents */
int rc;
int pid;
int cancel;
int status;
int sequence;
int expected_rc;
int synchronous;
enum svc_action_flags flags;
char *stderr_data;
char *stdout_data;
/*!
* Data stored by the creator of the action.
*
* This may be used to hold data that is needed later on by a callback,
* for example.
*/
void *cb_data;
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 a list of what was found. The list items are char *.
* \note It is the caller's responsibility to free the result with g_list_free_full(list, free).
*/
GList *get_directory_list(const char *root, gboolean files, gboolean executable);
/**
* Get a list of services
*
* \return a list of services. The list items are gchar *. This list _must_
* be destroyed using g_list_free_full(list, free).
*/
GList *services_list(void);
/**
* \brief Get a list of providers
*
* \param[in] standard list providers of this standard (e.g. ocf, lsb, etc.)
*
* \return a 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 using this standard (e.g. ocf, lsb, etc.) (or NULL for all)
* \param[in] provider list agents from this provider (or NULL for all)
*
* \return a list of resource agents. The list items are char *.
* \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 a list of resource standards. The list items are char *. This list _must_
* be destroyed using g_list_free_full(list, free).
*/
GList *resources_list_standards(void);
/**
* Does the given standard, provider, and agent describe a resource that can exist?
*
* \param[in] standard Which class of agent does the resource belong to?
* \param[in] provider What provides the agent (NULL for most standards)?
* \param[in] agent What is the name of the agent?
*
* \return A boolean
*/
gboolean resources_agent_exists(const char *standard, const char *provider, const char *agent);
svc_action_t *services_action_create(const char *name, const char *action,
guint interval_ms, int timeout /* ms */);
/**
* \brief Create a new resource action
*
* \param[in] name Name of resource
* \param[in] standard Resource agent standard (ocf, lsb, etc.)
* \param[in] provider Resource agent provider
* \param[in] agent Resource agent name
* \param[in] action action (start, stop, monitor, etc.)
* \param[in] interval_ms How often to repeat this action (if 0, execute once)
* \param[in] timeout Consider action failed if it does not complete in this many milliseconds
* \param[in] params Action parameters
*
* \return newly allocated action instance
*
* \post After the call, 'params' is owned, and later free'd by the svc_action_t result
* \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 /* ms */, GHashTable *params,
enum svc_action_flags flags);
/**
* Kick a recurring action so it is scheduled immediately for re-execution
*/
gboolean services_action_kick(const char *name, const char *action,
guint interval_ms);
const char *resources_find_service_class(const char *agent);
/**
* Utilize services API to execute 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 command to execute
* \param[in] args arguments to the command, NULL terminated
*
* \return a svc_action_t object, used to pass to the execute function
* (services_action_sync() or services_action_async()) and is
* provided to the callback.
*/
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);
/**
* Run an action asynchronously.
*
* \param[in] op services action data
* \param[in] action_callback callback for when the action completes
*
* \retval TRUE succesfully started execution
* \retval FALSE failed to start execution, no callback will be received
*/
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));
static inline const char *services_lrm_status_str(enum op_status status) {
switch (status) {
case PCMK_LRM_OP_PENDING:
return "pending";
case PCMK_LRM_OP_DONE:return "complete";
case PCMK_LRM_OP_CANCELLED:return "Cancelled";
case PCMK_LRM_OP_TIMEOUT:return "Timed Out";
case PCMK_LRM_OP_NOTSUPPORTED:return "NOT SUPPORTED";
case PCMK_LRM_OP_ERROR:return "Error";
case PCMK_LRM_OP_NOT_INSTALLED:return "Not installed";
default:return "UNKNOWN!";
}
}
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 "unknown 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_MASTER:
return "master";
case PCMK_OCF_FAILED_MASTER:
return "master (failed)";
case PCMK_OCF_SIGNAL:
return "OCF_SIGNAL";
case PCMK_OCF_NOT_SUPPORTED:
return "OCF_NOT_SUPPORTED";
case PCMK_OCF_PENDING:
return "OCF_PENDING";
case PCMK_OCF_CANCELLED:
return "OCF_CANCELLED";
case PCMK_OCF_TIMEOUT:
return "OCF_TIMEOUT";
case PCMK_OCF_OTHER_ERROR:
return "OCF_OTHER_ERROR";
case PCMK_OCF_DEGRADED:
return "OCF_DEGRADED";
case PCMK_OCF_DEGRADED_MASTER:
return "OCF_DEGRADED_MASTER";
default:
return "unknown";
}
}
/**
* \brief Get OCF equivalent of LSB exit code
*
* \param[in] action LSB action that produced exit code
* \param[in] lsb_exitcode Exit code of LSB action
*
* \return PCMK_OCF_* constant that corresponds to LSB exit code
*/
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 && strcmp(action, "status") && strcmp(action, "monitor")) {
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 /* __PCMK_SERVICES__ */
diff --git a/include/crm/stonith-ng.h b/include/crm/stonith-ng.h
index 886e77ba68..1fbfdd07a0 100644
--- a/include/crm/stonith-ng.h
+++ b/include/crm/stonith-ng.h
@@ -1,541 +1,543 @@
/*
- * Copyright 2004-2019 Andrew Beekhof <andrew@beekhof.net>
+ * Copyright 2004-2019 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.
*/
#ifdef __cplusplus
extern "C" {
#endif
/**
* \file
* \brief Fencing aka. STONITH
* \ingroup fencing
*/
#ifndef STONITH_NG__H
# define STONITH_NG__H
# include <dlfcn.h>
# include <errno.h>
# include <stdbool.h> // bool
# include <stdint.h> // uint32_t
# include <time.h> // time_t
# define T_STONITH_NOTIFY_DISCONNECT "st_notify_disconnect"
# define T_STONITH_NOTIFY_FENCE "st_notify_fence"
# define T_STONITH_NOTIFY_HISTORY "st_notify_history"
/* *INDENT-OFF* */
enum stonith_state {
stonith_connected_command,
stonith_connected_query,
stonith_disconnected,
};
enum stonith_call_options {
st_opt_none = 0x00000000,
st_opt_verbose = 0x00000001,
st_opt_allow_suicide = 0x00000002,
st_opt_manual_ack = 0x00000008,
st_opt_discard_reply = 0x00000010,
/* st_opt_all_replies = 0x00000020, */
st_opt_topology = 0x00000040,
st_opt_scope_local = 0x00000100,
st_opt_cs_nodeid = 0x00000200,
st_opt_sync_call = 0x00001000,
/*! Allow the timeout period for a callback to be adjusted
* based on the time the server reports the operation will take. */
st_opt_timeout_updates = 0x00002000,
/*! Only report back if operation is a success in callback */
st_opt_report_only_success = 0x00004000,
/* used where ever apropriate - e.g. cleanup of history */
st_opt_cleanup = 0x000080000,
/* used where ever apropriate - e.g. send out a history query to all nodes */
st_opt_broadcast = 0x000100000,
};
/*! Order matters here, do not change values */
enum op_state
{
st_query,
st_exec,
st_done,
st_duplicate,
st_failed,
};
// Supported fence agent interface standards
enum stonith_namespace {
st_namespace_invalid,
st_namespace_any,
st_namespace_internal, // Implemented internally by Pacemaker
/* Neither of these projects are active any longer, but the fence agent
* interfaces they created are still in use and supported by Pacemaker.
*/
st_namespace_rhcs, // Red Hat Cluster Suite compatible
st_namespace_lha, // Linux-HA compatible
};
enum stonith_namespace stonith_text2namespace(const char *namespace_s);
const char *stonith_namespace2text(enum stonith_namespace st_namespace);
enum stonith_namespace stonith_get_namespace(const char *agent,
const char *namespace_s);
typedef struct stonith_key_value_s {
char *key;
char *value;
struct stonith_key_value_s *next;
} stonith_key_value_t;
typedef struct stonith_history_s {
char *target;
char *action;
char *origin;
char *delegate;
char *client;
int state;
time_t completed;
struct stonith_history_s *next;
} stonith_history_t;
typedef struct stonith_s stonith_t;
typedef struct stonith_event_s
{
char *id;
char *type;
char *message;
char *operation;
int result;
char *origin;
char *target;
char *action;
char *executioner;
char *device;
/*! The name of the client that initiated the action. */
char *client_origin;
} stonith_event_t;
typedef struct stonith_callback_data_s
{
int rc;
int call_id;
void *userdata;
} stonith_callback_data_t;
typedef struct stonith_api_operations_s
{
/*!
* \brief Destroy the stonith api structure.
*/
int (*free) (stonith_t *st);
/*!
* \brief Connect to the local stonith daemon.
*
* \retval 0, success
* \retval negative error code on failure
*/
int (*connect) (stonith_t *st, const char *name, int *stonith_fd);
/*!
* \brief Disconnect from the local stonith daemon.
*
* \retval 0, success
* \retval negative error code on failure
*/
int (*disconnect)(stonith_t *st);
/*!
* \brief Remove a registered stonith device with the local stonith daemon.
*
* \note Synchronous, guaranteed to occur in daemon before function returns.
*
* \retval 0, success
* \retval negative error code on failure
*/
int (*remove_device)(
stonith_t *st, int options, const char *name);
/*!
* \brief Register a stonith device with the local stonith daemon.
*
* \note Synchronous, guaranteed to occur in daemon before function returns.
*
* \retval 0, success
* \retval negative error code on failure
*/
int (*register_device)(
stonith_t *st, int options, const char *id,
const char *provider, const char *agent, stonith_key_value_t *params);
/*!
* \brief Remove a fencing level for a specific node.
*
* \note This feature is not available when stonith is in standalone mode.
*
* \retval 0, success
* \retval negative error code on failure
*/
int (*remove_level)(
stonith_t *st, int options, const char *node, int level);
/*!
* \brief Register a fencing level containing the fencing devices to be used
* at that level for a specific node.
*
* \note This feature is not available when stonith is in standalone mode.
*
* \retval 0, success
* \retval negative error code on failure
*/
int (*register_level)(
stonith_t *st, int options, const char *node, int level, stonith_key_value_t *device_list);
/*!
* \brief Get the metadata documentation for a resource.
*
* \note Value is returned in output. Output must be freed when set.
*
* \retval 0 success
* \retval negative error code on failure
*/
int (*metadata)(stonith_t *st, int options,
const char *device, const char *provider, char **output, int timeout);
/*!
* \brief Retrieve a list of installed stonith agents
*
* \note if provider is not provided, all known agents will be returned
* \note list must be freed using stonith_key_value_freeall()
* \note call_options parameter is not used, it is reserved for future use.
*
* \retval num items in list on success
* \retval negative error code on failure
*/
int (*list_agents)(stonith_t *stonith, int call_options, const char *provider,
stonith_key_value_t **devices, int timeout);
/*!
* \brief Retrieve string listing hosts and port assignments from a local stonith device.
*
* \retval 0 on success
* \retval negative error code on failure
*/
int (*list)(stonith_t *st, int options, const char *id, char **list_output, int timeout);
/*!
* \brief Check to see if a local stonith device is reachable
*
* \retval 0 on success
* \retval negative error code on failure
*/
int (*monitor)(stonith_t *st, int options, const char *id, int timeout);
/*!
* \brief Check to see if a local stonith device's port is reachable
*
* \retval 0 on success
* \retval negative error code on failure
*/
int (*status)(stonith_t *st, int options, const char *id, const char *port, int timeout);
/*!
* \brief Retrieve a list of registered stonith devices.
*
* \note If node is provided, only devices that can fence the node id
* will be returned.
*
* \retval num items in list on success
* \retval negative error code on failure
*/
int (*query)(stonith_t *st, int options, const char *node,
stonith_key_value_t **devices, int timeout);
/*!
* \brief Issue a fencing action against a node.
*
* \note Possible actions are, 'on', 'off', and 'reboot'.
*
* \param st, stonith connection
* \param options, call options
* \param node, The target node to fence
* \param action, The fencing action to take
* \param timeout, The default per device timeout to use with each device
* capable of fencing the target.
*
* \retval 0 success
* \retval negative error code on failure.
*/
int (*fence)(stonith_t *st, int options, const char *node, const char *action,
int timeout, int tolerance);
/*!
* \brief Manually confirm that a node is down.
*
* \retval 0 success
* \retval negative error code on failure.
*/
int (*confirm)(stonith_t *st, int options, const char *node);
/*!
* \brief Retrieve a list of fencing operations that have occurred for a specific node.
*
* \note History is not available in standalone mode.
*
* \retval 0 success
* \retval negative error code on failure.
*/
int (*history)(stonith_t *st, int options, const char *node, stonith_history_t **output, int timeout);
int (*register_notification)(
stonith_t *st, const char *event,
void (*notify)(stonith_t *st, stonith_event_t *e));
int (*remove_notification)(stonith_t *st, const char *event);
/*!
* \brief Register a callback to receive the result of an asynchronous call
*
* \param[in] call_id The call ID to register callback for
* \param[in] timeout Default time to wait until callback expires
* \param[in] options Bitmask of \c stonith_call_options (respects
* \c st_opt_timeout_updates and
* \c st_opt_report_only_success)
* \param[in] userdata Pointer that will be given to callback
* \param[in] callback_name Unique name to identify callback
* \param[in] callback The callback function to register
*
* \return \c TRUE on success, \c FALSE if call_id is negative, -errno otherwise
*
* \todo This function should return \c pcmk_ok on success, and \c call_id
* when negative, but that would break backward compatibility.
*/
int (*register_callback)(stonith_t *st,
int call_id,
int timeout,
int options,
void *userdata,
const char *callback_name,
void (*callback)(stonith_t *st, stonith_callback_data_t *data));
/*!
* \brief Remove a registered callback for a given call id.
*/
int (*remove_callback)(stonith_t *st, int call_id, bool all_callbacks);
/*!
* \brief Remove fencing level for specific node, node regex or attribute
*
* \param[in] st Fencer connection to use
* \param[in] options Bitmask of stonith_call_options to pass to the fencer
* \param[in] node If not NULL, target level by this node name
* \param[in] pattern If not NULL, target by node name using this regex
* \param[in] attr If not NULL, target by this node attribute
* \param[in] value If not NULL, target by this node attribute value
* \param[in] level Index number of level to remove
*
* \return 0 on success, negative error code otherwise
*
* \note This feature is not available when stonith is in standalone mode.
* The caller should set only one of node, pattern or attr/value.
*/
int (*remove_level_full)(stonith_t *st, int options,
const char *node, const char *pattern,
const char *attr, const char *value, int level);
/*!
* \brief Register fencing level for specific node, node regex or attribute
*
* \param[in] st Fencer connection to use
* \param[in] options Bitmask of stonith_call_options to pass to fencer
* \param[in] node If not NULL, target level by this node name
* \param[in] pattern If not NULL, target by node name using this regex
* \param[in] attr If not NULL, target by this node attribute
* \param[in] value If not NULL, target by this node attribute value
* \param[in] level Index number of level to add
* \param[in] device_list Devices to use in level
*
* \return 0 on success, negative error code otherwise
*
* \note This feature is not available when stonith is in standalone mode.
* The caller should set only one of node, pattern or attr/value.
*/
int (*register_level_full)(stonith_t *st, int options,
const char *node, const char *pattern,
const char *attr, const char *value,
int level, stonith_key_value_t *device_list);
/*!
* \brief Validate an arbitrary stonith device configuration
*
* \param[in] st Stonithd connection to use
* \param[in] call_options Bitmask of stonith_call_options to use with fencer
* \param[in] rsc_id ID used to replace CIB secrets in params
* \param[in] namespace_s Namespace of fence agent to validate (optional)
* \param[in] agent Fence agent to validate
* \param[in] params Configuration parameters to pass to fence agent
* \param[in] timeout Fail if no response within this many seconds
* \param[out] output If non-NULL, where to store any agent output
* \param[out] error_output If non-NULL, where to store agent error output
*
* \return pcmk_ok if validation succeeds, -errno otherwise
*
* \note If pcmk_ok is returned, the caller is responsible for freeing
* the output (if requested).
*/
int (*validate)(stonith_t *st, int call_options, const char *rsc_id,
const char *namespace_s, const char *agent,
stonith_key_value_t *params, int timeout, char **output,
char **error_output);
} stonith_api_operations_t;
struct stonith_s
{
enum stonith_state state;
int call_id;
int call_timeout;
void *st_private;
stonith_api_operations_t *cmds;
};
/* *INDENT-ON* */
/* Core functions */
stonith_t *stonith_api_new(void);
void stonith_api_delete(stonith_t * st);
void stonith_dump_pending_callbacks(stonith_t * st);
// deprecated (use stonith_get_namespace() instead)
const char *get_stonith_provider(const char *agent, const char *provider);
bool stonith_dispatch(stonith_t * st);
stonith_key_value_t *stonith_key_value_add(stonith_key_value_t * kvp, const char *key,
const char *value);
void stonith_key_value_freeall(stonith_key_value_t * kvp, int keys, int values);
void stonith_history_free(stonith_history_t *history);
/* Basic helpers that allows nodes to be fenced and the history to be
* queried without mainloop or the caller understanding the full API
*
* At least one of nodeid and uname are required
*/
int stonith_api_kick(uint32_t nodeid, const char *uname, int timeout, bool off);
time_t stonith_api_time(uint32_t nodeid, const char *uname, bool in_progress);
/*
* Helpers for using the above functions without install-time dependencies
*
* Usage:
* #include <crm/stonith-ng.h>
*
* To turn a node off by corosync nodeid:
* stonith_api_kick_helper(nodeid, 120, 1);
*
* To check the last fence date/time (also by nodeid):
* last = stonith_api_time_helper(nodeid, 0);
*
* To check if fencing is in progress:
* if(stonith_api_time_helper(nodeid, 1) > 0) { ... }
*
* eg.
#include <stdio.h>
#include <time.h>
#include <crm/stonith-ng.h>
int
main(int argc, char ** argv)
{
int rc = 0;
int nodeid = 102;
rc = stonith_api_time_helper(nodeid, 0);
printf("%d last fenced at %s\n", nodeid, ctime(rc));
rc = stonith_api_kick_helper(nodeid, 120, 1);
printf("%d fence result: %d\n", nodeid, rc);
rc = stonith_api_time_helper(nodeid, 0);
printf("%d last fenced at %s\n", nodeid, ctime(rc));
return 0;
}
*/
# define STONITH_LIBRARY "libstonithd.so.26"
typedef int (*st_api_kick_fn) (int nodeid, const char *uname, int timeout, bool off);
typedef time_t (*st_api_time_fn) (int nodeid, const char *uname, bool in_progress);
static inline int
stonith_api_kick_helper(uint32_t nodeid, int timeout, bool off)
{
static void *st_library = NULL;
static st_api_kick_fn st_kick_fn;
if (st_library == NULL) {
st_library = dlopen(STONITH_LIBRARY, RTLD_LAZY);
}
if (st_library && st_kick_fn == NULL) {
st_kick_fn = (st_api_kick_fn) dlsym(st_library, "stonith_api_kick");
}
if (st_kick_fn == NULL) {
#ifdef ELIBACC
return -ELIBACC;
#else
return -ENOSYS;
#endif
}
return (*st_kick_fn) (nodeid, NULL, timeout, off);
}
static inline time_t
stonith_api_time_helper(uint32_t nodeid, bool in_progress)
{
static void *st_library = NULL;
static st_api_time_fn st_time_fn;
if (st_library == NULL) {
st_library = dlopen(STONITH_LIBRARY, RTLD_LAZY);
}
if (st_library && st_time_fn == NULL) {
st_time_fn = (st_api_time_fn) dlsym(st_library, "stonith_api_time");
}
if (st_time_fn == NULL) {
return 0;
}
return (*st_time_fn) (nodeid, NULL, in_progress);
}
/**
* Does the given agent describe a stonith resource that can exist?
*
* \param[in] agent What is the name of the agent?
* \param[in] timeout Timeout to use when querying. If 0 is given,
* use a default of 120.
*
* \return A boolean
*/
bool stonith_agent_exists(const char *agent, int timeout);
#ifdef __cplusplus
}
#endif
#endif
diff --git a/include/crm/transition.h b/include/crm/transition.h
index ad8219749c..6e9a875027 100644
--- a/include/crm/transition.h
+++ b/include/crm/transition.h
@@ -1,151 +1,153 @@
/*
- * Copyright (C) 2004 Andrew Beekhof <andrew@beekhof.net>
+ * Copyright 2004-2018 the Pacemaker project contributors
+ *
+ * The version control history for this file may have further details.
*
* 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 software 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
* 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_TRANSITION__H
# define CRM_TRANSITION__H
#ifdef __cplusplus
extern "C" {
#endif
#include <crm/crm.h>
#include <crm/msg_xml.h>
#include <crm/common/xml.h>
typedef enum {
action_type_pseudo,
action_type_rsc,
action_type_crm
} action_type_e;
typedef struct te_timer_s crm_action_timer_t;
typedef struct crm_graph_s crm_graph_t;
typedef struct synapse_s {
int id;
int priority;
gboolean ready;
gboolean failed;
gboolean executed;
gboolean confirmed;
GListPtr actions; /* crm_action_t* */
GListPtr inputs; /* crm_action_t* */
} synapse_t;
typedef struct crm_action_s {
int id;
int timeout;
guint interval_ms;
GHashTable *params;
action_type_e type;
crm_action_timer_t *timer;
synapse_t *synapse;
gboolean sent_update; /* sent to the CIB */
gboolean executed; /* sent to the CRM */
gboolean confirmed;
gboolean failed;
gboolean can_fail;
xmlNode *xml;
} crm_action_t;
struct te_timer_s {
int source_id;
int timeout;
crm_action_t *action;
};
/* order matters here */
enum transition_action {
tg_done,
tg_stop,
tg_restart,
tg_shutdown,
};
struct crm_graph_s {
int id;
char *source;
int abort_priority;
gboolean complete;
const char *abort_reason;
enum transition_action completion_action;
int num_actions;
int num_synapses;
int batch_limit;
int network_delay;
int stonith_timeout;
int transition_timeout;
int fired;
int pending;
int skipped;
int completed;
int incomplete;
GListPtr synapses; /* synapse_t* */
int migration_limit;
};
typedef struct crm_graph_functions_s {
gboolean(*pseudo) (crm_graph_t * graph, crm_action_t * action);
gboolean(*rsc) (crm_graph_t * graph, crm_action_t * action);
gboolean(*crmd) (crm_graph_t * graph, crm_action_t * action);
gboolean(*stonith) (crm_graph_t * graph, crm_action_t * action);
gboolean(*allowed) (crm_graph_t * graph, crm_action_t * action);
} crm_graph_functions_t;
enum transition_status {
transition_active,
transition_pending, /* active but no actions performed this time */
transition_complete,
transition_stopped,
transition_terminated,
transition_action_failed,
transition_failed,
};
void set_default_graph_functions(void);
void set_graph_functions(crm_graph_functions_t * fns);
crm_graph_t *unpack_graph(xmlNode * xml_graph, const char *reference);
int run_graph(crm_graph_t * graph);
gboolean update_graph(crm_graph_t * graph, crm_action_t * action);
void destroy_graph(crm_graph_t * graph);
const char *transition_status(enum transition_status state);
void print_graph(unsigned int log_level, crm_graph_t * graph);
void print_action(int log_level, const char *prefix, crm_action_t * action);
bool update_abort_priority(crm_graph_t * graph, int priority,
enum transition_action action, const char *abort_reason);
const char *actiontype2text(action_type_e type);
lrmd_event_data_t *convert_graph_action(xmlNode * resource, crm_action_t * action, int status,
int rc);
#ifdef __cplusplus
}
#endif
#endif
diff --git a/include/crm_config.h.in b/include/crm_config.h.in
index fbea425552..a81e39f386 100644
--- a/include/crm_config.h.in
+++ b/include/crm_config.h.in
@@ -1,84 +1,85 @@
/* crm_config.h.in */
/*
- * Copyright (C) 2006 - 2007
- * Andrew Beekhof <andrew@beekhof.net>
+ * Copyright 2006-2018 the Pacemaker project contributors
+ *
+ * The version control history for this file may have further details.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU 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_CONFIG__H__IN
#define CRM_CONFIG__H__IN
/****** Versions ******/
/* Current pacemaker version */
#undef PACEMAKER_VERSION
/* Build version */
#undef BUILD_VERSION
/****** Other ******/
/* Group to run Pacemaker daemons as */
#undef CRM_DAEMON_GROUP
/* User to run Pacemaker daemons as */
#undef CRM_DAEMON_USER
/****** Directories ******/
/* Where Pacemaker can store log files */
#undef CRM_LOG_DIR
/* Location for Pacemaker daemons */
#undef CRM_DAEMON_DIR
/* Where to keep blackbox dumps */
#undef CRM_BLACKBOX_DIR
/* Where to keep configuration files */
#undef CRM_CONFIG_DIR
/* Where to keep scheduler outputs */
#undef PE_STATE_DIR
/* Location to store core files produced by Pacemaker daemons */
#undef CRM_CORE_DIR
/* Where to keep state files and sockets */
#undef CRM_STATE_DIR
/* Location for the Pacemaker Relax-NG Schema */
#undef CRM_SCHEMA_DIRECTORY
/* Where to keep configuration files like authkey */
#undef PACEMAKER_CONFIG_DIR
/****** Features ******/
/* Set of enabled features */
#undef CRM_FEATURES
/* Support the Corosync messaging and membership layer */
#undef SUPPORT_COROSYNC
/* Support systemd based system services */
#undef SUPPORT_SYSTEMD
/* Support upstart based system services */
#undef SUPPORT_UPSTART
#endif /* CRM_CONFIG__H__IN */
diff --git a/include/crm_internal.h b/include/crm_internal.h
index c4fca96186..8bc1188b1b 100644
--- a/include/crm_internal.h
+++ b/include/crm_internal.h
@@ -1,303 +1,305 @@
/*
- * Copyright 2006-2018 Andrew Beekhof <andrew@beekhof.net>
+ * Copyright 2006-2018 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 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);
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);
crm_exit_t crm_help(char cmd, crm_exit_t 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);
long crm_auto_watchdog_timeout(void);
gboolean check_sbd_timeout(const char *value);
void crm_args_fini(void);
/* char2score */
extern int node_score_red;
extern int node_score_green;
extern int node_score_yellow;
/* Assorted convenience functions */
void crm_make_daemon(const char *name, gboolean daemonize, const char *pidfile);
// printf-style format to create operation ID from resource, action, interval
#define CRM_OP_FMT "%s_%s_%u"
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);
pid_t pcmk_locate_sbd(void);
# 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 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_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
# 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
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 */
diff --git a/include/doxygen.h b/include/doxygen.h
index 511c782443..c1a5e03124 100644
--- a/include/doxygen.h
+++ b/include/doxygen.h
@@ -1,48 +1,50 @@
/*
- * Copyright 2006-2018 Andrew Beekhof <andrew@beekhof.net>
+ * Copyright 2006-2018 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 DOXYGEN__H
# define DOXYGEN__H
/**
* \file
* \brief Fake header file that contains doxygen documentation.
* \author Andrew Beekhof <andrew@beekhof.net>
*
* The purpose of this file is to provide a file that can be used to create
* doxygen pages. It should contain _only_ comment blocks.
*
*
* \defgroup core Core API
* \defgroup date ISO-8601 Date/Time API
* \defgroup cib Configuration API
* \defgroup lrmd Executor API
* \defgroup pengine Scheduler API
* \defgroup fencing Fencing API
*/
/**
* \mainpage
* Welcome to the developer documentation for The Pacemaker Project! For more
* information about Pacemaker, please visit the
* <a href="http://clusterlabs.org/">project web site</a>.
*
* Here are some pointers on where to go from here.
*
* Using Pacemaker APIs:
* - \ref core
* - \ref date
* - \ref cib
* - \ref lrmd
* - \ref pengine
* - \ref fencing
*
* Contributing to the Pacemaker Project:
* - <a href="https://clusterlabs.org/pacemaker/doc/en-US/Pacemaker/2.0/html-single/Pacemaker_Development/">Pacemaker Development</a>
*/
#endif /* DOXYGEN__H */
diff --git a/include/pacemaker-internal.h b/include/pacemaker-internal.h
index 752fd8d31f..3627ba5012 100644
--- a/include/pacemaker-internal.h
+++ b/include/pacemaker-internal.h
@@ -1,18 +1,20 @@
/*
- * Copyright 2019 Chris Lumens <clumens@redhat.com>
+ * Copyright 2019 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 PACEMAKER_INTERNAL__H
# define PACEMAKER_INTERNAL__H
# include <pcmki/pcmki_error.h>
# include <pcmki/pcmki_sched_allocate.h>
# include <pcmki/pcmki_sched_notif.h>
# include <pcmki/pcmki_sched_transition.h>
# include <pcmki/pcmki_sched_utils.h>
# include <pcmki/pcmki_scheduler.h>
#endif
diff --git a/include/pcmki/Makefile.am b/include/pcmki/Makefile.am
index e4b223240a..b163e89039 100644
--- a/include/pcmki/Makefile.am
+++ b/include/pcmki/Makefile.am
@@ -1,17 +1,19 @@
#
-# Copyright 2019 Chris Lumens <clumens@redhat.com>
+# Copyright 2019 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
noinst_HEADERS = pcmki_error.h \
pcmki_sched_allocate.h \
pcmki_sched_notif.h \
pcmki_sched_transition.h \
pcmki_sched_utils.h \
pcmki_scheduler.h
.PHONY: $(ARCHIVE_VERSION)
diff --git a/include/pcmki/pcmki_error.h b/include/pcmki/pcmki_error.h
index a82f5f3d87..4fd6b41439 100644
--- a/include/pcmki/pcmki_error.h
+++ b/include/pcmki/pcmki_error.h
@@ -1,9 +1,17 @@
+/*
+ * Copyright 2007-2019 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 PCMKI_ERROR__H
# define PCMKI_ERROR__H
#define CMD_ERR(fmt, args...) do { \
crm_warn(fmt, ##args); \
fprintf(stderr, fmt "\n", ##args); \
} while(0)
#endif
diff --git a/include/pcmki/pcmki_sched_allocate.h b/include/pcmki/pcmki_sched_allocate.h
index b5239328a3..f18c937587 100644
--- a/include/pcmki/pcmki_sched_allocate.h
+++ b/include/pcmki/pcmki_sched_allocate.h
@@ -1,179 +1,181 @@
/*
- * Copyright 2004-2018 Andrew Beekhof <andrew@beekhof.net>
+ * Copyright 2004-2019 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 SCHED_ALLOCATE__H
# define SCHED_ALLOCATE__H
# include <glib.h>
# include <crm/common/xml.h>
# include <crm/pengine/status.h>
# include <crm/pengine/complex.h>
# include <crm/pengine/internal.h>
# include <pcmki/pcmki_scheduler.h>
struct resource_alloc_functions_s {
GHashTable *(*merge_weights) (resource_t *, const char *, GHashTable *, const char *, float,
enum pe_weights);
node_t *(*allocate) (resource_t *, node_t *, pe_working_set_t *);
void (*create_actions) (resource_t *, pe_working_set_t *);
gboolean(*create_probe) (resource_t *, node_t *, action_t *, gboolean, pe_working_set_t *);
void (*internal_constraints) (resource_t *, pe_working_set_t *);
void (*rsc_colocation_lh) (pe_resource_t *, pe_resource_t *,
rsc_colocation_t *, pe_working_set_t *);
void (*rsc_colocation_rh) (pe_resource_t *, pe_resource_t *,
rsc_colocation_t *, pe_working_set_t *);
void (*rsc_location) (pe_resource_t *, pe__location_t *);
enum pe_action_flags (*action_flags) (action_t *, node_t *);
enum pe_graph_flags (*update_actions) (pe_action_t *, pe_action_t *,
pe_node_t *, enum pe_action_flags,
enum pe_action_flags,
enum pe_ordering,
pe_working_set_t *data_set);
void (*expand) (resource_t *, pe_working_set_t *);
void (*append_meta) (resource_t * rsc, xmlNode * xml);
};
extern GHashTable *rsc_merge_weights(resource_t * rsc, const char *rhs, GHashTable * nodes,
const char *attr, float factor, enum pe_weights flags);
extern GHashTable *clone_merge_weights(resource_t * rsc, const char *rhs, GHashTable * nodes,
const char *attr, float factor, enum pe_weights flags);
extern GHashTable *container_merge_weights(resource_t * rsc, const char *rhs, GHashTable * nodes,
const char *attr, float factor, enum pe_weights flags);
extern GHashTable *native_merge_weights(resource_t * rsc, const char *rhs, GHashTable * nodes,
const char *attr, float factor, enum pe_weights flags);
extern GHashTable *group_merge_weights(resource_t * rsc, const char *rhs, GHashTable * nodes,
const char *attr, float factor, enum pe_weights flags);
extern node_t *native_color(resource_t * rsc, node_t * preferred, pe_working_set_t * data_set);
extern void native_create_actions(resource_t * rsc, pe_working_set_t * data_set);
extern void native_internal_constraints(resource_t * rsc, pe_working_set_t * data_set);
void native_rsc_colocation_lh(pe_resource_t *lh_rsc, pe_resource_t *rh_rsc,
rsc_colocation_t *constraint,
pe_working_set_t *data_set);
void native_rsc_colocation_rh(pe_resource_t *lh_rsc, pe_resource_t *rh_rsc,
rsc_colocation_t *constraint,
pe_working_set_t *data_set);
extern void rsc_ticket_constraint(resource_t * lh_rsc, rsc_ticket_t * rsc_ticket,
pe_working_set_t * data_set);
extern enum pe_action_flags native_action_flags(action_t * action, node_t * node);
void native_rsc_location(pe_resource_t *rsc, pe__location_t *constraint);
extern void native_expand(resource_t * rsc, pe_working_set_t * data_set);
extern gboolean native_create_probe(resource_t * rsc, node_t * node, action_t * complete,
gboolean force, pe_working_set_t * data_set);
extern void native_append_meta(resource_t * rsc, xmlNode * xml);
extern node_t *group_color(resource_t * rsc, node_t * preferred, pe_working_set_t * data_set);
extern void group_create_actions(resource_t * rsc, pe_working_set_t * data_set);
extern void group_internal_constraints(resource_t * rsc, pe_working_set_t * data_set);
void group_rsc_colocation_lh(pe_resource_t *lh_rsc, pe_resource_t *rh_rsc,
rsc_colocation_t *constraint,
pe_working_set_t *data_set);
void group_rsc_colocation_rh(pe_resource_t *lh_rsc, pe_resource_t *rh_rsc,
rsc_colocation_t *constraint,
pe_working_set_t *data_set);
extern enum pe_action_flags group_action_flags(action_t * action, node_t * node);
void group_rsc_location(pe_resource_t *rsc, pe__location_t *constraint);
extern void group_expand(resource_t * rsc, pe_working_set_t * data_set);
extern void group_append_meta(resource_t * rsc, xmlNode * xml);
extern node_t *container_color(resource_t * rsc, node_t * preferred, pe_working_set_t * data_set);
extern void container_create_actions(resource_t * rsc, pe_working_set_t * data_set);
extern void container_internal_constraints(resource_t * rsc, pe_working_set_t * data_set);
void container_rsc_colocation_lh(pe_resource_t *lh_rsc, pe_resource_t *rh_rsc,
rsc_colocation_t *constraint,
pe_working_set_t *data_set);
void container_rsc_colocation_rh(pe_resource_t *lh_rsc, pe_resource_t *rh_rsc,
rsc_colocation_t *constraint,
pe_working_set_t *data_set);
void container_rsc_location(pe_resource_t *rsc, pe__location_t *constraint);
extern enum pe_action_flags container_action_flags(action_t * action, node_t * node);
extern void container_expand(resource_t * rsc, pe_working_set_t * data_set);
extern gboolean container_create_probe(resource_t * rsc, node_t * node, action_t * complete,
gboolean force, pe_working_set_t * data_set);
extern void container_append_meta(resource_t * rsc, xmlNode * xml);
extern node_t *clone_color(resource_t * rsc, node_t * preferred, pe_working_set_t * data_set);
extern void clone_create_actions(resource_t * rsc, pe_working_set_t * data_set);
extern void clone_internal_constraints(resource_t * rsc, pe_working_set_t * data_set);
void clone_rsc_colocation_lh(pe_resource_t *lh_rsc, pe_resource_t *rh_rsc,
rsc_colocation_t *constraint,
pe_working_set_t *data_set);
void clone_rsc_colocation_rh(pe_resource_t *lh_rsc, pe_resource_t *rh_rsc,
rsc_colocation_t *constraint,
pe_working_set_t *data_set);
void clone_rsc_location(pe_resource_t *rsc, pe__location_t *constraint);
extern enum pe_action_flags clone_action_flags(action_t * action, node_t * node);
extern void clone_expand(resource_t * rsc, pe_working_set_t * data_set);
extern gboolean clone_create_probe(resource_t * rsc, node_t * node, action_t * complete,
gboolean force, pe_working_set_t * data_set);
extern void clone_append_meta(resource_t * rsc, xmlNode * xml);
void apply_master_prefs(resource_t *rsc);
node_t *color_promotable(resource_t *rsc, pe_working_set_t *data_set);
void create_promotable_actions(resource_t *rsc, pe_working_set_t *data_set);
void promote_demote_constraints(resource_t *rsc, pe_working_set_t *data_set);
void promotable_constraints(resource_t *rsc, pe_working_set_t *data_set);
void promotable_colocation_rh(resource_t *lh_rsc, resource_t *rh_rsc,
rsc_colocation_t *constraint,
pe_working_set_t *data_set);
/* extern resource_object_functions_t resource_variants[]; */
extern resource_alloc_functions_t resource_class_alloc_functions[];
gboolean is_active(pe__location_t *cons);
extern gboolean unpack_rsc_order(xmlNode * xml_obj, pe_working_set_t * data_set);
extern gboolean unpack_rsc_colocation(xmlNode * xml_obj, pe_working_set_t * data_set);
extern gboolean unpack_location(xmlNode * xml_obj, pe_working_set_t * data_set);
extern gboolean unpack_rsc_ticket(xmlNode * xml_obj, pe_working_set_t * data_set);
void LogNodeActions(pe_working_set_t * data_set, gboolean terminal);
void LogActions(resource_t * rsc, pe_working_set_t * data_set, gboolean terminal);
void container_LogActions(resource_t * rsc, pe_working_set_t * data_set, gboolean terminal);
extern void rsc_stonith_ordering(resource_t * rsc, action_t * stonith_op,
pe_working_set_t * data_set);
enum pe_graph_flags native_update_actions(pe_action_t *first, pe_action_t *then,
pe_node_t *node,
enum pe_action_flags flags,
enum pe_action_flags filter,
enum pe_ordering type,
pe_working_set_t *data_set);
enum pe_graph_flags group_update_actions(pe_action_t *first, pe_action_t *then,
pe_node_t *node,
enum pe_action_flags flags,
enum pe_action_flags filter,
enum pe_ordering type,
pe_working_set_t *data_set);
enum pe_graph_flags container_update_actions(pe_action_t *first,
pe_action_t *then, pe_node_t *node,
enum pe_action_flags flags,
enum pe_action_flags filter,
enum pe_ordering type,
pe_working_set_t *data_set);
gboolean update_action_flags(action_t * action, enum pe_action_flags flags, const char *source, int line);
gboolean update_action(pe_action_t *action, pe_working_set_t *data_set);
void complex_set_cmds(resource_t * rsc);
void clone_create_pseudo_actions(
resource_t * rsc, GListPtr children, notify_data_t **start_notify, notify_data_t **stop_notify, pe_working_set_t * data_set);
void libpengine_fini(void);
#endif
diff --git a/include/pcmki/pcmki_sched_notif.h b/include/pcmki/pcmki_sched_notif.h
index da6887403a..2eefdfeafa 100644
--- a/include/pcmki/pcmki_sched_notif.h
+++ b/include/pcmki/pcmki_sched_notif.h
@@ -1,43 +1,45 @@
/*
- * Copyright (C) 2004-2016 Andrew Beekhof <andrew@beekhof.net>
+ * Copyright 2004-2019 the Pacemaker project contributors
+ *
+ * The version control history for this file may have further details.
*
* 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 software 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
* 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_PE_NOTIF__H
# define CRM_PE_NOTIF__H
# include <crm/pengine/internal.h>
notify_data_t * create_notification_boundaries(resource_t *rsc,
const char *action,
action_t *start, action_t *end,
pe_working_set_t *data_set);
void collect_notification_data(resource_t *rsc, gboolean state,
gboolean activity, notify_data_t *n_data);
gboolean expand_notification_data(resource_t *rsc, notify_data_t *n_data,
pe_working_set_t *data_set);
void create_notifications(resource_t *rsc, notify_data_t *n_data,
pe_working_set_t *data_set);
void free_notification_data(notify_data_t *n_data);
void create_secondary_notification(pe_action_t *action, resource_t *rsc,
pe_action_t *stonith_op,
pe_working_set_t *data_set);
#endif /* CRM_PE_NOTIF__H */
diff --git a/include/pcmki/pcmki_sched_transition.h b/include/pcmki/pcmki_sched_transition.h
index 4615bf92ec..41f5d61539 100644
--- a/include/pcmki/pcmki_sched_transition.h
+++ b/include/pcmki/pcmki_sched_transition.h
@@ -1,14 +1,22 @@
+/*
+ * Copyright 2014-2019 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 SCHED_TRANSITION__H
# define SCHED_TRANSITION__H
#include <crm/cib.h>
void modify_configuration(
pe_working_set_t * data_set, cib_t *cib,
const char *quorum, const char *watchdog, GListPtr node_up, GListPtr node_down, GListPtr node_fail,
GListPtr op_inject, GListPtr ticket_grant, GListPtr ticket_revoke,
GListPtr ticket_standby, GListPtr ticket_activate);
int run_simulation(pe_working_set_t * data_set, cib_t *cib, GListPtr op_fail_list, bool quiet);
#endif
diff --git a/include/pcmki/pcmki_sched_utils.h b/include/pcmki/pcmki_sched_utils.h
index 6c3cb460a6..f85858fd27 100644
--- a/include/pcmki/pcmki_sched_utils.h
+++ b/include/pcmki/pcmki_sched_utils.h
@@ -1,77 +1,79 @@
/*
- * Copyright 2004-2019 Andrew Beekhof <andrew@beekhof.net>
+ * Copyright 2004-2019 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 PENGINE_AUTILS__H
# define PENGINE_AUTILS__H
/* Constraint helper functions */
extern rsc_colocation_t *invert_constraint(rsc_colocation_t * constraint);
pe__location_t *copy_constraint(pe__location_t *constraint);
pe__location_t *rsc2node_new(const char *id, pe_resource_t *rsc, int weight,
const char *discovery_mode, pe_node_t *node,
pe_working_set_t *data_set);
extern gboolean rsc_colocation_new(const char *id, const char *node_attr, int score,
resource_t * rsc_lh, resource_t * rsc_rh,
const char *state_lh, const char *state_rh,
pe_working_set_t * data_set);
extern gboolean rsc_ticket_new(const char *id, resource_t * rsc_lh, ticket_t * ticket,
const char *state_lh, const char *loss_policy,
pe_working_set_t * data_set);
GList *sort_nodes_by_weight(GList *nodes, pe_node_t *active_node,
pe_working_set_t *data_set);
extern gboolean can_run_resources(const node_t * node);
extern gboolean native_assign_node(resource_t * rsc, GListPtr candidates, node_t * chosen,
gboolean force);
void native_deallocate(resource_t * rsc);
extern void log_action(unsigned int log_level, const char *pre_text,
action_t * action, gboolean details);
gboolean can_run_any(GHashTable * nodes);
bool can_interleave_actions(pe_action_t *first, pe_action_t *then);
pe_resource_t *find_compatible_child(pe_resource_t *local_child,
pe_resource_t *rsc, enum rsc_role_e filter,
gboolean current,
pe_working_set_t *data_set);
resource_t *find_compatible_child_by_node(resource_t * local_child, node_t * local_node, resource_t * rsc,
enum rsc_role_e filter, gboolean current);
gboolean is_child_compatible(resource_t *child_rsc, node_t * local_node, enum rsc_role_e filter, gboolean current);
bool assign_node(resource_t * rsc, node_t * node, gboolean force);
enum pe_action_flags summary_action_flags(action_t * action, GListPtr children, node_t * node);
enum action_tasks clone_child_action(action_t * action);
int copies_per_node(resource_t * rsc);
enum filter_colocation_res {
influence_nothing = 0,
influence_rsc_location,
influence_rsc_priority,
};
extern enum filter_colocation_res
filter_colocation_constraint(resource_t * rsc_lh, resource_t * rsc_rh,
rsc_colocation_t * constraint, gboolean preview);
extern int compare_capacity(const node_t * node1, const node_t * node2);
extern void calculate_utilization(GHashTable * current_utilization,
GHashTable * utilization, gboolean plus);
extern void process_utilization(resource_t * rsc, node_t ** prefer, pe_working_set_t * data_set);
pe_action_t *create_pseudo_resource_op(resource_t * rsc, const char *task, bool optional, bool runnable, pe_working_set_t *data_set);
pe_action_t *pe_cancel_op(pe_resource_t *rsc, const char *name,
guint interval_ms, pe_node_t *node,
pe_working_set_t *data_set);
pe_action_t *sched_shutdown_op(pe_node_t *node, pe_working_set_t *data_set);
# define LOAD_STOPPED "load_stopped"
#endif
diff --git a/include/pcmki/pcmki_scheduler.h b/include/pcmki/pcmki_scheduler.h
index 0101b4fd3a..0d49f21c04 100644
--- a/include/pcmki/pcmki_scheduler.h
+++ b/include/pcmki/pcmki_scheduler.h
@@ -1,110 +1,112 @@
/*
- * Copyright 2004-2018 Andrew Beekhof <andrew@beekhof.net>
+ * Copyright 2014-2019 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 PENGINE__H
# define PENGINE__H
typedef struct rsc_colocation_s rsc_colocation_t;
typedef struct rsc_ticket_s rsc_ticket_t;
typedef struct lrm_agent_s lrm_agent_t;
# include <glib.h>
# include <crm/crm.h>
# include <crm/common/iso8601.h>
# include <crm/pengine/rules.h>
# include <crm/pengine/common.h>
# include <crm/pengine/status.h>
# include <crm/pengine/complex.h>
enum pe_stop_fail {
pesf_block,
pesf_stonith,
pesf_ignore
};
enum pe_weights {
pe_weights_none = 0x0,
pe_weights_init = 0x1,
pe_weights_forward = 0x4,
pe_weights_positive = 0x8,
pe_weights_rollback = 0x10,
};
struct rsc_colocation_s {
const char *id;
const char *node_attribute;
resource_t *rsc_lh;
resource_t *rsc_rh;
int role_lh;
int role_rh;
int score;
};
enum loss_ticket_policy_e {
loss_ticket_stop,
loss_ticket_demote,
loss_ticket_fence,
loss_ticket_freeze
};
struct rsc_ticket_s {
const char *id;
resource_t *rsc_lh;
ticket_t *ticket;
enum loss_ticket_policy_e loss_policy;
int role_lh;
};
extern gboolean stage0(pe_working_set_t * data_set);
extern gboolean probe_resources(pe_working_set_t * data_set);
extern gboolean stage2(pe_working_set_t * data_set);
extern gboolean stage3(pe_working_set_t * data_set);
extern gboolean stage4(pe_working_set_t * data_set);
extern gboolean stage5(pe_working_set_t * data_set);
extern gboolean stage6(pe_working_set_t * data_set);
extern gboolean stage7(pe_working_set_t * data_set);
extern gboolean stage8(pe_working_set_t * data_set);
extern gboolean summary(GListPtr resources);
extern gboolean unpack_constraints(xmlNode * xml_constraints, pe_working_set_t * data_set);
extern gboolean update_action_states(GListPtr actions);
extern gboolean shutdown_constraints(node_t * node, action_t * shutdown_op,
pe_working_set_t * data_set);
extern gboolean stonith_constraints(node_t * node, action_t * stonith_op,
pe_working_set_t * data_set);
extern int custom_action_order(resource_t * lh_rsc, char *lh_task, action_t * lh_action,
resource_t * rh_rsc, char *rh_task, action_t * rh_action,
enum pe_ordering type, pe_working_set_t * data_set);
extern int new_rsc_order(resource_t * lh_rsc, const char *lh_task,
resource_t * rh_rsc, const char *rh_task,
enum pe_ordering type, pe_working_set_t * data_set);
# define order_start_start(rsc1,rsc2, type) \
new_rsc_order(rsc1, CRMD_ACTION_START, rsc2, CRMD_ACTION_START, type, data_set)
# define order_stop_stop(rsc1, rsc2, type) \
new_rsc_order(rsc1, CRMD_ACTION_STOP, rsc2, CRMD_ACTION_STOP, type, data_set)
extern void graph_element_from_action(action_t * action, pe_working_set_t * data_set);
extern void add_maintenance_update(pe_working_set_t *data_set);
extern gboolean show_scores;
extern int scores_log_level;
extern gboolean show_utilization;
extern int utilization_log_level;
extern const char *transition_idle_timeout;
#endif
diff --git a/include/portability.h b/include/portability.h
index 322af33c5a..ee8fd1f5fb 100644
--- a/include/portability.h
+++ b/include/portability.h
@@ -1,186 +1,188 @@
/*
- * Copyright 2001-2018 Alan Robertson <alanr@unix.sh>
+ * Copyright 2001-2018 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 PORTABILITY_H
# define PORTABILITY_H
# define EOS '\0'
# define DIMOF(a) ((int) (sizeof(a)/sizeof(a[0])) )
/* Needs to be defined before any other includes, otherwise some system
* headers do not behave as expected! Major black magic... */
# undef _GNU_SOURCE /* in case it was defined on the command line */
# define _GNU_SOURCE
/* Please leave this as the first #include - Solaris needs it there */
# ifdef HAVE_CONFIG_H
# include <config.h>
# endif
/* Prototypes for libreplace functions */
# ifndef HAVE_DAEMON
/* We supply a replacement function, but need a prototype */
int daemon(int nochdir, int noclose);
# endif /* HAVE_DAEMON */
# ifndef HAVE_SETENV
/* We supply a replacement function, but need a prototype */
int setenv(const char *name, const char *value, int why);
# endif /* HAVE_SETENV */
# ifndef HAVE_STRERROR
/* We supply a replacement function, but need a prototype */
char *strerror(int errnum);
# endif /* HAVE_STRERROR */
# ifndef HAVE_STRCHRNUL
/* We supply a replacement function, but need a prototype */
char *strchrnul(const char *s, int c_in);
# endif /* HAVE_STRCHRNUL */
# ifndef HAVE_ALPHASORT
# include <dirent.h>
int
alphasort(const void *dirent1, const void *dirent2);
# endif /* HAVE_ALPHASORT */
# ifndef HAVE_STRNLEN
size_t strnlen(const char *s, size_t maxlen);
# else
# define USE_GNU
# endif
# ifndef HAVE_STRNDUP
char *strndup(const char *str, size_t len);
# else
# define USE_GNU
# endif
// This test could be better, but it covers platforms of interest
# if defined(ON_BSD) || defined(ON_SOLARIS)
# define SUPPORT_PROCFS 0
# else
# define SUPPORT_PROCFS 1
# endif
# include <glib.h>
# if !GLIB_CHECK_VERSION(2,28,0)
# include <string.h>
/* Since: 2.28 */
static inline void
g_list_free_full(GList * list, GDestroyNotify free_func)
{
g_list_foreach(list, (GFunc) free_func, NULL);
g_list_free(list);
}
# endif
# if SUPPORT_DBUS
# ifndef HAVE_DBUSBASICVALUE
# include <stdint.h>
# include <dbus/dbus.h>
/**
* An 8-byte struct you could use to access int64 without having
* int64 support
*/
typedef struct
{
uint32_t first32; /**< first 32 bits in the 8 bytes (beware endian issues) */
uint32_t second32; /**< second 32 bits in the 8 bytes (beware endian issues) */
} DBus8ByteStruct;
/**
* A simple value union that lets you access bytes as if they
* were various types; useful when dealing with basic types via
* void pointers and varargs.
*
* This union also contains a pointer member (which can be used
* to retrieve a string from dbus_message_iter_get_basic(), for
* instance), so on future platforms it could conceivably be larger
* than 8 bytes.
*/
typedef union
{
unsigned char bytes[8]; /**< as 8 individual bytes */
int16_t i16; /**< as int16 */
uint16_t u16; /**< as int16 */
int32_t i32; /**< as int32 */
uint32_t u32; /**< as int32 */
uint32_t bool_val; /**< as boolean */
# ifdef DBUS_HAVE_INT64
int64_t i64; /**< as int64 */
uint64_t u64; /**< as int64 */
# endif
DBus8ByteStruct eight; /**< as 8-byte struct */
double dbl; /**< as double */
unsigned char byt; /**< as byte */
char *str; /**< as char* (string, object path or signature) */
int fd; /**< as Unix file descriptor */
} DBusBasicValue;
# endif
# endif
/* Replacement error codes for non-linux */
# include <errno.h>
# ifndef ENOTUNIQ
# define ENOTUNIQ 190
# endif
# ifndef ECOMM
# define ECOMM 191
# endif
# ifndef ELIBACC
# define ELIBACC 192
# endif
# ifndef EREMOTEIO
# define EREMOTEIO 193
# endif
# ifndef EUNATCH
# define EUNATCH 194
# endif
# ifndef ENOKEY
# define ENOKEY 195
# endif
# ifndef ENODATA
# define ENODATA 196
# endif
# ifndef ETIME
# define ETIME 197
# endif
# ifndef ENOSR
# define ENOSR 198
# endif
# ifndef ENOSTR
# define ENOSTR 199
# endif
# ifndef EKEYREJECTED
# define EKEYREJECTED 200
# endif
/*
* Some compilers (eg. Sun studio) do not define __FUNCTION__
*/
# ifdef __SUNPRO_C
# define __FUNCTION__ __func__
# endif
# ifdef __MY_UNKNOWN_C
# define __FUNCTION__ "__FUNCTION__"
# endif
#endif /* PORTABILITY_H */

File Metadata

Mime Type
text/x-diff
Expires
Tue, Jul 8, 6:20 PM (12 h, 18 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1981031
Default Alt Text
(280 KB)

Event Timeline