Page Menu
Home
ClusterLabs Projects
Search
Configure Global Search
Log In
Files
F1841686
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
26 KB
Referenced Files
None
Subscribers
None
View Options
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
Details
Attached
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)
Attached To
Mode
rP Pacemaker
Attached
Detach File
Event Timeline
Log In to Comment