Page MenuHomeClusterLabs Projects

No OneTemporary

diff --git a/include/crm/crm.h b/include/crm/crm.h
index dc2adc12c9..ce2074b63b 100644
--- a/include/crm/crm.h
+++ b/include/crm/crm.h
@@ -1,231 +1,231 @@
/*
* Copyright 2004-2020 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>
/*!
* The CRM feature set assists with compatibility in mixed-version clusters.
* The major version number increases when nodes with different versions
* would not work (rolling upgrades are not allowed). The minor version
* number increases when mixed-version clusters are allowed only during
* rolling upgrades (a node with the oldest feature set will be elected DC). The
* minor-minor version number is ignored, but allows resource agents to detect
* cluster support for various features.
*
* The feature set also affects the processing of old saved CIBs (such as for
* many scheduler regression tests).
*
* Particular feature points currently used by pacemaker:
*
* >2.1: Operation updates include timing data
* >=3.0.5: XML v2 digests are created
* >=3.0.8: Peers do not need acks for cancellations
* >=3.0.9: DC will send its own shutdown request to all peers
* XML v2 patchsets are created by default
* >=3.0.13: Fail counts include operation name and interval
* >=3.2.0: DC supports PCMK_LRM_OP_INVALID and PCMK_LRM_OP_NOT_CONNECTED
*/
-# define CRM_FEATURE_SET "3.4.0"
+# define CRM_FEATURE_SET "3.4.1"
# 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/tools/crmadmin.c b/tools/crmadmin.c
index 4688458988..2ebdd14588 100644
--- a/tools/crmadmin.c
+++ b/tools/crmadmin.c
@@ -1,473 +1,614 @@
/*
* Copyright 2004-2020 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 <stdbool.h>
#include <stdlib.h> // atoi()
#include <glib.h> // gboolean, GMainLoop, etc.
#include <libxml/tree.h> // xmlNode
#include <crm/crm.h>
#include <crm/cib.h>
#include <crm/msg_xml.h>
#include <crm/common/xml.h>
+#include <crm/common/iso8601.h>
#include <crm/common/ipc_controld.h>
+#include <crm/common/ipc_pacemakerd.h>
#include <crm/common/mainloop.h>
#define DEFAULT_MESSAGE_TIMEOUT_MS 30000
static guint message_timer_id = 0;
static guint message_timeout_ms = DEFAULT_MESSAGE_TIMEOUT_MS;
static GMainLoop *mainloop = NULL;
bool do_work(pcmk_ipc_api_t *api);
void do_find_node_list(xmlNode *xml_node);
+static char *ipc_name = NULL;
+
gboolean admin_message_timeout(gpointer data);
static enum {
cmd_none,
cmd_shutdown,
cmd_health,
cmd_elect_dc,
cmd_whois_dc,
cmd_list_nodes,
+ cmd_pacemakerd_health,
} command = cmd_none;
static gboolean BE_VERBOSE = FALSE;
static gboolean BASH_EXPORT = FALSE;
static gboolean BE_SILENT = FALSE;
static char *dest_node = NULL;
static crm_exit_t exit_code = CRM_EX_OK;
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
},
{
"quiet", no_argument, NULL, 'q',
"\tDisplay only the essential query information", pcmk__option_default
},
{
"verbose", no_argument, NULL, 'V',
"\tIncrease debug output", pcmk__option_default
},
{
"-spacer-", no_argument, NULL, '-',
"\nCommands:", pcmk__option_default
},
/* daemon options */
{
"status", required_argument, NULL, 'S',
"Display the status of the specified node.", pcmk__option_default
},
{
"-spacer-", no_argument, NULL, '-',
"\n\tResult is state of node's internal finite state machine, which "
"can be useful for debugging\n",
pcmk__option_default
},
+ {
+ "pacemakerd", no_argument, NULL, 'P',
+ "Display the status of local pacemakerd.", pcmk__option_default
+ },
+ {
+ "-spacer-", no_argument, NULL, '-',
+ "\n\tResult is the state of the sub-daemons watched by pacemakerd.\n",
+ pcmk__option_default
+ },
{
"dc_lookup", no_argument, NULL, 'D',
"Display the uname of the node co-ordinating the cluster.",
pcmk__option_default
},
{
"-spacer-", no_argument, NULL, '-',
"\n\tThis is an internal detail rarely useful to administrators "
"except when deciding on which node to examine the logs.\n",
pcmk__option_default
},
{
"nodes", no_argument, NULL, 'N',
"\tDisplay the uname of all member nodes", pcmk__option_default
},
{
"election", no_argument, NULL, 'E',
"(Advanced) Start an election for the cluster co-ordinator",
pcmk__option_default
},
{
"kill", required_argument, NULL, 'K',
"(Advanced) Stop controller (not rest of cluster stack) on "
"specified node", pcmk__option_default
},
{
"health", no_argument, NULL, 'H',
NULL, pcmk__option_hidden
},
{
"-spacer-", no_argument, NULL, '-',
"\nAdditional Options:", pcmk__option_default
},
{
XML_ATTR_TIMEOUT, required_argument, NULL, 't',
"Time (in milliseconds) to wait before declaring the operation failed",
pcmk__option_default
},
{
"bash-export", no_argument, NULL, 'B',
"Display nodes as shell commands of the form 'export uname=uuid' "
- "(valid with -N/--nodes)'\n",
+ "(valid with -N/--nodes)",
+ pcmk__option_default
+ },
+ {
+ "ipc-name", required_argument, NULL, 'i',
+ "Name to use for ipc instead of 'crmadmin' (with -P/--pacemakerd).",
pcmk__option_default
},
{
"-spacer-", no_argument, NULL, '-',
- "Notes:", pcmk__option_default
+ "\nNotes:", pcmk__option_default
},
{
"-spacer-", no_argument, NULL, '-',
- "The -K and -E commands do not work and may be removed in a future "
+ "\nThe -K and -E commands do not work and may be removed in a future "
"version.",
pcmk__option_default
},
{ 0, 0, 0, 0 }
};
static void
quit_main_loop(crm_exit_t ec)
{
exit_code = ec;
if (mainloop != NULL) {
GMainLoop *mloop = mainloop;
mainloop = NULL; // Don't re-enter this block
pcmk_quit_main_loop(mloop, 10);
g_main_loop_unref(mloop);
}
}
static void
controller_event_cb(pcmk_ipc_api_t *controld_api,
enum pcmk_ipc_event event_type, crm_exit_t status,
void *event_data, void *user_data)
{
pcmk_controld_api_reply_t *reply = event_data;
switch (event_type) {
case pcmk_ipc_event_disconnect:
if (exit_code == CRM_EX_DISCONNECT) { // Unexpected
fprintf(stderr, "error: Lost connection to controller\n");
}
goto done;
break;
case pcmk_ipc_event_reply:
break;
default:
return;
}
if (message_timer_id != 0) {
g_source_remove(message_timer_id);
message_timer_id = 0;
}
if (status != CRM_EX_OK) {
fprintf(stderr, "error: Bad reply from controller: %s",
crm_exit_str(status));
exit_code = status;
goto done;
}
if (reply->reply_type != pcmk_controld_reply_ping) {
fprintf(stderr, "error: Unknown reply type %d from controller\n",
reply->reply_type);
goto done;
}
// Parse desired information from reply
switch (command) {
case cmd_health:
printf("Status of %s@%s: %s (%s)\n",
reply->data.ping.sys_from,
reply->host_from,
reply->data.ping.fsa_state,
reply->data.ping.result);
if (BE_SILENT && (reply->data.ping.fsa_state != NULL)) {
fprintf(stderr, "%s\n", reply->data.ping.fsa_state);
}
exit_code = CRM_EX_OK;
break;
case cmd_whois_dc:
printf("Designated Controller is: %s\n", reply->host_from);
if (BE_SILENT && (reply->host_from != NULL)) {
fprintf(stderr, "%s\n", reply->host_from);
}
exit_code = CRM_EX_OK;
break;
default: // Not really possible here
exit_code = CRM_EX_SOFTWARE;
break;
}
done:
pcmk_disconnect_ipc(controld_api);
quit_main_loop(exit_code);
}
+static void
+pacemakerd_event_cb(pcmk_ipc_api_t *pacemakerd_api,
+ enum pcmk_ipc_event event_type, crm_exit_t status,
+ void *event_data, void *user_data)
+{
+ pcmk_pacemakerd_api_reply_t *reply = event_data;
+
+ switch (event_type) {
+ case pcmk_ipc_event_disconnect:
+ if (exit_code == CRM_EX_DISCONNECT) { // Unexpected
+ fprintf(stderr, "error: Lost connection to pacemakerd\n");
+ }
+ goto done;
+ break;
+
+ case pcmk_ipc_event_reply:
+ break;
+
+ default:
+ return;
+ }
+
+ if (message_timer_id != 0) {
+ g_source_remove(message_timer_id);
+ message_timer_id = 0;
+ }
+
+ if (status != CRM_EX_OK) {
+ fprintf(stderr, "error: Bad reply from pacemakerd: %s",
+ crm_exit_str(status));
+ exit_code = status;
+ goto done;
+ }
+
+ if (reply->reply_type != pcmk_pacemakerd_reply_ping) {
+ fprintf(stderr, "error: Unknown reply type %d from pacemakerd\n",
+ reply->reply_type);
+ goto done;
+ }
+
+ // Parse desired information from reply
+ switch (command) {
+ case cmd_pacemakerd_health:
+ {
+ crm_time_t *crm_when = crm_time_new(NULL);
+ char *pinged_buf = NULL;
+
+ crm_time_set_timet(crm_when, &reply->data.ping.last_good);
+ pinged_buf = crm_time_as_string(crm_when,
+ crm_time_log_date | crm_time_log_timeofday |
+ crm_time_log_with_timezone);
+
+ printf("Status of %s: '%s' %s %s\n",
+ reply->data.ping.sys_from,
+ (reply->data.ping.status == pcmk_rc_ok)?
+ pcmk_pacemakerd_api_daemon_state_enum2text(
+ reply->data.ping.state):"query failed",
+ (reply->data.ping.status == pcmk_rc_ok)?"last updated":"",
+ (reply->data.ping.status == pcmk_rc_ok)?pinged_buf:"");
+ if (BE_SILENT &&
+ (reply->data.ping.state != pcmk_pacemakerd_state_invalid)) {
+ fprintf(stderr, "%s\n",
+ (reply->data.ping.status == pcmk_rc_ok)?
+ pcmk_pacemakerd_api_daemon_state_enum2text(
+ reply->data.ping.state):
+ "query failed");
+ }
+ exit_code = CRM_EX_OK;
+ free(pinged_buf);
+ }
+ break;
+
+ default: // Not really possible here
+ exit_code = CRM_EX_SOFTWARE;
+ break;
+ }
+
+done:
+ pcmk_disconnect_ipc(pacemakerd_api);
+ quit_main_loop(exit_code);
+}
+
// \return Standard Pacemaker return code
static int
list_nodes()
{
cib_t *the_cib = cib_new();
xmlNode *output = NULL;
int rc;
if (the_cib == NULL) {
return ENOMEM;
}
rc = the_cib->cmds->signon(the_cib, crm_system_name, cib_command);
if (rc != pcmk_ok) {
return pcmk_legacy2rc(rc);
}
rc = the_cib->cmds->query(the_cib, NULL, &output,
cib_scope_local | cib_sync_call);
if (rc == pcmk_ok) {
do_find_node_list(output);
free_xml(output);
}
the_cib->cmds->signoff(the_cib);
return pcmk_legacy2rc(rc);
}
int
main(int argc, char **argv)
{
int option_index = 0;
int argerr = 0;
int flag;
int rc;
pcmk_ipc_api_t *controld_api = NULL;
+ pcmk_ipc_api_t *pacemakerd_api = NULL;
bool need_controld_api = true;
+ bool need_pacemakerd_api = false;
crm_log_cli_init("crmadmin");
pcmk__set_cli_options(NULL, "<command> [options]", long_options,
"query and manage the Pacemaker controller");
if (argc < 2) {
pcmk__cli_help('?', CRM_EX_USAGE);
}
while (1) {
flag = pcmk__next_cli_option(argc, argv, &option_index, NULL);
if (flag == -1)
break;
switch (flag) {
case 'V':
BE_VERBOSE = TRUE;
crm_bump_log_level(argc, argv);
break;
case 't':
message_timeout_ms = (guint) atoi(optarg);
if (message_timeout_ms < 1) {
message_timeout_ms = DEFAULT_MESSAGE_TIMEOUT_MS;
}
break;
-
+ case 'i':
+ ipc_name = strdup(optarg);
+ break;
case '$':
case '?':
pcmk__cli_help(flag, CRM_EX_OK);
break;
case 'D':
command = cmd_whois_dc;
break;
case 'B':
BASH_EXPORT = TRUE;
break;
case 'K':
command = cmd_shutdown;
crm_trace("Option %c => %s", flag, optarg);
if (dest_node != NULL) {
free(dest_node);
}
dest_node = strdup(optarg);
break;
case 'q':
BE_SILENT = TRUE;
break;
+ case 'P':
+ command = cmd_pacemakerd_health;
+ need_pacemakerd_api = true;
+ need_controld_api = false;
+ break;
case 'S':
command = cmd_health;
crm_trace("Option %c => %s", flag, optarg);
if (dest_node != NULL) {
free(dest_node);
}
dest_node = strdup(optarg);
break;
case 'E':
command = cmd_elect_dc;
break;
case 'N':
command = cmd_list_nodes;
need_controld_api = false;
break;
case 'H':
fprintf(stderr, "Cluster-wide health option not supported\n");
++argerr;
break;
default:
printf("Argument code 0%o (%c) is not (?yet?) supported\n", flag, flag);
++argerr;
break;
}
}
if (optind < argc) {
printf("non-option ARGV-elements: ");
while (optind < argc)
printf("%s ", argv[optind++]);
printf("\n");
}
if (optind > argc) {
++argerr;
}
if (command == cmd_none) {
fprintf(stderr, "error: Must specify a command option\n\n");
++argerr;
}
if (argerr) {
pcmk__cli_help('?', CRM_EX_USAGE);
}
// Connect to the controller if needed
if (need_controld_api) {
rc = pcmk_new_ipc_api(&controld_api, pcmk_ipc_controld);
if (controld_api == NULL) {
fprintf(stderr, "error: Could not connect to controller: %s\n",
pcmk_rc_str(rc));
exit_code = pcmk_rc2exitc(rc);
goto done;
}
pcmk_register_ipc_callback(controld_api, controller_event_cb, NULL);
rc = pcmk_connect_ipc(controld_api, pcmk_ipc_dispatch_main);
if (rc != pcmk_rc_ok) {
fprintf(stderr, "error: Could not connect to controller: %s\n",
pcmk_rc_str(rc));
exit_code = pcmk_rc2exitc(rc);
goto done;
}
}
- if (do_work(controld_api)) {
+ // Connect to pacemakerd if needed
+ if (need_pacemakerd_api) {
+ rc = pcmk_new_ipc_api(&pacemakerd_api, pcmk_ipc_pacemakerd);
+ if (pacemakerd_api == NULL) {
+ fprintf(stderr, "error: Could not connect to pacemakerd: %s\n",
+ pcmk_rc_str(rc));
+ exit_code = pcmk_rc2exitc(rc);
+ goto done;
+ }
+ pcmk_register_ipc_callback(pacemakerd_api, pacemakerd_event_cb, NULL);
+ rc = pcmk_connect_ipc(pacemakerd_api, pcmk_ipc_dispatch_main);
+ if (rc != pcmk_rc_ok) {
+ fprintf(stderr, "error: Could not connect to pacemakerd: %s\n",
+ pcmk_rc_str(rc));
+ exit_code = pcmk_rc2exitc(rc);
+ goto done;
+ }
+ }
+
+ if (do_work(controld_api?controld_api:pacemakerd_api)) {
// A reply is needed from controller, so run main loop to get it
exit_code = CRM_EX_DISCONNECT; // For unexpected disconnects
mainloop = g_main_loop_new(NULL, FALSE);
message_timer_id = g_timeout_add(message_timeout_ms,
admin_message_timeout, NULL);
g_main_loop_run(mainloop);
}
done:
+
if (controld_api != NULL) {
pcmk_ipc_api_t *capi = controld_api;
-
controld_api = NULL; // Ensure we can't free this twice
pcmk_free_ipc_api(capi);
}
+
+ if (pacemakerd_api != NULL) {
+ pcmk_ipc_api_t *capi = pacemakerd_api;
+ pacemakerd_api = NULL; // Ensure we can't free this twice
+ pcmk_free_ipc_api(capi);
+ }
+
if (mainloop != NULL) {
g_main_loop_unref(mainloop);
mainloop = NULL;
}
return crm_exit(exit_code);
}
// \return True if reply from controller is needed
bool
-do_work(pcmk_ipc_api_t *controld_api)
+do_work(pcmk_ipc_api_t *api)
{
bool need_reply = false;
int rc = pcmk_rc_ok;
switch (command) {
case cmd_shutdown:
- rc = pcmk_controld_api_shutdown(controld_api, dest_node);
+ rc = pcmk_controld_api_shutdown(api, dest_node);
break;
case cmd_health: // dest_node != NULL
case cmd_whois_dc: // dest_node == NULL
- rc = pcmk_controld_api_ping(controld_api, dest_node);
+ rc = pcmk_controld_api_ping(api, dest_node);
need_reply = true;
break;
case cmd_elect_dc:
- rc = pcmk_controld_api_start_election(controld_api);
+ rc = pcmk_controld_api_start_election(api);
break;
case cmd_list_nodes:
rc = list_nodes();
break;
+ case cmd_pacemakerd_health:
+ rc = pcmk_pacemakerd_api_ping(api, ipc_name);
+ need_reply = true;
+ break;
+
case cmd_none: // not actually possible here
break;
}
if (rc != pcmk_rc_ok) {
fprintf(stderr, "error: Command failed: %s", pcmk_rc_str(rc));
exit_code = pcmk_rc2exitc(rc);
}
return need_reply;
}
gboolean
admin_message_timeout(gpointer data)
{
fprintf(stderr,
"error: No reply received from controller before timeout (%dms)\n",
message_timeout_ms);
message_timer_id = 0;
quit_main_loop(CRM_EX_TIMEOUT);
return FALSE; // Tells glib to remove source
}
void
do_find_node_list(xmlNode * xml_node)
{
int found = 0;
xmlNode *node = NULL;
xmlNode *nodes = get_object_root(XML_CIB_TAG_NODES, xml_node);
for (node = first_named_child(nodes, XML_CIB_TAG_NODE); node != NULL;
node = crm_next_same_xml(node)) {
if (BASH_EXPORT) {
printf("export %s=%s\n",
crm_element_value(node, XML_ATTR_UNAME),
crm_element_value(node, XML_ATTR_ID));
} else {
const char *node_type = crm_element_value(node, XML_ATTR_TYPE);
if (node_type == NULL) {
node_type = "member";
}
printf("%s node: %s (%s)\n", node_type,
crm_element_value(node, XML_ATTR_UNAME),
crm_element_value(node, XML_ATTR_ID));
}
found++;
}
// @TODO List Pacemaker Remote nodes that don't have a <node> entry
if (found == 0) {
printf("No nodes configured\n");
}
}

File Metadata

Mime Type
text/x-diff
Expires
Sat, Nov 23, 7:00 AM (1 d, 14 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1018372
Default Alt Text
(26 KB)

Event Timeline