Page MenuHomeClusterLabs Projects

No OneTemporary

diff --git a/tools/Makefile.am b/tools/Makefile.am
index 2e09e8527b..8882028801 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -1,173 +1,174 @@
#
# Copyright 2004-2022 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.
#
include $(top_srcdir)/mk/common.mk
include $(top_srcdir)/mk/man.mk
if BUILD_SYSTEMD
systemdsystemunit_DATA = crm_mon.service
endif
noinst_HEADERS = crm_mon.h crm_resource.h
pcmkdir = $(datadir)/$(PACKAGE)
pcmk_DATA = report.common report.collector
sbin_SCRIPTS = crm_report crm_standby crm_master crm_failcount
if BUILD_CIBSECRETS
sbin_SCRIPTS += cibsecret
endif
noinst_SCRIPTS = pcmk_simtimes
-EXTRA_DIST = crm_attribute.8.inc \
+EXTRA_DIST = attrd_updater.8.inc \
+ crm_attribute.8.inc \
crm_diff.8.inc \
crm_error.8.inc \
crm_mon.8.inc \
crm_node.8.inc \
crm_resource.8.inc \
crm_rule.8.inc \
crm_simulate.8.inc \
crm_verify.8.inc \
crmadmin.8.inc \
fix-manpages \
stonith_admin.8.inc
sbin_PROGRAMS = attrd_updater \
cibadmin \
crmadmin \
crm_simulate \
crm_attribute \
crm_diff \
crm_error \
crm_mon \
crm_node \
crm_resource \
crm_rule \
crm_shadow \
crm_verify \
crm_ticket \
iso8601 \
stonith_admin
if BUILD_SERVICELOG
sbin_PROGRAMS += notifyServicelogEvent
endif
if BUILD_OPENIPMI_SERVICELOG
sbin_PROGRAMS += ipmiservicelogd
endif
## SOURCES
# A few tools are just thin wrappers around crm_attribute.
# This makes their help get updated when crm_attribute changes
# (see mk/common.mk).
MAN8DEPS = crm_attribute
crmadmin_SOURCES = crmadmin.c
crmadmin_LDADD = $(top_builddir)/lib/pengine/libpe_status.la \
$(top_builddir)/lib/cib/libcib.la \
$(top_builddir)/lib/common/libcrmcommon.la \
$(top_builddir)/lib/pacemaker/libpacemaker.la
crm_error_SOURCES = crm_error.c
crm_error_LDADD = $(top_builddir)/lib/common/libcrmcommon.la
cibadmin_SOURCES = cibadmin.c
cibadmin_LDADD = $(top_builddir)/lib/pacemaker/libpacemaker.la \
$(top_builddir)/lib/cib/libcib.la \
$(top_builddir)/lib/common/libcrmcommon.la
crm_shadow_SOURCES = crm_shadow.c
crm_shadow_LDADD = $(top_builddir)/lib/cib/libcib.la \
$(top_builddir)/lib/common/libcrmcommon.la
crm_node_SOURCES = crm_node.c
crm_node_LDADD = $(top_builddir)/lib/cib/libcib.la \
$(top_builddir)/lib/common/libcrmcommon.la
crm_simulate_SOURCES = crm_simulate.c
crm_simulate_LDADD = $(top_builddir)/lib/pengine/libpe_status.la \
$(top_builddir)/lib/pacemaker/libpacemaker.la \
$(top_builddir)/lib/cib/libcib.la \
$(top_builddir)/lib/common/libcrmcommon.la
crm_diff_SOURCES = crm_diff.c
crm_diff_LDADD = $(top_builddir)/lib/common/libcrmcommon.la
crm_mon_SOURCES = crm_mon.c crm_mon_curses.c
crm_mon_LDADD = $(top_builddir)/lib/pengine/libpe_status.la \
$(top_builddir)/lib/fencing/libstonithd.la \
$(top_builddir)/lib/pacemaker/libpacemaker.la \
$(top_builddir)/lib/cib/libcib.la \
$(top_builddir)/lib/common/libcrmcommon.la \
$(CURSESLIBS)
crm_verify_SOURCES = crm_verify.c
crm_verify_LDADD = $(top_builddir)/lib/pengine/libpe_status.la \
$(top_builddir)/lib/pacemaker/libpacemaker.la \
$(top_builddir)/lib/cib/libcib.la \
$(top_builddir)/lib/common/libcrmcommon.la
crm_attribute_SOURCES = crm_attribute.c
crm_attribute_LDADD = $(top_builddir)/lib/cluster/libcrmcluster.la \
$(top_builddir)/lib/cib/libcib.la \
$(top_builddir)/lib/common/libcrmcommon.la
crm_resource_SOURCES = crm_resource.c \
crm_resource_ban.c \
crm_resource_print.c \
crm_resource_runtime.c
crm_resource_LDADD = $(top_builddir)/lib/pengine/libpe_rules.la \
$(top_builddir)/lib/fencing/libstonithd.la \
$(top_builddir)/lib/lrmd/liblrmd.la \
$(top_builddir)/lib/services/libcrmservice.la \
$(top_builddir)/lib/pengine/libpe_status.la \
$(top_builddir)/lib/pacemaker/libpacemaker.la \
$(top_builddir)/lib/cib/libcib.la \
$(top_builddir)/lib/common/libcrmcommon.la
crm_rule_SOURCES = crm_rule.c
crm_rule_LDADD = $(top_builddir)/lib/cib/libcib.la \
$(top_builddir)/lib/pengine/libpe_rules.la \
$(top_builddir)/lib/pengine/libpe_status.la \
$(top_builddir)/lib/common/libcrmcommon.la
iso8601_SOURCES = iso8601.c
iso8601_LDADD = $(top_builddir)/lib/common/libcrmcommon.la
attrd_updater_SOURCES = attrd_updater.c
attrd_updater_LDADD = $(top_builddir)/lib/common/libcrmcommon.la
crm_ticket_SOURCES = crm_ticket.c
crm_ticket_LDADD = $(top_builddir)/lib/pengine/libpe_rules.la \
$(top_builddir)/lib/pengine/libpe_status.la \
$(top_builddir)/lib/pacemaker/libpacemaker.la \
$(top_builddir)/lib/cib/libcib.la \
$(top_builddir)/lib/common/libcrmcommon.la
stonith_admin_SOURCES = stonith_admin.c
stonith_admin_LDADD = $(top_builddir)/lib/pacemaker/libpacemaker.la \
$(top_builddir)/lib/cib/libcib.la \
$(top_builddir)/lib/pengine/libpe_status.la \
$(top_builddir)/lib/fencing/libstonithd.la \
$(top_builddir)/lib/common/libcrmcommon.la
if BUILD_SERVICELOG
notifyServicelogEvent_SOURCES = notifyServicelogEvent.c
notifyServicelogEvent_CFLAGS = $(SERVICELOG_CFLAGS)
notifyServicelogEvent_LDADD = $(top_builddir)/lib/common/libcrmcommon.la $(SERVICELOG_LIBS)
endif
if BUILD_OPENIPMI_SERVICELOG
ipmiservicelogd_SOURCES = ipmiservicelogd.c
ipmiservicelogd_CFLAGS = $(OPENIPMI_SERVICELOG_CFLAGS) $(SERVICELOG_CFLAGS)
ipmiservicelogd_LDFLAGS = $(top_builddir)/lib/common/libcrmcommon.la $(OPENIPMI_SERVICELOG_LIBS) $(SERVICELOG_LIBS)
endif
CLEANFILES = $(man8_MANS)
diff --git a/tools/attrd_updater.8.inc b/tools/attrd_updater.8.inc
new file mode 100644
index 0000000000..256969a999
--- /dev/null
+++ b/tools/attrd_updater.8.inc
@@ -0,0 +1,5 @@
+[synopsis]
+attrd_updater -n <attribute> <command> [options]
+
+/node attributes/
+.SH OPTIONS
diff --git a/tools/attrd_updater.c b/tools/attrd_updater.c
index ae1c18da01..9c0266e615 100644
--- a/tools/attrd_updater.c
+++ b/tools/attrd_updater.c
@@ -1,470 +1,448 @@
/*
* Copyright 2004-2022 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.
*/
#include <crm_internal.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <libgen.h>
#include <sys/param.h>
#include <sys/types.h>
#include <crm/crm.h>
#include <crm/msg_xml.h>
+#include <crm/common/cmdline_internal.h>
#include <crm/common/xml_internal.h>
#include <crm/common/ipc.h>
#include <crm/common/attrd_internal.h>
-static pcmk__cli_option_t long_options[] = {
- // long option, argument type, storage, short option, description, flags
- {
- "help", no_argument, NULL, '?',
- "\tThis text", pcmk__option_default
- },
- {
- "version", no_argument, NULL, '$',
- "\tVersion information", pcmk__option_default
- },
- {
- "verbose", no_argument, NULL, 'V',
- "\tIncrease debug output\n", pcmk__option_default
- },
- {
- "name", required_argument, NULL, 'n',
- "The attribute's name", pcmk__option_default
- },
- {
- "-spacer-", no_argument, NULL, '-',
- "\nCommands:", pcmk__option_default
- },
- {
- "update", required_argument, NULL, 'U',
- "Update attribute's value in pacemaker-attrd. If this causes the value "
- "to change, it will also be updated in the cluster configuration.",
- pcmk__option_default
- },
- {
- "update-both", required_argument, NULL, 'B',
- "Update attribute's value and time to wait (dampening) in "
- "pacemaker-attrd. If this causes the value or dampening to change, "
- "the attribute will also be written to the cluster configuration, "
- "so be aware that repeatedly changing the dampening reduces its "
- "effectiveness.",
- pcmk__option_default
- },
- {
- "update-delay", no_argument, NULL, 'Y',
- "Update attribute's dampening in pacemaker-attrd (requires "
- "-d/--delay). If this causes the dampening to change, the "
- "attribute will also be written to the cluster configuration, so "
- "be aware that repeatedly changing the dampening reduces its "
- "effectiveness.",
- pcmk__option_default
- },
- {
- "query", no_argument, NULL, 'Q',
- "\tQuery the attribute's value from pacemaker-attrd",
- pcmk__option_default
- },
- {
- "delete", no_argument, NULL, 'D',
- "\tDelete attribute from pacemaker-attrd. If a value was previously "
- "set, it will also be removed from the cluster configuration",
- pcmk__option_default
- },
- {
- "refresh", no_argument, NULL, 'R',
- "\t(Advanced) Force the pacemaker-attrd daemon to resend all current "
- "values to the CIB",
- pcmk__option_default
- },
-
- {
- "-spacer-", no_argument, NULL, '-',
- "\nAdditional options:", pcmk__option_default
- },
- {
- "delay", required_argument, NULL, 'd',
- "The time to wait (dampening) in seconds for further changes "
- "before writing",
- pcmk__option_default
- },
- {
- "set", required_argument, NULL, 's',
- "(Advanced) The attribute set in which to place the value",
- pcmk__option_default
- },
- {
- "node", required_argument, NULL, 'N',
- "Set the attribute for the named node (instead of the local one)",
- pcmk__option_default
- },
- {
- "all", no_argument, NULL, 'A',
- "Show values of the attribute for all nodes (query only)",
- pcmk__option_default
- },
-
- // @TODO Implement --lifetime
- {
- "lifetime", required_argument, NULL, 'l',
- "(Not yet implemented) Lifetime of the node attribute (silently "
- "ignored by cluster)",
- pcmk__option_default
- },
- {
- "private", no_argument, NULL, 'p',
- "\tIf this creates a new attribute, never write the attribute to CIB",
- pcmk__option_default
- },
-
- /* Legacy options */
- {
- "quiet", no_argument, NULL, 'q',
- NULL, pcmk__option_hidden
- },
- {
- "update", required_argument, NULL, 'v',
- NULL, pcmk__option_hidden
- },
- {
- "section", required_argument, NULL, 'S',
- NULL, pcmk__option_hidden
- },
- { 0, 0, 0, 0 }
+#define SUMMARY "query and update Pacemaker node attributes"
+
+GError *error = NULL;
+
+struct {
+ char command;
+ gchar *attr_dampen;
+ gchar *attr_name;
+ gchar *attr_node;
+ gchar *attr_section;
+ gchar *attr_set;
+ char *attr_value;
+ int attr_options;
+ gboolean query_all;
+} options = {
+ .attr_options = pcmk__node_attr_none,
+ .command = 'Q',
+};
+
+static gboolean
+command_cb (const gchar *option_name, const gchar *optarg, gpointer data, GError **err) {
+ pcmk__str_update(&options.attr_value, optarg);
+
+ if (pcmk__str_any_of(option_name, "--update-both", "-B", NULL)) {
+ options.command = 'B';
+ } else if (pcmk__str_any_of(option_name, "--delete", "-D", NULL)) {
+ options.command = 'D';
+ } else if (pcmk__str_any_of(option_name, "--query", "-Q", NULL)) {
+ options.command = 'Q';
+ } else if (pcmk__str_any_of(option_name, "--refresh", "-R", NULL)) {
+ options.command = 'R';
+ } else if (pcmk__str_any_of(option_name, "--update", "-U", NULL)) {
+ options.command = 'U';
+ }
+
+ return TRUE;
+}
+
+static gboolean
+private_cb (const gchar *option_name, const gchar *optarg, gpointer data, GError **err) {
+ pcmk__set_node_attr_flags(options.attr_options, pcmk__node_attr_private);
+ return TRUE;
+}
+
+#define INDENT " "
+
+static GOptionEntry required_entries[] = {
+ { "name", 'n', 0, G_OPTION_ARG_STRING, &options.attr_name,
+ "The attribute's name",
+ "NAME" },
+
+ { NULL }
+};
+
+static GOptionEntry command_entries[] = {
+ { "update", 'U', 0, G_OPTION_ARG_CALLBACK, command_cb,
+ "Update attribute's value in pacemaker-attrd. If this causes the value\n"
+ INDENT "to change, it will also be updated in the cluster configuration.",
+ "VALUE" },
+
+ { "update-both", 'B', 0, G_OPTION_ARG_CALLBACK, command_cb,
+ "Update attribute's value and time to wait (dampening) in\n"
+ INDENT "pacemaker-attrd. If this causes the value or dampening to change,\n"
+ INDENT "the attribute will also be written to the cluster configuration,\n"
+ INDENT "so be aware that repeatedly changing the dampening reduces its\n"
+ INDENT "effectiveness.",
+ "VALUE" },
+
+ { "update-delay", 'Y', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, command_cb,
+ "Update attribute's dampening in pacemaker-attrd (requires\n"
+ INDENT "-d/--delay). If this causes the dampening to change, the\n"
+ INDENT "attribute will also be written to the cluster configuration, so\n"
+ INDENT "be aware that repeatedly changing the dampening reduces its\n"
+ INDENT "effectiveness.",
+ NULL },
+
+ { "query", 'Q', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, command_cb,
+ "Query the attribute's value from pacemaker-attrd",
+ NULL },
+
+ { "delete", 'D', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, command_cb,
+ "Unset attribute from pacemaker-attrd. At the moment, there is no way\n"
+ INDENT "to remove an attribute. This option will instead set its value\n"
+ INDENT "to the empty string.",
+ NULL },
+
+ { "refresh", 'R', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, command_cb,
+ "(Advanced) Force the pacemaker-attrd daemon to resend all current\n"
+ INDENT "values to the CIB",
+ NULL },
+
+ { NULL }
+};
+
+static GOptionEntry addl_entries[] = {
+ { "delay", 'd', 0, G_OPTION_ARG_STRING, &options.attr_dampen,
+ "The time to wait (dampening) in seconds for further changes\n"
+ INDENT "before sending to the CIB",
+ "SECONDS" },
+
+ { "set", 's', 0, G_OPTION_ARG_STRING, &options.attr_set,
+ "(Advanced) The attribute set in which to place the value",
+ "SET" },
+
+ { "node", 'N', 0, G_OPTION_ARG_STRING, &options.attr_node,
+ "Set the attribute for the named node (instead of the local one)",
+ "NODE" },
+
+ { "all", 'A', 0, G_OPTION_ARG_NONE, &options.query_all,
+ "Show values of the attribute for all nodes (query only)",
+ NULL },
+
+ { "lifetime", 'l', 0, G_OPTION_ARG_STRING, &options.attr_section,
+ "(Not yet implemented) Lifetime of the node attribute (silently\n"
+ INDENT "ignored by cluster)",
+ "SECTION" },
+
+ { "private", 'p', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, private_cb,
+ "If this creates a new attribute, never write the attribute to CIB",
+ NULL },
+
+ { NULL }
+};
+
+static GOptionEntry deprecated_entries[] = {
+ { NULL, 'v', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_CALLBACK, command_cb,
+ NULL,
+ NULL },
+
+ { "section", 'S', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, &options.attr_section,
+ NULL,
+ NULL },
+
+ { NULL }
};
static int do_query(const char *attr_name, const char *attr_node, gboolean query_all);
static int do_update(char command, const char *attr_node, const char *attr_name,
const char *attr_value, const char *attr_section,
const char *attr_set, const char *attr_dampen, int attr_options);
-// Free memory at exit to make analyzers happy
-#define cleanup_memory() \
- free(attr_dampen); \
- free(attr_name); \
- free(attr_node); \
- free(attr_section); \
- free(attr_set);
+static GOptionContext *
+build_arg_context(pcmk__common_args_t *args) {
+ GOptionContext *context = NULL;
+
+ context = pcmk__build_arg_context(args, NULL, NULL, NULL);
+
+ pcmk__add_arg_group(context, "required", "Required Arguments:",
+ "Show required arguments", required_entries);
+ pcmk__add_arg_group(context, "command", "Command:",
+ "Show command options (mutually exclusive)", command_entries);
+ pcmk__add_arg_group(context, "additional", "Additional Options:",
+ "Show additional options", addl_entries);
+ pcmk__add_arg_group(context, "deprecated", "Deprecated Options:",
+ "Show deprecated options", deprecated_entries);
+
+ return context;
+}
int
main(int argc, char **argv)
{
- int index = 0;
- int argerr = 0;
- int attr_options = pcmk__node_attr_none;
- int flag;
crm_exit_t exit_code = CRM_EX_OK;
- char *attr_node = NULL;
- char *attr_name = NULL;
- char *attr_set = NULL;
- char *attr_section = NULL;
- char *attr_dampen = NULL;
- const char *attr_value = NULL;
- char command = 'Q';
-
- gboolean query_all = FALSE;
-
- pcmk__cli_init_logging("attrd_updater", 0);
- pcmk__set_cli_options(NULL, "-n <attribute> <command> [options]",
- long_options,
- "query and update Pacemaker node attributes");
-
- if (argc < 2) {
- pcmk__cli_help('?', CRM_EX_USAGE);
- }
- while (1) {
- flag = pcmk__next_cli_option(argc, argv, &index, NULL);
- if (flag == -1)
- break;
-
- switch (flag) {
- case 'V':
- crm_bump_log_level(argc, argv);
- break;
- case '?':
- case '$':
- cleanup_memory();
- pcmk__cli_help(flag, CRM_EX_OK);
- break;
- case 'n':
- pcmk__str_update(&attr_name, optarg);
- break;
- case 's':
- pcmk__str_update(&attr_set, optarg);
- break;
- case 'd':
- pcmk__str_update(&attr_dampen, optarg);
- break;
- case 'l':
- case 'S':
- pcmk__str_update(&attr_section, optarg);
- break;
- case 'N':
- pcmk__str_update(&attr_node, optarg);
- break;
- case 'A':
- query_all = TRUE;
- break;
- case 'p':
- pcmk__set_node_attr_flags(attr_options, pcmk__node_attr_private);
- break;
- case 'q':
- break;
- case 'Y':
- command = flag;
- crm_log_args(argc, argv); /* Too much? */
- break;
- case 'Q':
- case 'B':
- case 'R':
- case 'D':
- case 'U':
- case 'v':
- command = flag;
- attr_value = optarg;
- crm_log_args(argc, argv); /* Too much? */
- break;
- default:
- ++argerr;
- break;
- }
- }
+ pcmk__common_args_t *args = pcmk__new_common_args(SUMMARY);
+ GOptionContext *context = build_arg_context(args);
+ gchar **processed_args = pcmk__cmdline_preproc(argv, "dlnsvBNUS");
- if (optind > argc) {
- ++argerr;
+ if (!g_option_context_parse_strv(context, &processed_args, &error)) {
+ exit_code = CRM_EX_USAGE;
+ goto done;
}
- if (command != 'R' && attr_name == NULL) {
- ++argerr;
+ pcmk__cli_init_logging("attrd_updater", args->verbosity);
+
+ if (args->version) {
+ /* FIXME: When attrd_updater is converted to use formatted output, this can go. */
+ pcmk__cli_help('v', CRM_EX_OK);
}
- if (argerr) {
- cleanup_memory();
- pcmk__cli_help('?', CRM_EX_USAGE);
+ if (options.command != 'R' && options.attr_name == NULL) {
+ exit_code = CRM_EX_USAGE;
+ g_set_error(&error, PCMK__EXITC_ERROR, exit_code, "Command requires --name argument");
+ goto done;
}
- if (command == 'Q') {
- exit_code = crm_errno2exit(do_query(attr_name, attr_node, query_all));
+ if (options.command == 'Q') {
+ int rc = do_query(options.attr_name, options.attr_node, options.query_all);
+ exit_code = pcmk_rc2exitc(rc);
} else {
/* @TODO We don't know whether the specified node is a Pacemaker Remote
* node or not, so we can't set pcmk__node_attr_remote when appropriate.
* However, it's not a big problem, because pacemaker-attrd will learn
* and remember a node's "remoteness".
*/
- const char *target = pcmk__node_attr_target(attr_node);
+ const char *target = pcmk__node_attr_target(options.attr_node);
- exit_code = pcmk_rc2exitc(do_update(command,
- target == NULL ? attr_node : target,
- attr_name, attr_value,
- attr_section, attr_set,
- attr_dampen, attr_options));
+ exit_code = pcmk_rc2exitc(do_update(options.command,
+ target == NULL ? options.attr_node : target,
+ options.attr_name, options.attr_value,
+ options.attr_section, options.attr_set,
+ options.attr_dampen, options.attr_options));
}
- cleanup_memory();
+done:
+ g_strfreev(processed_args);
+ pcmk__free_arg_context(context);
+ g_free(options.attr_dampen);
+ g_free(options.attr_name);
+ g_free(options.attr_node);
+ g_free(options.attr_section);
+ g_free(options.attr_set);
+ free(options.attr_value);
+
+ pcmk__output_and_clear_error(error, NULL);
+
crm_exit(exit_code);
}
/*!
* \internal
* \brief Submit a query request to pacemaker-attrd and wait for reply
*
* \param[in] name Name of attribute to query
* \param[in] host Query applies to this host only (or all hosts if NULL)
* \param[out] reply On success, will be set to new XML tree with reply
*
- * \return pcmk_ok on success, -errno on error
+ * \return Standard Pacemaker return code
* \note On success, caller is responsible for freeing result via free_xml(*reply)
*/
static int
send_attrd_query(const char *name, const char *host, xmlNode **reply)
{
- int rc;
+ int rc = pcmk_rc_ok;
crm_ipc_t *ipc;
xmlNode *query;
/* Build the query XML */
query = create_xml_node(NULL, __func__);
if (query == NULL) {
- return -ENOMEM;
+ return ENOMEM;
}
crm_xml_add(query, F_TYPE, T_ATTRD);
crm_xml_add(query, F_ORIG, crm_system_name);
crm_xml_add(query, PCMK__XA_ATTR_NODE_NAME, host);
crm_xml_add(query, PCMK__XA_TASK, PCMK__ATTRD_CMD_QUERY);
crm_xml_add(query, PCMK__XA_ATTR_NAME, name);
/* Connect to pacemaker-attrd, send query XML and get reply */
crm_debug("Sending query for value of %s on %s", name, (host? host : "all nodes"));
ipc = crm_ipc_new(T_ATTRD, 0);
- if (crm_ipc_connect(ipc) == FALSE) {
+ if (!crm_ipc_connect(ipc)) {
crm_perror(LOG_ERR, "Connection to cluster attribute manager failed");
- rc = -ENOTCONN;
+ rc = ENOTCONN;
} else {
rc = crm_ipc_send(ipc, query, crm_ipc_client_response, 0, reply);
if (rc > 0) {
- rc = pcmk_ok;
+ rc = pcmk_rc_ok;
}
crm_ipc_close(ipc);
}
crm_ipc_destroy(ipc);
free_xml(query);
return(rc);
}
/*!
* \brief Validate pacemaker-attrd's XML reply to an query
*
* param[in] reply Root of reply XML tree to validate
* param[in] attr_name Name of attribute that was queried
*
- * \return pcmk_ok on success,
- * -errno on error (-ENXIO = requested attribute does not exist)
+ * \return Standard Pacemaker return code
+ * \note A return value of ENXIO means the requested attribute does not exist
*/
static int
validate_attrd_reply(xmlNode *reply, const char *attr_name)
{
+ int rc = pcmk_rc_ok;
const char *reply_attr;
if (reply == NULL) {
- fprintf(stderr, "Could not query value of %s: reply did not contain valid XML\n",
- attr_name);
- return -pcmk_err_schema_validation;
+ rc = pcmk_rc_schema_validation;
+ g_set_error(&error, PCMK__RC_ERROR, rc,
+ "Could not query value of %s: reply did not contain valid XML",
+ attr_name);
+ return rc;
}
crm_log_xml_trace(reply, "Reply");
reply_attr = crm_element_value(reply, PCMK__XA_ATTR_NAME);
if (reply_attr == NULL) {
- fprintf(stderr, "Could not query value of %s: attribute does not exist\n",
- attr_name);
- return -ENXIO;
+ rc = ENXIO;
+ g_set_error(&error, PCMK__RC_ERROR, rc,
+ "Could not query value of %s: attribute does not exist",
+ attr_name);
+ return rc;
}
if (!pcmk__str_eq(crm_element_value(reply, F_TYPE), T_ATTRD, pcmk__str_casei)
|| (crm_element_value(reply, PCMK__XA_ATTR_VERSION) == NULL)
|| strcmp(reply_attr, attr_name)) {
- fprintf(stderr,
- "Could not query value of %s: reply did not contain expected identification\n",
- attr_name);
- return -pcmk_err_schema_validation;
+ rc = pcmk_rc_schema_validation;
+ g_set_error(&error, PCMK__RC_ERROR, rc,
+ "Could not query value of %s: reply did not contain expected identification",
+ attr_name);
+ return rc;
}
- return pcmk_ok;
+
+ return pcmk_rc_ok;
}
/*!
* \brief Print the attribute values in a pacemaker-attrd XML query reply
*
* \param[in] reply Root of XML tree with query reply
* \param[in] attr_name Name of attribute that was queried
*
- * \return TRUE if any values were printed
+ * \return true if any values were printed
*/
-static gboolean
+static bool
print_attrd_values(xmlNode *reply, const char *attr_name)
{
xmlNode *child;
const char *reply_host, *reply_value;
- gboolean have_values = FALSE;
+ bool have_values = false;
/* Iterate through reply's XML tags (a node tag for each host-value pair) */
for (child = pcmk__xml_first_child(reply); child != NULL;
child = pcmk__xml_next(child)) {
if (!pcmk__str_eq((const char *)child->name, XML_CIB_TAG_NODE,
pcmk__str_casei)) {
crm_warn("Ignoring unexpected %s tag in query reply", child->name);
} else {
reply_host = crm_element_value(child, PCMK__XA_ATTR_NODE_NAME);
reply_value = crm_element_value(child, PCMK__XA_ATTR_VALUE);
if (reply_host == NULL) {
crm_warn("Ignoring %s tag without %s attribute in query reply",
XML_CIB_TAG_NODE, PCMK__XA_ATTR_NODE_NAME);
} else {
printf("name=\"%s\" host=\"%s\" value=\"%s\"\n",
attr_name, reply_host, (reply_value? reply_value : ""));
- have_values = TRUE;
+ have_values = true;
}
}
}
+
return have_values;
}
/*!
* \brief Submit a query to pacemaker-attrd and print reply
*
* \param[in] attr_name Name of attribute to be affected by request
* \param[in] attr_node Name of host to query for (or NULL for localhost)
* \param[in] query_all If TRUE, ignore attr_node and query all nodes instead
*
- * \return pcmk_ok on success, -errno on error
+ * \return Standard Pacemaker return code
*/
static int
do_query(const char *attr_name, const char *attr_node, gboolean query_all)
{
xmlNode *reply = NULL;
- int rc;
+ int rc = pcmk_rc_ok;
/* Decide which node(s) to query */
if (query_all == TRUE) {
attr_node = NULL;
} else {
const char *target = pcmk__node_attr_target(attr_node);
if (target != NULL) {
attr_node = target;
}
}
/* Build and send pacemaker-attrd request, and get XML reply */
rc = send_attrd_query(attr_name, attr_node, &reply);
- if (rc != pcmk_ok) {
- fprintf(stderr, "Could not query value of %s: %s (%d)\n", attr_name, pcmk_strerror(rc), rc);
+ if (rc != pcmk_rc_ok) {
+ g_set_error(&error, PCMK__RC_ERROR, rc, "Could not query value of %s: %s (%d)",
+ attr_name, pcmk_strerror(rc), rc);
return rc;
}
/* Validate the XML reply */
rc = validate_attrd_reply(reply, attr_name);
- if (rc != pcmk_ok) {
+ if (rc != pcmk_rc_ok) {
if (reply != NULL) {
free_xml(reply);
}
return rc;
}
/* Print the values from the reply */
- if (print_attrd_values(reply, attr_name) == FALSE) {
- fprintf(stderr,
- "Could not query value of %s: reply had attribute name but no host values\n",
- attr_name);
+ if (!print_attrd_values(reply, attr_name)) {
+ g_set_error(&error, PCMK__RC_ERROR, rc,
+ "Could not query value of %s: reply had attribute name but no host values",
+ attr_name);
free_xml(reply);
- return -pcmk_err_schema_validation;
+ return pcmk_rc_schema_validation;
}
- return pcmk_ok;
+ return pcmk_rc_ok;
}
static int
do_update(char command, const char *attr_node, const char *attr_name,
const char *attr_value, const char *attr_section,
const char *attr_set, const char *attr_dampen, int attr_options)
{
int rc = pcmk__node_attr_request(NULL, command, attr_node, attr_name,
attr_value, attr_section, attr_set,
attr_dampen, NULL, attr_options);
if (rc != pcmk_rc_ok) {
- fprintf(stderr, "Could not update %s=%s: %s (%d)\n",
- attr_name, attr_value, pcmk_rc_str(rc), rc);
+ g_set_error(&error, PCMK__RC_ERROR, rc, "Could not update %s=%s: %s (%d)",
+ attr_name, attr_value, pcmk_rc_str(rc), rc);
}
return rc;
}

File Metadata

Mime Type
text/x-diff
Expires
Tue, Jul 8, 6:16 PM (16 h, 37 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2002556
Default Alt Text
(30 KB)

Event Timeline