diff --git a/tools/attrd.c b/tools/attrd.c index 67ca072c6a..83e029efa9 100644 --- a/tools/attrd.c +++ b/tools/attrd.c @@ -1,894 +1,891 @@ /* * Copyright (C) 2004 Andrew Beekhof * * 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 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 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 */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define OPTARGS "hV" #if SUPPORT_HEARTBEAT -ll_cluster_t *attrd_cluster_conn; +ll_cluster_t *attrd_cluster_conn; #endif -GMainLoop* mainloop = NULL; +GMainLoop *mainloop = NULL; char *attrd_uname = NULL; char *attrd_uuid = NULL; gboolean need_shutdown = FALSE; GHashTable *attr_hash = NULL; cib_t *cib_conn = NULL; -typedef struct attr_hash_entry_s -{ - char *uuid; - char *id; - char *set; - char *section; +typedef struct attr_hash_entry_s { + char *uuid; + char *id; + char *set; + char *section; - char *value; - char *stored_value; + char *value; + char *stored_value; - int timeout; - char *dampen; - guint timer_id; + int timeout; + char *dampen; + guint timer_id; - char *user; - -} attr_hash_entry_t; + char *user; +} attr_hash_entry_t; static void free_hash_entry(gpointer data) { - attr_hash_entry_t *entry = data; - if (entry == NULL) { - return; - } - crm_free(entry->id); - crm_free(entry->set); - crm_free(entry->dampen); - crm_free(entry->section); - crm_free(entry->uuid); - crm_free(entry->value); - crm_free(entry->stored_value); - crm_free(entry->user); - crm_free(entry); + attr_hash_entry_t *entry = data; + + if (entry == NULL) { + return; + } + crm_free(entry->id); + crm_free(entry->set); + crm_free(entry->dampen); + crm_free(entry->section); + crm_free(entry->uuid); + crm_free(entry->value); + crm_free(entry->stored_value); + crm_free(entry->user); + crm_free(entry); } void attrd_local_callback(xmlNode * msg); gboolean attrd_timer_callback(void *user_data); -gboolean attrd_trigger_update(attr_hash_entry_t *hash_entry); -void attrd_perform_update(attr_hash_entry_t *hash_entry); +gboolean attrd_trigger_update(attr_hash_entry_t * hash_entry); +void attrd_perform_update(attr_hash_entry_t * hash_entry); static void attrd_shutdown(int nsig) { - need_shutdown = TRUE; - crm_info("Exiting"); - if (mainloop != NULL && g_main_is_running(mainloop)) { - g_main_quit(mainloop); - } else { - exit(0); - } + need_shutdown = TRUE; + crm_info("Exiting"); + if (mainloop != NULL && g_main_is_running(mainloop)) { + g_main_quit(mainloop); + } else { + exit(0); + } } static void -usage(const char* cmd, int exit_status) +usage(const char *cmd, int exit_status) { - FILE* stream; + FILE *stream; - stream = exit_status ? stderr : stdout; + stream = exit_status ? stderr : stdout; - fprintf(stream, "usage: %s [-srkh] [-c configure file]\n", cmd); + fprintf(stream, "usage: %s [-srkh] [-c configure file]\n", cmd); /* fprintf(stream, "\t-d\tsets debug level\n"); */ /* fprintf(stream, "\t-s\tgets daemon status\n"); */ /* fprintf(stream, "\t-r\trestarts daemon\n"); */ /* fprintf(stream, "\t-k\tstops daemon\n"); */ /* fprintf(stream, "\t-h\thelp message\n"); */ - fflush(stream); + fflush(stream); - exit(exit_status); + exit(exit_status); } -typedef struct attrd_client_s -{ - char *id; - char *name; - char *user; - - IPC_Channel *channel; - GCHSource *source; +typedef struct attrd_client_s { + char *id; + char *name; + char *user; + + IPC_Channel *channel; + GCHSource *source; } attrd_client_t; static void -stop_attrd_timer(attr_hash_entry_t *hash_entry) +stop_attrd_timer(attr_hash_entry_t * hash_entry) { - if(hash_entry != NULL && hash_entry->timer_id != 0) { - crm_debug_2("Stopping %s timer", hash_entry->id); - g_source_remove(hash_entry->timer_id); - hash_entry->timer_id = 0; - } + if (hash_entry != NULL && hash_entry->timer_id != 0) { + crm_debug_2("Stopping %s timer", hash_entry->id); + g_source_remove(hash_entry->timer_id); + hash_entry->timer_id = 0; + } } static gboolean -attrd_ipc_callback(IPC_Channel *client, gpointer user_data) +attrd_ipc_callback(IPC_Channel * client, gpointer user_data) { - int lpc = 0; - xmlNode *msg = NULL; - attrd_client_t *curr_client = (attrd_client_t*)user_data; - gboolean stay_connected = TRUE; - - crm_debug_2("Invoked: %s", curr_client->id); - - while(IPC_ISRCONN(client)) { - if(client->ops->is_message_pending(client) == 0) { - break; - } - - msg = xmlfromIPC(client, MAX_IPC_DELAY); - if (msg == NULL) { - break; - } - - lpc++; - + int lpc = 0; + xmlNode *msg = NULL; + attrd_client_t *curr_client = (attrd_client_t *) user_data; + gboolean stay_connected = TRUE; + + crm_debug_2("Invoked: %s", curr_client->id); + + while (IPC_ISRCONN(client)) { + if (client->ops->is_message_pending(client) == 0) { + break; + } + + msg = xmlfromIPC(client, MAX_IPC_DELAY); + if (msg == NULL) { + break; + } + + lpc++; + #if ENABLE_ACL - determine_request_user(&curr_client->user, client, msg, F_ATTRD_USER); + determine_request_user(&curr_client->user, client, msg, F_ATTRD_USER); #endif - crm_debug_2("Processing msg from %s", curr_client->id); - crm_log_xml(LOG_DEBUG_3, __PRETTY_FUNCTION__, msg); - - attrd_local_callback(msg); - - free_xml(msg); - msg = NULL; - - if(client->ch_status != IPC_CONNECT) { - break; - } - } - - crm_debug_2("Processed %d messages", lpc); - if (client->ch_status != IPC_CONNECT) { - stay_connected = FALSE; - } - - return stay_connected; + crm_debug_2("Processing msg from %s", curr_client->id); + crm_log_xml(LOG_DEBUG_3, __PRETTY_FUNCTION__, msg); + + attrd_local_callback(msg); + + free_xml(msg); + msg = NULL; + + if (client->ch_status != IPC_CONNECT) { + break; + } + } + + crm_debug_2("Processed %d messages", lpc); + if (client->ch_status != IPC_CONNECT) { + stay_connected = FALSE; + } + + return stay_connected; } static void attrd_connection_destroy(gpointer user_data) { - attrd_client_t *client = user_data; - - /* cib_process_disconnect */ - - if(client == NULL) { - return; - } - - if(client->source != NULL) { - crm_debug_4("Deleting %s (%p) from mainloop", - client->name, client->source); - G_main_del_IPC_Channel(client->source); - client->source = NULL; - } - - crm_debug_3("Destroying %s (%p)", client->name, client); - crm_free(client->name); - crm_free(client->id); - crm_free(client->user); - crm_free(client); - crm_debug_4("Freed the cib client"); - - return; + attrd_client_t *client = user_data; + + /* cib_process_disconnect */ + + if (client == NULL) { + return; + } + + if (client->source != NULL) { + crm_debug_4("Deleting %s (%p) from mainloop", client->name, client->source); + G_main_del_IPC_Channel(client->source); + client->source = NULL; + } + + crm_debug_3("Destroying %s (%p)", client->name, client); + crm_free(client->name); + crm_free(client->id); + crm_free(client->user); + crm_free(client); + crm_debug_4("Freed the cib client"); + + return; } static gboolean -attrd_connect(IPC_Channel *channel, gpointer user_data) +attrd_connect(IPC_Channel * channel, gpointer user_data) { - attrd_client_t *new_client = NULL; - crm_debug_3("Connecting channel"); - - if(channel == NULL) { - crm_err("Channel was NULL"); - return FALSE; - - } else if(channel->ch_status != IPC_CONNECT) { - crm_err("Channel was disconnected"); - return FALSE; - } else if(need_shutdown) { - crm_info("Ignoring connection request during shutdown"); - return FALSE; - } - - - crm_malloc0(new_client, sizeof(attrd_client_t)); - new_client->channel = channel; - - crm_debug_3("Created channel %p for channel %s", - new_client, new_client->id); - + attrd_client_t *new_client = NULL; + + crm_debug_3("Connecting channel"); + + if (channel == NULL) { + crm_err("Channel was NULL"); + return FALSE; + + } else if (channel->ch_status != IPC_CONNECT) { + crm_err("Channel was disconnected"); + return FALSE; + } else if (need_shutdown) { + crm_info("Ignoring connection request during shutdown"); + return FALSE; + } + + crm_malloc0(new_client, sizeof(attrd_client_t)); + new_client->channel = channel; + + crm_debug_3("Created channel %p for channel %s", new_client, new_client->id); + /* channel->ops->set_recv_qlen(channel, 100); */ /* channel->ops->set_send_qlen(channel, 400); */ - - new_client->source = G_main_add_IPC_Channel( - G_PRIORITY_DEFAULT, channel, FALSE, attrd_ipc_callback, - new_client, attrd_connection_destroy); - - crm_debug_3("Client %s connected", new_client->id); - - return TRUE; + + new_client->source = + G_main_add_IPC_Channel(G_PRIORITY_DEFAULT, channel, FALSE, attrd_ipc_callback, new_client, + attrd_connection_destroy); + + crm_debug_3("Client %s connected", new_client->id); + + return TRUE; } static void -log_hash_entry(int level, attr_hash_entry_t *entry, const char *text) +log_hash_entry(int level, attr_hash_entry_t * entry, const char *text) { - do_crm_log(level, "%s", text); - do_crm_log(level, "Set: %s", entry->section); - do_crm_log(level, "Name: %s", entry->id); - do_crm_log(level, "Value: %s", entry->value); - do_crm_log(level, "Timeout: %s", entry->dampen); + do_crm_log(level, "%s", text); + do_crm_log(level, "Set: %s", entry->section); + do_crm_log(level, "Name: %s", entry->id); + do_crm_log(level, "Value: %s", entry->value); + do_crm_log(level, "Timeout: %s", entry->dampen); } static attr_hash_entry_t * -find_hash_entry(xmlNode * msg) +find_hash_entry(xmlNode * msg) { - const char *value = NULL; - const char *attr = crm_element_value(msg, F_ATTRD_ATTRIBUTE); - attr_hash_entry_t *hash_entry = NULL; - - if(attr == NULL) { - crm_info("Ignoring message with no attribute name"); - return NULL; - } - - hash_entry = g_hash_table_lookup(attr_hash, attr); - - if(hash_entry == NULL) { - /* create one and add it */ - crm_info("Creating hash entry for %s", attr); - crm_malloc0(hash_entry, sizeof(attr_hash_entry_t)); - hash_entry->id = crm_strdup(attr); - - g_hash_table_insert(attr_hash, hash_entry->id, hash_entry); - hash_entry = g_hash_table_lookup(attr_hash, attr); - CRM_CHECK(hash_entry != NULL, return NULL); - } - - value = crm_element_value(msg, F_ATTRD_SET); - if(value != NULL) { - crm_free(hash_entry->set); - hash_entry->set = crm_strdup(value); - crm_debug("\t%s->set: %s", attr, value); - } - - value = crm_element_value(msg, F_ATTRD_SECTION); - if(value == NULL) { - value = XML_CIB_TAG_STATUS; - } - crm_free(hash_entry->section); - hash_entry->section = crm_strdup(value); - crm_debug_2("\t%s->section: %s", attr, value); - - value = crm_element_value(msg, F_ATTRD_DAMPEN); - if(value != NULL) { - crm_free(hash_entry->dampen); - hash_entry->dampen = crm_strdup(value); - - hash_entry->timeout = crm_get_msec(value); - crm_debug_2("\t%s->timeout: %s", attr, value); - } + const char *value = NULL; + const char *attr = crm_element_value(msg, F_ATTRD_ATTRIBUTE); + attr_hash_entry_t *hash_entry = NULL; + + if (attr == NULL) { + crm_info("Ignoring message with no attribute name"); + return NULL; + } + hash_entry = g_hash_table_lookup(attr_hash, attr); + + if (hash_entry == NULL) { + /* create one and add it */ + crm_info("Creating hash entry for %s", attr); + crm_malloc0(hash_entry, sizeof(attr_hash_entry_t)); + hash_entry->id = crm_strdup(attr); + + g_hash_table_insert(attr_hash, hash_entry->id, hash_entry); + hash_entry = g_hash_table_lookup(attr_hash, attr); + CRM_CHECK(hash_entry != NULL, return NULL); + } + + value = crm_element_value(msg, F_ATTRD_SET); + if (value != NULL) { + crm_free(hash_entry->set); + hash_entry->set = crm_strdup(value); + crm_debug("\t%s->set: %s", attr, value); + } + + value = crm_element_value(msg, F_ATTRD_SECTION); + if (value == NULL) { + value = XML_CIB_TAG_STATUS; + } + crm_free(hash_entry->section); + hash_entry->section = crm_strdup(value); + crm_debug_2("\t%s->section: %s", attr, value); + + value = crm_element_value(msg, F_ATTRD_DAMPEN); + if (value != NULL) { + crm_free(hash_entry->dampen); + hash_entry->dampen = crm_strdup(value); + + hash_entry->timeout = crm_get_msec(value); + crm_debug_2("\t%s->timeout: %s", attr, value); + } #if ENABLE_ACL - crm_free(hash_entry->user); + crm_free(hash_entry->user); - value = crm_element_value(msg, F_ATTRD_USER); - if(value != NULL) { - hash_entry->user = crm_strdup(value); - crm_debug_2("\t%s->user: %s", attr, value); - } + value = crm_element_value(msg, F_ATTRD_USER); + if (value != NULL) { + hash_entry->user = crm_strdup(value); + crm_debug_2("\t%s->user: %s", attr, value); + } #endif - log_hash_entry(LOG_DEBUG_2, hash_entry, "Found (and updated) entry:"); - return hash_entry; + log_hash_entry(LOG_DEBUG_2, hash_entry, "Found (and updated) entry:"); + return hash_entry; } #if SUPPORT_HEARTBEAT static void attrd_ha_connection_destroy(gpointer user_data) { - crm_debug_3("Invoked"); - if(need_shutdown) { - /* we signed out, so this is expected */ - crm_info("Heartbeat disconnection complete"); - return; - } - - crm_crit("Lost connection to heartbeat service!"); - if (mainloop != NULL && g_main_is_running(mainloop)) { - g_main_quit(mainloop); - return; - } - exit(LSB_EXIT_OK); + crm_debug_3("Invoked"); + if (need_shutdown) { + /* we signed out, so this is expected */ + crm_info("Heartbeat disconnection complete"); + return; + } + + crm_crit("Lost connection to heartbeat service!"); + if (mainloop != NULL && g_main_is_running(mainloop)) { + g_main_quit(mainloop); + return; + } + exit(LSB_EXIT_OK); } static void -attrd_ha_callback(HA_Message *msg, void* private_data) +attrd_ha_callback(HA_Message * msg, void *private_data) { - attr_hash_entry_t *hash_entry = NULL; - xmlNode *xml = convert_ha_message(NULL, msg, __FUNCTION__); - const char *from = crm_element_value(xml, F_ORIG); - const char *op = crm_element_value(xml, F_ATTRD_TASK); - const char *host = crm_element_value(xml, F_ATTRD_HOST); - const char *ignore = crm_element_value(xml, F_ATTRD_IGNORE_LOCALLY); - - if(host != NULL && safe_str_eq(host, attrd_uname)) { - crm_info("Update relayed from %s", from); - attrd_local_callback(xml); - - } else if(ignore == NULL || safe_str_neq(from, attrd_uname)) { - crm_info("%s message from %s", op, from); - hash_entry = find_hash_entry(xml); - stop_attrd_timer(hash_entry); - attrd_perform_update(hash_entry); - } - free_xml(xml); + attr_hash_entry_t *hash_entry = NULL; + xmlNode *xml = convert_ha_message(NULL, msg, __FUNCTION__); + const char *from = crm_element_value(xml, F_ORIG); + const char *op = crm_element_value(xml, F_ATTRD_TASK); + const char *host = crm_element_value(xml, F_ATTRD_HOST); + const char *ignore = crm_element_value(xml, F_ATTRD_IGNORE_LOCALLY); + + if (host != NULL && safe_str_eq(host, attrd_uname)) { + crm_info("Update relayed from %s", from); + attrd_local_callback(xml); + + } else if (ignore == NULL || safe_str_neq(from, attrd_uname)) { + crm_info("%s message from %s", op, from); + hash_entry = find_hash_entry(xml); + stop_attrd_timer(hash_entry); + attrd_perform_update(hash_entry); + } + free_xml(xml); } #endif #if SUPPORT_COROSYNC static gboolean -attrd_ais_dispatch(AIS_Message *wrapper, char *data, int sender) +attrd_ais_dispatch(AIS_Message * wrapper, char *data, int sender) { xmlNode *xml = NULL; - if(wrapper->header.id == crm_class_cluster) { - xml = string2xml(data); - if(xml == NULL) { - crm_err("Bad message received: %d:'%.120s'", wrapper->id, data); - } - } - - if(xml != NULL) { - attr_hash_entry_t *hash_entry = NULL; - const char *op = crm_element_value(xml, F_ATTRD_TASK); - const char *host = crm_element_value(xml, F_ATTRD_HOST); - const char *ignore = crm_element_value(xml, F_ATTRD_IGNORE_LOCALLY); - - crm_xml_add_int(xml, F_SEQ, wrapper->id); - crm_xml_add(xml, F_ORIG, wrapper->sender.uname); - - if(host != NULL && safe_str_eq(host, attrd_uname)) { - crm_notice("Update relayed from %s", wrapper->sender.uname); - attrd_local_callback(xml); - - } else if(ignore == NULL || safe_str_neq(wrapper->sender.uname, attrd_uname)) { - crm_debug_2("%s message from %s", op, wrapper->sender.uname); - hash_entry = find_hash_entry(xml); - stop_attrd_timer(hash_entry); - attrd_perform_update(hash_entry); - } - - free_xml(xml); - } - + if (wrapper->header.id == crm_class_cluster) { + xml = string2xml(data); + if (xml == NULL) { + crm_err("Bad message received: %d:'%.120s'", wrapper->id, data); + } + } + + if (xml != NULL) { + attr_hash_entry_t *hash_entry = NULL; + const char *op = crm_element_value(xml, F_ATTRD_TASK); + const char *host = crm_element_value(xml, F_ATTRD_HOST); + const char *ignore = crm_element_value(xml, F_ATTRD_IGNORE_LOCALLY); + + crm_xml_add_int(xml, F_SEQ, wrapper->id); + crm_xml_add(xml, F_ORIG, wrapper->sender.uname); + + if (host != NULL && safe_str_eq(host, attrd_uname)) { + crm_notice("Update relayed from %s", wrapper->sender.uname); + attrd_local_callback(xml); + + } else if (ignore == NULL || safe_str_neq(wrapper->sender.uname, attrd_uname)) { + crm_debug_2("%s message from %s", op, wrapper->sender.uname); + hash_entry = find_hash_entry(xml); + stop_attrd_timer(hash_entry); + attrd_perform_update(hash_entry); + } + + free_xml(xml); + } + return TRUE; } static void attrd_ais_destroy(gpointer unused) { ais_fd_sync = -1; - if(need_shutdown) { - /* we signed out, so this is expected */ - crm_info("OpenAIS disconnection complete"); - return; + if (need_shutdown) { + /* we signed out, so this is expected */ + crm_info("OpenAIS disconnection complete"); + return; } - + crm_crit("Lost connection to OpenAIS service!"); if (mainloop != NULL && g_main_is_running(mainloop)) { - g_main_quit(mainloop); - return; + g_main_quit(mainloop); + return; } exit(LSB_EXIT_GENERIC); } #endif static void attrd_cib_connection_destroy(gpointer user_data) { - if(need_shutdown) { - crm_info("Connection to the CIB terminated..."); - - } else { - /* eventually this will trigger a reconnect, not a shutdown */ - crm_err("Connection to the CIB terminated..."); - exit(1); - } - - return; + if (need_shutdown) { + crm_info("Connection to the CIB terminated..."); + + } else { + /* eventually this will trigger a reconnect, not a shutdown */ + crm_err("Connection to the CIB terminated..."); + exit(1); + } + + return; } static void update_for_hash_entry(gpointer key, gpointer value, gpointer user_data) { attr_hash_entry_t *entry = value; - if(entry->value != NULL) { - attrd_timer_callback(value); + + if (entry->value != NULL) { + attrd_timer_callback(value); } } static void -do_cib_replaced(const char *event, xmlNode *msg) +do_cib_replaced(const char *event, xmlNode * msg) { crm_info("Sending full refresh"); g_hash_table_foreach(attr_hash, update_for_hash_entry, NULL); } static gboolean -cib_connect(void *user_data) +cib_connect(void *user_data) { static int attempts = 1; static int max_retry = 20; gboolean was_err = FALSE; static cib_t *local_conn = NULL; - - if(local_conn == NULL) { - local_conn = cib_new(); + + if (local_conn == NULL) { + local_conn = cib_new(); } - - if(was_err == FALSE) { - enum cib_errors rc = cib_not_connected; - if(attempts < max_retry) { - crm_debug("CIB signon attempt %d", attempts); - rc = local_conn->cmds->signon(local_conn, T_ATTRD, cib_command); - } + if (was_err == FALSE) { + enum cib_errors rc = cib_not_connected; - if(rc != cib_ok && attempts > max_retry) { - crm_err("Signon to CIB failed: %s", cib_error2string(rc)); - was_err = TRUE; + if (attempts < max_retry) { + crm_debug("CIB signon attempt %d", attempts); + rc = local_conn->cmds->signon(local_conn, T_ATTRD, cib_command); + } - } else if(rc != cib_ok) { - attempts++; - return TRUE; - } + if (rc != cib_ok && attempts > max_retry) { + crm_err("Signon to CIB failed: %s", cib_error2string(rc)); + was_err = TRUE; + + } else if (rc != cib_ok) { + attempts++; + return TRUE; + } } crm_info("Connected to the CIB after %d signon attempts", attempts); - - if(was_err == FALSE) { - enum cib_errors rc = local_conn->cmds->set_connection_dnotify( - local_conn, attrd_cib_connection_destroy); - if(rc != cib_ok) { - crm_err("Could not set dnotify callback"); - was_err = TRUE; - } + + if (was_err == FALSE) { + enum cib_errors rc = + local_conn->cmds->set_connection_dnotify(local_conn, attrd_cib_connection_destroy); + if (rc != cib_ok) { + crm_err("Could not set dnotify callback"); + was_err = TRUE; + } } - if(was_err == FALSE) { - if(cib_ok != local_conn->cmds->add_notify_callback( - local_conn, T_CIB_REPLACE_NOTIFY, do_cib_replaced)) { - crm_err("Could not set CIB notification callback"); - was_err = TRUE; - } + if (was_err == FALSE) { + if (cib_ok != + local_conn->cmds->add_notify_callback(local_conn, T_CIB_REPLACE_NOTIFY, + do_cib_replaced)) { + crm_err("Could not set CIB notification callback"); + was_err = TRUE; + } } - if(was_err) { - crm_err("Aborting startup"); - exit(100); + if (was_err) { + crm_err("Aborting startup"); + exit(100); } cib_conn = local_conn; - + crm_info("Sending full refresh"); g_hash_table_foreach(attr_hash, update_for_hash_entry, NULL); - + return FALSE; } - int -main(int argc, char ** argv) +main(int argc, char **argv) { - int flag = 0; - int argerr = 0; - gboolean was_err = FALSE; - char *channel_name = crm_strdup(T_ATTRD); - - crm_log_init(T_ATTRD, LOG_NOTICE, TRUE, FALSE, argc, argv); - mainloop_add_signal(SIGTERM, attrd_shutdown); - - while ((flag = getopt(argc, argv, OPTARGS)) != EOF) { - switch(flag) { - case 'V': - cl_log_enable_stderr(1); - alter_debug(DEBUG_INC); - break; - case 'h': /* Help message */ - usage(T_ATTRD, LSB_EXIT_OK); - break; - default: - ++argerr; - break; - } - } - - if (optind > argc) { - ++argerr; - } - - if (argerr) { - usage(T_ATTRD, LSB_EXIT_GENERIC); - } - - attr_hash = g_hash_table_new_full( - crm_str_hash, g_str_equal, NULL, free_hash_entry); - - crm_info("Starting up"); - - if(was_err == FALSE) { - void *destroy = NULL; - void *dispatch = NULL; - void *data = NULL; - + int flag = 0; + int argerr = 0; + gboolean was_err = FALSE; + char *channel_name = crm_strdup(T_ATTRD); + + crm_log_init(T_ATTRD, LOG_NOTICE, TRUE, FALSE, argc, argv); + mainloop_add_signal(SIGTERM, attrd_shutdown); + + while ((flag = getopt(argc, argv, OPTARGS)) != EOF) { + switch (flag) { + case 'V': + cl_log_enable_stderr(1); + alter_debug(DEBUG_INC); + break; + case 'h': /* Help message */ + usage(T_ATTRD, LSB_EXIT_OK); + break; + default: + ++argerr; + break; + } + } + + if (optind > argc) { + ++argerr; + } + + if (argerr) { + usage(T_ATTRD, LSB_EXIT_GENERIC); + } + + attr_hash = g_hash_table_new_full(crm_str_hash, g_str_equal, NULL, free_hash_entry); + + crm_info("Starting up"); + + if (was_err == FALSE) { + void *destroy = NULL; + void *dispatch = NULL; + void *data = NULL; + #if SUPPORT_COROSYNC - if(is_openais_cluster()) { - destroy = attrd_ais_destroy; - dispatch = attrd_ais_dispatch; - } + if (is_openais_cluster()) { + destroy = attrd_ais_destroy; + dispatch = attrd_ais_dispatch; + } #endif - + #if SUPPORT_HEARTBEAT - if(is_heartbeat_cluster()) { - data = &attrd_cluster_conn; - dispatch = attrd_ha_callback; - destroy = attrd_ha_connection_destroy; - } + if (is_heartbeat_cluster()) { + data = &attrd_cluster_conn; + dispatch = attrd_ha_callback; + destroy = attrd_ha_connection_destroy; + } #endif - - if(FALSE == crm_cluster_connect( - &attrd_uname, &attrd_uuid, dispatch, destroy, data)) { - crm_err("HA Signon failed"); - was_err = TRUE; - } - } - - crm_info("Cluster connection active"); - - if(was_err == FALSE) { - int rc = init_server_ipc_comms( - channel_name, attrd_connect, - default_ipc_connection_destroy); - - if(rc != 0) { - crm_err("Could not start IPC server"); - was_err = TRUE; - } - } - - crm_info("Accepting attribute updates"); - - mainloop = g_main_new(FALSE); - - if(0 == g_timeout_add_full(G_PRIORITY_LOW+1, 5000, cib_connect, NULL, NULL)) { - crm_info("Adding timer failed"); - was_err = TRUE; - } - - if(was_err) { - crm_err("Aborting startup"); - return 100; - } - - crm_notice("Starting mainloop..."); - g_main_run(mainloop); - crm_notice("Exiting..."); + + if (FALSE == crm_cluster_connect(&attrd_uname, &attrd_uuid, dispatch, destroy, data)) { + crm_err("HA Signon failed"); + was_err = TRUE; + } + } + + crm_info("Cluster connection active"); + + if (was_err == FALSE) { + int rc = init_server_ipc_comms(channel_name, attrd_connect, + default_ipc_connection_destroy); + + if (rc != 0) { + crm_err("Could not start IPC server"); + was_err = TRUE; + } + } + + crm_info("Accepting attribute updates"); + + mainloop = g_main_new(FALSE); + + if (0 == g_timeout_add_full(G_PRIORITY_LOW + 1, 5000, cib_connect, NULL, NULL)) { + crm_info("Adding timer failed"); + was_err = TRUE; + } + + if (was_err) { + crm_err("Aborting startup"); + return 100; + } + + crm_notice("Starting mainloop..."); + g_main_run(mainloop); + crm_notice("Exiting..."); #if SUPPORT_HEARTBEAT - if(is_heartbeat_cluster()) { - attrd_cluster_conn->llc_ops->signoff(attrd_cluster_conn, TRUE); - attrd_cluster_conn->llc_ops->delete(attrd_cluster_conn); - } + if (is_heartbeat_cluster()) { + attrd_cluster_conn->llc_ops->signoff(attrd_cluster_conn, TRUE); + attrd_cluster_conn->llc_ops->delete(attrd_cluster_conn); + } #endif - if(cib_conn) { - cib_conn->cmds->signoff(cib_conn); - cib_delete(cib_conn); - } - - g_hash_table_destroy(attr_hash); - crm_free(channel_name); - crm_free(attrd_uuid); - empty_uuid_cache(); - - return 0; + if (cib_conn) { + cib_conn->cmds->signoff(cib_conn); + cib_delete(cib_conn); + } + + g_hash_table_destroy(attr_hash); + crm_free(channel_name); + crm_free(attrd_uuid); + empty_uuid_cache(); + + return 0; } -struct attrd_callback_s -{ - char *attr; - char *value; +struct attrd_callback_s { + char *attr; + char *value; }; static void -attrd_cib_callback(xmlNode *msg, int call_id, int rc, - xmlNode *output, void *user_data) +attrd_cib_callback(xmlNode * msg, int call_id, int rc, xmlNode * output, void *user_data) { - attr_hash_entry_t *hash_entry = NULL; - struct attrd_callback_s *data = user_data; - if(data->value == NULL && rc == cib_NOTEXISTS) { - rc = cib_ok; - } - - switch(rc) { - case cib_ok: - crm_debug("Update %d for %s=%s passed", call_id, data->attr, data->value); - hash_entry = g_hash_table_lookup(attr_hash, data->attr); - - if(hash_entry) { - crm_free(hash_entry->stored_value); - hash_entry->stored_value = NULL; - if(data->value != NULL) { - hash_entry->stored_value = crm_strdup(data->value); - } - } - break; - case cib_diff_failed: /* When an attr changes while the CIB is syncing */ - case cib_remote_timeout: /* When an attr changes while there is a DC election */ - case cib_NOTEXISTS: /* When an attr changes while the CIB is syncing a - * newer config from a node that just came up - */ - crm_warn("Update %d for %s=%s failed: %s", - call_id, data->attr, data->value, cib_error2string(rc)); - break; - default: - crm_err("Update %d for %s=%s failed: %s", - call_id, data->attr, data->value, cib_error2string(rc)); - } - - crm_free(data->value); - crm_free(data->attr); - crm_free(data); -} + attr_hash_entry_t *hash_entry = NULL; + struct attrd_callback_s *data = user_data; + + if (data->value == NULL && rc == cib_NOTEXISTS) { + rc = cib_ok; + } + + switch (rc) { + case cib_ok: + crm_debug("Update %d for %s=%s passed", call_id, data->attr, data->value); + hash_entry = g_hash_table_lookup(attr_hash, data->attr); + + if (hash_entry) { + crm_free(hash_entry->stored_value); + hash_entry->stored_value = NULL; + if (data->value != NULL) { + hash_entry->stored_value = crm_strdup(data->value); + } + } + break; + case cib_diff_failed: /* When an attr changes while the CIB is syncing */ + case cib_remote_timeout: /* When an attr changes while there is a DC election */ + case cib_NOTEXISTS: /* When an attr changes while the CIB is syncing a + * newer config from a node that just came up + */ + crm_warn("Update %d for %s=%s failed: %s", + call_id, data->attr, data->value, cib_error2string(rc)); + break; + default: + crm_err("Update %d for %s=%s failed: %s", + call_id, data->attr, data->value, cib_error2string(rc)); + } + crm_free(data->value); + crm_free(data->attr); + crm_free(data); +} void -attrd_perform_update(attr_hash_entry_t *hash_entry) +attrd_perform_update(attr_hash_entry_t * hash_entry) { - int rc = cib_ok; - struct attrd_callback_s *data = NULL; - const char *user_name = NULL; - - if(hash_entry == NULL) { - return; - - } else if(cib_conn == NULL) { - crm_info("Delaying operation %s=%s: cib not connected", hash_entry->id, crm_str(hash_entry->value)); - return; - - } + int rc = cib_ok; + struct attrd_callback_s *data = NULL; + const char *user_name = NULL; + + if (hash_entry == NULL) { + return; + + } else if (cib_conn == NULL) { + crm_info("Delaying operation %s=%s: cib not connected", hash_entry->id, + crm_str(hash_entry->value)); + return; + } #if ENABLE_ACL - if(hash_entry->user) { - user_name = hash_entry->user; - crm_debug_2("Performing request from user '%s'", hash_entry->user); - } + if (hash_entry->user) { + user_name = hash_entry->user; + crm_debug_2("Performing request from user '%s'", hash_entry->user); + } #endif - if(hash_entry->value == NULL) { - /* delete the attr */ - rc = delete_attr_delegate(cib_conn, cib_none, hash_entry->section, attrd_uuid, NULL, - hash_entry->set, hash_entry->uuid, hash_entry->id, NULL, FALSE, user_name); - - if(hash_entry->stored_value) { - crm_notice("Sent delete %d: node=%s, attr=%s, id=%s, set=%s, section=%s", - rc, attrd_uuid, hash_entry->id, hash_entry->uuid?hash_entry->uuid:"", - hash_entry->set, hash_entry->section); - - } else if(rc < 0 && rc != cib_NOTEXISTS) { - crm_notice("Delete operation failed: node=%s, attr=%s, id=%s, set=%s, section=%s: %s (%d)", - attrd_uuid, hash_entry->id, hash_entry->uuid?hash_entry->uuid:"", - hash_entry->set, hash_entry->section, cib_error2string(rc), rc); - - } else { - crm_debug_2("Sent delete %d: node=%s, attr=%s, id=%s, set=%s, section=%s", - rc, attrd_uuid, hash_entry->id, hash_entry->uuid?hash_entry->uuid:"", - hash_entry->set, hash_entry->section); - } - - } else { - /* send update */ - rc = update_attr_delegate(cib_conn, cib_none, hash_entry->section, - attrd_uuid, NULL, hash_entry->set, hash_entry->uuid, - hash_entry->id, hash_entry->value, FALSE, user_name); - if(safe_str_neq(hash_entry->value, hash_entry->stored_value) || rc < 0) { - crm_notice("Sent update %d: %s=%s", rc, hash_entry->id, hash_entry->value); - } else { - crm_debug_2("Sent update %d: %s=%s", rc, hash_entry->id, hash_entry->value); - } - } - - crm_malloc0(data, sizeof(struct attrd_callback_s)); - data->attr = crm_strdup(hash_entry->id); - if(hash_entry->value != NULL) { - data->value = crm_strdup(hash_entry->value); - } - add_cib_op_callback(cib_conn, rc, FALSE, data, attrd_cib_callback); - - return; + if (hash_entry->value == NULL) { + /* delete the attr */ + rc = delete_attr_delegate(cib_conn, cib_none, hash_entry->section, attrd_uuid, NULL, + hash_entry->set, hash_entry->uuid, hash_entry->id, NULL, FALSE, + user_name); + + if (hash_entry->stored_value) { + crm_notice("Sent delete %d: node=%s, attr=%s, id=%s, set=%s, section=%s", + rc, attrd_uuid, hash_entry->id, + hash_entry->uuid ? hash_entry->uuid : "", hash_entry->set, + hash_entry->section); + + } else if (rc < 0 && rc != cib_NOTEXISTS) { + crm_notice + ("Delete operation failed: node=%s, attr=%s, id=%s, set=%s, section=%s: %s (%d)", + attrd_uuid, hash_entry->id, hash_entry->uuid ? hash_entry->uuid : "", + hash_entry->set, hash_entry->section, cib_error2string(rc), rc); + + } else { + crm_debug_2("Sent delete %d: node=%s, attr=%s, id=%s, set=%s, section=%s", + rc, attrd_uuid, hash_entry->id, + hash_entry->uuid ? hash_entry->uuid : "", hash_entry->set, + hash_entry->section); + } + + } else { + /* send update */ + rc = update_attr_delegate(cib_conn, cib_none, hash_entry->section, + attrd_uuid, NULL, hash_entry->set, hash_entry->uuid, + hash_entry->id, hash_entry->value, FALSE, user_name); + if (safe_str_neq(hash_entry->value, hash_entry->stored_value) || rc < 0) { + crm_notice("Sent update %d: %s=%s", rc, hash_entry->id, hash_entry->value); + } else { + crm_debug_2("Sent update %d: %s=%s", rc, hash_entry->id, hash_entry->value); + } + } + + crm_malloc0(data, sizeof(struct attrd_callback_s)); + data->attr = crm_strdup(hash_entry->id); + if (hash_entry->value != NULL) { + data->value = crm_strdup(hash_entry->value); + } + add_cib_op_callback(cib_conn, rc, FALSE, data, attrd_cib_callback); + + return; } void attrd_local_callback(xmlNode * msg) { - static int plus_plus_len = 5; - attr_hash_entry_t *hash_entry = NULL; - const char *from = crm_element_value(msg, F_ORIG); - const char *op = crm_element_value(msg, F_ATTRD_TASK); - const char *attr = crm_element_value(msg, F_ATTRD_ATTRIBUTE); - const char *value = crm_element_value(msg, F_ATTRD_VALUE); - const char *host = crm_element_value(msg, F_ATTRD_HOST); - - if(safe_str_eq(op, "refresh")) { - crm_notice("Sending full refresh (origin=%s)", from); - g_hash_table_foreach(attr_hash, update_for_hash_entry, NULL); - return; - } - - if(host != NULL && safe_str_neq(host, attrd_uname)) { - send_cluster_message(host, crm_msg_attrd, msg, FALSE); - return; - } - - crm_debug("%s message from %s: %s=%s", op, from, attr, crm_str(value)); - hash_entry = find_hash_entry(msg); - if(hash_entry == NULL) { - return; - } - - if(hash_entry->uuid == NULL) { - const char *key = crm_element_value(msg, F_ATTRD_KEY); - if(key) { - hash_entry->uuid = crm_strdup(key); - } - } - - crm_debug("Supplied: %s, Current: %s, Stored: %s", - value, hash_entry->value, hash_entry->stored_value); - - if(safe_str_eq(value, hash_entry->value) - && safe_str_eq(value, hash_entry->stored_value)) { - crm_debug_2("Ignoring non-change"); - return; - - } else if(value) { - int offset = 1; - int int_value = 0; - int value_len = strlen(value); - if(value_len < (plus_plus_len + 2) - || value[plus_plus_len] != '+' - || (value[plus_plus_len+1] != '+' && value[plus_plus_len+1] != '=')) { - goto set_unexpanded; - } - - int_value = char2score(hash_entry->value); - if(value[plus_plus_len+1] != '+') { - const char *offset_s = value+(plus_plus_len+2); - offset = char2score(offset_s); - } - int_value += offset; - - if(int_value > INFINITY) { - int_value = INFINITY; - } - - crm_info("Expanded %s=%s to %d", attr, value, int_value); - crm_xml_add_int(msg, F_ATTRD_VALUE, int_value); - value = crm_element_value(msg, F_ATTRD_VALUE); - } + static int plus_plus_len = 5; + attr_hash_entry_t *hash_entry = NULL; + const char *from = crm_element_value(msg, F_ORIG); + const char *op = crm_element_value(msg, F_ATTRD_TASK); + const char *attr = crm_element_value(msg, F_ATTRD_ATTRIBUTE); + const char *value = crm_element_value(msg, F_ATTRD_VALUE); + const char *host = crm_element_value(msg, F_ATTRD_HOST); + + if (safe_str_eq(op, "refresh")) { + crm_notice("Sending full refresh (origin=%s)", from); + g_hash_table_foreach(attr_hash, update_for_hash_entry, NULL); + return; + } + + if (host != NULL && safe_str_neq(host, attrd_uname)) { + send_cluster_message(host, crm_msg_attrd, msg, FALSE); + return; + } + + crm_debug("%s message from %s: %s=%s", op, from, attr, crm_str(value)); + hash_entry = find_hash_entry(msg); + if (hash_entry == NULL) { + return; + } + + if (hash_entry->uuid == NULL) { + const char *key = crm_element_value(msg, F_ATTRD_KEY); + + if (key) { + hash_entry->uuid = crm_strdup(key); + } + } + + crm_debug("Supplied: %s, Current: %s, Stored: %s", + value, hash_entry->value, hash_entry->stored_value); + + if (safe_str_eq(value, hash_entry->value) + && safe_str_eq(value, hash_entry->stored_value)) { + crm_debug_2("Ignoring non-change"); + return; + + } else if (value) { + int offset = 1; + int int_value = 0; + int value_len = strlen(value); + + if (value_len < (plus_plus_len + 2) + || value[plus_plus_len] != '+' + || (value[plus_plus_len + 1] != '+' && value[plus_plus_len + 1] != '=')) { + goto set_unexpanded; + } + + int_value = char2score(hash_entry->value); + if (value[plus_plus_len + 1] != '+') { + const char *offset_s = value + (plus_plus_len + 2); + + offset = char2score(offset_s); + } + int_value += offset; + + if (int_value > INFINITY) { + int_value = INFINITY; + } + + crm_info("Expanded %s=%s to %d", attr, value, int_value); + crm_xml_add_int(msg, F_ATTRD_VALUE, int_value); + value = crm_element_value(msg, F_ATTRD_VALUE); + } set_unexpanded: - if(safe_str_eq(value, hash_entry->value) && hash_entry->timer_id) { - /* We're already waiting to set this value */ - return; - } - - crm_free(hash_entry->value); - hash_entry->value = NULL; - if(value != NULL) { - hash_entry->value = crm_strdup(value); - crm_debug("New value of %s is %s", attr, value); - } - - stop_attrd_timer(hash_entry); - - if(hash_entry->timeout > 0) { - hash_entry->timer_id = g_timeout_add( - hash_entry->timeout, attrd_timer_callback, hash_entry); - } else { - attrd_trigger_update(hash_entry); - } - - return; + if (safe_str_eq(value, hash_entry->value) && hash_entry->timer_id) { + /* We're already waiting to set this value */ + return; + } + + crm_free(hash_entry->value); + hash_entry->value = NULL; + if (value != NULL) { + hash_entry->value = crm_strdup(value); + crm_debug("New value of %s is %s", attr, value); + } + + stop_attrd_timer(hash_entry); + + if (hash_entry->timeout > 0) { + hash_entry->timer_id = g_timeout_add(hash_entry->timeout, attrd_timer_callback, hash_entry); + } else { + attrd_trigger_update(hash_entry); + } + + return; } gboolean attrd_timer_callback(void *user_data) { stop_attrd_timer(user_data); attrd_trigger_update(user_data); - return TRUE; /* Always return true, removed cleanly by stop_attrd_timer() */ + return TRUE; /* Always return true, removed cleanly by stop_attrd_timer() */ } gboolean -attrd_trigger_update(attr_hash_entry_t *hash_entry) +attrd_trigger_update(attr_hash_entry_t * hash_entry) { - xmlNode *msg = NULL; - - /* send HA message to everyone */ - crm_notice("Sending flush op to all hosts for: %s (%s)", - hash_entry->id, crm_str(hash_entry->value)); - log_hash_entry(LOG_DEBUG_2, hash_entry, "Sending flush op to all hosts for:"); - - msg = create_xml_node(NULL, __FUNCTION__); - crm_xml_add(msg, F_TYPE, T_ATTRD); - crm_xml_add(msg, F_ORIG, attrd_uname); - crm_xml_add(msg, F_ATTRD_TASK, "flush"); - crm_xml_add(msg, F_ATTRD_ATTRIBUTE, hash_entry->id); - crm_xml_add(msg, F_ATTRD_SET, hash_entry->set); - crm_xml_add(msg, F_ATTRD_SECTION, hash_entry->section); - crm_xml_add(msg, F_ATTRD_DAMPEN, hash_entry->dampen); - crm_xml_add(msg, F_ATTRD_VALUE, hash_entry->value); + xmlNode *msg = NULL; + + /* send HA message to everyone */ + crm_notice("Sending flush op to all hosts for: %s (%s)", + hash_entry->id, crm_str(hash_entry->value)); + log_hash_entry(LOG_DEBUG_2, hash_entry, "Sending flush op to all hosts for:"); + + msg = create_xml_node(NULL, __FUNCTION__); + crm_xml_add(msg, F_TYPE, T_ATTRD); + crm_xml_add(msg, F_ORIG, attrd_uname); + crm_xml_add(msg, F_ATTRD_TASK, "flush"); + crm_xml_add(msg, F_ATTRD_ATTRIBUTE, hash_entry->id); + crm_xml_add(msg, F_ATTRD_SET, hash_entry->set); + crm_xml_add(msg, F_ATTRD_SECTION, hash_entry->section); + crm_xml_add(msg, F_ATTRD_DAMPEN, hash_entry->dampen); + crm_xml_add(msg, F_ATTRD_VALUE, hash_entry->value); #if ENABLE_ACL - if(hash_entry->user) { - crm_xml_add(msg, F_ATTRD_USER, hash_entry->user); - } + if (hash_entry->user) { + crm_xml_add(msg, F_ATTRD_USER, hash_entry->user); + } #endif - if(hash_entry->timeout <= 0) { - crm_xml_add(msg, F_ATTRD_IGNORE_LOCALLY, hash_entry->value); - attrd_perform_update(hash_entry); - } + if (hash_entry->timeout <= 0) { + crm_xml_add(msg, F_ATTRD_IGNORE_LOCALLY, hash_entry->value); + attrd_perform_update(hash_entry); + } + + send_cluster_message(NULL, crm_msg_attrd, msg, FALSE); + free_xml(msg); - send_cluster_message(NULL, crm_msg_attrd, msg, FALSE); - free_xml(msg); - - return TRUE; + return TRUE; } diff --git a/tools/attrd_updater.c b/tools/attrd_updater.c index bf4c124a4d..3fbb6a360b 100644 --- a/tools/attrd_updater.c +++ b/tools/attrd_updater.c @@ -1,153 +1,156 @@ /* * Copyright (C) 2004 Andrew Beekhof * * 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 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 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 */ #include #include #include #include #include #include #include #include #include #include const char *attr_name = NULL; const char *attr_value = NULL; const char *attr_set = NULL; const char *attr_section = NULL; const char *attr_dampen = NULL; char command = 'q'; /* *INDENT-OFF* */ static struct crm_option long_options[] = { /* Top-level Options */ {"help", 0, 0, '?', "\tThis text"}, {"version", 0, 0, '$', "\tVersion information" }, {"verbose", 0, 0, 'V', "\tIncrease debug output\n"}, {"quiet", 0, 0, 'q', "\tPrint only the value on stdout\n"}, {"name", 1, 0, 'n', "The attribute's name"}, {"-spacer-",1, 0, '-', "\nCommands:"}, {"update", 1, 0, 'U', "Update the attribute's value in attrd. If this causes the value to change, it will also be updated in the cluster configuration"}, {"query", 0, 0, 'Q', "\tQuery the attribute's value from attrd"}, {"delete", 0, 0, 'D', "\tDelete the attribute in attrd. If a value was previously set, it will also be removed from the cluster configuration"}, {"refresh", 0, 0, 'R', "\t(Advanced) Force the attrd daemon to resend all current values to the CIB\n"}, {"-spacer-",1, 0, '-', "\nAdditional options:"}, {"lifetime",1, 0, 'l', "Lifetime of the node attribute. Allowed values: forever, reboot"}, {"delay", 1, 0, 'd', "The time to wait (dampening) in seconds further changes occur"}, {"set", 1, 0, 's', "(Advanced) The attribute set in which to place the value"}, /* Legacy options */ {"update", 1, 0, 'v', NULL, 1}, {"section", 1, 0, 'S', NULL, 1}, {0, 0, 0, 0} }; /* *INDENT-ON* */ int -main(int argc, char ** argv) +main(int argc, char **argv) { int index = 0; int argerr = 0; int flag; int BE_QUIET = FALSE; crm_log_init_quiet(NULL, LOG_ERR, FALSE, FALSE, argc, argv); - crm_set_options(NULL, "command -n attribute [options]", long_options, "Tool for updating cluster node attributes"); + crm_set_options(NULL, "command -n attribute [options]", long_options, + "Tool for updating cluster node attributes"); - if(argc < 2) { - crm_help('?', LSB_EXIT_EINVAL); + if (argc < 2) { + crm_help('?', LSB_EXIT_EINVAL); } while (1) { - flag = crm_get_option(argc, argv, &index); - if (flag == -1) - break; - - switch(flag) { - case 'V': - alter_debug(DEBUG_INC); - break; - case '?': - case '$': - crm_help(flag, LSB_EXIT_OK); - break; - case 'n': - attr_name = crm_strdup(optarg); - break; - case 's': - attr_set = crm_strdup(optarg); - break; - case 'd': - attr_dampen = crm_strdup(optarg); - break; - case 'l': - case 'S': - attr_section = crm_strdup(optarg); - break; - case 'q': - BE_QUIET = TRUE; - break; - case 'Q': - case 'R': - case 'D': - case 'U': - case 'v': - command = flag; - attr_value = optarg; - break; - default: - ++argerr; - break; - } + flag = crm_get_option(argc, argv, &index); + if (flag == -1) + break; + + switch (flag) { + case 'V': + alter_debug(DEBUG_INC); + break; + case '?': + case '$': + crm_help(flag, LSB_EXIT_OK); + break; + case 'n': + attr_name = crm_strdup(optarg); + break; + case 's': + attr_set = crm_strdup(optarg); + break; + case 'd': + attr_dampen = crm_strdup(optarg); + break; + case 'l': + case 'S': + attr_section = crm_strdup(optarg); + break; + case 'q': + BE_QUIET = TRUE; + break; + case 'Q': + case 'R': + case 'D': + case 'U': + case 'v': + command = flag; + attr_value = optarg; + break; + default: + ++argerr; + break; + } } - if(BE_QUIET == FALSE) { - cl_log_args(argc, argv); + if (BE_QUIET == FALSE) { + cl_log_args(argc, argv); } - + if (optind > argc) { - ++argerr; + ++argerr; } - if(command != 'R' && attr_name == NULL) { - ++argerr; + if (command != 'R' && attr_name == NULL) { + ++argerr; } - + if (argerr) { - crm_help('?', LSB_EXIT_GENERIC); + crm_help('?', LSB_EXIT_GENERIC); } - - if(command == 'Q') { - fprintf(stderr, "-Q,--query is not yet implemented, use -D to delete existing values\n\n"); - crm_help('?', LSB_EXIT_GENERIC); - } else if(attrd_lazy_update(command, NULL, attr_name, attr_value, attr_section, attr_set, attr_dampen) == FALSE) { - fprintf(stderr, "Could not update %s=%s\n", attr_name, attr_value); - return 1; + if (command == 'Q') { + fprintf(stderr, "-Q,--query is not yet implemented, use -D to delete existing values\n\n"); + crm_help('?', LSB_EXIT_GENERIC); + + } else + if (attrd_lazy_update + (command, NULL, attr_name, attr_value, attr_section, attr_set, attr_dampen) == FALSE) { + fprintf(stderr, "Could not update %s=%s\n", attr_name, attr_value); + return 1; } - + return 0; } diff --git a/tools/ccm_epoche.c b/tools/ccm_epoche.c index f3849668d1..fc2a339824 100644 --- a/tools/ccm_epoche.c +++ b/tools/ccm_epoche.c @@ -1,590 +1,594 @@ /* * Copyright (C) 2004 Andrew Beekhof * * 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 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 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 */ #include #include #include #include #include #include #include #include -#include /* for basename() */ +#include /* for basename() */ #include #include #include #include int command = 0; int ccm_fd = 0; gboolean do_quiet = FALSE; char *target_uuid = NULL; char *target_uname = NULL; const char *standby_value = NULL; const char *standby_scope = NULL; #include <../lib/common/stack.h> /* *INDENT-OFF* */ static struct crm_option long_options[] = { /* Top-level Options */ {"help", 0, 0, '?', "\tThis text"}, {"version", 0, 0, '$', "\tVersion information" }, {"verbose", 0, 0, 'V', "\tIncrease debug output"}, {"quiet", 0, 0, 'Q', "\tEssential output only"}, {"-spacer-", 1, 0, '-', "\nStack:"}, #ifdef SUPPORT_CMAN {"cman", 0, 0, 'c', "\tOnly try connecting to a cman-based cluster"}, #endif #ifdef SUPPORT_COROSYNC {"openais", 0, 0, 'A', "\tOnly try connecting to an OpenAIS-based cluster"}, #endif #ifdef SUPPORT_HEARTBEAT {"heartbeat", 0, 0, 'H', "Only try connecting to a Heartbeat-based cluster"}, #endif {"-spacer-", 1, 0, '-', "\nCommands:"}, {"epoch", 0, 0, 'e', "\tDisplay the epoch during which this node joined the cluster"}, {"quorum", 0, 0, 'q', "\tDisplay a 1 if our partition has quorum, 0 if not"}, {"list", 0, 0, 'l', "\tDisplay all known members (past and present) of this cluster (Not available for heartbeat clusters)"}, {"partition", 0, 0, 'p', "Display the members of this partition"}, {"cluster-id", 0, 0, 'i', "Display this node's cluster id"}, {"remove", 1, 0, 'R', "(Advanced, AIS-Only) Remove the (stopped) node with the specified nodeid from the cluster"}, {"-spacer-", 1, 0, '-', "\nAdditional Options:"}, {"force", 0, 0, 'f'}, {0, 0, 0, 0} }; /* *INDENT-ON* */ int local_id = 0; - #if SUPPORT_HEARTBEAT # include # include # include # define UUID_LEN 16 oc_ev_t *ccm_token = NULL; static void *ccm_library = NULL; -void oc_ev_special(const oc_ev_t *, oc_ev_class_t , int ); +void oc_ev_special(const oc_ev_t *, oc_ev_class_t, int); -static gboolean read_local_hb_uuid(void) +static gboolean +read_local_hb_uuid(void) { cl_uuid_t uuid; char *buffer = NULL; long start = 0, read_len = 0; FILE *input = fopen(UUID_FILE, "r"); - - if(input == NULL) { - crm_info("Could not open UUID file %s\n", UUID_FILE); - return FALSE; + + if (input == NULL) { + crm_info("Could not open UUID file %s\n", UUID_FILE); + return FALSE; } - + /* see how big the file is */ - start = ftell(input); + start = ftell(input); fseek(input, 0L, SEEK_END); - if(UUID_LEN != ftell(input)) { - fprintf(stderr, "%s must contain exactly %d bytes\n", UUID_FILE, UUID_LEN); - abort(); + if (UUID_LEN != ftell(input)) { + fprintf(stderr, "%s must contain exactly %d bytes\n", UUID_FILE, UUID_LEN); + abort(); } - + fseek(input, 0L, start); - if(start != ftell(input)) { - fprintf(stderr, "fseek not behaving: %ld vs. %ld\n", start, ftell(input)); - exit(2); + if (start != ftell(input)) { + fprintf(stderr, "fseek not behaving: %ld vs. %ld\n", start, ftell(input)); + exit(2); } buffer = malloc(50); read_len = fread(uuid.uuid, 1, UUID_LEN, input); fclose(input); - if(read_len != UUID_LEN) { - fprintf(stderr, "Expected and read bytes differ: %d vs. %ld\n", - UUID_LEN, read_len); - exit(3); - - } else if(buffer != NULL) { - cl_uuid_unparse(&uuid, buffer); - fprintf(stdout, "%s\n", buffer); - return TRUE; - + if (read_len != UUID_LEN) { + fprintf(stderr, "Expected and read bytes differ: %d vs. %ld\n", UUID_LEN, read_len); + exit(3); + + } else if (buffer != NULL) { + cl_uuid_unparse(&uuid, buffer); + fprintf(stdout, "%s\n", buffer); + return TRUE; + } else { - fprintf(stderr, "No buffer to unparse\n"); - exit(4); + fprintf(stderr, "No buffer to unparse\n"); + exit(4); } free(buffer); return FALSE; } -static void +static void ccm_age_callback(oc_ed_t event, void *cookie, size_t size, const void *data) { int lpc; int node_list_size; const oc_ev_membership_t *oc = (const oc_ev_membership_t *)data; - int (*ccm_api_callback_done)(void *cookie) = find_library_function( - &ccm_library, CCM_LIBRARY, "oc_ev_callback_done"); + int (*ccm_api_callback_done) (void *cookie) = + find_library_function(&ccm_library, CCM_LIBRARY, "oc_ev_callback_done"); node_list_size = oc->m_n_member; - if(command == 'q') { - crm_debug("Processing \"%s\" event.", - event==OC_EV_MS_NEW_MEMBERSHIP?"NEW MEMBERSHIP": - event==OC_EV_MS_NOT_PRIMARY?"NOT PRIMARY": - event==OC_EV_MS_PRIMARY_RESTORED?"PRIMARY RESTORED": - event==OC_EV_MS_EVICTED?"EVICTED": - "NO QUORUM MEMBERSHIP"); - if(ccm_have_quorum(event)) { - fprintf(stdout, "1\n"); - } else { - fprintf(stdout, "0\n"); - } - - } else if(command == 'e') { - crm_debug("Searching %d members for our birth", oc->m_n_member); + if (command == 'q') { + crm_debug("Processing \"%s\" event.", + event == OC_EV_MS_NEW_MEMBERSHIP ? "NEW MEMBERSHIP" : + event == OC_EV_MS_NOT_PRIMARY ? "NOT PRIMARY" : + event == OC_EV_MS_PRIMARY_RESTORED ? "PRIMARY RESTORED" : + event == OC_EV_MS_EVICTED ? "EVICTED" : "NO QUORUM MEMBERSHIP"); + if (ccm_have_quorum(event)) { + fprintf(stdout, "1\n"); + } else { + fprintf(stdout, "0\n"); + } + + } else if (command == 'e') { + crm_debug("Searching %d members for our birth", oc->m_n_member); } - for(lpc=0; lpcm_array[oc->m_memb_idx+lpc].node_uname); - - } else if(command == 'e') { - int (*ccm_api_is_my_nodeid)(const oc_ev_t *token, const oc_node_t *node) = find_library_function( - &ccm_library, CCM_LIBRARY, "oc_ev_is_my_nodeid"); - if((*ccm_api_is_my_nodeid)(ccm_token, &(oc->m_array[lpc]))){ - crm_debug("MATCH: nodeid=%d, uname=%s, born=%d", - oc->m_array[oc->m_memb_idx+lpc].node_id, - oc->m_array[oc->m_memb_idx+lpc].node_uname, - oc->m_array[oc->m_memb_idx+lpc].node_born_on); - fprintf(stdout, "%d\n", - oc->m_array[oc->m_memb_idx+lpc].node_born_on); - } - } + for (lpc = 0; lpc < node_list_size; lpc++) { + if (command == 'p') { + fprintf(stdout, "%s ", oc->m_array[oc->m_memb_idx + lpc].node_uname); + + } else if (command == 'e') { + int (*ccm_api_is_my_nodeid) (const oc_ev_t * token, const oc_node_t * node) = + find_library_function(&ccm_library, CCM_LIBRARY, "oc_ev_is_my_nodeid"); + if ((*ccm_api_is_my_nodeid) (ccm_token, &(oc->m_array[lpc]))) { + crm_debug("MATCH: nodeid=%d, uname=%s, born=%d", + oc->m_array[oc->m_memb_idx + lpc].node_id, + oc->m_array[oc->m_memb_idx + lpc].node_uname, + oc->m_array[oc->m_memb_idx + lpc].node_born_on); + fprintf(stdout, "%d\n", oc->m_array[oc->m_memb_idx + lpc].node_born_on); + } + } } - (*ccm_api_callback_done)(cookie); + (*ccm_api_callback_done) (cookie); - if(command == 'p') { - fprintf(stdout, "\n"); + if (command == 'p') { + fprintf(stdout, "\n"); } fflush(stdout); exit(0); } static gboolean -ccm_age_connect(int *ccm_fd) +ccm_age_connect(int *ccm_fd) { gboolean did_fail = FALSE; int ret = 0; - int (*ccm_api_register)(oc_ev_t **token) = find_library_function( - &ccm_library, CCM_LIBRARY, "oc_ev_register"); - - int (*ccm_api_set_callback)(const oc_ev_t *token, - oc_ev_class_t class, - oc_ev_callback_t *fn, - oc_ev_callback_t **prev_fn) = find_library_function( - &ccm_library, CCM_LIBRARY, "oc_ev_set_callback"); - - - void (*ccm_api_special)(const oc_ev_t *, oc_ev_class_t , int ) = find_library_function( - &ccm_library, CCM_LIBRARY, "oc_ev_special"); - int (*ccm_api_activate)(const oc_ev_t *token, int *fd) = find_library_function( - &ccm_library, CCM_LIBRARY, "oc_ev_activate"); - + int (*ccm_api_register) (oc_ev_t ** token) = + find_library_function(&ccm_library, CCM_LIBRARY, "oc_ev_register"); + + int (*ccm_api_set_callback) (const oc_ev_t * token, + oc_ev_class_t class, + oc_ev_callback_t * fn, + oc_ev_callback_t ** prev_fn) = + find_library_function(&ccm_library, CCM_LIBRARY, "oc_ev_set_callback"); + + void (*ccm_api_special) (const oc_ev_t *, oc_ev_class_t, int) = + find_library_function(&ccm_library, CCM_LIBRARY, "oc_ev_special"); + int (*ccm_api_activate) (const oc_ev_t * token, int *fd) = + find_library_function(&ccm_library, CCM_LIBRARY, "oc_ev_activate"); + crm_debug("Registering with CCM"); - ret = (*ccm_api_register)(&ccm_token); + ret = (*ccm_api_register) (&ccm_token); if (ret != 0) { - crm_info("CCM registration failed: %d", ret); - did_fail = TRUE; + crm_info("CCM registration failed: %d", ret); + did_fail = TRUE; } - - if(did_fail == FALSE) { - crm_debug("Setting up CCM callbacks"); - ret = (*ccm_api_set_callback)(ccm_token, OC_EV_MEMB_CLASS, - ccm_age_callback, NULL); - if (ret != 0) { - crm_warn("CCM callback not set: %d", ret); - did_fail = TRUE; - } + + if (did_fail == FALSE) { + crm_debug("Setting up CCM callbacks"); + ret = (*ccm_api_set_callback) (ccm_token, OC_EV_MEMB_CLASS, ccm_age_callback, NULL); + if (ret != 0) { + crm_warn("CCM callback not set: %d", ret); + did_fail = TRUE; + } } - if(did_fail == FALSE) { - (*ccm_api_special)(ccm_token, OC_EV_MEMB_CLASS, 0/*don't care*/); - - crm_debug("Activating CCM token"); - ret = (*ccm_api_activate)(ccm_token, ccm_fd); - if (ret != 0){ - crm_warn("CCM Activation failed: %d", ret); - did_fail = TRUE; - } + if (did_fail == FALSE) { + (*ccm_api_special) (ccm_token, OC_EV_MEMB_CLASS, 0 /*don't care */ ); + + crm_debug("Activating CCM token"); + ret = (*ccm_api_activate) (ccm_token, ccm_fd); + if (ret != 0) { + crm_warn("CCM Activation failed: %d", ret); + did_fail = TRUE; + } } - + return !did_fail; } -static gboolean try_heartbeat(int command, enum cluster_type_e stack) +static gboolean +try_heartbeat(int command, enum cluster_type_e stack) { crm_debug("Attempting to process %c command", command); - - if(command == 'i') { - if(read_local_hb_uuid()) { - exit(0); - } - - } else if(ccm_age_connect(&ccm_fd)) { - int rc = 0; - fd_set rset; - int (*ccm_api_handle_event)(const oc_ev_t *token) = find_library_function( - &ccm_library, CCM_LIBRARY, "oc_ev_handle_event"); - - while (1) { - - sleep(1); - FD_ZERO(&rset); - FD_SET(ccm_fd, &rset); - - errno = 0; - rc = select(ccm_fd + 1, &rset, NULL,NULL,NULL); - - if(rc > 0 && (*ccm_api_handle_event)(ccm_token) != 0) { - crm_err("oc_ev_handle_event failed"); - return FALSE; - - } else if(rc < 0 && errno != EINTR) { - crm_perror(LOG_ERR, "select failed: %d", rc); - return FALSE; - } - } + + if (command == 'i') { + if (read_local_hb_uuid()) { + exit(0); + } + + } else if (ccm_age_connect(&ccm_fd)) { + int rc = 0; + fd_set rset; + int (*ccm_api_handle_event) (const oc_ev_t * token) = + find_library_function(&ccm_library, CCM_LIBRARY, "oc_ev_handle_event"); + + while (1) { + + sleep(1); + FD_ZERO(&rset); + FD_SET(ccm_fd, &rset); + + errno = 0; + rc = select(ccm_fd + 1, &rset, NULL, NULL, NULL); + + if (rc > 0 && (*ccm_api_handle_event) (ccm_token) != 0) { + crm_err("oc_ev_handle_event failed"); + return FALSE; + + } else if (rc < 0 && errno != EINTR) { + crm_perror(LOG_ERR, "select failed: %d", rc); + return FALSE; + } + } } return FALSE; } #endif #if SUPPORT_CMAN # include # define MAX_NODES 256 -static gboolean try_cman(int command, enum cluster_type_e stack) +static gboolean +try_cman(int command, enum cluster_type_e stack) { int rc = -1, lpc = 0, node_count = 0; cman_node_t node; cman_cluster_t cluster; cman_handle_t cman_handle = NULL; cman_node_t cman_nodes[MAX_NODES]; memset(&cluster, 0, sizeof(cluster)); cman_handle = cman_init(NULL); - if(cman_handle == NULL || cman_is_active(cman_handle) == FALSE) { - crm_info("Couldn't connect to cman"); - return FALSE; + if (cman_handle == NULL || cman_is_active(cman_handle) == FALSE) { + crm_info("Couldn't connect to cman"); + return FALSE; } - switch(command) { - case 'R': - fprintf(stderr, "Node removal not supported for cman based clusters\n"); - exit(cib_NOTSUPPORTED); - break; - - case 'e': - /* Age makes no sense (yet?) in a cman cluster */ - fprintf(stdout, "1\n"); - break; - - case 'q': - fprintf(stdout, "%d\n", cman_is_quorate(cman_handle)); - break; - - case 'l': - case 'p': - rc = cman_get_nodes(cman_handle, MAX_NODES, &node_count, cman_nodes); - if (rc != 0) { - fprintf(stderr, "Couldn't query cman node list: %d %d", rc, errno); - goto cman_bail; - } - - for (lpc = 0; lpc < node_count; lpc++) { - if(command == 'l') { - printf("%s ", cman_nodes[lpc].cn_name); - - } else if (cman_nodes[lpc].cn_nodeid != 0 && cman_nodes[lpc].cn_member) { - /* Never allow node ID 0 to be considered a member #315711 */ - printf("%s ", cman_nodes[lpc].cn_name); - } - } - printf("\n"); - break; - - case 'i': - rc = cman_get_node(cman_handle, CMAN_NODEID_US, &node); - if ( rc != 0) { - fprintf(stderr, "Couldn't query cman node id: %d %d", rc, errno); - goto cman_bail; - } - fprintf(stdout, "%u\n", node.cn_nodeid); - break; - - default: - fprintf(stderr, "Unknown option '%c'\n", command); - crm_help('?', LSB_EXIT_GENERIC); + switch (command) { + case 'R': + fprintf(stderr, "Node removal not supported for cman based clusters\n"); + exit(cib_NOTSUPPORTED); + break; + + case 'e': + /* Age makes no sense (yet?) in a cman cluster */ + fprintf(stdout, "1\n"); + break; + + case 'q': + fprintf(stdout, "%d\n", cman_is_quorate(cman_handle)); + break; + + case 'l': + case 'p': + rc = cman_get_nodes(cman_handle, MAX_NODES, &node_count, cman_nodes); + if (rc != 0) { + fprintf(stderr, "Couldn't query cman node list: %d %d", rc, errno); + goto cman_bail; + } + + for (lpc = 0; lpc < node_count; lpc++) { + if (command == 'l') { + printf("%s ", cman_nodes[lpc].cn_name); + + } else if (cman_nodes[lpc].cn_nodeid != 0 && cman_nodes[lpc].cn_member) { + /* Never allow node ID 0 to be considered a member #315711 */ + printf("%s ", cman_nodes[lpc].cn_name); + } + } + printf("\n"); + break; + + case 'i': + rc = cman_get_node(cman_handle, CMAN_NODEID_US, &node); + if (rc != 0) { + fprintf(stderr, "Couldn't query cman node id: %d %d", rc, errno); + goto cman_bail; + } + fprintf(stdout, "%u\n", node.cn_nodeid); + break; + + default: + fprintf(stderr, "Unknown option '%c'\n", command); + crm_help('?', LSB_EXIT_GENERIC); } cman_finish(cman_handle); exit(0); cman_bail: cman_finish(cman_handle); exit(LSB_EXIT_GENERIC); } #endif #if SUPPORT_COROSYNC static void ais_membership_destroy(gpointer user_data) { crm_err("AIS connection terminated"); ais_fd_sync = -1; exit(1); } -static gint member_sort(gconstpointer a, gconstpointer b) +static gint +member_sort(gconstpointer a, gconstpointer b) { const crm_node_t *node_a = a; const crm_node_t *node_b = b; + return strcmp(node_a->uname, node_b->uname); } -static void crm_add_member( - gpointer key, gpointer value, gpointer user_data) +static void +crm_add_member(gpointer key, gpointer value, gpointer user_data) { GList **list = user_data; crm_node_t *node = value; - if(node->uname != NULL) { - *list = g_list_insert_sorted(*list, node, member_sort); + + if (node->uname != NULL) { + *list = g_list_insert_sorted(*list, node, member_sort); } } static gboolean -ais_membership_dispatch(AIS_Message *wrapper, char *data, int sender) +ais_membership_dispatch(AIS_Message * wrapper, char *data, int sender) { - switch(wrapper->header.id) { - case crm_class_members: - case crm_class_notify: - case crm_class_quorum: - break; - default: - return TRUE; - - break; + switch (wrapper->header.id) { + case crm_class_members: + case crm_class_notify: + case crm_class_quorum: + break; + default: + return TRUE; + + break; } - if(command == 'q') { - if(crm_have_quorum) { - fprintf(stdout, "1\n"); - } else { - fprintf(stdout, "0\n"); - } - - } else if(command == 'l') { - GList *nodes = NULL; - GListPtr lpc = NULL; - g_hash_table_foreach(crm_peer_cache, crm_add_member, &nodes); - for(lpc = nodes; lpc != NULL; lpc = lpc->next) { - crm_node_t *node = (crm_node_t*)lpc->data; - fprintf(stdout, "%u %s %s\n", node->id, node->uname, node->state); - } - fprintf(stdout, "\n"); - - } else if(command == 'p') { - GList *nodes = NULL; - GListPtr lpc = NULL; - g_hash_table_foreach(crm_peer_cache, crm_add_member, &nodes); - for(lpc = nodes; lpc != NULL; lpc = lpc->next) { - crm_node_t *node = (crm_node_t*)lpc->data; - if(node->uname && crm_is_member_active(node)) { - fprintf(stdout, "%s ", node->uname); - } - } - fprintf(stdout, "\n"); + if (command == 'q') { + if (crm_have_quorum) { + fprintf(stdout, "1\n"); + } else { + fprintf(stdout, "0\n"); + } + + } else if (command == 'l') { + GList *nodes = NULL; + GListPtr lpc = NULL; + + g_hash_table_foreach(crm_peer_cache, crm_add_member, &nodes); + for (lpc = nodes; lpc != NULL; lpc = lpc->next) { + crm_node_t *node = (crm_node_t *) lpc->data; + + fprintf(stdout, "%u %s %s\n", node->id, node->uname, node->state); + } + fprintf(stdout, "\n"); + + } else if (command == 'p') { + GList *nodes = NULL; + GListPtr lpc = NULL; + + g_hash_table_foreach(crm_peer_cache, crm_add_member, &nodes); + for (lpc = nodes; lpc != NULL; lpc = lpc->next) { + crm_node_t *node = (crm_node_t *) lpc->data; + + if (node->uname && crm_is_member_active(node)) { + fprintf(stdout, "%s ", node->uname); + } + } + fprintf(stdout, "\n"); } exit(0); - + return TRUE; } -static gboolean try_corosync(int command, enum cluster_type_e stack) +static gboolean +try_corosync(int command, enum cluster_type_e stack) { - if(init_ais_connection_once( - ais_membership_dispatch, ais_membership_destroy, NULL, NULL, &local_id)) { - - GMainLoop* amainloop = NULL; - switch(command) { - case 'R': - send_ais_text(crm_class_rmpeer, target_uname, TRUE, NULL, crm_msg_ais); - exit(0); - - case 'e': - /* Age makes no sense (yet) in an AIS cluster */ - fprintf(stdout, "1\n"); - exit(0); - - case 'q': - send_ais_text(crm_class_quorum, NULL, TRUE, NULL, crm_msg_ais); - break; - - case 'l': - case 'p': - crm_info("Requesting the list of configured nodes"); - send_ais_text(crm_class_members, __FUNCTION__, TRUE, NULL, crm_msg_ais); - break; - - case 'i': - printf("%u\n", local_id); - exit(0); - - default: - fprintf(stderr, "Unknown option '%c'\n", command); - crm_help('?', LSB_EXIT_GENERIC); - } - amainloop = g_main_new(FALSE); - g_main_run(amainloop); + if (init_ais_connection_once + (ais_membership_dispatch, ais_membership_destroy, NULL, NULL, &local_id)) { + + GMainLoop *amainloop = NULL; + + switch (command) { + case 'R': + send_ais_text(crm_class_rmpeer, target_uname, TRUE, NULL, crm_msg_ais); + exit(0); + + case 'e': + /* Age makes no sense (yet) in an AIS cluster */ + fprintf(stdout, "1\n"); + exit(0); + + case 'q': + send_ais_text(crm_class_quorum, NULL, TRUE, NULL, crm_msg_ais); + break; + + case 'l': + case 'p': + crm_info("Requesting the list of configured nodes"); + send_ais_text(crm_class_members, __FUNCTION__, TRUE, NULL, crm_msg_ais); + break; + + case 'i': + printf("%u\n", local_id); + exit(0); + + default: + fprintf(stderr, "Unknown option '%c'\n", command); + crm_help('?', LSB_EXIT_GENERIC); + } + amainloop = g_main_new(FALSE); + g_main_run(amainloop); } return FALSE; } #endif int set_cluster_type(enum cluster_type_e type); int -main(int argc, char ** argv) +main(int argc, char **argv) { int flag = 0; int argerr = 0; gboolean force_flag = FALSE; gboolean dangerous_cmd = FALSE; enum cluster_type_e try_stack = pcmk_cluster_unknown; int option_index = 0; - crm_peer_init(); crm_log_init(NULL, LOG_INFO, FALSE, FALSE, argc, argv); crm_set_options(NULL, "command [options]", long_options, - "Tool for displaying low-level node information"); - + "Tool for displaying low-level node information"); + while (flag >= 0) { - flag = crm_get_option(argc, argv, &option_index); - switch(flag) { - case -1: - break; - case 'V': - cl_log_enable_stderr(TRUE); - alter_debug(DEBUG_INC); - break; - case '$': - case '?': - crm_help(flag, LSB_EXIT_OK); - break; - case 'Q': - do_quiet = TRUE; - break; - case 'H': - set_cluster_type(pcmk_cluster_heartbeat); - break; - case 'A': - set_cluster_type(pcmk_cluster_classic_ais); - break; - case 'C': - set_cluster_type(pcmk_cluster_corosync); - break; - case 'c': - set_cluster_type(pcmk_cluster_cman); - break; - case 'f': - force_flag = TRUE; - break; - case 'R': - dangerous_cmd = TRUE; - command = flag; - target_uname = optarg; - break; - case 'p': - case 'e': - case 'q': - case 'i': - case 'l': - command = flag; - break; - default: - ++argerr; - break; - } + flag = crm_get_option(argc, argv, &option_index); + switch (flag) { + case -1: + break; + case 'V': + cl_log_enable_stderr(TRUE); + alter_debug(DEBUG_INC); + break; + case '$': + case '?': + crm_help(flag, LSB_EXIT_OK); + break; + case 'Q': + do_quiet = TRUE; + break; + case 'H': + set_cluster_type(pcmk_cluster_heartbeat); + break; + case 'A': + set_cluster_type(pcmk_cluster_classic_ais); + break; + case 'C': + set_cluster_type(pcmk_cluster_corosync); + break; + case 'c': + set_cluster_type(pcmk_cluster_cman); + break; + case 'f': + force_flag = TRUE; + break; + case 'R': + dangerous_cmd = TRUE; + command = flag; + target_uname = optarg; + break; + case 'p': + case 'e': + case 'q': + case 'i': + case 'l': + command = flag; + break; + default: + ++argerr; + break; + } } - + if (optind > argc) { - ++argerr; + ++argerr; } - + if (argerr) { - crm_help('?', LSB_EXIT_GENERIC); + crm_help('?', LSB_EXIT_GENERIC); } - if(dangerous_cmd && force_flag == FALSE) { - fprintf(stderr, "The supplied command is considered dangerous." - " To prevent accidental destruction of the cluster," - " the --force flag is required in order to proceed.\n"); - fflush(stderr); - exit(LSB_EXIT_GENERIC); + if (dangerous_cmd && force_flag == FALSE) { + fprintf(stderr, "The supplied command is considered dangerous." + " To prevent accidental destruction of the cluster," + " the --force flag is required in order to proceed.\n"); + fflush(stderr); + exit(LSB_EXIT_GENERIC); } try_stack = get_cluster_type(); - crm_debug("Attempting to process -%c command for cluster type: %s", command, name_for_cluster_type(try_stack)); + crm_debug("Attempting to process -%c command for cluster type: %s", command, + name_for_cluster_type(try_stack)); #if SUPPORT_CMAN - if(try_stack == pcmk_cluster_cman) { - try_cman(command, try_stack); + if (try_stack == pcmk_cluster_cman) { + try_cman(command, try_stack); } #endif - + #if SUPPORT_COROSYNC - if(try_stack == pcmk_cluster_corosync - || try_stack == pcmk_cluster_classic_ais) { - try_corosync(command, try_stack); + if (try_stack == pcmk_cluster_corosync || try_stack == pcmk_cluster_classic_ais) { + try_corosync(command, try_stack); } -#endif +#endif -#if SUPPORT_HEARTBEAT - if(try_stack == pcmk_cluster_heartbeat) { - try_heartbeat(command, try_stack); +#if SUPPORT_HEARTBEAT + if (try_stack == pcmk_cluster_heartbeat) { + try_heartbeat(command, try_stack); } #endif - - return(1); + + return (1); } diff --git a/tools/cib_shadow.c b/tools/cib_shadow.c index 240bede9c9..a7bad0654c 100644 --- a/tools/cib_shadow.c +++ b/tools/cib_shadow.c @@ -1,595 +1,603 @@ /* * Copyright (C) 2004 Andrew Beekhof * * 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 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 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 */ #include #include #include #include #include #include #include #include #include #include #include #include #include int exit_code = cib_ok; GMainLoop *mainloop = NULL; IPC_Channel *crmd_channel = NULL; const char *host = NULL; void usage(const char *cmd, int exit_status); int command_options = cib_sync_call; const char *cib_action = NULL; cib_t *real_cib = NULL; -int dump_data_element( - int depth, char **buffer, int *max, int *offset, const char *prefix, xmlNode *data, gboolean formatted); +int dump_data_element(int depth, char **buffer, int *max, int *offset, const char *prefix, + xmlNode * data, gboolean formatted); -void print_xml_diff(FILE *where, xmlNode *diff); +void print_xml_diff(FILE * where, xmlNode * diff); static int force_flag = 0; static int batch_flag = 0; -static char *get_shadow_prompt(const char *name) +static char * +get_shadow_prompt(const char *name) { int len = 16; char *prompt = NULL; + CRM_ASSERT(name != NULL); - + len += strlen(name); crm_malloc0(prompt, len); - + snprintf(prompt, len, "shadow[%s] # ", name); return prompt; } - -static void shadow_setup(char *name, gboolean do_switch) +static void +shadow_setup(char *name, gboolean do_switch) { const char *prompt = getenv("PS1"); const char *shell = getenv("SHELL"); char *new_prompt = get_shadow_prompt(name); + printf("Setting up shadow instance\n"); - if(safe_str_eq(new_prompt, prompt)) { - /* nothing to do */ - goto done; - - } else if(batch_flag == FALSE && shell != NULL) { - setenv("PS1", new_prompt, 1); - setenv("CIB_shadow", name, 1); - printf("Type Ctrl-D to exit the crm_shadow shell\n"); - - if(strstr(shell, "bash")) { - execl(shell, "--norc", "--noprofile", NULL); - } else { - execl(shell, "--noprofile", NULL); - } - + if (safe_str_eq(new_prompt, prompt)) { + /* nothing to do */ + goto done; + + } else if (batch_flag == FALSE && shell != NULL) { + setenv("PS1", new_prompt, 1); + setenv("CIB_shadow", name, 1); + printf("Type Ctrl-D to exit the crm_shadow shell\n"); + + if (strstr(shell, "bash")) { + execl(shell, "--norc", "--noprofile", NULL); + } else { + execl(shell, "--noprofile", NULL); + } + } else if (do_switch) { - printf("To switch to the named shadow instance, paste the following into your shell:\n"); + printf("To switch to the named shadow instance, paste the following into your shell:\n"); } else { - printf("A new shadow instance was created. To begin using it paste the following into your shell:\n"); + printf + ("A new shadow instance was created. To begin using it paste the following into your shell:\n"); } printf(" CIB_shadow=%s ; export CIB_shadow\n", name); done: crm_free(new_prompt); } -static void shadow_teardown(char *name) +static void +shadow_teardown(char *name) { const char *prompt = getenv("PS1"); char *our_prompt = get_shadow_prompt(name); - - if(prompt != NULL && strstr(prompt, our_prompt)) { - printf("Now type Ctrl-D to exit the crm_shadow shell\n"); - + + if (prompt != NULL && strstr(prompt, our_prompt)) { + printf("Now type Ctrl-D to exit the crm_shadow shell\n"); + } else { - printf("Please remember to unset the CIB_shadow variable by pasting the following into your shell:\n"); - printf(" unset CIB_shadow\n"); + printf + ("Please remember to unset the CIB_shadow variable by pasting the following into your shell:\n"); + printf(" unset CIB_shadow\n"); } crm_free(our_prompt); } /* *INDENT-OFF* */ static struct crm_option long_options[] = { /* Top-level Options */ {"help", 0, 0, '?', "\t\tThis text"}, {"version", 0, 0, '$', "\t\tVersion information" }, {"verbose", 0, 0, 'V', "\t\tIncrease debug output"}, {"-spacer-", 1, 0, '-', "\nQueries:"}, {"which", no_argument, NULL, 'w', "\t\tIndicate the active shadow copy"}, {"display", no_argument, NULL, 'p', "\t\tDisplay the contents of the active shadow copy"}, {"edit", no_argument, NULL, 'E', "\t\tEdit the contents of the active shadow copy with your favorite $EDITOR"}, {"diff", no_argument, NULL, 'd', "\t\tDisplay the changes in the active shadow copy\n"}, {"file", no_argument, NULL, 'F', "\t\tDisplay the location of the active shadow copy file\n"}, {"-spacer-", 1, 0, '-', "\nCommands:"}, {"create", required_argument, NULL, 'c', "\tCreate the named shadow copy of the active cluster configuration"}, {"create-empty", required_argument, NULL, 'e', "Create the named shadow copy with an empty cluster configuration"}, {"commit", required_argument, NULL, 'C', "\tUpload the contents of the named shadow copy to the cluster"}, {"delete", required_argument, NULL, 'D', "\tDelete the contents of the named shadow copy"}, {"reset", required_argument, NULL, 'r', "\tRecreate the named shadow copy from the active cluster configuration"}, {"switch", required_argument, NULL, 's', "\t(Advanced) Switch to the named shadow copy"}, {"-spacer-", 1, 0, '-', "\nAdditional Options:"}, {"force", no_argument, NULL, 'f', "\t\t(Advanced) Force the action to be performed"}, {"batch", no_argument, NULL, 'b', "\t\t(Advanced) Don't spawn a new shell" }, {"all", no_argument, NULL, 'a', "\t\t(Advanced) Upload the entire CIB, including status, with --commit" }, {"-spacer-", 1, 0, '-', "\nExamples:", pcmk_option_paragraph}, {"-spacer-", 1, 0, '-', "Create a blank shadow configuration:", pcmk_option_paragraph}, {"-spacer-", 1, 0, '-', " crm_shadow --create-empty myShadow", pcmk_option_example}, {"-spacer-", 1, 0, '-', "Create a shadow configuration from the running cluster:", pcmk_option_paragraph}, {"-spacer-", 1, 0, '-', " crm_shadow --create myShadow", pcmk_option_example}, {"-spacer-", 1, 0, '-', "Display the current shadow configuration:", pcmk_option_paragraph}, {"-spacer-", 1, 0, '-', " crm_shadow --display", pcmk_option_example}, {"-spacer-", 1, 0, '-', "Discard the current shadow configuration (named myShadow):", pcmk_option_paragraph}, {"-spacer-", 1, 0, '-', " crm_shadow --delete myShadow", pcmk_option_example}, {"-spacer-", 1, 0, '-', "Upload the current shadow configuration (named myShadow) to the running cluster:", pcmk_option_paragraph}, {"-spacer-", 1, 0, '-', " crm_shadow --commit myShadow", pcmk_option_example}, {0, 0, 0, 0} }; /* *INDENT-ON* */ int main(int argc, char **argv) { int rc = 0; int flag; int argerr = 0; static int command = '?'; char *shadow = NULL; char *shadow_file = NULL; gboolean full_upload = FALSE; gboolean dangerous_cmd = FALSE; struct stat buf; int option_index = 0; crm_log_init("crm_shadow", LOG_CRIT, FALSE, FALSE, argc, argv); crm_set_options(NULL, "(query|command) [modifiers]", long_options, - "Perform configuration changes in a sandbox before updating the live cluster." - "\n\nSets up an environment in which configuration tools (cibadmin, crm_resource, etc) work" - " offline instead of against a live cluster, allowing changes to be previewed and tested" - " for side-effects.\n"); - - if(argc < 2) { - crm_help('?', LSB_EXIT_EINVAL); + "Perform configuration changes in a sandbox before updating the live cluster." + "\n\nSets up an environment in which configuration tools (cibadmin, crm_resource, etc) work" + " offline instead of against a live cluster, allowing changes to be previewed and tested" + " for side-effects.\n"); + + if (argc < 2) { + crm_help('?', LSB_EXIT_EINVAL); } while (1) { - flag = crm_get_option(argc, argv, &option_index); - if (flag == -1 || flag == 0) - break; - - switch(flag) { - case 'a': - full_upload = TRUE; - break; - case 'd': - case 'E': - case 'p': - case 'w': - case 'F': - command = flag; - crm_free(shadow); - shadow = crm_strdup(getenv("CIB_shadow")); - break; - case 'e': - case 'c': - case 's': - case 'r': - command = flag; - crm_free(shadow); - shadow = crm_strdup(optarg); - break; - case 'C': - case 'D': - command = flag; - dangerous_cmd = TRUE; - crm_free(shadow); - shadow = crm_strdup(optarg); - break; - case 'V': - command_options = command_options | cib_verbose; - cl_log_enable_stderr(TRUE); - alter_debug(DEBUG_INC); - break; - case '$': - case '?': - crm_help(flag, LSB_EXIT_OK); - break; - case 'f': - command_options |= cib_quorum_override; - force_flag = 1; - break; - case 'b': - batch_flag = 1; - break; - default: - printf("Argument code 0%o (%c)" - " is not (?yet?) supported\n", - flag, flag); - ++argerr; - break; - } + flag = crm_get_option(argc, argv, &option_index); + if (flag == -1 || flag == 0) + break; + + switch (flag) { + case 'a': + full_upload = TRUE; + break; + case 'd': + case 'E': + case 'p': + case 'w': + case 'F': + command = flag; + crm_free(shadow); + shadow = crm_strdup(getenv("CIB_shadow")); + break; + case 'e': + case 'c': + case 's': + case 'r': + command = flag; + crm_free(shadow); + shadow = crm_strdup(optarg); + break; + case 'C': + case 'D': + command = flag; + dangerous_cmd = TRUE; + crm_free(shadow); + shadow = crm_strdup(optarg); + break; + case 'V': + command_options = command_options | cib_verbose; + cl_log_enable_stderr(TRUE); + alter_debug(DEBUG_INC); + break; + case '$': + case '?': + crm_help(flag, LSB_EXIT_OK); + break; + case 'f': + command_options |= cib_quorum_override; + force_flag = 1; + break; + case 'b': + batch_flag = 1; + 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"); - crm_help('?', LSB_EXIT_EINVAL); + printf("non-option ARGV-elements: "); + while (optind < argc) + printf("%s ", argv[optind++]); + printf("\n"); + crm_help('?', LSB_EXIT_EINVAL); } if (optind > argc) { - ++argerr; + ++argerr; } - + if (argerr) { - crm_help('?', LSB_EXIT_GENERIC); + crm_help('?', LSB_EXIT_GENERIC); } - if(command == 'w') { - /* which shadow instance is active? */ - const char *local = getenv("CIB_shadow"); - if(local == NULL) { - fprintf(stderr, "No shadow instance provided\n"); - rc = cib_NOTEXISTS; - goto done; - } - fprintf(stdout, "%s\n", local); - rc = 0; - goto done; + if (command == 'w') { + /* which shadow instance is active? */ + const char *local = getenv("CIB_shadow"); + + if (local == NULL) { + fprintf(stderr, "No shadow instance provided\n"); + rc = cib_NOTEXISTS; + goto done; + } + fprintf(stdout, "%s\n", local); + rc = 0; + goto done; } - - if(shadow == NULL) { - fprintf(stderr, "No shadow instance provided\n"); - fflush(stderr); - rc = CIBRES_MISSING_FIELD; - goto done; - - } else if(command != 's' && command != 'c') { - const char *local = getenv("CIB_shadow"); - if(local != NULL && safe_str_neq(local, shadow) && force_flag == FALSE) { - fprintf(stderr, "The supplied shadow instance (%s) is not the same as the active one (%s).\n" - " To prevent accidental destruction of the cluster," - " the --force flag is required in order to proceed.\n", shadow, local); - fflush(stderr); - rc = LSB_EXIT_GENERIC; - goto done; - } + + if (shadow == NULL) { + fprintf(stderr, "No shadow instance provided\n"); + fflush(stderr); + rc = CIBRES_MISSING_FIELD; + goto done; + + } else if (command != 's' && command != 'c') { + const char *local = getenv("CIB_shadow"); + + if (local != NULL && safe_str_neq(local, shadow) && force_flag == FALSE) { + fprintf(stderr, + "The supplied shadow instance (%s) is not the same as the active one (%s).\n" + " To prevent accidental destruction of the cluster," + " the --force flag is required in order to proceed.\n", shadow, local); + fflush(stderr); + rc = LSB_EXIT_GENERIC; + goto done; + } } - if(dangerous_cmd && force_flag == FALSE) { - fprintf(stderr, "The supplied command is considered dangerous." - " To prevent accidental destruction of the cluster," - " the --force flag is required in order to proceed.\n"); - fflush(stderr); - rc = LSB_EXIT_GENERIC; - goto done; + if (dangerous_cmd && force_flag == FALSE) { + fprintf(stderr, "The supplied command is considered dangerous." + " To prevent accidental destruction of the cluster," + " the --force flag is required in order to proceed.\n"); + fflush(stderr); + rc = LSB_EXIT_GENERIC; + goto done; } shadow_file = get_shadow_file(shadow); - if(command == 'D') { - /* delete the file */ - rc = stat(shadow_file, &buf); - if(rc == 0) { - rc = unlink(shadow_file); - if(rc != 0) { - fprintf(stderr, "Could not remove shadow instance '%s': %s\n", shadow, strerror(errno)); - goto done; - } - } - - shadow_teardown(shadow); - goto done; - - } else if(command == 'F') { - printf("%s\n", shadow_file); - rc = 0; - goto done; + if (command == 'D') { + /* delete the file */ + rc = stat(shadow_file, &buf); + if (rc == 0) { + rc = unlink(shadow_file); + if (rc != 0) { + fprintf(stderr, "Could not remove shadow instance '%s': %s\n", shadow, + strerror(errno)); + goto done; + } + } + + shadow_teardown(shadow); + goto done; + + } else if (command == 'F') { + printf("%s\n", shadow_file); + rc = 0; + goto done; } - if(command == 'd' || command == 'r' || command == 'c' || command == 'C') { - real_cib = cib_new_no_shadow(); - rc = real_cib->cmds->signon(real_cib, crm_system_name, cib_command); - if(rc != cib_ok) { - fprintf(stderr, "Signon to CIB failed: %s\n", cib_error2string(rc)); - goto done; - } + if (command == 'd' || command == 'r' || command == 'c' || command == 'C') { + real_cib = cib_new_no_shadow(); + rc = real_cib->cmds->signon(real_cib, crm_system_name, cib_command); + if (rc != cib_ok) { + fprintf(stderr, "Signon to CIB failed: %s\n", cib_error2string(rc)); + goto done; + } } - + rc = stat(shadow_file, &buf); - if(command == 'e' || command == 'c') { - if (rc == 0 && force_flag == FALSE) { - fprintf(stderr, "A shadow instance '%s' already exists.\n" - " To prevent accidental destruction of the cluster," - " the --force flag is required in order to proceed.\n", shadow); - rc = cib_EXISTS; - goto done; - } - - } else if(rc != 0) { - fprintf(stderr, "Could not access shadow instance '%s': %s\n", shadow, strerror(errno)); - rc = cib_NOTEXISTS; - goto done; + if (command == 'e' || command == 'c') { + if (rc == 0 && force_flag == FALSE) { + fprintf(stderr, "A shadow instance '%s' already exists.\n" + " To prevent accidental destruction of the cluster," + " the --force flag is required in order to proceed.\n", shadow); + rc = cib_EXISTS; + goto done; + } + + } else if (rc != 0) { + fprintf(stderr, "Could not access shadow instance '%s': %s\n", shadow, strerror(errno)); + rc = cib_NOTEXISTS; + goto done; } rc = cib_ok; - if(command == 'c' || command == 'e') { - xmlNode *output = NULL; - - /* create a shadow instance based on the current cluster config */ - if(command == 'c') { - rc = real_cib->cmds->query(real_cib, NULL, &output, command_options); - if(rc != cib_ok) { - fprintf(stderr, "Could not connect to the CIB: %s\n", cib_error2string(rc)); - goto done; - } - - } else { - output = createEmptyCib(); - crm_xml_add(output, XML_ATTR_GENERATION, "0"); - crm_xml_add(output, XML_ATTR_NUMUPDATES, "0"); - crm_xml_add(output, XML_ATTR_GENERATION_ADMIN, "0"); - crm_xml_add(output, XML_ATTR_VALIDATION, LATEST_SCHEMA_VERSION); - } - - rc = write_xml_file(output, shadow_file, FALSE); - free_xml(output); - - if(rc < 0) { - fprintf(stderr, "Could not create the shadow instance '%s': %s\n", - shadow, strerror(errno)); - goto done; - } - shadow_setup(shadow, FALSE); - rc = cib_ok; - - } else if(command == 'E') { - const char *err = NULL; - char *editor = getenv("EDITOR"); - if(editor == NULL) { - fprintf(stderr, "No value for $EDITOR defined\n"); - rc = cib_missing; - goto done; - } - - execlp(editor, "--", shadow_file, NULL); - err = strerror(errno); - fprintf(stderr, "Could not invoke $EDITOR (%s %s): %s\n", editor, shadow_file, err); - rc = cib_missing; - goto done; - - } else if(command == 's') { - shadow_setup(shadow, TRUE); - rc = 0; - goto done; - - } else if(command == 'P') { - /* display the current contents */ - char *output_s = NULL; - xmlNode *output = filename2xml(shadow_file); - - output_s = dump_xml_formatted(output); - printf("%s", output_s); - - crm_free(output_s); - free_xml(output); - - } else if(command == 'd') { - /* diff against cluster */ - xmlNode *diff = NULL; - xmlNode *old_config = NULL; - xmlNode *new_config = filename2xml(shadow_file); - - rc = real_cib->cmds->query(real_cib, NULL, &old_config, command_options); - - if(rc != cib_ok) { - fprintf(stderr, "Could not query the CIB: %s\n", cib_error2string(rc)); - goto done; - } - - diff = diff_xml_object(old_config, new_config, FALSE); - if(diff != NULL) { - print_xml_diff(stdout, diff); - rc = 1; - goto done; - } - rc = 0; - goto done; - - } else if(command == 'C') { - /* commit to the cluster */ - xmlNode *input = filename2xml(shadow_file); - if(full_upload) { - rc = real_cib->cmds->replace(real_cib, NULL, input, command_options); - } else { - xmlNode *config = first_named_child(input, XML_CIB_TAG_CONFIGURATION); - rc = real_cib->cmds->replace(real_cib, XML_CIB_TAG_CONFIGURATION, config, command_options); - } - - if(rc != cib_ok) { - fprintf(stderr, "Could not commit shadow instance '%s' to the CIB: %s\n", - shadow, cib_error2string(rc)); - return rc; - } - shadow_teardown(shadow); - free_xml(input); + if (command == 'c' || command == 'e') { + xmlNode *output = NULL; + + /* create a shadow instance based on the current cluster config */ + if (command == 'c') { + rc = real_cib->cmds->query(real_cib, NULL, &output, command_options); + if (rc != cib_ok) { + fprintf(stderr, "Could not connect to the CIB: %s\n", cib_error2string(rc)); + goto done; + } + + } else { + output = createEmptyCib(); + crm_xml_add(output, XML_ATTR_GENERATION, "0"); + crm_xml_add(output, XML_ATTR_NUMUPDATES, "0"); + crm_xml_add(output, XML_ATTR_GENERATION_ADMIN, "0"); + crm_xml_add(output, XML_ATTR_VALIDATION, LATEST_SCHEMA_VERSION); + } + + rc = write_xml_file(output, shadow_file, FALSE); + free_xml(output); + + if (rc < 0) { + fprintf(stderr, "Could not create the shadow instance '%s': %s\n", + shadow, strerror(errno)); + goto done; + } + shadow_setup(shadow, FALSE); + rc = cib_ok; + + } else if (command == 'E') { + const char *err = NULL; + char *editor = getenv("EDITOR"); + + if (editor == NULL) { + fprintf(stderr, "No value for $EDITOR defined\n"); + rc = cib_missing; + goto done; + } + + execlp(editor, "--", shadow_file, NULL); + err = strerror(errno); + fprintf(stderr, "Could not invoke $EDITOR (%s %s): %s\n", editor, shadow_file, err); + rc = cib_missing; + goto done; + + } else if (command == 's') { + shadow_setup(shadow, TRUE); + rc = 0; + goto done; + + } else if (command == 'P') { + /* display the current contents */ + char *output_s = NULL; + xmlNode *output = filename2xml(shadow_file); + + output_s = dump_xml_formatted(output); + printf("%s", output_s); + + crm_free(output_s); + free_xml(output); + + } else if (command == 'd') { + /* diff against cluster */ + xmlNode *diff = NULL; + xmlNode *old_config = NULL; + xmlNode *new_config = filename2xml(shadow_file); + + rc = real_cib->cmds->query(real_cib, NULL, &old_config, command_options); + + if (rc != cib_ok) { + fprintf(stderr, "Could not query the CIB: %s\n", cib_error2string(rc)); + goto done; + } + + diff = diff_xml_object(old_config, new_config, FALSE); + if (diff != NULL) { + print_xml_diff(stdout, diff); + rc = 1; + goto done; + } + rc = 0; + goto done; + + } else if (command == 'C') { + /* commit to the cluster */ + xmlNode *input = filename2xml(shadow_file); + + if (full_upload) { + rc = real_cib->cmds->replace(real_cib, NULL, input, command_options); + } else { + xmlNode *config = first_named_child(input, XML_CIB_TAG_CONFIGURATION); + + rc = real_cib->cmds->replace(real_cib, XML_CIB_TAG_CONFIGURATION, config, + command_options); + } + + if (rc != cib_ok) { + fprintf(stderr, "Could not commit shadow instance '%s' to the CIB: %s\n", + shadow, cib_error2string(rc)); + return rc; + } + shadow_teardown(shadow); + free_xml(input); } done: crm_xml_cleanup(); crm_free(shadow_file); crm_free(shadow); return rc; } -#define bhead(buffer, offset) ((*buffer) + (*offset)) -#define bremain(max, offset) ((*max) - (*offset)) +#define bhead(buffer, offset) ((*buffer) + (*offset)) +#define bremain(max, offset) ((*max) - (*offset)) #define update_buffer_head(len) do { \ int total = (*offset) + len + 1; \ if(total >= (*max)) { /* too late */ \ (*buffer) = EOS; return -1; \ } else if(((*max) - total) < 256) { \ (*max) *= 10; \ crm_realloc(*buffer, (*max)); \ } \ (*offset) += len; \ } while(0) extern int print_spaces(char *buffer, int depth, int max); int -dump_data_element( - int depth, char **buffer, int *max, int *offset, const char *prefix, xmlNode *data, gboolean formatted) +dump_data_element(int depth, char **buffer, int *max, int *offset, const char *prefix, + xmlNode * data, gboolean formatted) { int printed = 0; int has_children = 0; xmlNode *child = NULL; const char *name = NULL; - + CRM_CHECK(data != NULL, return 0); - + name = crm_element_name(data); - + CRM_CHECK(name != NULL, return 0); CRM_CHECK(buffer != NULL && *buffer != NULL, return 0); - + crm_debug_5("Dumping %s...", name); - if(prefix) { - printed = snprintf(bhead(buffer, offset), bremain(max, offset), "%s", prefix); - update_buffer_head(printed); + if (prefix) { + printed = snprintf(bhead(buffer, offset), bremain(max, offset), "%s", prefix); + update_buffer_head(printed); } - if(formatted) { - printed = print_spaces(bhead(buffer, offset), depth, bremain(max, offset)); - update_buffer_head(printed); + if (formatted) { + printed = print_spaces(bhead(buffer, offset), depth, bremain(max, offset)); + update_buffer_head(printed); } - + printed = snprintf(bhead(buffer, offset), bremain(max, offset), "<%s", name); update_buffer_head(printed); - + xml_prop_iter(data, prop_name, prop_value, - crm_debug_5("Dumping <%s %s=\"%s\"...", - name, prop_name, prop_value); - printed = snprintf(bhead(buffer, offset), bremain(max, offset), " %s=\"%s\"", prop_name, prop_value); - update_buffer_head(printed); - ); - + crm_debug_5("Dumping <%s %s=\"%s\"...", + name, prop_name, prop_value); + printed = + snprintf(bhead(buffer, offset), bremain(max, offset), " %s=\"%s\"", prop_name, + prop_value); update_buffer_head(printed);); + has_children = xml_has_children(data); - printed = snprintf(bhead(buffer, offset), bremain(max, offset), "%s>%s", - has_children==0?"/":"", formatted?"\n":""); + printed = snprintf(bhead(buffer, offset), bremain(max, offset), "%s>%s", + has_children == 0 ? "/" : "", formatted ? "\n" : ""); update_buffer_head(printed); - - if(has_children == 0) { - return 0; + + if (has_children == 0) { + return 0; } - - for(child = __xml_first_child(data); child != NULL; child = __xml_next(child)) { - if(dump_data_element(depth+1, buffer, max, offset, prefix, child, formatted) < 0) { - return -1; - } + + for (child = __xml_first_child(data); child != NULL; child = __xml_next(child)) { + if (dump_data_element(depth + 1, buffer, max, offset, prefix, child, formatted) < 0) { + return -1; + } } - - if(prefix) { - printed = snprintf(bhead(buffer, offset), bremain(max, offset), "%s", prefix); - update_buffer_head(printed); + + if (prefix) { + printed = snprintf(bhead(buffer, offset), bremain(max, offset), "%s", prefix); + update_buffer_head(printed); } - if(formatted) { - printed = print_spaces(bhead(buffer, offset), depth, bremain(max, offset)); - update_buffer_head(printed); + if (formatted) { + printed = print_spaces(bhead(buffer, offset), depth, bremain(max, offset)); + update_buffer_head(printed); } - - printed = snprintf(bhead(buffer, offset), bremain(max, offset), "%s", name, formatted?"\n":""); + + printed = + snprintf(bhead(buffer, offset), bremain(max, offset), "%s", name, + formatted ? "\n" : ""); update_buffer_head(printed); crm_debug_5("Dumped %s...", name); - + return has_children; } void -print_xml_diff(FILE *where, xmlNode *diff) +print_xml_diff(FILE * where, xmlNode * diff) { char *buffer = NULL; xmlNode *child = NULL; int max = 1024, len = 0; gboolean is_first = TRUE; xmlNode *added = find_xml_node(diff, "diff-added", FALSE); xmlNode *removed = find_xml_node(diff, "diff-removed", FALSE); is_first = TRUE; - for(child = __xml_first_child(removed); child != NULL; child = __xml_next(child)) { - len = 0; - max = 1024; - crm_free(buffer); - crm_malloc0(buffer, max); - - if(is_first) { - is_first = FALSE; - } else { - fprintf(where, " --- \n"); - } - - CRM_CHECK(dump_data_element( - 0, &buffer, &max, &len, "-", child, TRUE) >= 0, - continue); - fprintf(where, "%s", buffer); + for (child = __xml_first_child(removed); child != NULL; child = __xml_next(child)) { + len = 0; + max = 1024; + crm_free(buffer); + crm_malloc0(buffer, max); + + if (is_first) { + is_first = FALSE; + } else { + fprintf(where, " --- \n"); + } + + CRM_CHECK(dump_data_element(0, &buffer, &max, &len, "-", child, TRUE) >= 0, continue); + fprintf(where, "%s", buffer); } - is_first = TRUE; - for(child = __xml_first_child(added); child != NULL; child = __xml_next(child)) { - len = 0; - max = 1024; - crm_free(buffer); - crm_malloc0(buffer, max); - - if(is_first) { - is_first = FALSE; - } else { - fprintf(where, " +++ \n"); - } - - CRM_CHECK(dump_data_element( - 0, &buffer, &max, &len, "+", child, TRUE) >= 0, - continue); - fprintf(where, "%s", buffer); + for (child = __xml_first_child(added); child != NULL; child = __xml_next(child)) { + len = 0; + max = 1024; + crm_free(buffer); + crm_malloc0(buffer, max); + + if (is_first) { + is_first = FALSE; + } else { + fprintf(where, " +++ \n"); + } + + CRM_CHECK(dump_data_element(0, &buffer, &max, &len, "+", child, TRUE) >= 0, continue); + fprintf(where, "%s", buffer); } } - diff --git a/tools/cibadmin.c b/tools/cibadmin.c index 6efa418b93..490f0efb01 100644 --- a/tools/cibadmin.c +++ b/tools/cibadmin.c @@ -1,588 +1,573 @@ /* * Copyright (C) 2004 Andrew Beekhof * * 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 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 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 */ #include #include #include #include #include #include #include #include #include #include #include #include #include int exit_code = cib_ok; int message_timer_id = -1; int message_timeout_ms = 30; GMainLoop *mainloop = NULL; IPC_Channel *crmd_channel = NULL; const char *host = NULL; void usage(const char *cmd, int exit_status); enum cib_errors do_init(void); -int do_work(xmlNode *input, int command_options, xmlNode **output); +int do_work(xmlNode * input, int command_options, xmlNode ** output); gboolean admin_msg_callback(IPC_Channel * source_data, void *private_data); gboolean admin_message_timeout(gpointer data); void cib_connection_destroy(gpointer user_data); -void cibadmin_op_callback(xmlNode *msg, int call_id, int rc, - xmlNode *output, void *user_data); +void cibadmin_op_callback(xmlNode * msg, int call_id, int rc, xmlNode * output, void *user_data); int command_options = 0; const char *cib_action = NULL; -typedef struct str_list_s -{ - int num_items; - char *value; - struct str_list_s *next; +typedef struct str_list_s { + int num_items; + char *value; + struct str_list_s *next; } str_list_t; char *obj_type = NULL; char *status = NULL; char *migrate_from = NULL; char *migrate_res = NULL; char *subtype = NULL; char *reset = NULL; int request_id = 0; int operation_status = 0; cib_t *the_cib = NULL; gboolean force_flag = FALSE; /* *INDENT-OFF* */ static struct crm_option long_options[] = { {"help", 0, 0, '?', "\tThis text"}, {"version", 0, 0, '$', "\tVersion information" }, {"verbose", 0, 0, 'V', "\tIncrease debug output\n"}, {"-spacer-", 0, 0, '-', "Commands:"}, {"upgrade", 0, 0, 'u', "\tUpgrade the configuration to the latest syntax"}, {"query", 0, 0, 'Q', "\tQuery the contents of the CIB"}, {"erase", 0, 0, 'E', "\tErase the contents of the whole CIB"}, {"bump", 0, 0, 'B', "\tIncrease the CIB's epoch value by 1"}, {"create", 0, 0, 'C', "\tCreate an object in the CIB. Will fail if the object already exists."}, {"modify", 0, 0, 'M', "\tFind the object somewhere in the CIB's XML tree and update it. Fails if the object does not exist unless -c is specified"}, {"patch", 0, 0, 'P', "\tSupply an update in the form of an xml diff (See also: crm_diff)"}, {"replace", 0, 0, 'R', "\tRecursivly replace an object in the CIB"}, {"delete", 0, 0, 'D', "\tDelete the first object matching the supplied criteria, Eg. "}, {"-spacer-", 0, 0, '-', "\n\t\t\tThe tagname and all attributes must match in order for the element to be deleted"}, {"delete-all", 0, 0, 'd', "\tWhen used with --xpath, remove all matching objects in the configuration instead of just the first one"}, {"md5-sum", 0, 0, '5', "\tCalculate a CIB digest"}, {"sync", 0, 0, 'S', "\t(Advanced) Force a refresh of the CIB to all nodes\n"}, {"make-slave", 0, 0, 'r', NULL, 1}, {"make-master", 0, 0, 'w', NULL, 1}, {"is-master", 0, 0, 'm', NULL, 1}, {"empty", 0, 0, 'a', "\tOutput an empty CIB", 1}, {"blank", 0, 0, 'a', NULL, 1}, {"-spacer-",1, 0, '-', "\nAdditional options:"}, {"force", 0, 0, 'f'}, {"timeout", 1, 0, 't', "Time (in seconds) to wait before declaring the operation failed"}, {"sync-call", 0, 0, 's', "Wait for call to complete before returning"}, {"local", 0, 0, 'l', "\tCommand takes effect locally. Should only be used for queries"}, {"allow-create",0, 0, 'c', "(Advanced) Allow the target of a -M operation to be created if they do not exist"}, {"no-children", 0, 0, 'n', "(Advanced) When querying an object, do not return include its children in the result\n"}, {"no-bcast", 0, 0, 'b', NULL, 1}, {"-spacer-", 0, 0, '-', "Data:"}, {"xml-text", 1, 0, 'X', "Retrieve XML from the supplied string"}, {"xml-file", 1, 0, 'x', "Retrieve XML from the named file"}, {"xml-pipe", 0, 0, 'p', "Retrieve XML from stdin\n"}, {"xpath", 1, 0, 'A', "A valid XPath to use instead of -o"}, {"scope", 1, 0, 'o', "Limit the scope of the operation to a specific section of the CIB."}, {"-spacer-", 0, 0, '-', "\t\t\tValid values are: nodes, resources, constraints, crm_config, rsc_defaults, op_defaults, status"}, {"node", 1, 0, 'N', "(Advanced) Send command to the specified host\n"}, {"-space-", 0, 0, '!', NULL, 1}, {"-spacer-", 0, 0, '-', "\nExamples:\n"}, {"-spacer-", 0, 0, '-', "Query the configuration from the local node:", pcmk_option_paragraph}, {"-spacer-", 0, 0, '-', " cibadmin --query --local", pcmk_option_example}, {"-spacer-", 0, 0, '-', "Query the just the cluster options configuration:", pcmk_option_paragraph}, {"-spacer-", 0, 0, '-', " cibadmin --query --scope crm_config", pcmk_option_example}, {"-spacer-", 0, 0, '-', "Query all 'target-role' settings:", pcmk_option_paragraph}, {"-spacer-", 0, 0, '-', " cibadmin --query --xpath \"//nvpair[@name='target-role']\"", pcmk_option_example}, {"-spacer-", 0, 0, '-', "Remove all 'is-managed' settings:", pcmk_option_paragraph}, {"-spacer-", 0, 0, '-', " cibadmin --delete-all --xpath \"//nvpair[@name='is-managed']\"", pcmk_option_example}, {"-spacer-", 0, 0, '-', "Remove the resource named 'old':", pcmk_option_paragraph}, {"-spacer-", 0, 0, '-', " cibadmin --delete --xml-text ''", pcmk_option_example}, {"-spacer-", 0, 0, '-', "Remove all resources from the configuration:", pcmk_option_paragraph}, {"-spacer-", 0, 0, '-', " cibadmin --replace --scope resources --xml-text ''", pcmk_option_example}, {"-spacer-", 0, 0, '-', "Replace the complete configuration with the contents of $HOME/pacemaker.xml:", pcmk_option_paragraph}, {"-spacer-", 0, 0, '-', " cibadmin --replace --xml-file $HOME/pacemaker.xml", pcmk_option_example}, {"-spacer-", 0, 0, '-', "Replace the constraints section of the configuration with the contents of $HOME/constraints.xml:", pcmk_option_paragraph}, {"-spacer-", 0, 0, '-', " cibadmin --replace --scope constraints --xml-file $HOME/constraints.xml", pcmk_option_example}, {"-spacer-", 0, 0, '-', "Increase the configuration version to prevent old configurations from being loaded accidentally:", pcmk_option_paragraph}, {"-spacer-", 0, 0, '-', " cibadmin --modify --xml-text ''", pcmk_option_example}, {"-spacer-", 0, 0, '-', "Edit the configuration with your favorite $EDITOR:", pcmk_option_paragraph}, {"-spacer-", 0, 0, '-', " cibadmin --query > $HOME/local.xml", pcmk_option_example}, {"-spacer-", 0, 0, '-', " $EDITOR $HOME/local.xml", pcmk_option_example}, {"-spacer-", 0, 0, '-', " cibadmin --replace --xml-file $HOME/local.xml", pcmk_option_example}, {"-spacer-", 0, 0, '-', "SEE ALSO:"}, {"-spacer-", 0, 0, '-', " CRM shell, crm(8), crm_shadow(8)"}, /* Legacy options */ {"host", 0, 0, 'h', NULL, 1}, {"force-quorum", 0, 0, 'f', NULL, 1}, {"obj_type", 1, 0, 'o', NULL, 1}, {F_CRM_DATA, 1, 0, 'X', NULL, 1}, {CIB_OP_ERASE, 0, 0, 'E', NULL, 1}, {CIB_OP_QUERY, 0, 0, 'Q', NULL, 1}, {CIB_OP_CREATE, 0, 0, 'C', NULL, 1}, {CIB_OP_REPLACE, 0, 0, 'R', NULL, 1}, {CIB_OP_UPDATE, 0, 0, 'U', NULL, 1}, {CIB_OP_MODIFY, 0, 0, 'M', NULL, 1}, {CIB_OP_DELETE, 0, 0, 'D', NULL, 1}, {CIB_OP_BUMP, 0, 0, 'B', NULL, 1}, {CIB_OP_SYNC, 0, 0, 'S', NULL, 1}, {CIB_OP_SLAVE, 0, 0, 'r', NULL, 1}, {CIB_OP_MASTER, 0, 0, 'w', NULL, 1}, {CIB_OP_ISMASTER,0, 0, 'm', NULL, 1}, {0, 0, 0, 0} }; /* *INDENT-ON* */ int main(int argc, char **argv) { int argerr = 0; int flag; const char *source = NULL; char *admin_input_xml = NULL; char *admin_input_file = NULL; gboolean dangerous_cmd = FALSE; gboolean admin_input_stdin = FALSE; xmlNode *output = NULL; xmlNode *input = NULL; - + int option_index = 0; + crm_log_init(NULL, LOG_CRIT, FALSE, FALSE, argc, argv); crm_set_options(NULL, "command [options] [data]", long_options, - "Provides direct access to the cluster configuration." - "\n\n Allows the configuration, or sections of it, to be queried, modified, replaced and deleted." - "\n\n Where necessary, XML data will be obtained using the -X, -x, or -p options\n"); + "Provides direct access to the cluster configuration." + "\n\n Allows the configuration, or sections of it, to be queried, modified, replaced and deleted." + "\n\n Where necessary, XML data will be obtained using the -X, -x, or -p options\n"); - if(argc < 2) { - crm_help('?',LSB_EXIT_EINVAL); + if (argc < 2) { + crm_help('?', LSB_EXIT_EINVAL); } while (1) { - flag = crm_get_option(argc, argv, &option_index); - if (flag == -1) - break; - - switch(flag) { - case 't': - message_timeout_ms = atoi(optarg); - if(message_timeout_ms < 1) { - message_timeout_ms = 30; - } - break; - case 'A': - obj_type = crm_strdup(optarg); - command_options |= cib_xpath; - break; - case 'u': - cib_action = CIB_OP_UPGRADE; - dangerous_cmd = TRUE; - break; - case 'E': - cib_action = CIB_OP_ERASE; - dangerous_cmd = TRUE; - break; - case 'Q': - cib_action = CIB_OP_QUERY; - break; - case 'P': - cib_action = CIB_OP_APPLY_DIFF; - break; - case 'S': - cib_action = CIB_OP_SYNC; - break; - case 'U': - case 'M': - cib_action = CIB_OP_MODIFY; - break; - case 'R': - cib_action = CIB_OP_REPLACE; - break; - case 'C': - cib_action = CIB_OP_CREATE; - break; - case 'D': - cib_action = CIB_OP_DELETE; - break; - case '5': - cib_action = "md5-sum"; - break; - case 'c': - command_options |= cib_can_create; - break; - case 'n': - command_options |= cib_no_children; - break; - case 'm': - cib_action = CIB_OP_ISMASTER; - command_options |= cib_scope_local; - break; - case 'B': - cib_action = CIB_OP_BUMP; - break; - case 'r': - dangerous_cmd = TRUE; - cib_action = CIB_OP_SLAVE; - break; - case 'w': - dangerous_cmd = TRUE; - cib_action = CIB_OP_MASTER; - command_options |= cib_scope_local; - break; - case 'V': - command_options = command_options | cib_verbose; - cl_log_enable_stderr(TRUE); - alter_debug(DEBUG_INC); - break; - case '?': - case '$': - case '!': - crm_help(flag, LSB_EXIT_OK); - break; - case 'o': - crm_debug_2("Option %c => %s", flag, optarg); - obj_type = crm_strdup(optarg); - break; - case 'X': - crm_debug_2("Option %c => %s", flag, optarg); - admin_input_xml = crm_strdup(optarg); - break; - case 'x': - crm_debug_2("Option %c => %s", flag, optarg); - admin_input_file = crm_strdup(optarg); - break; - case 'p': - admin_input_stdin = TRUE; - break; - case 'h': - host = crm_strdup(optarg); - break; - case 'l': - command_options |= cib_scope_local; - break; - case 'd': - cib_action = CIB_OP_DELETE; - command_options |= cib_multiple; - dangerous_cmd = TRUE; - break; - case 'b': - dangerous_cmd = TRUE; - command_options |= cib_inhibit_bcast; - command_options |= cib_scope_local; - break; - case 's': - command_options |= cib_sync_call; - break; - case 'f': - force_flag = TRUE; - command_options |= cib_quorum_override; - break; - case 'a': - output = createEmptyCib(); - crm_xml_add(output, XML_ATTR_CRM_VERSION, CRM_FEATURE_SET); - crm_xml_add(output, XML_ATTR_VALIDATION, LATEST_SCHEMA_VERSION); - crm_xml_add_int(output, XML_ATTR_GENERATION_ADMIN, 1); - crm_xml_add_int(output, XML_ATTR_GENERATION, 0); - crm_xml_add_int(output, XML_ATTR_NUMUPDATES, 0); - - admin_input_xml = dump_xml_formatted(output); - fprintf(stdout, "%s\n", crm_str(admin_input_xml)); - exit(0); - break; - default: - printf("Argument code 0%o (%c)" - " is not (?yet?) supported\n", - flag, flag); - ++argerr; - break; - } + flag = crm_get_option(argc, argv, &option_index); + if (flag == -1) + break; + + switch (flag) { + case 't': + message_timeout_ms = atoi(optarg); + if (message_timeout_ms < 1) { + message_timeout_ms = 30; + } + break; + case 'A': + obj_type = crm_strdup(optarg); + command_options |= cib_xpath; + break; + case 'u': + cib_action = CIB_OP_UPGRADE; + dangerous_cmd = TRUE; + break; + case 'E': + cib_action = CIB_OP_ERASE; + dangerous_cmd = TRUE; + break; + case 'Q': + cib_action = CIB_OP_QUERY; + break; + case 'P': + cib_action = CIB_OP_APPLY_DIFF; + break; + case 'S': + cib_action = CIB_OP_SYNC; + break; + case 'U': + case 'M': + cib_action = CIB_OP_MODIFY; + break; + case 'R': + cib_action = CIB_OP_REPLACE; + break; + case 'C': + cib_action = CIB_OP_CREATE; + break; + case 'D': + cib_action = CIB_OP_DELETE; + break; + case '5': + cib_action = "md5-sum"; + break; + case 'c': + command_options |= cib_can_create; + break; + case 'n': + command_options |= cib_no_children; + break; + case 'm': + cib_action = CIB_OP_ISMASTER; + command_options |= cib_scope_local; + break; + case 'B': + cib_action = CIB_OP_BUMP; + break; + case 'r': + dangerous_cmd = TRUE; + cib_action = CIB_OP_SLAVE; + break; + case 'w': + dangerous_cmd = TRUE; + cib_action = CIB_OP_MASTER; + command_options |= cib_scope_local; + break; + case 'V': + command_options = command_options | cib_verbose; + cl_log_enable_stderr(TRUE); + alter_debug(DEBUG_INC); + break; + case '?': + case '$': + case '!': + crm_help(flag, LSB_EXIT_OK); + break; + case 'o': + crm_debug_2("Option %c => %s", flag, optarg); + obj_type = crm_strdup(optarg); + break; + case 'X': + crm_debug_2("Option %c => %s", flag, optarg); + admin_input_xml = crm_strdup(optarg); + break; + case 'x': + crm_debug_2("Option %c => %s", flag, optarg); + admin_input_file = crm_strdup(optarg); + break; + case 'p': + admin_input_stdin = TRUE; + break; + case 'h': + host = crm_strdup(optarg); + break; + case 'l': + command_options |= cib_scope_local; + break; + case 'd': + cib_action = CIB_OP_DELETE; + command_options |= cib_multiple; + dangerous_cmd = TRUE; + break; + case 'b': + dangerous_cmd = TRUE; + command_options |= cib_inhibit_bcast; + command_options |= cib_scope_local; + break; + case 's': + command_options |= cib_sync_call; + break; + case 'f': + force_flag = TRUE; + command_options |= cib_quorum_override; + break; + case 'a': + output = createEmptyCib(); + crm_xml_add(output, XML_ATTR_CRM_VERSION, CRM_FEATURE_SET); + crm_xml_add(output, XML_ATTR_VALIDATION, LATEST_SCHEMA_VERSION); + crm_xml_add_int(output, XML_ATTR_GENERATION_ADMIN, 1); + crm_xml_add_int(output, XML_ATTR_GENERATION, 0); + crm_xml_add_int(output, XML_ATTR_NUMUPDATES, 0); + + admin_input_xml = dump_xml_formatted(output); + fprintf(stdout, "%s\n", crm_str(admin_input_xml)); + exit(0); + 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"); - crm_help('?', LSB_EXIT_EINVAL); + printf("non-option ARGV-elements: "); + while (optind < argc) + printf("%s ", argv[optind++]); + printf("\n"); + crm_help('?', LSB_EXIT_EINVAL); } if (optind > argc || cib_action == NULL) { - ++argerr; + ++argerr; } - + if (argerr) { - crm_help('?', LSB_EXIT_GENERIC); + crm_help('?', LSB_EXIT_GENERIC); } - if(dangerous_cmd && force_flag == FALSE) { - fprintf(stderr, "The supplied command is considered dangerous." - " To prevent accidental destruction of the cluster," - " the --force flag is required in order to proceed.\n"); - fflush(stderr); - exit(LSB_EXIT_GENERIC); + if (dangerous_cmd && force_flag == FALSE) { + fprintf(stderr, "The supplied command is considered dangerous." + " To prevent accidental destruction of the cluster," + " the --force flag is required in order to proceed.\n"); + fflush(stderr); + exit(LSB_EXIT_GENERIC); } - - if(admin_input_file != NULL) { - input = filename2xml(admin_input_file); - source = admin_input_file; - - } else if(admin_input_xml != NULL) { - source = "input string"; - input = string2xml(admin_input_xml); - - } else if(admin_input_stdin) { - source = "STDIN"; - input = stdin2xml(); + + if (admin_input_file != NULL) { + input = filename2xml(admin_input_file); + source = admin_input_file; + + } else if (admin_input_xml != NULL) { + source = "input string"; + input = string2xml(admin_input_xml); + + } else if (admin_input_stdin) { + source = "STDIN"; + input = stdin2xml(); } - - if(input != NULL) { - crm_log_xml_debug(input, "[admin input]"); - } else if(source) { - fprintf(stderr, "Couldn't parse input from %s.\n", source); - return 1; + if (input != NULL) { + crm_log_xml_debug(input, "[admin input]"); + + } else if (source) { + fprintf(stderr, "Couldn't parse input from %s.\n", source); + return 1; } - if(safe_str_eq(cib_action, "md5-sum")) { - char *digest = NULL; - if(input == NULL) { - fprintf(stderr, - "Please supply XML to process with -X, -x or -p\n"); - exit(1); - } - - digest = calculate_on_disk_digest(input); - fprintf(stderr, "Digest: "); - fprintf(stdout, "%s\n", crm_str(digest)); - crm_free(digest); - exit(0); + if (safe_str_eq(cib_action, "md5-sum")) { + char *digest = NULL; + + if (input == NULL) { + fprintf(stderr, "Please supply XML to process with -X, -x or -p\n"); + exit(1); + } + + digest = calculate_on_disk_digest(input); + fprintf(stderr, "Digest: "); + fprintf(stdout, "%s\n", crm_str(digest)); + crm_free(digest); + exit(0); } - + exit_code = do_init(); - if(exit_code != cib_ok) { - crm_err("Init failed, could not perform requested operations"); - fprintf(stderr, "Init failed, could not perform requested operations\n"); - return -exit_code; - } + if (exit_code != cib_ok) { + crm_err("Init failed, could not perform requested operations"); + fprintf(stderr, "Init failed, could not perform requested operations\n"); + return -exit_code; + } exit_code = do_work(input, command_options, &output); if (exit_code > 0) { - /* wait for the reply by creating a mainloop and running it until - * the callbacks are invoked... - */ - request_id = exit_code; - - the_cib->cmds->register_callback( - the_cib, request_id, message_timeout_ms, FALSE, NULL, - "cibadmin_op_callback", cibadmin_op_callback); - - mainloop = g_main_new(FALSE); - - crm_debug_3("%s waiting for reply from the local CIB", - crm_system_name); - - crm_info("Starting mainloop"); - g_main_run(mainloop); - - } else if(exit_code < 0) { - crm_err("Call failed: %s", cib_error2string(exit_code)); - fprintf(stderr, "Call failed: %s\n", - cib_error2string(exit_code)); - operation_status = exit_code; - - if(exit_code == cib_dtd_validation) { - if(crm_str_eq(cib_action, CIB_OP_UPGRADE, TRUE)) { - xmlNode *obj = NULL; - int version = 0, rc = 0; - rc = the_cib->cmds->query(the_cib, NULL, &obj, command_options); - if(rc == cib_ok) { - update_validation(&obj, &version, TRUE, FALSE); - } - - } else if(output) { - validate_xml_verbose(output); - } - } + /* wait for the reply by creating a mainloop and running it until + * the callbacks are invoked... + */ + request_id = exit_code; + + the_cib->cmds->register_callback(the_cib, request_id, message_timeout_ms, FALSE, NULL, + "cibadmin_op_callback", cibadmin_op_callback); + + mainloop = g_main_new(FALSE); + + crm_debug_3("%s waiting for reply from the local CIB", crm_system_name); + + crm_info("Starting mainloop"); + g_main_run(mainloop); + + } else if (exit_code < 0) { + crm_err("Call failed: %s", cib_error2string(exit_code)); + fprintf(stderr, "Call failed: %s\n", cib_error2string(exit_code)); + operation_status = exit_code; + + if (exit_code == cib_dtd_validation) { + if (crm_str_eq(cib_action, CIB_OP_UPGRADE, TRUE)) { + xmlNode *obj = NULL; + int version = 0, rc = 0; + + rc = the_cib->cmds->query(the_cib, NULL, &obj, command_options); + if (rc == cib_ok) { + update_validation(&obj, &version, TRUE, FALSE); + } + + } else if (output) { + validate_xml_verbose(output); + } + } } - if(output != NULL) { - char *buffer = dump_xml_formatted(output); - fprintf(stdout, "%s\n", crm_str(buffer)); - crm_free(buffer); - free_xml(output); + if (output != NULL) { + char *buffer = dump_xml_formatted(output); + + fprintf(stdout, "%s\n", crm_str(buffer)); + crm_free(buffer); + free_xml(output); } crm_debug_3("%s exiting normally", crm_system_name); - + free_xml(input); crm_free(admin_input_xml); crm_free(admin_input_file); the_cib->cmds->signoff(the_cib); cib_delete(the_cib); crm_xml_cleanup(); return -exit_code; } int -do_work(xmlNode *input, int call_options, xmlNode **output) +do_work(xmlNode * input, int call_options, xmlNode ** output) { /* construct the request */ the_cib->call_timeout = message_timeout_ms; if (strcasecmp(CIB_OP_REPLACE, cib_action) == 0 - && safe_str_eq(crm_element_name(input), XML_TAG_CIB)) { - xmlNode *status = get_object_root(XML_CIB_TAG_STATUS, input); - if(status == NULL) { - create_xml_node(input, XML_CIB_TAG_STATUS); - } + && safe_str_eq(crm_element_name(input), XML_TAG_CIB)) { + xmlNode *status = get_object_root(XML_CIB_TAG_STATUS, input); + + if (status == NULL) { + create_xml_node(input, XML_CIB_TAG_STATUS); + } } - + if (strcasecmp(CIB_OP_SYNC, cib_action) == 0) { - crm_debug_4("Performing %s op...", cib_action); - return the_cib->cmds->sync_from( - the_cib, host, obj_type, call_options); + crm_debug_4("Performing %s op...", cib_action); + return the_cib->cmds->sync_from(the_cib, host, obj_type, call_options); - } else if (strcasecmp(CIB_OP_SLAVE, cib_action) == 0 - && (call_options ^ cib_scope_local) ) { - crm_debug_4("Performing %s op on all nodes...", cib_action); - return the_cib->cmds->set_slave_all(the_cib, call_options); + } else if (strcasecmp(CIB_OP_SLAVE, cib_action) == 0 && (call_options ^ cib_scope_local)) { + crm_debug_4("Performing %s op on all nodes...", cib_action); + return the_cib->cmds->set_slave_all(the_cib, call_options); } else if (strcasecmp(CIB_OP_MASTER, cib_action) == 0) { - crm_debug_4("Performing %s op on all nodes...", cib_action); - return the_cib->cmds->set_master(the_cib, call_options); + crm_debug_4("Performing %s op on all nodes...", cib_action); + return the_cib->cmds->set_master(the_cib, call_options); + } else if (cib_action != NULL) { + crm_debug_4("Passing \"%s\" to variant_op...", cib_action); + return the_cib->cmds->variant_op(the_cib, cib_action, host, obj_type, + input, output, call_options); - } else if(cib_action != NULL) { - crm_debug_4("Passing \"%s\" to variant_op...", cib_action); - return the_cib->cmds->variant_op( - the_cib, cib_action, host, obj_type, - input, output, call_options); - } else { - crm_err("You must specify an operation"); + crm_err("You must specify an operation"); } return cib_operation; } enum cib_errors do_init(void) { enum cib_errors rc = cib_ok; the_cib = cib_new(); rc = the_cib->cmds->signon(the_cib, crm_system_name, cib_command); - if(rc != cib_ok) { - crm_err("Signon to CIB failed: %s", - cib_error2string(rc)); - fprintf(stderr, "Signon to CIB failed: %s\n", - cib_error2string(rc)); + if (rc != cib_ok) { + crm_err("Signon to CIB failed: %s", cib_error2string(rc)); + fprintf(stderr, "Signon to CIB failed: %s\n", cib_error2string(rc)); } - + return rc; } void cib_connection_destroy(gpointer user_data) { crm_err("Connection to the CIB terminated... exiting"); g_main_quit(mainloop); return; } void -cibadmin_op_callback(xmlNode *msg, int call_id, int rc, - xmlNode *output, void *user_data) +cibadmin_op_callback(xmlNode * msg, int call_id, int rc, xmlNode * output, void *user_data) { char *admin_input_xml = NULL; - + exit_code = rc; - if(output != NULL) { - admin_input_xml = dump_xml_formatted(output); + if (output != NULL) { + admin_input_xml = dump_xml_formatted(output); } - - if(safe_str_eq(cib_action, CIB_OP_ISMASTER) && rc != cib_ok) { - crm_info("CIB on %s is _not_ the master instance", - host?host:"localhost"); - fprintf(stderr, "CIB on %s is _not_ the master instance\n", - host?host:"localhost"); - - } else if(safe_str_eq(cib_action, CIB_OP_ISMASTER)) { - crm_info("CIB on %s _is_ the master instance", - host?host:"localhost"); - fprintf(stderr, "CIB on %s _is_ the master instance\n", - host?host:"localhost"); - - } else if(rc != 0) { - crm_warn("Call %s failed (%d): %s", - cib_action, rc, cib_error2string(rc)); - fprintf(stderr, "Call %s failed (%d): %s\n", - cib_action, rc, cib_error2string(rc)); - fprintf(stdout, "%s\n", crm_str(admin_input_xml)); - - } else if(safe_str_eq(cib_action, CIB_OP_QUERY) && output==NULL) { - crm_err("Output expected in query response"); - crm_log_xml(LOG_ERR, "no output", msg); - - } else if(output == NULL) { - crm_info("Call passed"); + + if (safe_str_eq(cib_action, CIB_OP_ISMASTER) && rc != cib_ok) { + crm_info("CIB on %s is _not_ the master instance", host ? host : "localhost"); + fprintf(stderr, "CIB on %s is _not_ the master instance\n", host ? host : "localhost"); + + } else if (safe_str_eq(cib_action, CIB_OP_ISMASTER)) { + crm_info("CIB on %s _is_ the master instance", host ? host : "localhost"); + fprintf(stderr, "CIB on %s _is_ the master instance\n", host ? host : "localhost"); + + } else if (rc != 0) { + crm_warn("Call %s failed (%d): %s", cib_action, rc, cib_error2string(rc)); + fprintf(stderr, "Call %s failed (%d): %s\n", cib_action, rc, cib_error2string(rc)); + fprintf(stdout, "%s\n", crm_str(admin_input_xml)); + + } else if (safe_str_eq(cib_action, CIB_OP_QUERY) && output == NULL) { + crm_err("Output expected in query response"); + crm_log_xml(LOG_ERR, "no output", msg); + + } else if (output == NULL) { + crm_info("Call passed"); } else { - crm_info("Call passed"); - fprintf(stdout, "%s\n", crm_str(admin_input_xml)); + crm_info("Call passed"); + fprintf(stdout, "%s\n", crm_str(admin_input_xml)); } crm_free(admin_input_xml); - if(call_id == request_id) { - g_main_quit(mainloop); + if (call_id == request_id) { + g_main_quit(mainloop); } else { - crm_info("Message was not the response we were looking for (%d vs. %d", call_id, request_id); + crm_info("Message was not the response we were looking for (%d vs. %d", call_id, + request_id); } } diff --git a/tools/crm_attribute.c b/tools/crm_attribute.c index e7f0880a91..77be382e92 100644 --- a/tools/crm_attribute.c +++ b/tools/crm_attribute.c @@ -1,318 +1,320 @@ /* * Copyright (C) 2004 Andrew Beekhof * * 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 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 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 */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include gboolean BE_QUIET = FALSE; char command = 'G'; char *dest_uname = NULL; char *dest_node = NULL; -char *set_name = NULL; -char *attr_id = NULL; +char *set_name = NULL; +char *attr_id = NULL; char *attr_name = NULL; -const char *type = NULL; -const char *rsc_id = NULL; +const char *type = NULL; +const char *rsc_id = NULL; const char *attr_value = NULL; const char *attr_default = NULL; const char *set_type = NULL; /* *INDENT-OFF* */ static struct crm_option long_options[] = { /* Top-level Options */ {"help", 0, 0, '?', "\tThis text"}, {"version", 0, 0, '$', "\tVersion information" }, {"verbose", 0, 0, 'V', "\tIncrease debug output"}, {"quiet", 0, 0, 'q', "\tPrint only the value on stdout\n"}, {"name", 1, 0, 'n', "Name of the attribute/option to operate on"}, {"-spacer-", 0, 0, '-', "\nCommands:"}, {"query", 0, 0, 'G', "\tQuery the current value of the attribute/option"}, {"update", 1, 0, 'v', "Update the value of the attribute/option"}, {"delete", 0, 0, 'D', "\tDelete the attribute/option"}, {"-spacer-", 0, 0, '-', "\nAdditional Options:"}, {"node", 1, 0, 'N', "Set an attribute for the named node (instead of a cluster option). See also: -l"}, {"type", 1, 0, 't', "Which part of the configuration to update/delete/query the option in."}, {"-spacer-", 0, 0, '-', "\t\t\tValid values: crm_config, rsc_defaults, op_defaults, tickets"}, {"lifetime", 1, 0, 'l', "Lifetime of the node attribute."}, {"-spacer-", 0, 0, '-', "\t\t\tValid values: reboot, forever"}, {"utilization", 0, 0, 'z', "Set an utilization attribute for the node."}, {"set-name", 1, 0, 's', "(Advanced) The attribute set in which to place the value"}, {"id", 1, 0, 'i', "\t(Advanced) The ID used to identify the attribute"}, {"default", 1, 0, 'd', "(Advanced) The default value to display if none is found in the configuration"}, {"inhibit-policy-engine", 0, 0, '!', NULL, 1}, /* legacy */ {"quiet", 0, 0, 'Q', NULL, 1}, {"node-uname", 1, 0, 'U', NULL, 1}, {"node-uuid", 1, 0, 'u', NULL, 1}, {"get-value", 0, 0, 'G', NULL, 1}, {"delete-attr", 0, 0, 'D', NULL, 1}, {"attr-value", 1, 0, 'v', NULL, 1}, {"attr-name", 1, 0, 'n', NULL, 1}, {"attr-id", 1, 0, 'i', NULL, 1}, {"-spacer-", 1, 0, '-', "\nExamples:", pcmk_option_paragraph}, {"-spacer-", 1, 0, '-', "Add a new attribute called 'location' with the value of 'office' for host 'myhost':", pcmk_option_paragraph}, {"-spacer-", 1, 0, '-', " crm_attribute --node myhost --name location --update office", pcmk_option_example}, {"-spacer-", 1, 0, '-', "Query the value of the 'location' node attribute for host myhost:", pcmk_option_paragraph}, {"-spacer-", 1, 0, '-', " crm_attribute --node myhost --name location --query", pcmk_option_example}, {"-spacer-", 1, 0, '-', "Change the value of the 'location' node attribute for host myhost:", pcmk_option_paragraph}, {"-spacer-", 1, 0, '-', " crm_attribute --node myhost --name location --update backoffice", pcmk_option_example}, {"-spacer-", 1, 0, '-', "Delete the 'location' node attribute for the host myhost:", pcmk_option_paragraph}, {"-spacer-", 1, 0, '-', " crm_attribute --node myhost --name location --delete", pcmk_option_example}, {"-spacer-", 1, 0, '-', "Query the value of the cluster-delay cluster option:", pcmk_option_paragraph}, {"-spacer-", 1, 0, '-', " crm_attribute --type crm_config --name cluster-delay --query", pcmk_option_example}, {"-spacer-", 1, 0, '-', "Query the value of the cluster-delay cluster option. Only print the value:", pcmk_option_paragraph}, {"-spacer-", 1, 0, '-', " crm_attribute --type crm_config --name cluster-delay --query --quiet", pcmk_option_example}, {0, 0, 0, 0} }; /* *INDENT-ON* */ int main(int argc, char **argv) { - cib_t * the_cib = NULL; - enum cib_errors rc = cib_ok; - - int cib_opts = cib_sync_call; - int argerr = 0; - int flag; - - int option_index = 0; - - crm_log_init_quiet(NULL, LOG_ERR, FALSE, FALSE, argc, argv); - crm_set_options(NULL, "command -n attribute [options]", long_options, - "Manage node's attributes and cluster options." - "\n\nAllows node attributes and cluster options to be queried, modified and deleted.\n"); - - if(argc < 2) { - crm_help('?', LSB_EXIT_EINVAL); - } - - while (1) { - flag = crm_get_option(argc, argv, &option_index); - if (flag == -1) - break; - - switch(flag) { - case 'V': - cl_log_enable_stderr(TRUE); - alter_debug(DEBUG_INC); - break; - case '$': - case '?': - crm_help(flag, LSB_EXIT_OK); - break; - case 'D': - case 'G': - case 'v': - command = flag; - attr_value = optarg; - break; - case 'q': - case 'Q': - BE_QUIET = TRUE; - break; - case 'U': - case 'N': - dest_uname = crm_strdup(optarg); - break; - case 'u': - dest_node = crm_strdup(optarg); - break; - case 's': - set_name = crm_strdup(optarg); - break; - case 'l': - case 't': - type = optarg; - break; - case 'z': - type = XML_CIB_TAG_NODES; - set_type = XML_TAG_UTILIZATION; - break; - case 'n': - attr_name = crm_strdup(optarg); - break; - case 'i': - attr_id = crm_strdup(optarg); - break; - case 'r': - rsc_id = optarg; - break; - case 'd': - attr_default = optarg; - break; - case '!': - crm_warn("Inhibiting notifications for this update"); - cib_opts |= cib_inhibit_notify; - break; - default: - printf("Argument code 0%o (%c) is not (?yet?) supported\n", flag, flag); - ++argerr; - break; - } - } - - if(BE_QUIET == FALSE) { - cl_log_args(argc, argv); - } - - if (optind < argc) { - printf("non-option ARGV-elements: "); - while (optind < argc) - printf("%s ", argv[optind++]); - printf("\n"); - } - - if (optind > argc) { - ++argerr; - } - - if (argerr) { - crm_help('?', LSB_EXIT_GENERIC); - } - - the_cib = cib_new(); - rc = the_cib->cmds->signon(the_cib, crm_system_name, cib_command); - - if(rc != cib_ok) { - fprintf(stderr, "Error signing on to the CIB service: %s\n", cib_error2string(rc)); - return rc; - } - - if(safe_str_eq(type, "reboot")) { - type = XML_CIB_TAG_STATUS; - - } else if(safe_str_eq(type, "forever")) { - type = XML_CIB_TAG_NODES; - } - - if(type == NULL && dest_uname == NULL) { - /* we're updating cluster options - dont populate dest_node */ - type = XML_CIB_TAG_CRMCONFIG; - - } else if(safe_str_neq(type, XML_CIB_TAG_TICKETS)){ - determine_host(the_cib, &dest_uname, &dest_node); - } - - if(rc != cib_ok) { - crm_info("Error during setup of %s=%s update", attr_name, command=='D'?"":attr_value); - - } else if( (command=='v' || command=='D') - && safe_str_eq(type, XML_CIB_TAG_STATUS) - && attrd_lazy_update(command, dest_uname, attr_name, attr_value, type, set_name, NULL)) { - crm_info("Update %s=%s sent via attrd", attr_name, command=='D'?"":attr_value); - - } else if(command=='D') { - rc = delete_attr(the_cib, cib_opts, type, dest_node, set_type, set_name, - attr_id, attr_name, attr_value, TRUE); - - if(rc == cib_NOTEXISTS) { - /* Nothing to delete... - * which means its not there... - * which is what the admin wanted - */ - rc = cib_ok; - } else if(rc != cib_missing_data - && safe_str_eq(crm_system_name, "crm_failcount")) { - char *now_s = NULL; - time_t now = time(NULL); - now_s = crm_itoa(now); - update_attr(the_cib, cib_sync_call, - XML_CIB_TAG_CRMCONFIG, NULL, NULL, NULL, NULL, - "last-lrm-refresh", now_s, TRUE); - crm_free(now_s); - } - - } else if(command=='v') { - CRM_LOG_ASSERT(type != NULL); - CRM_LOG_ASSERT(attr_name != NULL); - CRM_LOG_ASSERT(attr_value != NULL); - - rc = update_attr(the_cib, cib_opts, type, dest_node, set_type, set_name, - attr_id, attr_name, attr_value, TRUE); - - } else /* query */ { - char *read_value = NULL; - rc = read_attr(the_cib, type, dest_node, set_type, set_name, - attr_id, attr_name, &read_value, TRUE); - - if(rc == cib_NOTEXISTS && attr_default) { - read_value = crm_strdup(attr_default); - rc = cib_ok; - } - - crm_info("Read %s=%s %s%s", - attr_name, crm_str(read_value), - set_name?"in ":"", set_name?set_name:""); - - if(rc == cib_missing_data) { - rc = cib_ok; - - } else if(BE_QUIET == FALSE) { - fprintf(stdout, "%s%s %s%s %s%s value=%s\n", - type?"scope=":"", type?type:"", - attr_id?"id=":"", attr_id?attr_id:"", - attr_name?"name=":"", attr_name?attr_name:"", - read_value?read_value:"(null)"); - - } else if(read_value != NULL) { - fprintf(stdout, "%s\n", read_value); - } - } - - if(rc == cib_missing_data) { - printf("Please choose from one of the matches above and suppy the 'id' with --attr-id\n"); - } else if(rc != cib_ok) { - fprintf(stderr, "Error performing operation: %s\n", - cib_error2string(rc)); - } - - the_cib->cmds->signoff(the_cib); - cib_delete(the_cib); - crm_xml_cleanup(); - return rc; + cib_t *the_cib = NULL; + enum cib_errors rc = cib_ok; + + int cib_opts = cib_sync_call; + int argerr = 0; + int flag; + + int option_index = 0; + + crm_log_init_quiet(NULL, LOG_ERR, FALSE, FALSE, argc, argv); + crm_set_options(NULL, "command -n attribute [options]", long_options, + "Manage node's attributes and cluster options." + "\n\nAllows node attributes and cluster options to be queried, modified and deleted.\n"); + + if (argc < 2) { + crm_help('?', LSB_EXIT_EINVAL); + } + + while (1) { + flag = crm_get_option(argc, argv, &option_index); + if (flag == -1) + break; + + switch (flag) { + case 'V': + cl_log_enable_stderr(TRUE); + alter_debug(DEBUG_INC); + break; + case '$': + case '?': + crm_help(flag, LSB_EXIT_OK); + break; + case 'D': + case 'G': + case 'v': + command = flag; + attr_value = optarg; + break; + case 'q': + case 'Q': + BE_QUIET = TRUE; + break; + case 'U': + case 'N': + dest_uname = crm_strdup(optarg); + break; + case 'u': + dest_node = crm_strdup(optarg); + break; + case 's': + set_name = crm_strdup(optarg); + break; + case 'l': + case 't': + type = optarg; + break; + case 'z': + type = XML_CIB_TAG_NODES; + set_type = XML_TAG_UTILIZATION; + break; + case 'n': + attr_name = crm_strdup(optarg); + break; + case 'i': + attr_id = crm_strdup(optarg); + break; + case 'r': + rsc_id = optarg; + break; + case 'd': + attr_default = optarg; + break; + case '!': + crm_warn("Inhibiting notifications for this update"); + cib_opts |= cib_inhibit_notify; + break; + default: + printf("Argument code 0%o (%c) is not (?yet?) supported\n", flag, flag); + ++argerr; + break; + } + } + + if (BE_QUIET == FALSE) { + cl_log_args(argc, argv); + } + + if (optind < argc) { + printf("non-option ARGV-elements: "); + while (optind < argc) + printf("%s ", argv[optind++]); + printf("\n"); + } + + if (optind > argc) { + ++argerr; + } + + if (argerr) { + crm_help('?', LSB_EXIT_GENERIC); + } + + the_cib = cib_new(); + rc = the_cib->cmds->signon(the_cib, crm_system_name, cib_command); + + if (rc != cib_ok) { + fprintf(stderr, "Error signing on to the CIB service: %s\n", cib_error2string(rc)); + return rc; + } + + if (safe_str_eq(type, "reboot")) { + type = XML_CIB_TAG_STATUS; + + } else if (safe_str_eq(type, "forever")) { + type = XML_CIB_TAG_NODES; + } + + if (type == NULL && dest_uname == NULL) { + /* we're updating cluster options - dont populate dest_node */ + type = XML_CIB_TAG_CRMCONFIG; + + } else if (safe_str_neq(type, XML_CIB_TAG_TICKETS)) { + determine_host(the_cib, &dest_uname, &dest_node); + } + + if (rc != cib_ok) { + crm_info("Error during setup of %s=%s update", attr_name, + command == 'D' ? "" : attr_value); + + } else if ((command == 'v' || command == 'D') + && safe_str_eq(type, XML_CIB_TAG_STATUS) + && attrd_lazy_update(command, dest_uname, attr_name, attr_value, type, set_name, + NULL)) { + crm_info("Update %s=%s sent via attrd", attr_name, command == 'D' ? "" : attr_value); + + } else if (command == 'D') { + rc = delete_attr(the_cib, cib_opts, type, dest_node, set_type, set_name, + attr_id, attr_name, attr_value, TRUE); + + if (rc == cib_NOTEXISTS) { + /* Nothing to delete... + * which means its not there... + * which is what the admin wanted + */ + rc = cib_ok; + } else if (rc != cib_missing_data && safe_str_eq(crm_system_name, "crm_failcount")) { + char *now_s = NULL; + time_t now = time(NULL); + + now_s = crm_itoa(now); + update_attr(the_cib, cib_sync_call, + XML_CIB_TAG_CRMCONFIG, NULL, NULL, NULL, NULL, + "last-lrm-refresh", now_s, TRUE); + crm_free(now_s); + } + + } else if (command == 'v') { + CRM_LOG_ASSERT(type != NULL); + CRM_LOG_ASSERT(attr_name != NULL); + CRM_LOG_ASSERT(attr_value != NULL); + + rc = update_attr(the_cib, cib_opts, type, dest_node, set_type, set_name, + attr_id, attr_name, attr_value, TRUE); + + } else { /* query */ + + char *read_value = NULL; + + rc = read_attr(the_cib, type, dest_node, set_type, set_name, + attr_id, attr_name, &read_value, TRUE); + + if (rc == cib_NOTEXISTS && attr_default) { + read_value = crm_strdup(attr_default); + rc = cib_ok; + } + + crm_info("Read %s=%s %s%s", + attr_name, crm_str(read_value), set_name ? "in " : "", set_name ? set_name : ""); + + if (rc == cib_missing_data) { + rc = cib_ok; + + } else if (BE_QUIET == FALSE) { + fprintf(stdout, "%s%s %s%s %s%s value=%s\n", + type ? "scope=" : "", type ? type : "", + attr_id ? "id=" : "", attr_id ? attr_id : "", + attr_name ? "name=" : "", attr_name ? attr_name : "", + read_value ? read_value : "(null)"); + + } else if (read_value != NULL) { + fprintf(stdout, "%s\n", read_value); + } + } + + if (rc == cib_missing_data) { + printf("Please choose from one of the matches above and suppy the 'id' with --attr-id\n"); + } else if (rc != cib_ok) { + fprintf(stderr, "Error performing operation: %s\n", cib_error2string(rc)); + } + + the_cib->cmds->signoff(the_cib); + cib_delete(the_cib); + crm_xml_cleanup(); + return rc; } diff --git a/tools/crm_inject.c b/tools/crm_inject.c index c617da8070..ff923b7434 100644 --- a/tools/crm_inject.c +++ b/tools/crm_inject.c @@ -1,1188 +1,1247 @@ /* * Copyright (C) 2009 Andrew Beekhof * * 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 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 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 */ #include #include #include #include #include #include #include #include #include #include #include #include #include cib_t *global_cib = NULL; GListPtr op_fail = NULL; gboolean quiet = FALSE; - + #define new_node_template "//"XML_CIB_TAG_NODE"[@uname='%s']" #define node_template "//"XML_CIB_TAG_STATE"[@uname='%s']" #define rsc_template "//"XML_CIB_TAG_STATE"[@uname='%s']//"XML_LRM_TAG_RESOURCE"[@id='%s']" #define op_template "//"XML_CIB_TAG_STATE"[@uname='%s']//"XML_LRM_TAG_RESOURCE"[@id='%s']/"XML_LRM_TAG_RSC_OP"[@id='%s']" /* #define op_template "//"XML_CIB_TAG_STATE"[@uname='%s']//"XML_LRM_TAG_RESOURCE"[@id='%s']/"XML_LRM_TAG_RSC_OP"[@id='%s' and @"XML_LRM_ATTR_CALLID"='%d']" */ #define FAKE_TE_ID "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" #define quiet_log(fmt, args...) do { \ if(quiet == FALSE) { \ printf(fmt , ##args); \ } \ } while(0) -extern void cleanup_alloc_calculations(pe_working_set_t *data_set); +extern void cleanup_alloc_calculations(pe_working_set_t * data_set); -extern xmlNode * do_calculations( - pe_working_set_t *data_set, xmlNode *xml_input, ha_time_t *now); +extern xmlNode *do_calculations(pe_working_set_t * data_set, xmlNode * xml_input, ha_time_t * now); char *use_date = NULL; -static ha_time_t *get_date(void) +static ha_time_t * +get_date(void) { - if(use_date) { - char *date_m = use_date; - return parse_date(&date_m); + if (use_date) { + char *date_m = use_date; + + return parse_date(&date_m); } return NULL; } -static xmlNode *find_resource(xmlNode *cib_node, const char *resource) +static xmlNode * +find_resource(xmlNode * cib_node, const char *resource) { char *xpath = NULL; xmlNode *match = NULL; const char *node = crm_element_value(cib_node, XML_ATTR_UNAME); int max = strlen(rsc_template) + strlen(resource) + strlen(node) + 1; + crm_malloc0(xpath, max); - + snprintf(xpath, max, rsc_template, node, resource); match = get_xpath_object(xpath, cib_node, LOG_DEBUG_2); - + crm_free(xpath); return match; } -static void create_node_entry(cib_t *cib_conn, char *node) +static void +create_node_entry(cib_t * cib_conn, char *node) { int rc = cib_ok; int max = strlen(new_node_template) + strlen(node) + 1; char *xpath = NULL; + crm_malloc0(xpath, max); snprintf(xpath, max, new_node_template, node); - rc = cib_conn->cmds->query(cib_conn, xpath, NULL, cib_xpath|cib_sync_call|cib_scope_local); + rc = cib_conn->cmds->query(cib_conn, xpath, NULL, cib_xpath | cib_sync_call | cib_scope_local); if (rc == cib_NOTEXISTS) { - xmlNode *cib_object = create_xml_node(NULL, XML_CIB_TAG_NODE); - - /* Using node uname as uuid ala corosync/openais */ - crm_xml_add(cib_object, XML_ATTR_ID, node); - crm_xml_add(cib_object, XML_ATTR_UNAME, node); - crm_xml_add(cib_object, XML_ATTR_TYPE, NORMALNODE); - cib_conn->cmds->create(cib_conn, XML_CIB_TAG_NODES, cib_object, cib_sync_call|cib_scope_local); - /* Not bothering with subsequent query to see if it exists, - we'll bomb out later in the call to determine_host... */ - - free_xml(cib_object); + xmlNode *cib_object = create_xml_node(NULL, XML_CIB_TAG_NODE); + + /* Using node uname as uuid ala corosync/openais */ + crm_xml_add(cib_object, XML_ATTR_ID, node); + crm_xml_add(cib_object, XML_ATTR_UNAME, node); + crm_xml_add(cib_object, XML_ATTR_TYPE, NORMALNODE); + cib_conn->cmds->create(cib_conn, XML_CIB_TAG_NODES, cib_object, + cib_sync_call | cib_scope_local); + /* Not bothering with subsequent query to see if it exists, + we'll bomb out later in the call to determine_host... */ + + free_xml(cib_object); } crm_free(xpath); } -static xmlNode *inject_node_state(cib_t *cib_conn, char *node) +static xmlNode * +inject_node_state(cib_t * cib_conn, char *node) { int rc = cib_ok; int max = strlen(rsc_template) + strlen(node) + 1; char *xpath = NULL; xmlNode *cib_object = NULL; + crm_malloc0(xpath, max); create_node_entry(cib_conn, node); - + snprintf(xpath, max, node_template, node); - rc = cib_conn->cmds->query(cib_conn, xpath, &cib_object, cib_xpath|cib_sync_call|cib_scope_local); - - if(rc == cib_NOTEXISTS) { - char *uuid = NULL; - - cib_object = create_xml_node(NULL, XML_CIB_TAG_STATE); - determine_host(cib_conn, &node, &uuid); - crm_xml_add(cib_object, XML_ATTR_UUID, uuid); - crm_xml_add(cib_object, XML_ATTR_UNAME, node); - cib_conn->cmds->create(cib_conn, XML_CIB_TAG_STATUS, cib_object, cib_sync_call|cib_scope_local); - free_xml(cib_object); - crm_free(uuid); - - rc = cib_conn->cmds->query(cib_conn, xpath, &cib_object, cib_xpath|cib_sync_call|cib_scope_local); + rc = cib_conn->cmds->query(cib_conn, xpath, &cib_object, + cib_xpath | cib_sync_call | cib_scope_local); + + if (rc == cib_NOTEXISTS) { + char *uuid = NULL; + + cib_object = create_xml_node(NULL, XML_CIB_TAG_STATE); + determine_host(cib_conn, &node, &uuid); + crm_xml_add(cib_object, XML_ATTR_UUID, uuid); + crm_xml_add(cib_object, XML_ATTR_UNAME, node); + cib_conn->cmds->create(cib_conn, XML_CIB_TAG_STATUS, cib_object, + cib_sync_call | cib_scope_local); + free_xml(cib_object); + crm_free(uuid); + + rc = cib_conn->cmds->query(cib_conn, xpath, &cib_object, + cib_xpath | cib_sync_call | cib_scope_local); } - + crm_free(xpath); CRM_ASSERT(rc == cib_ok); return cib_object; } -static xmlNode *modify_node(cib_t *cib_conn, char *node, gboolean up) +static xmlNode * +modify_node(cib_t * cib_conn, char *node, gboolean up) { xmlNode *cib_node = inject_node_state(cib_conn, node); - if(up) { - crm_xml_add(cib_node, XML_CIB_ATTR_HASTATE, ACTIVESTATUS); - crm_xml_add(cib_node, XML_CIB_ATTR_INCCM, XML_BOOLEAN_YES); - crm_xml_add(cib_node, XML_CIB_ATTR_CRMDSTATE, ONLINESTATUS); - crm_xml_add(cib_node, XML_CIB_ATTR_JOINSTATE, CRMD_JOINSTATE_MEMBER); - crm_xml_add(cib_node, XML_CIB_ATTR_EXPSTATE, CRMD_JOINSTATE_MEMBER); + + if (up) { + crm_xml_add(cib_node, XML_CIB_ATTR_HASTATE, ACTIVESTATUS); + crm_xml_add(cib_node, XML_CIB_ATTR_INCCM, XML_BOOLEAN_YES); + crm_xml_add(cib_node, XML_CIB_ATTR_CRMDSTATE, ONLINESTATUS); + crm_xml_add(cib_node, XML_CIB_ATTR_JOINSTATE, CRMD_JOINSTATE_MEMBER); + crm_xml_add(cib_node, XML_CIB_ATTR_EXPSTATE, CRMD_JOINSTATE_MEMBER); } else { - crm_xml_add(cib_node, XML_CIB_ATTR_HASTATE, DEADSTATUS); - crm_xml_add(cib_node, XML_CIB_ATTR_INCCM, XML_BOOLEAN_NO); - crm_xml_add(cib_node, XML_CIB_ATTR_CRMDSTATE, OFFLINESTATUS); - crm_xml_add(cib_node, XML_CIB_ATTR_JOINSTATE, CRMD_JOINSTATE_DOWN); - crm_xml_add(cib_node, XML_CIB_ATTR_EXPSTATE, CRMD_JOINSTATE_DOWN); + crm_xml_add(cib_node, XML_CIB_ATTR_HASTATE, DEADSTATUS); + crm_xml_add(cib_node, XML_CIB_ATTR_INCCM, XML_BOOLEAN_NO); + crm_xml_add(cib_node, XML_CIB_ATTR_CRMDSTATE, OFFLINESTATUS); + crm_xml_add(cib_node, XML_CIB_ATTR_JOINSTATE, CRMD_JOINSTATE_DOWN); + crm_xml_add(cib_node, XML_CIB_ATTR_EXPSTATE, CRMD_JOINSTATE_DOWN); } - + crm_xml_add(cib_node, XML_ATTR_ORIGIN, crm_system_name); return cib_node; } -static void inject_transient_attr(xmlNode *cib_node, const char *name, const char *value) +static void +inject_transient_attr(xmlNode * cib_node, const char *name, const char *value) { xmlNode *attrs = NULL; xmlNode *container = NULL; xmlNode *nvp = NULL; const char *node_uuid = ID(cib_node); char *nvp_id = crm_concat(name, node_uuid, '-'); - crm_info("Injecting attribute %s=%s into %s '%s'", name, value, xmlGetNodePath(cib_node), ID(cib_node)); - + crm_info("Injecting attribute %s=%s into %s '%s'", name, value, xmlGetNodePath(cib_node), + ID(cib_node)); + attrs = first_named_child(cib_node, XML_TAG_TRANSIENT_NODEATTRS); - if(attrs == NULL) { - attrs = create_xml_node(cib_node, XML_TAG_TRANSIENT_NODEATTRS); - crm_xml_add(attrs, XML_ATTR_ID, node_uuid); + if (attrs == NULL) { + attrs = create_xml_node(cib_node, XML_TAG_TRANSIENT_NODEATTRS); + crm_xml_add(attrs, XML_ATTR_ID, node_uuid); } - + container = first_named_child(attrs, XML_TAG_ATTR_SETS); - if(container == NULL) { - container = create_xml_node(attrs, XML_TAG_ATTR_SETS); - crm_xml_add(container, XML_ATTR_ID, node_uuid); + if (container == NULL) { + container = create_xml_node(attrs, XML_TAG_ATTR_SETS); + crm_xml_add(container, XML_ATTR_ID, node_uuid); } nvp = create_xml_node(container, XML_CIB_TAG_NVPAIR); crm_xml_add(nvp, XML_ATTR_ID, nvp_id); crm_xml_add(nvp, XML_NVPAIR_ATTR_NAME, name); crm_xml_add(nvp, XML_NVPAIR_ATTR_VALUE, value); crm_free(nvp_id); } -static xmlNode *inject_resource(xmlNode *cib_node, const char *resource, const char *rclass, const char *rtype, const char *rprovider) +static xmlNode * +inject_resource(xmlNode * cib_node, const char *resource, const char *rclass, const char *rtype, + const char *rprovider) { xmlNode *lrm = NULL; xmlNode *container = NULL; xmlNode *cib_resource = NULL; cib_resource = find_resource(cib_node, resource); - if(cib_resource != NULL) { - return cib_resource; + if (cib_resource != NULL) { + return cib_resource; } - + /* One day, add query for class, provider, type */ - - if(rclass == NULL || rtype == NULL) { - fprintf(stderr, "Resource %s not found in the status section of %s." - " Please supply the class and type to continue\n", resource, ID(cib_node)); - return NULL; - - } else if(safe_str_neq(rclass, "ocf") - && safe_str_neq(rclass, "stonith") - && safe_str_neq(rclass, "heartbeat") - && safe_str_neq(rclass, "lsb")) { - fprintf(stderr, "Invalid class for %s: %s\n", resource, rclass); - return NULL; - - } else if(safe_str_eq(rclass, "ocf") && rprovider == NULL) { - fprintf(stderr, "Please specify the provider for resource %s\n", resource); - return NULL; + + if (rclass == NULL || rtype == NULL) { + fprintf(stderr, "Resource %s not found in the status section of %s." + " Please supply the class and type to continue\n", resource, ID(cib_node)); + return NULL; + + } else if (safe_str_neq(rclass, "ocf") + && safe_str_neq(rclass, "stonith") + && safe_str_neq(rclass, "heartbeat") + && safe_str_neq(rclass, "lsb")) { + fprintf(stderr, "Invalid class for %s: %s\n", resource, rclass); + return NULL; + + } else if (safe_str_eq(rclass, "ocf") && rprovider == NULL) { + fprintf(stderr, "Please specify the provider for resource %s\n", resource); + return NULL; } - crm_info("Injecting new resource %s into %s '%s'", resource, xmlGetNodePath(cib_node), ID(cib_node)); - + crm_info("Injecting new resource %s into %s '%s'", resource, xmlGetNodePath(cib_node), + ID(cib_node)); + lrm = first_named_child(cib_node, XML_CIB_TAG_LRM); - if(lrm == NULL) { - const char *node_uuid = ID(cib_node); - lrm = create_xml_node(cib_node, XML_CIB_TAG_LRM); - crm_xml_add(lrm, XML_ATTR_ID, node_uuid); + if (lrm == NULL) { + const char *node_uuid = ID(cib_node); + + lrm = create_xml_node(cib_node, XML_CIB_TAG_LRM); + crm_xml_add(lrm, XML_ATTR_ID, node_uuid); } - + container = first_named_child(lrm, XML_LRM_TAG_RESOURCES); - if(container == NULL) { - container = create_xml_node(lrm, XML_LRM_TAG_RESOURCES); + if (container == NULL) { + container = create_xml_node(lrm, XML_LRM_TAG_RESOURCES); } - + cib_resource = create_xml_node(container, XML_LRM_TAG_RESOURCE); crm_xml_add(cib_resource, XML_ATTR_ID, resource); - + crm_xml_add(cib_resource, XML_AGENT_ATTR_CLASS, rclass); crm_xml_add(cib_resource, XML_AGENT_ATTR_PROVIDER, rprovider); crm_xml_add(cib_resource, XML_ATTR_TYPE, rtype); - + return cib_resource; } -static lrm_op_t *create_op( - xmlNode *cib_resource, const char *task, int interval, int outcome) +static lrm_op_t * +create_op(xmlNode * cib_resource, const char *task, int interval, int outcome) { lrm_op_t *op = NULL; xmlNode *xop = NULL; + crm_malloc0(op, sizeof(lrm_op_t)); - + op->app_name = crm_strdup(crm_system_name); op->rsc_id = crm_strdup(ID(cib_resource)); op->interval = interval; op->op_type = crm_strdup(task); op->rc = outcome; op->op_status = 0; - op->params = NULL; /* TODO: Fill me in */ + op->params = NULL; /* TODO: Fill me in */ op->call_id = 0; - for(xop = __xml_first_child(cib_resource); xop != NULL; xop = __xml_next(xop)) { - int tmp = 0; - crm_element_value_int(xop, XML_LRM_ATTR_CALLID, &tmp); - if(tmp > op->call_id) { - op->call_id = tmp; - } + for (xop = __xml_first_child(cib_resource); xop != NULL; xop = __xml_next(xop)) { + int tmp = 0; + + crm_element_value_int(xop, XML_LRM_ATTR_CALLID, &tmp); + if (tmp > op->call_id) { + op->call_id = tmp; + } } op->call_id++; - + return op; } -static xmlNode *inject_op(xmlNode *cib_resource, lrm_op_t *op, int target_rc) +static xmlNode * +inject_op(xmlNode * cib_resource, lrm_op_t * op, int target_rc) { - return create_operation_update(cib_resource, op, CRM_FEATURE_SET, target_rc, crm_system_name, LOG_DEBUG_2); + return create_operation_update(cib_resource, op, CRM_FEATURE_SET, target_rc, crm_system_name, + LOG_DEBUG_2); } -static void update_failcounts(xmlNode *cib_node, const char *resource, int interval, int rc) +static void +update_failcounts(xmlNode * cib_node, const char *resource, int interval, int rc) { - if(rc == 0) { - return; + if (rc == 0) { + return; - } else if(rc == 7 && interval == 0) { - return; + } else if (rc == 7 && interval == 0) { + return; } else { - char *name = NULL; - char *now = crm_itoa(time(NULL)); - - name = crm_concat("fail-count", resource, '-'); - inject_transient_attr(cib_node, name, "value++"); - - name = crm_concat("last-failure", resource, '-'); - inject_transient_attr(cib_node, name, now); - - crm_free(name); - crm_free(now); + char *name = NULL; + char *now = crm_itoa(time(NULL)); + + name = crm_concat("fail-count", resource, '-'); + inject_transient_attr(cib_node, name, "value++"); + + name = crm_concat("last-failure", resource, '-'); + inject_transient_attr(cib_node, name, now); + + crm_free(name); + crm_free(now); } } -static gboolean exec_pseudo_action(crm_graph_t *graph, crm_action_t *action) +static gboolean +exec_pseudo_action(crm_graph_t * graph, crm_action_t * action) { action->confirmed = TRUE; update_graph(graph, action); return TRUE; } -static gboolean exec_rsc_action(crm_graph_t *graph, crm_action_t *action) +static gboolean +exec_rsc_action(crm_graph_t * graph, crm_action_t * action) { int rc = 0; GListPtr gIter = NULL; lrm_op_t *op = NULL; int target_outcome = 0; const char *rtype = NULL; const char *rclass = NULL; const char *resource = NULL; const char *rprovider = NULL; const char *target_rc_s = crm_meta_value(action->params, XML_ATTR_TE_TARGET_RC); - + xmlNode *cib_node = NULL; xmlNode *cib_resource = NULL; xmlNode *action_rsc = first_named_child(action->xml, XML_CIB_TAG_RESOURCE); - + char *node = crm_element_value_copy(action->xml, XML_LRM_ATTR_TARGET); - if(safe_str_eq(crm_element_value(action->xml, "operation"), "probe_complete")) { - crm_info("Skipping %s op for %s\n", crm_element_value(action->xml, "operation"), node); - goto done; + if (safe_str_eq(crm_element_value(action->xml, "operation"), "probe_complete")) { + crm_info("Skipping %s op for %s\n", crm_element_value(action->xml, "operation"), node); + goto done; } - - if(action_rsc == NULL) { - crm_log_xml_err(action->xml, "Bad"); - crm_free(node); - return FALSE; + + if (action_rsc == NULL) { + crm_log_xml_err(action->xml, "Bad"); + crm_free(node); + return FALSE; } - + resource = ID(action_rsc); rclass = crm_element_value(action_rsc, XML_AGENT_ATTR_CLASS); rtype = crm_element_value(action_rsc, XML_ATTR_TYPE); rprovider = crm_element_value(action_rsc, XML_AGENT_ATTR_PROVIDER); - if(target_rc_s != NULL) { - target_outcome = crm_parse_int(target_rc_s, "0"); + if (target_rc_s != NULL) { + target_outcome = crm_parse_int(target_rc_s, "0"); } - CRM_ASSERT(global_cib->cmds->query(global_cib, NULL, NULL, cib_sync_call|cib_scope_local) == cib_ok); + CRM_ASSERT(global_cib->cmds->query(global_cib, NULL, NULL, cib_sync_call | cib_scope_local) == + cib_ok); cib_node = inject_node_state(global_cib, node); CRM_ASSERT(cib_node != NULL); cib_resource = inject_resource(cib_node, resource, rclass, rtype, rprovider); CRM_ASSERT(cib_resource != NULL); op = convert_graph_action(cib_resource, action, 0, target_outcome); - quiet_log(" * Executing action %d: %s_%s_%d on %s\n", action->id, resource, op->op_type, op->interval, node); - - for(gIter = op_fail; gIter != NULL; gIter = gIter->next) { - char *spec = (char*)gIter->data; - char *key = NULL; - crm_malloc0(key, 1+strlen(spec)); - snprintf(key, strlen(spec), "%s_%s_%d@%s=", resource, op->op_type, op->interval, node); - - if(strncasecmp(key, spec, strlen(key)) == 0) { - rc = sscanf(spec, "%*[^=]=%d", &op->rc); - - action->failed = TRUE; - graph->abort_priority = INFINITY; - printf("\tPretending action %d failed with rc=%d\n", action->id, op->rc); - update_failcounts(cib_node, resource, op->interval, op->rc); - crm_free(key); - break; - } - crm_free(key); + quiet_log(" * Executing action %d: %s_%s_%d on %s\n", action->id, resource, op->op_type, + op->interval, node); + + for (gIter = op_fail; gIter != NULL; gIter = gIter->next) { + char *spec = (char *)gIter->data; + char *key = NULL; + + crm_malloc0(key, 1 + strlen(spec)); + snprintf(key, strlen(spec), "%s_%s_%d@%s=", resource, op->op_type, op->interval, node); + + if (strncasecmp(key, spec, strlen(key)) == 0) { + rc = sscanf(spec, "%*[^=]=%d", &op->rc); + + action->failed = TRUE; + graph->abort_priority = INFINITY; + printf("\tPretending action %d failed with rc=%d\n", action->id, op->rc); + update_failcounts(cib_node, resource, op->interval, op->rc); + crm_free(key); + break; + } + crm_free(key); } - + inject_op(cib_resource, op, target_outcome); free_lrm_op(op); - - rc = global_cib->cmds->modify(global_cib, XML_CIB_TAG_STATUS, cib_node, cib_sync_call|cib_scope_local); + + rc = global_cib->cmds->modify(global_cib, XML_CIB_TAG_STATUS, cib_node, + cib_sync_call | cib_scope_local); CRM_ASSERT(rc == cib_ok); done: crm_free(node); free_xml(cib_node); action->confirmed = TRUE; update_graph(graph, action); return TRUE; } -static gboolean exec_crmd_action(crm_graph_t *graph, crm_action_t *action) +static gboolean +exec_crmd_action(crm_graph_t * graph, crm_action_t * action) { action->confirmed = TRUE; update_graph(graph, action); return TRUE; } #define STATUS_PATH_MAX 512 -static gboolean exec_stonith_action(crm_graph_t *graph, crm_action_t *action) +static gboolean +exec_stonith_action(crm_graph_t * graph, crm_action_t * action) { int rc = 0; char xpath[STATUS_PATH_MAX]; char *target = crm_element_value_copy(action->xml, XML_LRM_ATTR_TARGET); - xmlNode *cib_node = modify_node(global_cib, target, FALSE); + xmlNode *cib_node = modify_node(global_cib, target, FALSE); + crm_xml_add(cib_node, XML_ATTR_ORIGIN, __FUNCTION__); CRM_ASSERT(cib_node != NULL); quiet_log(" * Fencing %s\n", target); - rc = global_cib->cmds->replace(global_cib, XML_CIB_TAG_STATUS, cib_node, cib_sync_call|cib_scope_local); + rc = global_cib->cmds->replace(global_cib, XML_CIB_TAG_STATUS, cib_node, + cib_sync_call | cib_scope_local); CRM_ASSERT(rc == cib_ok); snprintf(xpath, STATUS_PATH_MAX, "//node_state[@uname='%s']/%s", target, XML_CIB_TAG_LRM); - rc = global_cib->cmds->delete(global_cib, xpath, NULL, cib_xpath|cib_sync_call|cib_scope_local); + rc = global_cib->cmds->delete(global_cib, xpath, NULL, + cib_xpath | cib_sync_call | cib_scope_local); + + snprintf(xpath, STATUS_PATH_MAX, "//node_state[@uname='%s']/%s", target, + XML_TAG_TRANSIENT_NODEATTRS); + rc = global_cib->cmds->delete(global_cib, xpath, NULL, + cib_xpath | cib_sync_call | cib_scope_local); - snprintf(xpath, STATUS_PATH_MAX, "//node_state[@uname='%s']/%s", target, XML_TAG_TRANSIENT_NODEATTRS); - rc = global_cib->cmds->delete(global_cib, xpath, NULL, cib_xpath|cib_sync_call|cib_scope_local); - action->confirmed = TRUE; update_graph(graph, action); free_xml(cib_node); crm_free(target); return TRUE; } static char * -add_list_element(char *list, const char *value) +add_list_element(char *list, const char *value) { int len = 0; int last = 0; - if(value == NULL) { - return list; + if (value == NULL) { + return list; } - if(list) { - last = strlen(list); + if (list) { + last = strlen(list); } - len = last + 2; /* +1 space, +1 EOS */ + len = last + 2; /* +1 space, +1 EOS */ len += strlen(value); crm_realloc(list, len); sprintf(list + last, " %s", value); return list; } -static void print_cluster_status(pe_working_set_t *data_set) +static void +print_cluster_status(pe_working_set_t * data_set) { char *online_nodes = NULL; char *offline_nodes = NULL; GListPtr gIter = NULL; - for(gIter = data_set->nodes; gIter != NULL; gIter = gIter->next) { - node_t *node = (node_t*)gIter->data; - const char *node_mode = NULL; - - if(node->details->unclean) { - if(node->details->online && node->details->unclean) { - node_mode = "UNCLEAN (online)"; - - } else if(node->details->pending) { - node_mode = "UNCLEAN (pending)"; - - } else { - node_mode = "UNCLEAN (offline)"; - } - - } else if(node->details->pending) { - node_mode = "pending"; - - } else if(node->details->standby_onfail && node->details->online) { - node_mode = "standby (on-fail)"; - - } else if(node->details->standby) { - if(node->details->online) { - node_mode = "standby"; - } else { - node_mode = "OFFLINE (standby)"; - } - - } else if(node->details->online) { - node_mode = "online"; - online_nodes = add_list_element(online_nodes, node->details->uname); - continue; - - } else { - node_mode = "OFFLINE"; - offline_nodes = add_list_element(offline_nodes, node->details->uname); - continue; - } - - if(safe_str_eq(node->details->uname, node->details->id)) { - printf("Node %s: %s\n", - node->details->uname, node_mode); - } else { - printf("Node %s (%s): %s\n", - node->details->uname, node->details->id, - node_mode); - } + + for (gIter = data_set->nodes; gIter != NULL; gIter = gIter->next) { + node_t *node = (node_t *) gIter->data; + const char *node_mode = NULL; + + if (node->details->unclean) { + if (node->details->online && node->details->unclean) { + node_mode = "UNCLEAN (online)"; + + } else if (node->details->pending) { + node_mode = "UNCLEAN (pending)"; + + } else { + node_mode = "UNCLEAN (offline)"; + } + + } else if (node->details->pending) { + node_mode = "pending"; + + } else if (node->details->standby_onfail && node->details->online) { + node_mode = "standby (on-fail)"; + + } else if (node->details->standby) { + if (node->details->online) { + node_mode = "standby"; + } else { + node_mode = "OFFLINE (standby)"; + } + + } else if (node->details->online) { + node_mode = "online"; + online_nodes = add_list_element(online_nodes, node->details->uname); + continue; + + } else { + node_mode = "OFFLINE"; + offline_nodes = add_list_element(offline_nodes, node->details->uname); + continue; + } + + if (safe_str_eq(node->details->uname, node->details->id)) { + printf("Node %s: %s\n", node->details->uname, node_mode); + } else { + printf("Node %s (%s): %s\n", node->details->uname, node->details->id, node_mode); + } } - if(online_nodes) { - printf("Online: [%s ]\n", online_nodes); - crm_free(online_nodes); + if (online_nodes) { + printf("Online: [%s ]\n", online_nodes); + crm_free(online_nodes); } - if(offline_nodes) { - printf("OFFLINE: [%s ]\n", offline_nodes); - crm_free(offline_nodes); + if (offline_nodes) { + printf("OFFLINE: [%s ]\n", offline_nodes); + crm_free(offline_nodes); } - + fprintf(stdout, "\n"); - for(gIter = data_set->resources; gIter != NULL; gIter = gIter->next) { - resource_t *rsc = (resource_t*)gIter->data; - if(is_set(rsc->flags, pe_rsc_orphan) - && rsc->role == RSC_ROLE_STOPPED) { - continue; - } - rsc->fns->print(rsc, NULL, pe_print_printf, stdout); + for (gIter = data_set->resources; gIter != NULL; gIter = gIter->next) { + resource_t *rsc = (resource_t *) gIter->data; + + if (is_set(rsc->flags, pe_rsc_orphan) + && rsc->role == RSC_ROLE_STOPPED) { + continue; + } + rsc->fns->print(rsc, NULL, pe_print_printf, stdout); } fprintf(stdout, "\n"); } static int -run_simulation(pe_working_set_t *data_set) -{ +run_simulation(pe_working_set_t * data_set) +{ crm_graph_t *transition = NULL; enum transition_status graph_rc = -1; - crm_graph_functions_t exec_fns = - { - exec_pseudo_action, - exec_rsc_action, - exec_crmd_action, - exec_stonith_action, - }; + crm_graph_functions_t exec_fns = { + exec_pseudo_action, + exec_rsc_action, + exec_crmd_action, + exec_stonith_action, + }; set_graph_functions(&exec_fns); quiet_log("\nExecuting cluster transition:\n"); transition = unpack_graph(data_set->graph, crm_system_name); print_graph(LOG_DEBUG, transition); - + do { - graph_rc = run_graph(transition); - - } while(graph_rc == transition_active); - - if(graph_rc != transition_complete) { - fprintf(stdout, "Transition failed: %s\n", transition_status(graph_rc)); - print_graph(LOG_ERR, transition); + graph_rc = run_graph(transition); + + } while (graph_rc == transition_active); + + if (graph_rc != transition_complete) { + fprintf(stdout, "Transition failed: %s\n", transition_status(graph_rc)); + print_graph(LOG_ERR, transition); } destroy_graph(transition); - if(graph_rc != transition_complete) { - fprintf(stdout, "An invalid transition was produced\n"); + if (graph_rc != transition_complete) { + fprintf(stdout, "An invalid transition was produced\n"); } - if(quiet == FALSE) { - xmlNode *cib_object = NULL; - int rc = global_cib->cmds->query(global_cib, NULL, &cib_object, cib_sync_call|cib_scope_local); - - CRM_ASSERT(rc == cib_ok); - quiet_log("\nRevised cluster status:\n"); - cleanup_alloc_calculations(data_set); - data_set->input = cib_object; - data_set->now = get_date(); - - cluster_status(data_set); - print_cluster_status(data_set); + if (quiet == FALSE) { + xmlNode *cib_object = NULL; + int rc = + global_cib->cmds->query(global_cib, NULL, &cib_object, cib_sync_call | cib_scope_local); + + CRM_ASSERT(rc == cib_ok); + quiet_log("\nRevised cluster status:\n"); + cleanup_alloc_calculations(data_set); + data_set->input = cib_object; + data_set->now = get_date(); + + cluster_status(data_set); + print_cluster_status(data_set); } - - if(graph_rc != transition_complete) { - return graph_rc; + + if (graph_rc != transition_complete) { + return graph_rc; } return 0; } static char * -create_action_name(action_t *action) +create_action_name(action_t * action) { char *action_name = NULL; const char *action_host = NULL; - if(action->node) { - action_host = action->node->details->uname; - action_name = crm_concat(action->uuid, action_host, ' '); - } else if(is_set(action->flags, pe_action_pseudo)) { - action_name = crm_strdup(action->uuid); - + if (action->node) { + action_host = action->node->details->uname; + action_name = crm_concat(action->uuid, action_host, ' '); + + } else if (is_set(action->flags, pe_action_pseudo)) { + action_name = crm_strdup(action->uuid); + } else { - action_host = ""; - action_name = crm_concat(action->uuid, action_host, ' '); + action_host = ""; + action_name = crm_concat(action->uuid, action_host, ' '); } - if(safe_str_eq(action->task, RSC_CANCEL)) { - char *tmp_action_name = action_name; - action_name = crm_concat("Cancel", tmp_action_name, ' '); - crm_free(tmp_action_name); + if (safe_str_eq(action->task, RSC_CANCEL)) { + char *tmp_action_name = action_name; + + action_name = crm_concat("Cancel", tmp_action_name, ' '); + crm_free(tmp_action_name); } - + return action_name; } static void -create_dotfile(pe_working_set_t *data_set, const char *dot_file, gboolean all_actions) +create_dotfile(pe_working_set_t * data_set, const char *dot_file, gboolean all_actions) { GListPtr gIter = NULL; FILE *dot_strm = fopen(dot_file, "w"); - if(dot_strm == NULL) { - crm_perror(LOG_ERR,"Could not open %s for writing", dot_file); - return; + + if (dot_strm == NULL) { + crm_perror(LOG_ERR, "Could not open %s for writing", dot_file); + return; } fprintf(dot_strm, " digraph \"g\" {\n"); - for(gIter = data_set->actions; gIter != NULL; gIter = gIter->next) { - action_t *action = (action_t*)gIter->data; - const char *style = "dashed"; - const char *font = "black"; - const char *color = "black"; - char *action_name = create_action_name(action); - crm_debug_3("Action %d: %p", action->id, action); - - if(is_set(action->flags, pe_action_pseudo)) { - font = "orange"; - } - - if(is_set(action->flags, pe_action_dumped)) { - style = "bold"; - color = "green"; - - } else if(action->rsc != NULL - && is_not_set(action->rsc->flags, pe_rsc_managed)) { - color = "red"; - font = "purple"; - if(all_actions == FALSE) { - goto dont_write; - } - - } else if(is_set(action->flags, pe_action_optional)) { - color = "blue"; - if(all_actions == FALSE) { - goto dont_write; - } - - } else { - color = "red"; - CRM_CHECK(is_set(action->flags, pe_action_runnable) == FALSE, ;); - } - - set_bit_inplace(action->flags, pe_action_dumped); - fprintf(dot_strm, "\"%s\" [ style=%s color=\"%s\" fontcolor=\"%s\"]\n", - action_name, style, color, font); - dont_write: - crm_free(action_name); + for (gIter = data_set->actions; gIter != NULL; gIter = gIter->next) { + action_t *action = (action_t *) gIter->data; + const char *style = "dashed"; + const char *font = "black"; + const char *color = "black"; + char *action_name = create_action_name(action); + + crm_debug_3("Action %d: %p", action->id, action); + + if (is_set(action->flags, pe_action_pseudo)) { + font = "orange"; + } + + if (is_set(action->flags, pe_action_dumped)) { + style = "bold"; + color = "green"; + + } else if (action->rsc != NULL && is_not_set(action->rsc->flags, pe_rsc_managed)) { + color = "red"; + font = "purple"; + if (all_actions == FALSE) { + goto dont_write; + } + + } else if (is_set(action->flags, pe_action_optional)) { + color = "blue"; + if (all_actions == FALSE) { + goto dont_write; + } + + } else { + color = "red"; + CRM_CHECK(is_set(action->flags, pe_action_runnable) == FALSE,; + ); + } + + set_bit_inplace(action->flags, pe_action_dumped); + fprintf(dot_strm, "\"%s\" [ style=%s color=\"%s\" fontcolor=\"%s\"]\n", + action_name, style, color, font); + dont_write: + crm_free(action_name); } - for(gIter = data_set->actions; gIter != NULL; gIter = gIter->next) { - action_t *action = (action_t*)gIter->data; - - GListPtr gIter2 = NULL; - for(gIter2 = action->actions_before; gIter2 != NULL; gIter2 = gIter2->next) { - action_wrapper_t *before = (action_wrapper_t*)gIter2->data; - - char *before_name = NULL; - char *after_name = NULL; - const char *style = "dashed"; - gboolean optional = TRUE; - if(before->state == pe_link_dumped) { - optional = FALSE; - style = "bold"; - } else if(is_set(action->flags, pe_action_pseudo) - && (before->type & pe_order_stonith_stop)) { - continue; - } else if(before->state == pe_link_dup) { - continue; - } else if(before->type == pe_order_none) { - continue; - } else if(is_set(before->action->flags, pe_action_dumped) && is_set(action->flags, pe_action_dumped)) { - optional = FALSE; - } - - if(all_actions || optional == FALSE) { - before_name = create_action_name(before->action); - after_name = create_action_name(action); - fprintf(dot_strm, "\"%s\" -> \"%s\" [ style = %s]\n", - before_name, after_name, style); - crm_free(before_name); - crm_free(after_name); - } - } + for (gIter = data_set->actions; gIter != NULL; gIter = gIter->next) { + action_t *action = (action_t *) gIter->data; + + GListPtr gIter2 = NULL; + + for (gIter2 = action->actions_before; gIter2 != NULL; gIter2 = gIter2->next) { + action_wrapper_t *before = (action_wrapper_t *) gIter2->data; + + char *before_name = NULL; + char *after_name = NULL; + const char *style = "dashed"; + gboolean optional = TRUE; + + if (before->state == pe_link_dumped) { + optional = FALSE; + style = "bold"; + } else if (is_set(action->flags, pe_action_pseudo) + && (before->type & pe_order_stonith_stop)) { + continue; + } else if (before->state == pe_link_dup) { + continue; + } else if (before->type == pe_order_none) { + continue; + } else if (is_set(before->action->flags, pe_action_dumped) + && is_set(action->flags, pe_action_dumped)) { + optional = FALSE; + } + + if (all_actions || optional == FALSE) { + before_name = create_action_name(before->action); + after_name = create_action_name(action); + fprintf(dot_strm, "\"%s\" -> \"%s\" [ style = %s]\n", + before_name, after_name, style); + crm_free(before_name); + crm_free(after_name); + } + } } fprintf(dot_strm, "}\n"); - if(dot_strm != NULL) { - fflush(dot_strm); - fclose(dot_strm); + if (dot_strm != NULL) { + fflush(dot_strm); + fclose(dot_strm); } } -static void modify_configuration( - pe_working_set_t *data_set, - const char *quorum, GListPtr node_up, GListPtr node_down, GListPtr node_fail, GListPtr op_inject) +static void +modify_configuration(pe_working_set_t * data_set, + const char *quorum, GListPtr node_up, GListPtr node_down, GListPtr node_fail, + GListPtr op_inject) { int rc = cib_ok; GListPtr gIter = NULL; xmlNode *cib_op = NULL; xmlNode *cib_node = NULL; xmlNode *cib_resource = NULL; lrm_op_t *op = NULL; - if(quorum) { - xmlNode *top = create_xml_node(NULL, XML_TAG_CIB); - quiet_log(" + Setting quorum: %s\n", quorum); - /* crm_xml_add(top, XML_ATTR_DC_UUID, dc_uuid); */ - crm_xml_add(top, XML_ATTR_HAVE_QUORUM, quorum); + if (quorum) { + xmlNode *top = create_xml_node(NULL, XML_TAG_CIB); - rc = global_cib->cmds->modify(global_cib, NULL, top, cib_sync_call|cib_scope_local); - CRM_ASSERT(rc == cib_ok); + quiet_log(" + Setting quorum: %s\n", quorum); + /* crm_xml_add(top, XML_ATTR_DC_UUID, dc_uuid); */ + crm_xml_add(top, XML_ATTR_HAVE_QUORUM, quorum); + + rc = global_cib->cmds->modify(global_cib, NULL, top, cib_sync_call | cib_scope_local); + CRM_ASSERT(rc == cib_ok); } - - for(gIter = node_up; gIter != NULL; gIter = gIter->next) { - char *node = (char*)gIter->data; - - quiet_log(" + Bringing node %s online\n", node); - cib_node = modify_node(global_cib, node, TRUE); - CRM_ASSERT(cib_node != NULL); - - rc = global_cib->cmds->modify(global_cib, XML_CIB_TAG_STATUS, cib_node, cib_sync_call|cib_scope_local); - CRM_ASSERT(rc == cib_ok); + + for (gIter = node_up; gIter != NULL; gIter = gIter->next) { + char *node = (char *)gIter->data; + + quiet_log(" + Bringing node %s online\n", node); + cib_node = modify_node(global_cib, node, TRUE); + CRM_ASSERT(cib_node != NULL); + + rc = global_cib->cmds->modify(global_cib, XML_CIB_TAG_STATUS, cib_node, + cib_sync_call | cib_scope_local); + CRM_ASSERT(rc == cib_ok); } - for(gIter = node_down; gIter != NULL; gIter = gIter->next) { - char *node = (char*)gIter->data; - - quiet_log(" + Taking node %s offline\n", node); - cib_node = modify_node(global_cib, node, FALSE); - CRM_ASSERT(cib_node != NULL); + for (gIter = node_down; gIter != NULL; gIter = gIter->next) { + char *node = (char *)gIter->data; - rc = global_cib->cmds->modify(global_cib, XML_CIB_TAG_STATUS, cib_node, cib_sync_call|cib_scope_local); - CRM_ASSERT(rc == cib_ok); + quiet_log(" + Taking node %s offline\n", node); + cib_node = modify_node(global_cib, node, FALSE); + CRM_ASSERT(cib_node != NULL); + + rc = global_cib->cmds->modify(global_cib, XML_CIB_TAG_STATUS, cib_node, + cib_sync_call | cib_scope_local); + CRM_ASSERT(rc == cib_ok); } - for(gIter = node_fail; gIter != NULL; gIter = gIter->next) { - char *node = (char*)gIter->data; - - quiet_log(" + Failing node %s\n", node); - cib_node = modify_node(global_cib, node, TRUE); - crm_xml_add(cib_node, XML_CIB_ATTR_INCCM, XML_BOOLEAN_NO); - CRM_ASSERT(cib_node != NULL); + for (gIter = node_fail; gIter != NULL; gIter = gIter->next) { + char *node = (char *)gIter->data; - rc = global_cib->cmds->modify(global_cib, XML_CIB_TAG_STATUS, cib_node, cib_sync_call|cib_scope_local); - CRM_ASSERT(rc == cib_ok); + quiet_log(" + Failing node %s\n", node); + cib_node = modify_node(global_cib, node, TRUE); + crm_xml_add(cib_node, XML_CIB_ATTR_INCCM, XML_BOOLEAN_NO); + CRM_ASSERT(cib_node != NULL); + + rc = global_cib->cmds->modify(global_cib, XML_CIB_TAG_STATUS, cib_node, + cib_sync_call | cib_scope_local); + CRM_ASSERT(rc == cib_ok); } - for(gIter = op_inject; gIter != NULL; gIter = gIter->next) { - char *spec = (char*)gIter->data; - - int rc = 0; - int outcome = 0; - int interval = 0; - - char *key = NULL; - char *node = NULL; - char *task = NULL; - char *resource = NULL; - - const char *rtype = NULL; - const char *rclass = NULL; - const char *rprovider = NULL; - - resource_t *rsc = NULL; - quiet_log(" + Injecting %s into the configuration\n", spec); - - crm_malloc0(key, strlen(spec)+1); - crm_malloc0(node, strlen(spec)+1); - rc = sscanf(spec, "%[^@]@%[^=]=%d", key, node, &outcome); - CRM_CHECK(rc == 3, fprintf(stderr, "Invalid operation spec: %s. Only found %d fields\n", spec, rc); continue); - - parse_op_key(key, &resource, &task, &interval); - crm_free(task); - - rsc = pe_find_resource(data_set->resources, resource); - if(rsc == NULL) { - fprintf(stderr, " - Invalid resource name: %s\n", resource); - } else { - rclass = crm_element_value(rsc->xml, XML_AGENT_ATTR_CLASS); - rtype = crm_element_value(rsc->xml, XML_ATTR_TYPE); - rprovider = crm_element_value(rsc->xml, XML_AGENT_ATTR_PROVIDER); - - cib_node = inject_node_state(global_cib, node); - CRM_ASSERT(cib_node != NULL); - - update_failcounts(cib_node, resource, interval, outcome); - - cib_resource = inject_resource(cib_node, resource, rclass, rtype, rprovider); - CRM_ASSERT(cib_resource != NULL); - - op = create_op(cib_resource, task, interval, outcome); - CRM_ASSERT(op != NULL); - - cib_op = inject_op(cib_resource, op, 0); - CRM_ASSERT(cib_op != NULL); - free_lrm_op(op); - - rc = global_cib->cmds->modify(global_cib, XML_CIB_TAG_STATUS, cib_node, cib_sync_call|cib_scope_local); - CRM_ASSERT(rc == cib_ok); - } - crm_free(node); - crm_free(key); + for (gIter = op_inject; gIter != NULL; gIter = gIter->next) { + char *spec = (char *)gIter->data; + + int rc = 0; + int outcome = 0; + int interval = 0; + + char *key = NULL; + char *node = NULL; + char *task = NULL; + char *resource = NULL; + + const char *rtype = NULL; + const char *rclass = NULL; + const char *rprovider = NULL; + + resource_t *rsc = NULL; + + quiet_log(" + Injecting %s into the configuration\n", spec); + + crm_malloc0(key, strlen(spec) + 1); + crm_malloc0(node, strlen(spec) + 1); + rc = sscanf(spec, "%[^@]@%[^=]=%d", key, node, &outcome); + CRM_CHECK(rc == 3, + fprintf(stderr, "Invalid operation spec: %s. Only found %d fields\n", spec, rc); + continue); + + parse_op_key(key, &resource, &task, &interval); + crm_free(task); + + rsc = pe_find_resource(data_set->resources, resource); + if (rsc == NULL) { + fprintf(stderr, " - Invalid resource name: %s\n", resource); + } else { + rclass = crm_element_value(rsc->xml, XML_AGENT_ATTR_CLASS); + rtype = crm_element_value(rsc->xml, XML_ATTR_TYPE); + rprovider = crm_element_value(rsc->xml, XML_AGENT_ATTR_PROVIDER); + + cib_node = inject_node_state(global_cib, node); + CRM_ASSERT(cib_node != NULL); + + update_failcounts(cib_node, resource, interval, outcome); + + cib_resource = inject_resource(cib_node, resource, rclass, rtype, rprovider); + CRM_ASSERT(cib_resource != NULL); + + op = create_op(cib_resource, task, interval, outcome); + CRM_ASSERT(op != NULL); + + cib_op = inject_op(cib_resource, op, 0); + CRM_ASSERT(cib_op != NULL); + free_lrm_op(op); + + rc = global_cib->cmds->modify(global_cib, XML_CIB_TAG_STATUS, cib_node, + cib_sync_call | cib_scope_local); + CRM_ASSERT(rc == cib_ok); + } + crm_free(node); + crm_free(key); } } - + static void -setup_input(const char *input, const char *output) +setup_input(const char *input, const char *output) { int rc = cib_ok; cib_t *cib_conn = NULL; xmlNode *cib_object = NULL; char *local_output = NULL; - - if(input == NULL) { - /* Use live CIB */ - cib_conn = cib_new(); - rc = cib_conn->cmds->signon(cib_conn, crm_system_name, cib_command); - - if(rc == cib_ok) { - cib_object = get_cib_copy(cib_conn); - } - - cib_conn->cmds->signoff(cib_conn); - cib_delete(cib_conn); - cib_conn = NULL; - - if(cib_object == NULL) { - fprintf(stderr, "Live CIB query failed: empty result\n"); - exit(3); - } - - } else if(safe_str_eq(input, "-")) { - cib_object = filename2xml(NULL); - + + if (input == NULL) { + /* Use live CIB */ + cib_conn = cib_new(); + rc = cib_conn->cmds->signon(cib_conn, crm_system_name, cib_command); + + if (rc == cib_ok) { + cib_object = get_cib_copy(cib_conn); + } + + cib_conn->cmds->signoff(cib_conn); + cib_delete(cib_conn); + cib_conn = NULL; + + if (cib_object == NULL) { + fprintf(stderr, "Live CIB query failed: empty result\n"); + exit(3); + } + + } else if (safe_str_eq(input, "-")) { + cib_object = filename2xml(NULL); + } else { - cib_object = filename2xml(input); + cib_object = filename2xml(input); } - if(get_object_root(XML_CIB_TAG_STATUS, cib_object) == NULL) { - create_xml_node(cib_object, XML_CIB_TAG_STATUS); + if (get_object_root(XML_CIB_TAG_STATUS, cib_object) == NULL) { + create_xml_node(cib_object, XML_CIB_TAG_STATUS); } - if(cli_config_update(&cib_object, NULL, FALSE) == FALSE) { - free_xml(cib_object); - exit(cib_STALE); + if (cli_config_update(&cib_object, NULL, FALSE) == FALSE) { + free_xml(cib_object); + exit(cib_STALE); } - - if(validate_xml(cib_object, NULL, FALSE) != TRUE) { - free_xml(cib_object); - exit(cib_dtd_validation); + + if (validate_xml(cib_object, NULL, FALSE) != TRUE) { + free_xml(cib_object); + exit(cib_dtd_validation); } - - if(output == NULL) { - char *pid = crm_itoa(getpid()); - local_output = get_shadow_file(pid); - output = local_output; - crm_free(pid); + + if (output == NULL) { + char *pid = crm_itoa(getpid()); + + local_output = get_shadow_file(pid); + output = local_output; + crm_free(pid); } rc = write_xml_file(cib_object, output, FALSE); free_xml(cib_object); cib_object = NULL; - - if(rc < 0) { - fprintf(stderr, "Could not create '%s': %s\n", output, strerror(errno)); - exit(rc); + + if (rc < 0) { + fprintf(stderr, "Could not create '%s': %s\n", output, strerror(errno)); + exit(rc); } setenv("CIB_file", output, 1); crm_free(local_output); } /* *INDENT-OFF* */ static struct crm_option long_options[] = { /* Top-level Options */ {"help", 0, 0, '?', "\tThis text"}, {"version", 0, 0, '$', "\tVersion information" }, {"quiet", 0, 0, 'Q', "\tDisplay only essentialoutput"}, {"verbose", 0, 0, 'V', "\tIncrease debug output"}, {"-spacer-", 0, 0, '-', "\nOperations:"}, {"run", 0, 0, 'R', "\tDetermine the cluster's response to the given configuration and status"}, {"simulate", 0, 0, 'S', "Simulate the transition's execution and display the resulting cluster status"}, {"in-place", 0, 0, 'X', "Simulate the transition's execution and store the result back to the input file"}, {"show-scores", 0, 0, 's', "Show allocation scores"}, {"show-utilization", 0, 0, 'U', "Show utilization information"}, {"-spacer-", 0, 0, '-', "\nSynthetic Cluster Events:"}, {"node-up", 1, 0, 'u', "\tBring a node online"}, {"node-down", 1, 0, 'd', "\tTake a node offline"}, {"node-fail", 1, 0, 'f', "\tMark a node as failed"}, {"op-inject", 1, 0, 'i', "\t$rsc_$task_$interval@$node=$rc - Inject the specified task before running the simulation"}, {"op-fail", 1, 0, 'F', "\t$rsc_$task_$interval@$node=$rc - Fail the specified task while running the simulation"}, {"set-datetime", 1, 0, 't', "Set date/time"}, {"quorum", 1, 0, 'q', "\tSpecify a value for quorum"}, {"-spacer-", 0, 0, '-', "\nOutput Options:"}, {"save-input", 1, 0, 'I', "\tSave the input configuration to the named file"}, {"save-output", 1, 0, 'O', "Save the output configuration to the named file"}, {"save-graph", 1, 0, 'G', "\tSave the transition graph (XML format) to the named file"}, {"save-dotfile", 1, 0, 'D', "Save the transition graph (DOT format) to the named file"}, {"all-actions", 0, 0, 'a', "\tDisplay all possible actions in the DOT graph - even ones not part of the transition"}, {"-spacer-", 0, 0, '-', "\nData Source:"}, {"live-check", 0, 0, 'L', "\tConnect to the CIB and use the current contents as input"}, {"xml-file", 1, 0, 'x', "\tRetrieve XML from the named file"}, {"xml-pipe", 0, 0, 'p', "\tRetrieve XML from stdin"}, {0, 0, 0, 0} }; /* *INDENT-ON* */ int -main(int argc, char ** argv) +main(int argc, char **argv) { int rc = 0; guint modified = 0; gboolean store = FALSE; gboolean process = FALSE; gboolean verbose = FALSE; gboolean simulate = FALSE; gboolean all_actions = FALSE; pe_working_set_t data_set; const char *xml_file = "-"; const char *quorum = NULL; const char *dot_file = NULL; const char *graph_file = NULL; const char *input_file = NULL; const char *output_file = NULL; - + int flag = 0; int index = 0; int argerr = 0; GListPtr node_up = NULL; GListPtr node_down = NULL; GListPtr node_fail = NULL; GListPtr op_inject = NULL; - + xmlNode *input = NULL; crm_log_init(NULL, LOG_ERR, FALSE, FALSE, argc, argv); crm_set_options(NULL, "datasource operation [additional options]", - long_options, "Tool for simulating the cluster's response to events"); + long_options, "Tool for simulating the cluster's response to events"); - if(argc < 2) { - crm_help('?', LSB_EXIT_EINVAL); + if (argc < 2) { + crm_help('?', LSB_EXIT_EINVAL); } while (1) { - flag = crm_get_option(argc, argv, &index); - if (flag == -1) - break; - - switch(flag) { - case 'V': - verbose = TRUE; - alter_debug(DEBUG_INC); - - /* Redirect stderr to stdout so we can grep the output */ - close(STDERR_FILENO); - dup2(STDOUT_FILENO, STDERR_FILENO); - - cl_log_enable_stderr(TRUE); - break; - case '?': - case '$': - crm_help(flag, LSB_EXIT_OK); - break; - case 'p': - xml_file = "-"; - break; - case 'Q': - quiet = TRUE; - break; - case 'L': - xml_file = NULL; - break; - case 'x': - xml_file = optarg; - break; - case 'u': - modified++; - node_up = g_list_append(node_up, optarg); - break; - case 'd': - modified++; - node_down = g_list_append(node_down, optarg); - break; - case 'f': - modified++; - node_fail = g_list_append(node_fail, optarg); - break; - case 't': - use_date = crm_strdup(optarg); - break; - case 'i': - modified++; - op_inject = g_list_append(op_inject, optarg); - break; - case 'F': - process = TRUE; - simulate = TRUE; - op_fail = g_list_append(op_fail, optarg); - break; - case 'q': - modified++; - quorum = optarg; - break; - case 'a': - all_actions = TRUE; - break; - case 's': - process = TRUE; - show_scores = TRUE; - break; - case 'U': - process = TRUE; - show_utilization = TRUE; - break; - case 'S': - process = TRUE; - simulate = TRUE; - break; - case 'X': - store = TRUE; - process = TRUE; - simulate = TRUE; - break; - case 'R': - process = TRUE; - break; - case 'D': - process = TRUE; - dot_file = optarg; - break; - case 'G': - process = TRUE; - graph_file = optarg; - break; - case 'I': - input_file = optarg; - break; - case 'O': - simulate = TRUE; - output_file = optarg; - break; - default: - ++argerr; - break; - } + flag = crm_get_option(argc, argv, &index); + if (flag == -1) + break; + + switch (flag) { + case 'V': + verbose = TRUE; + alter_debug(DEBUG_INC); + + /* Redirect stderr to stdout so we can grep the output */ + close(STDERR_FILENO); + dup2(STDOUT_FILENO, STDERR_FILENO); + + cl_log_enable_stderr(TRUE); + break; + case '?': + case '$': + crm_help(flag, LSB_EXIT_OK); + break; + case 'p': + xml_file = "-"; + break; + case 'Q': + quiet = TRUE; + break; + case 'L': + xml_file = NULL; + break; + case 'x': + xml_file = optarg; + break; + case 'u': + modified++; + node_up = g_list_append(node_up, optarg); + break; + case 'd': + modified++; + node_down = g_list_append(node_down, optarg); + break; + case 'f': + modified++; + node_fail = g_list_append(node_fail, optarg); + break; + case 't': + use_date = crm_strdup(optarg); + break; + case 'i': + modified++; + op_inject = g_list_append(op_inject, optarg); + break; + case 'F': + process = TRUE; + simulate = TRUE; + op_fail = g_list_append(op_fail, optarg); + break; + case 'q': + modified++; + quorum = optarg; + break; + case 'a': + all_actions = TRUE; + break; + case 's': + process = TRUE; + show_scores = TRUE; + break; + case 'U': + process = TRUE; + show_utilization = TRUE; + break; + case 'S': + process = TRUE; + simulate = TRUE; + break; + case 'X': + store = TRUE; + process = TRUE; + simulate = TRUE; + break; + case 'R': + process = TRUE; + break; + case 'D': + process = TRUE; + dot_file = optarg; + break; + case 'G': + process = TRUE; + graph_file = optarg; + break; + case 'I': + input_file = optarg; + break; + case 'O': + simulate = TRUE; + output_file = optarg; + break; + default: + ++argerr; + break; + } } if (optind > argc) { - ++argerr; + ++argerr; } if (argerr) { - crm_help('?', LSB_EXIT_GENERIC); + crm_help('?', LSB_EXIT_GENERIC); } - update_all_trace_data(); /* again, so we see which trace points got updated */ - - setup_input(xml_file, store?xml_file:output_file); - + update_all_trace_data(); /* again, so we see which trace points got updated */ + + setup_input(xml_file, store ? xml_file : output_file); + global_cib = cib_new(); global_cib->cmds->signon(global_cib, crm_system_name, cib_command); set_working_set_defaults(&data_set); - - if(data_set.now != NULL) { - quiet_log(" + Setting effective cluster time: %s", use_date); - log_date(LOG_WARNING, "Set fake 'now' to", data_set.now, ha_log_date|ha_log_time); + + if (data_set.now != NULL) { + quiet_log(" + Setting effective cluster time: %s", use_date); + log_date(LOG_WARNING, "Set fake 'now' to", data_set.now, ha_log_date | ha_log_time); } - - rc = global_cib->cmds->query(global_cib, NULL, &input, cib_sync_call|cib_scope_local); + + rc = global_cib->cmds->query(global_cib, NULL, &input, cib_sync_call | cib_scope_local); CRM_ASSERT(rc == cib_ok); - + data_set.input = input; data_set.now = get_date(); cluster_status(&data_set); - - if(quiet == FALSE) { - quiet_log("\nCurrent cluster status:\n"); - print_cluster_status(&data_set); - } - - if(modified) { - quiet_log("Performing requested modifications\n"); - modify_configuration(&data_set, quorum, node_up, node_down, node_fail, op_inject); - - rc = global_cib->cmds->query(global_cib, NULL, &input, cib_sync_call); - if(rc != cib_ok) { - fprintf(stderr, "Could not connect to the CIB for input: %s\n", cib_error2string(rc)); - goto done; - } - - cleanup_alloc_calculations(&data_set); - data_set.now = get_date(); - data_set.input = input; - } - - if(input_file != NULL) { - rc = write_xml_file(input, input_file, FALSE); - if(rc < 0) { - fprintf(stderr, "Could not create '%s': %s\n", input_file, strerror(errno)); - goto done; - } + + if (quiet == FALSE) { + quiet_log("\nCurrent cluster status:\n"); + print_cluster_status(&data_set); + } + + if (modified) { + quiet_log("Performing requested modifications\n"); + modify_configuration(&data_set, quorum, node_up, node_down, node_fail, op_inject); + + rc = global_cib->cmds->query(global_cib, NULL, &input, cib_sync_call); + if (rc != cib_ok) { + fprintf(stderr, "Could not connect to the CIB for input: %s\n", cib_error2string(rc)); + goto done; + } + + cleanup_alloc_calculations(&data_set); + data_set.now = get_date(); + data_set.input = input; + } + + if (input_file != NULL) { + rc = write_xml_file(input, input_file, FALSE); + if (rc < 0) { + fprintf(stderr, "Could not create '%s': %s\n", input_file, strerror(errno)); + goto done; + } } rc = 0; - if(process || simulate) { - ha_time_t *local_date = NULL; - if(show_scores && show_utilization) { - printf("Allocation scores and utilization information:\n"); - } else if(show_scores) { - fprintf(stdout, "Allocation scores:\n"); - } else if(show_utilization) { - printf("Utilization information:\n"); - } - - do_calculations(&data_set, input, local_date); - input = NULL; /* Don't try and free it twice */ - - if(graph_file != NULL) { - char *msg_buffer = dump_xml_formatted(data_set.graph); - FILE *graph_strm = fopen(graph_file, "w"); - if(graph_strm == NULL) { - crm_perror(LOG_ERR,"Could not open %s for writing", graph_file); - - } else { - if(fprintf(graph_strm, "%s\n\n", msg_buffer) < 0) { - crm_perror(LOG_ERR,"Write to %s failed", graph_file); - } - fflush(graph_strm); - fclose(graph_strm); - } - crm_free(msg_buffer); - } - - if(dot_file != NULL) { - create_dotfile(&data_set, dot_file, all_actions); - } - - if(quiet == FALSE && verbose == FALSE) { - GListPtr gIter = NULL; - quiet_log("%sTransition Summary:\n", show_scores||show_utilization||modified?"\n":""); - fflush(stdout); - - crm_log_level = LOG_NOTICE; - cl_log_enable_stderr(TRUE); - for(gIter = data_set.resources; gIter != NULL; gIter = gIter->next) { - resource_t *rsc = (resource_t*)gIter->data; - LogActions(rsc, &data_set); - } - - cl_log_enable_stderr(FALSE); - } + if (process || simulate) { + ha_time_t *local_date = NULL; + + if (show_scores && show_utilization) { + printf("Allocation scores and utilization information:\n"); + } else if (show_scores) { + fprintf(stdout, "Allocation scores:\n"); + } else if (show_utilization) { + printf("Utilization information:\n"); + } + + do_calculations(&data_set, input, local_date); + input = NULL; /* Don't try and free it twice */ + + if (graph_file != NULL) { + char *msg_buffer = dump_xml_formatted(data_set.graph); + FILE *graph_strm = fopen(graph_file, "w"); + + if (graph_strm == NULL) { + crm_perror(LOG_ERR, "Could not open %s for writing", graph_file); + + } else { + if (fprintf(graph_strm, "%s\n\n", msg_buffer) < 0) { + crm_perror(LOG_ERR, "Write to %s failed", graph_file); + } + fflush(graph_strm); + fclose(graph_strm); + } + crm_free(msg_buffer); + } + + if (dot_file != NULL) { + create_dotfile(&data_set, dot_file, all_actions); + } + + if (quiet == FALSE && verbose == FALSE) { + GListPtr gIter = NULL; + + quiet_log("%sTransition Summary:\n", show_scores || show_utilization + || modified ? "\n" : ""); + fflush(stdout); + + crm_log_level = LOG_NOTICE; + cl_log_enable_stderr(TRUE); + for (gIter = data_set.resources; gIter != NULL; gIter = gIter->next) { + resource_t *rsc = (resource_t *) gIter->data; + + LogActions(rsc, &data_set); + } + + cl_log_enable_stderr(FALSE); + } } - - if(simulate) { - rc = run_simulation(&data_set); + + if (simulate) { + rc = run_simulation(&data_set); } done: cleanup_alloc_calculations(&data_set); - + global_cib->cmds->signoff(global_cib); cib_delete(global_cib); crm_free(use_date); crm_xml_cleanup(); fflush(stderr); return rc; } diff --git a/tools/crm_mon.c b/tools/crm_mon.c index 1f9573c397..98485a6fc8 100644 --- a/tools/crm_mon.c +++ b/tools/crm_mon.c @@ -1,2017 +1,2084 @@ /* * Copyright (C) 2004 Andrew Beekhof * * 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 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 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 */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include <../lib/pengine/unpack.h> /* GMainLoop *mainloop = NULL; */ void wait_for_refresh(int offset, const char *prefix, int msec); void clean_up(int rc); -void crm_diff_update(const char *event, xmlNode *msg); +void crm_diff_update(const char *event, xmlNode * msg); gboolean mon_refresh_display(gpointer user_data); int cib_connect(gboolean full); char *xml_file = NULL; char *as_html_file = NULL; char *pid_file = NULL; char *snmp_target = NULL; char *snmp_community = NULL; gboolean as_console = TRUE;; gboolean simple_status = FALSE; gboolean group_by_node = FALSE; gboolean inactive_resources = FALSE; gboolean web_cgi = FALSE; int reconnect_msec = 5000; gboolean daemonize = FALSE; GMainLoop *mainloop = NULL; guint timer_id = 0; GList *attr_list = NULL; const char *crm_mail_host = NULL; const char *crm_mail_prefix = NULL; const char *crm_mail_from = NULL; const char *crm_mail_to = NULL; const char *external_agent = NULL; const char *external_recipient = NULL; cib_t *cib = NULL; xmlNode *current_cib = NULL; gboolean one_shot = FALSE; gboolean has_warnings = FALSE; gboolean print_failcount = FALSE; gboolean print_operations = FALSE; gboolean print_timing = FALSE; gboolean print_nodes_attr = FALSE; gboolean print_last_updated = TRUE; gboolean print_last_change = TRUE; + #define FILTER_STR {"shutdown", "terminate", "standby", "fail-count", \ "last-failure", "probe_complete", "#id", "#uname", \ "#is_dc", NULL} gboolean log_diffs = FALSE; gboolean log_updates = FALSE; long last_refresh = 0; crm_trigger_t *refresh_trigger = NULL; /* * 1.3.6.1.4.1.32723 has been assigned to the project by IANA * http://www.iana.org/assignments/enterprise-numbers */ #define PACEMAKER_PREFIX "1.3.6.1.4.1.32723" #define PACEMAKER_TRAP_PREFIX PACEMAKER_PREFIX ".1" #define snmp_crm_trap_oid PACEMAKER_TRAP_PREFIX #define snmp_crm_oid_node PACEMAKER_TRAP_PREFIX ".1" #define snmp_crm_oid_rsc PACEMAKER_TRAP_PREFIX ".2" #define snmp_crm_oid_task PACEMAKER_TRAP_PREFIX ".3" #define snmp_crm_oid_desc PACEMAKER_TRAP_PREFIX ".4" #define snmp_crm_oid_status PACEMAKER_TRAP_PREFIX ".5" #define snmp_crm_oid_rc PACEMAKER_TRAP_PREFIX ".6" #define snmp_crm_oid_trc PACEMAKER_TRAP_PREFIX ".7" #if CURSES_ENABLED # define print_dot() if(as_console) { \ printw("."); \ clrtoeol(); \ refresh(); \ } else { \ fprintf(stdout, "."); \ } #else # define print_dot() fprintf(stdout, "."); #endif #if CURSES_ENABLED # define print_as(fmt, args...) if(as_console) { \ printw(fmt, ##args); \ clrtoeol(); \ refresh(); \ } else { \ fprintf(stdout, fmt, ##args); \ } #else # define print_as(fmt, args...) fprintf(stdout, fmt, ##args); #endif static void -blank_screen(void) +blank_screen(void) { #if CURSES_ENABLED int lpc = 0; - for(lpc = 0; lpc < LINES; lpc++) { - move(lpc, 0); - clrtoeol(); + + for (lpc = 0; lpc < LINES; lpc++) { + move(lpc, 0); + clrtoeol(); } move(0, 0); refresh(); #endif } static gboolean mon_timer_popped(gpointer data) { int rc = cib_ok; - if(timer_id > 0) { - g_source_remove(timer_id); + + if (timer_id > 0) { + g_source_remove(timer_id); } rc = cib_connect(TRUE); - - if(rc != cib_ok) { - print_dot(); - timer_id = g_timeout_add(reconnect_msec, mon_timer_popped, NULL); + + if (rc != cib_ok) { + print_dot(); + timer_id = g_timeout_add(reconnect_msec, mon_timer_popped, NULL); } return FALSE; } -static void mon_cib_connection_destroy(gpointer user_data) +static void +mon_cib_connection_destroy(gpointer user_data) { print_as("Connection to the CIB terminated\n"); - if(cib) { - print_as("Reconnecting..."); - cib->cmds->signoff(cib); - timer_id = g_timeout_add(reconnect_msec, mon_timer_popped, NULL); + if (cib) { + print_as("Reconnecting..."); + cib->cmds->signoff(cib); + timer_id = g_timeout_add(reconnect_msec, mon_timer_popped, NULL); } return; } /* * Mainloop signal handler. */ static void mon_shutdown(int nsig) { clean_up(LSB_EXIT_OK); } #if ON_DARWIN -# define sighandler_t sig_t +# define sighandler_t sig_t #endif #if CURSES_ENABLED static sighandler_t ncurses_winch_handler; static void mon_winresize(int nsig) { static int not_done; int lines = 0, cols = 0; - if(!not_done++) { - if(ncurses_winch_handler) - /* the original ncurses WINCH signal handler does the - * magic of retrieving the new window size; - * otherwise, we'd have to use ioctl or tgetent */ - (*ncurses_winch_handler) (SIGWINCH); - getmaxyx(stdscr, lines, cols); - resizeterm(lines,cols); - mainloop_set_trigger(refresh_trigger); + if (!not_done++) { + if (ncurses_winch_handler) + /* the original ncurses WINCH signal handler does the + * magic of retrieving the new window size; + * otherwise, we'd have to use ioctl or tgetent */ + (*ncurses_winch_handler) (SIGWINCH); + getmaxyx(stdscr, lines, cols); + resizeterm(lines, cols); + mainloop_set_trigger(refresh_trigger); } not_done--; } #endif -int cib_connect(gboolean full) +int +cib_connect(gboolean full) { int rc = cib_ok; static gboolean need_pass = TRUE; + CRM_CHECK(cib != NULL, return cib_missing); - if(getenv("CIB_passwd") != NULL) { - need_pass = FALSE; - } - - if(cib->state != cib_connected_query - && cib->state != cib_connected_command) { - crm_debug_4("Connecting to the CIB"); - if(as_console && need_pass && cib->variant == cib_remote) { - need_pass = FALSE; - print_as("Password:"); - } - - rc = cib->cmds->signon(cib, crm_system_name, cib_query); - - if(rc != cib_ok) { - return rc; - } - - current_cib = get_cib_copy(cib); - mon_refresh_display(NULL); - - if(full) { - if(rc == cib_ok) { - rc = cib->cmds->set_connection_dnotify(cib, mon_cib_connection_destroy); - if(rc == cib_NOTSUPPORTED) { - print_as("Notification setup failed, won't be able to reconnect after failure"); - if(as_console) { sleep(2); } - rc = cib_ok; - } - - } - - if(rc == cib_ok) { - cib->cmds->del_notify_callback(cib, T_CIB_DIFF_NOTIFY, crm_diff_update); - rc = cib->cmds->add_notify_callback(cib, T_CIB_DIFF_NOTIFY, crm_diff_update); - } - - if(rc != cib_ok) { - print_as("Notification setup failed, could not monitor CIB actions"); - if(as_console) { sleep(2); } - clean_up(-rc); - } - } + if (getenv("CIB_passwd") != NULL) { + need_pass = FALSE; + } + + if (cib->state != cib_connected_query && cib->state != cib_connected_command) { + crm_debug_4("Connecting to the CIB"); + if (as_console && need_pass && cib->variant == cib_remote) { + need_pass = FALSE; + print_as("Password:"); + } + + rc = cib->cmds->signon(cib, crm_system_name, cib_query); + + if (rc != cib_ok) { + return rc; + } + + current_cib = get_cib_copy(cib); + mon_refresh_display(NULL); + + if (full) { + if (rc == cib_ok) { + rc = cib->cmds->set_connection_dnotify(cib, mon_cib_connection_destroy); + if (rc == cib_NOTSUPPORTED) { + print_as("Notification setup failed, won't be able to reconnect after failure"); + if (as_console) { + sleep(2); + } + rc = cib_ok; + } + + } + + if (rc == cib_ok) { + cib->cmds->del_notify_callback(cib, T_CIB_DIFF_NOTIFY, crm_diff_update); + rc = cib->cmds->add_notify_callback(cib, T_CIB_DIFF_NOTIFY, crm_diff_update); + } + + if (rc != cib_ok) { + print_as("Notification setup failed, could not monitor CIB actions"); + if (as_console) { + sleep(2); + } + clean_up(-rc); + } + } } return rc; } /* *INDENT-OFF* */ static struct crm_option long_options[] = { /* Top-level Options */ {"help", 0, 0, '?', "\tThis text"}, {"version", 0, 0, '$', "\tVersion information" }, {"verbose", 0, 0, 'V', "\tIncrease debug output"}, {"quiet", 0, 0, 'Q', "\tDisplay only essential output" }, {"-spacer-", 1, 0, '-', "\nModes:"}, {"as-html", 1, 0, 'h', "Write cluster status to the named file"}, {"web-cgi", 0, 0, 'w', "\tWeb mode with output suitable for cgi"}, {"simple-status", 0, 0, 's', "Display the cluster status once as a simple one line output (suitable for nagios)"}, {"snmp-traps", 1, 0, 'S', "Send SNMP traps to this station", !ENABLE_SNMP}, {"snmp-community", 1, 0, 'C', "Specify community for SNMP traps(default is NULL)", !ENABLE_SNMP}, {"mail-to", 1, 0, 'T', "Send Mail alerts to this user. See also --mail-from, --mail-host, --mail-prefix", !ENABLE_ESMTP}, {"-spacer-", 1, 0, '-', "\nDisplay Options:"}, {"group-by-node", 0, 0, 'n', "\tGroup resources by node" }, {"inactive", 0, 0, 'r', "\tDisplay inactive resources" }, {"failcounts", 0, 0, 'f', "\tDisplay resource fail counts"}, {"operations", 0, 0, 'o', "\tDisplay resource operation history" }, {"timing-details", 0, 0, 't', "\tDisplay resource operation history with timing details" }, {"show-node-attributes", 0, 0, 'A', "Display node attributes\n" }, {"-spacer-", 1, 0, '-', "\nAdditional Options:"}, {"interval", 1, 0, 'i', "\tUpdate frequency in seconds" }, {"one-shot", 0, 0, '1', "\tDisplay the cluster status once on the console and exit"}, {"disable-ncurses",0, 0, 'N', "\tDisable the use of ncurses", !CURSES_ENABLED}, {"daemonize", 0, 0, 'd', "\tRun in the background as a daemon"}, {"pid-file", 1, 0, 'p', "\t(Advanced) Daemon pid file location"}, {"mail-from", 1, 0, 'F', "\tMail alerts should come from the named user", !ENABLE_ESMTP}, {"mail-host", 1, 0, 'H', "\tMail alerts should be sent via the named host", !ENABLE_ESMTP}, {"mail-prefix", 1, 0, 'P', "Subjects for mail alerts should start with this string", !ENABLE_ESMTP}, {"external-agent", 1, 0, 'E', "A program to run when resource operations take place."}, {"external-recipient",1, 0, 'e', "A recipient for your program (assuming you want the program to send something to someone)."}, {"xml-file", 1, 0, 'x', NULL, 1}, {"-spacer-", 1, 0, '-', "\nExamples:", pcmk_option_paragraph}, {"-spacer-", 1, 0, '-', "Display the cluster´s status on the console with updates as they occur:", pcmk_option_paragraph}, {"-spacer-", 1, 0, '-', " crm_mon", pcmk_option_example}, {"-spacer-", 1, 0, '-', "Display the cluster´s status on the console just once then exit:", pcmk_option_paragraph}, {"-spacer-", 1, 0, '-', " crm_mon -1", pcmk_option_example}, {"-spacer-", 1, 0, '-', "Display your cluster´s status, group resources by node, and include inactive resources in the list:", pcmk_option_paragraph}, {"-spacer-", 1, 0, '-', " crm_mon --group-by-node --inactive", pcmk_option_example}, {"-spacer-", 1, 0, '-', "Start crm_mon as a background daemon and have it write the cluster´s status to an HTML file:", pcmk_option_paragraph}, {"-spacer-", 1, 0, '-', " crm_mon --daemonize --as-html /path/to/docroot/filename.html", pcmk_option_example}, {"-spacer-", 1, 0, '-', "Start crm_mon as a background daemon and have it send email alerts:", pcmk_option_paragraph|!ENABLE_ESMTP}, {"-spacer-", 1, 0, '-', " crm_mon --daemonize --mail-to user@example.com --mail-host mail.example.com", pcmk_option_example|!ENABLE_ESMTP}, {"-spacer-", 1, 0, '-', "Start crm_mon as a background daemon and have it send SNMP alerts:", pcmk_option_paragraph|!ENABLE_SNMP}, {"-spacer-", 1, 0, '-', " crm_mon --daemonize --snmp-traps snmptrapd.example.com", pcmk_option_example|!ENABLE_SNMP}, {NULL, 0, 0, 0} }; /* *INDENT-ON* */ int main(int argc, char **argv) { int flag; int argerr = 0; int exit_code = 0; - int option_index = 0; + int option_index = 0; pid_file = crm_strdup("/tmp/ClusterMon.pid"); crm_log_init_quiet(NULL, LOG_CRIT, FALSE, FALSE, argc, argv); crm_set_options(NULL, "mode [options]", long_options, - "Provides a summary of cluster's current state." - "\n\nOutputs varying levels of detail in a number of different formats.\n"); + "Provides a summary of cluster's current state." + "\n\nOutputs varying levels of detail in a number of different formats.\n"); #ifndef ON_DARWIN /* prevent zombies */ signal(SIGCLD, SIG_IGN); #endif - - if (strcmp(crm_system_name, "crm_mon.cgi")==0) { - web_cgi = TRUE; - one_shot = TRUE; + + if (strcmp(crm_system_name, "crm_mon.cgi") == 0) { + web_cgi = TRUE; + one_shot = TRUE; } while (1) { - flag = crm_get_option(argc, argv, &option_index); - if (flag == -1) - break; - - switch(flag) { - case 'V': - cl_log_enable_stderr(TRUE); - alter_debug(DEBUG_INC); - break; - case 'Q': - print_last_updated = FALSE; - print_last_change = FALSE; - break; - case 'i': - reconnect_msec = crm_get_msec(optarg); - break; - case 'n': - group_by_node = TRUE; - break; - case 'r': - inactive_resources = TRUE; - break; - case 'd': - daemonize = TRUE; - break; - case 't': - print_timing = TRUE; - print_operations = TRUE; - break; - case 'o': - print_operations = TRUE; - break; - case 'f': - print_failcount = TRUE; - break; - case 'A': - print_nodes_attr = TRUE; - break; - case 'p': - crm_free(pid_file); - pid_file = crm_strdup(optarg); - break; - case 'x': - xml_file = crm_strdup(optarg); - one_shot = TRUE; - break; - case 'h': - as_html_file = crm_strdup(optarg); - break; - case 'w': - web_cgi = TRUE; - one_shot = TRUE; - break; - case 's': - simple_status = TRUE; - one_shot = TRUE; - break; - case 'S': - snmp_target = optarg; - break; - case 'T': - crm_mail_to = optarg; - break; - case 'F': - crm_mail_from = optarg; - break; - case 'H': - crm_mail_host = optarg; - break; - case 'P': - crm_mail_prefix = optarg; - break; - case 'E': - external_agent = optarg; - break; - case 'e': - external_recipient = optarg; - break; - case '1': - one_shot = TRUE; - break; - case 'N': - as_console = FALSE; - break; - case 'C': - snmp_community = optarg; - break; - case '$': - case '?': - crm_help(flag, LSB_EXIT_OK); - break; - default: - printf("Argument code 0%o (%c) is not (?yet?) supported\n", flag, flag); - ++argerr; - break; - } + flag = crm_get_option(argc, argv, &option_index); + if (flag == -1) + break; + + switch (flag) { + case 'V': + cl_log_enable_stderr(TRUE); + alter_debug(DEBUG_INC); + break; + case 'Q': + print_last_updated = FALSE; + print_last_change = FALSE; + break; + case 'i': + reconnect_msec = crm_get_msec(optarg); + break; + case 'n': + group_by_node = TRUE; + break; + case 'r': + inactive_resources = TRUE; + break; + case 'd': + daemonize = TRUE; + break; + case 't': + print_timing = TRUE; + print_operations = TRUE; + break; + case 'o': + print_operations = TRUE; + break; + case 'f': + print_failcount = TRUE; + break; + case 'A': + print_nodes_attr = TRUE; + break; + case 'p': + crm_free(pid_file); + pid_file = crm_strdup(optarg); + break; + case 'x': + xml_file = crm_strdup(optarg); + one_shot = TRUE; + break; + case 'h': + as_html_file = crm_strdup(optarg); + break; + case 'w': + web_cgi = TRUE; + one_shot = TRUE; + break; + case 's': + simple_status = TRUE; + one_shot = TRUE; + break; + case 'S': + snmp_target = optarg; + break; + case 'T': + crm_mail_to = optarg; + break; + case 'F': + crm_mail_from = optarg; + break; + case 'H': + crm_mail_host = optarg; + break; + case 'P': + crm_mail_prefix = optarg; + break; + case 'E': + external_agent = optarg; + break; + case 'e': + external_recipient = optarg; + break; + case '1': + one_shot = TRUE; + break; + case 'N': + as_console = FALSE; + break; + case 'C': + snmp_community = optarg; + break; + case '$': + case '?': + crm_help(flag, LSB_EXIT_OK); + 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"); + printf("non-option ARGV-elements: "); + while (optind < argc) + printf("%s ", argv[optind++]); + printf("\n"); } if (argerr) { - crm_help('?', LSB_EXIT_GENERIC); + crm_help('?', LSB_EXIT_GENERIC); } - - if(one_shot) { - as_console = FALSE; - } else if(daemonize) { - as_console = FALSE; - cl_log_enable_stderr(FALSE); - - if(!as_html_file && !snmp_target && !crm_mail_to && !external_agent) { - printf("Looks like you forgot to specify one or more of: --as-html, --mail-to, --snmp-target, --external-agent\n"); - crm_help('?', LSB_EXIT_GENERIC); - } + if (one_shot) { + as_console = FALSE; - crm_make_daemon(crm_system_name, TRUE, pid_file); + } else if (daemonize) { + as_console = FALSE; + cl_log_enable_stderr(FALSE); - } else if(as_console) { + if (!as_html_file && !snmp_target && !crm_mail_to && !external_agent) { + printf + ("Looks like you forgot to specify one or more of: --as-html, --mail-to, --snmp-target, --external-agent\n"); + crm_help('?', LSB_EXIT_GENERIC); + } + + crm_make_daemon(crm_system_name, TRUE, pid_file); + + } else if (as_console) { #if CURSES_ENABLED - initscr(); - cbreak(); - noecho(); - cl_log_enable_stderr(FALSE); + initscr(); + cbreak(); + noecho(); + cl_log_enable_stderr(FALSE); #else - one_shot = TRUE; - as_console = FALSE; - printf("Defaulting to one-shot mode\n"); - printf("You need to have curses available at compile time to enable console mode\n"); + one_shot = TRUE; + as_console = FALSE; + printf("Defaulting to one-shot mode\n"); + printf("You need to have curses available at compile time to enable console mode\n"); #endif } crm_info("Starting %s", crm_system_name); - if(xml_file != NULL) { - current_cib = filename2xml(xml_file); - mon_refresh_display(NULL); - return exit_code; + if (xml_file != NULL) { + current_cib = filename2xml(xml_file); + mon_refresh_display(NULL); + return exit_code; } - - if(current_cib == NULL) { - cib = cib_new(); - if(!one_shot) { - print_as("Attempting connection to the cluster..."); - } - - do { - exit_code = cib_connect(!one_shot); - - if(one_shot) { - break; - - } else if(exit_code != cib_ok) { - print_dot(); - sleep(reconnect_msec/1000); - } - - } while(exit_code == cib_connection); - - if(exit_code != cib_ok) { - print_as("\nConnection to cluster failed: %s\n", cib_error2string(exit_code)); - if(as_console) { sleep(2); } - clean_up(-exit_code); - } - } - - if(one_shot) { - return exit_code; + + if (current_cib == NULL) { + cib = cib_new(); + if (!one_shot) { + print_as("Attempting connection to the cluster..."); + } + + do { + exit_code = cib_connect(!one_shot); + + if (one_shot) { + break; + + } else if (exit_code != cib_ok) { + print_dot(); + sleep(reconnect_msec / 1000); + } + + } while (exit_code == cib_connection); + + if (exit_code != cib_ok) { + print_as("\nConnection to cluster failed: %s\n", cib_error2string(exit_code)); + if (as_console) { + sleep(2); + } + clean_up(-exit_code); + } + } + + if (one_shot) { + return exit_code; } mainloop = g_main_new(FALSE); mainloop_add_signal(SIGTERM, mon_shutdown); mainloop_add_signal(SIGINT, mon_shutdown); #if CURSES_ENABLED - if(as_console) { - ncurses_winch_handler = signal(SIGWINCH, mon_winresize); - if(ncurses_winch_handler == SIG_DFL || - ncurses_winch_handler == SIG_IGN || - ncurses_winch_handler == SIG_ERR) - ncurses_winch_handler = NULL; + if (as_console) { + ncurses_winch_handler = signal(SIGWINCH, mon_winresize); + if (ncurses_winch_handler == SIG_DFL || + ncurses_winch_handler == SIG_IGN || ncurses_winch_handler == SIG_ERR) + ncurses_winch_handler = NULL; } #endif refresh_trigger = mainloop_add_trigger(G_PRIORITY_LOW, mon_refresh_display, NULL); - + g_main_run(mainloop); g_main_destroy(mainloop); - - crm_info("Exiting %s", crm_system_name); + + crm_info("Exiting %s", crm_system_name); clean_up(0); - return 0; /* never reached */ + return 0; /* never reached */ } void -wait_for_refresh(int offset, const char *prefix, int msec) +wait_for_refresh(int offset, const char *prefix, int msec) { int lpc = msec / 1000; - struct timespec sleept = {1 , 0}; + struct timespec sleept = { 1, 0 }; - if(as_console == FALSE) { - timer_id = g_timeout_add(msec, mon_timer_popped, NULL); - return; + if (as_console == FALSE) { + timer_id = g_timeout_add(msec, mon_timer_popped, NULL); + return; } - - crm_notice("%sRefresh in %ds...", prefix?prefix:"", lpc); - while(lpc > 0) { + + crm_notice("%sRefresh in %ds...", prefix ? prefix : "", lpc); + while (lpc > 0) { #if CURSES_ENABLED - move(offset, 0); + move(offset, 0); /* printw("%sRefresh in \033[01;32m%ds\033[00m...", prefix?prefix:"", lpc); */ - printw("%sRefresh in %ds...\n", prefix?prefix:"", lpc); - clrtoeol(); - refresh(); + printw("%sRefresh in %ds...\n", prefix ? prefix : "", lpc); + clrtoeol(); + refresh(); #endif - lpc--; - if(lpc == 0) { - timer_id = g_timeout_add( - 1000, mon_timer_popped, NULL); - } else { - if (nanosleep(&sleept, NULL) != 0) { - return; - } - } + lpc--; + if (lpc == 0) { + timer_id = g_timeout_add(1000, mon_timer_popped, NULL); + } else { + if (nanosleep(&sleept, NULL) != 0) { + return; + } + } } } #define mon_warn(fmt...) do { \ if (!has_warnings) { \ print_as("Warning:"); \ } else { \ print_as(","); \ } \ print_as(fmt); \ has_warnings = TRUE; \ } while(0) -static int count_resources(pe_working_set_t *data_set, resource_t *rsc) +static int +count_resources(pe_working_set_t * data_set, resource_t * rsc) { int count = 0; GListPtr gIter = NULL; - - if(rsc == NULL) { - gIter = data_set->resources; - } else if(rsc->children) { - gIter = rsc->children; + + if (rsc == NULL) { + gIter = data_set->resources; + } else if (rsc->children) { + gIter = rsc->children; } else { - return is_not_set(rsc->flags, pe_rsc_orphan); + return is_not_set(rsc->flags, pe_rsc_orphan); } - for(; gIter != NULL; gIter = gIter->next) { - count += count_resources(data_set, gIter->data); + for (; gIter != NULL; gIter = gIter->next) { + count += count_resources(data_set, gIter->data); } return count; } static int -print_simple_status(pe_working_set_t *data_set) +print_simple_status(pe_working_set_t * data_set) { node_t *dc = NULL; GListPtr gIter = NULL; int nodes_online = 0; int nodes_standby = 0; dc = data_set->dc_node; - if(dc == NULL) { - mon_warn("No DC "); + if (dc == NULL) { + mon_warn("No DC "); } - for(gIter = data_set->nodes; gIter != NULL; gIter = gIter->next) { - node_t *node = (node_t*)gIter->data; - if(node->details->standby && node->details->online) { - nodes_standby++; - } else if(node->details->online) { - nodes_online++; - } else { - mon_warn("offline node: %s", node->details->uname); - } + for (gIter = data_set->nodes; gIter != NULL; gIter = gIter->next) { + node_t *node = (node_t *) gIter->data; + + if (node->details->standby && node->details->online) { + nodes_standby++; + } else if (node->details->online) { + nodes_online++; + } else { + mon_warn("offline node: %s", node->details->uname); + } } - + if (!has_warnings) { - print_as("Ok: %d nodes online", nodes_online); - if (nodes_standby > 0) { - print_as(", %d standby nodes", nodes_standby); - } - print_as(", %d resources configured", count_resources(data_set, NULL)); + print_as("Ok: %d nodes online", nodes_online); + if (nodes_standby > 0) { + print_as(", %d standby nodes", nodes_standby); + } + print_as(", %d resources configured", count_resources(data_set, NULL)); } - + print_as("\n"); return 0; } -extern int get_failcount(node_t *node, resource_t *rsc, int *last_failure, pe_working_set_t *data_set); +extern int get_failcount(node_t * node, resource_t * rsc, int *last_failure, + pe_working_set_t * data_set); -static void print_date(time_t time) +static void +print_date(time_t time) { int lpc = 0; char date_str[26]; + asctime_r(localtime(&time), date_str); - for(; lpc < 26; lpc++) { - if(date_str[lpc] == '\n') { - date_str[lpc] = 0; - } + for (; lpc < 26; lpc++) { + if (date_str[lpc] == '\n') { + date_str[lpc] = 0; + } } print_as("'%s'", date_str); } -static void print_rsc_summary(pe_working_set_t *data_set, node_t *node, resource_t *rsc, gboolean all) +static void +print_rsc_summary(pe_working_set_t * data_set, node_t * node, resource_t * rsc, gboolean all) { gboolean printed = FALSE; time_t last_failure = 0; char *fail_attr = crm_concat("fail-count", rsc->id, '-'); const char *value = g_hash_table_lookup(node->details->attrs, fail_attr); - int failcount = char2score(value); /* Get the true value, not the effective one from get_failcount() */ - get_failcount(node, rsc, (int*)&last_failure, data_set); + int failcount = char2score(value); /* Get the true value, not the effective one from get_failcount() */ + + get_failcount(node, rsc, (int *)&last_failure, data_set); crm_free(fail_attr); - if(all || failcount || last_failure > 0) { - printed = TRUE; - print_as(" %s: migration-threshold=%d", - rsc->id, rsc->migration_threshold); + if (all || failcount || last_failure > 0) { + printed = TRUE; + print_as(" %s: migration-threshold=%d", rsc->id, rsc->migration_threshold); } - - if(failcount > 0) { - printed = TRUE; - print_as(" fail-count=%d", failcount); + + if (failcount > 0) { + printed = TRUE; + print_as(" fail-count=%d", failcount); } - - if(last_failure > 0) { - printed = TRUE; - print_as(" last-failure="); - print_date(last_failure); + + if (last_failure > 0) { + printed = TRUE; + print_as(" last-failure="); + print_date(last_failure); } - if(printed) { - print_as("\n"); + if (printed) { + print_as("\n"); } } - -static void print_rsc_history(pe_working_set_t *data_set, node_t *node, xmlNode *rsc_entry) +static void +print_rsc_history(pe_working_set_t * data_set, node_t * node, xmlNode * rsc_entry) { GListPtr gIter = NULL; GListPtr op_list = NULL; gboolean print_name = TRUE; GListPtr sorted_op_list = NULL; const char *rsc_id = crm_element_value(rsc_entry, XML_ATTR_ID); resource_t *rsc = pe_find_resource(data_set->resources, rsc_id); xmlNode *rsc_op = NULL; - for(rsc_op = __xml_first_child(rsc_entry); rsc_op != NULL; rsc_op = __xml_next(rsc_op)) { - if(crm_str_eq((const char *)rsc_op->name, XML_LRM_TAG_RSC_OP, TRUE)) { - op_list = g_list_append(op_list, rsc_op); - } + + for (rsc_op = __xml_first_child(rsc_entry); rsc_op != NULL; rsc_op = __xml_next(rsc_op)) { + if (crm_str_eq((const char *)rsc_op->name, XML_LRM_TAG_RSC_OP, TRUE)) { + op_list = g_list_append(op_list, rsc_op); + } } - + sorted_op_list = g_list_sort(op_list, sort_op_by_callid); - for(gIter = sorted_op_list; gIter != NULL; gIter = gIter->next) { - xmlNode *xml_op = (xmlNode*)gIter->data; - const char *value = NULL; - const char *call = crm_element_value(xml_op, XML_LRM_ATTR_CALLID); - const char *task = crm_element_value(xml_op, XML_LRM_ATTR_TASK); - const char *op_rc = crm_element_value(xml_op, XML_LRM_ATTR_RC); - const char *interval = crm_element_value(xml_op, XML_LRM_ATTR_INTERVAL); - int rc = crm_parse_int(op_rc, "0"); - - if(safe_str_eq(task, CRMD_ACTION_STATUS) - && safe_str_eq(interval, "0")) { - task = "probe"; - } - - if(rc == 7 && safe_str_eq(task, "probe")) { - continue; - - } else if(safe_str_eq(task, CRMD_ACTION_NOTIFY)) { - continue; - } - - if(print_name) { - print_name = FALSE; - if(rsc == NULL) { - print_as("Orphan resource: %s", rsc_id); - } else { - print_rsc_summary(data_set, node, rsc, TRUE); - } - } - - print_as(" + (%s) %s:", call, task); - if(safe_str_neq(interval, "0")) { - print_as(" interval=%sms", interval); - } - - if(print_timing) { - int int_value; - const char *attr = "last-rc-change"; - value = crm_element_value(xml_op, attr); - if(value) { - int_value = crm_parse_int(value, NULL); - print_as(" %s=", attr); - print_date(int_value); - } - - attr = "last-run"; - value = crm_element_value(xml_op, attr); - if(value) { - int_value = crm_parse_int(value, NULL); - print_as(" %s=", attr); - print_date(int_value); - } - - attr = "exec-time"; - value = crm_element_value(xml_op, attr); - if(value) { - int_value = crm_parse_int(value, NULL); - print_as(" %s=%dms", attr, int_value); - } - - attr = "queue-time"; - value = crm_element_value(xml_op, attr); - if(value) { - int_value = crm_parse_int(value, NULL); - print_as(" %s=%dms", attr, int_value); - } - } - - print_as(" rc=%s (%s)\n", op_rc, execra_code2string(rc)); + for (gIter = sorted_op_list; gIter != NULL; gIter = gIter->next) { + xmlNode *xml_op = (xmlNode *) gIter->data; + const char *value = NULL; + const char *call = crm_element_value(xml_op, XML_LRM_ATTR_CALLID); + const char *task = crm_element_value(xml_op, XML_LRM_ATTR_TASK); + const char *op_rc = crm_element_value(xml_op, XML_LRM_ATTR_RC); + const char *interval = crm_element_value(xml_op, XML_LRM_ATTR_INTERVAL); + int rc = crm_parse_int(op_rc, "0"); + + if (safe_str_eq(task, CRMD_ACTION_STATUS) + && safe_str_eq(interval, "0")) { + task = "probe"; + } + + if (rc == 7 && safe_str_eq(task, "probe")) { + continue; + + } else if (safe_str_eq(task, CRMD_ACTION_NOTIFY)) { + continue; + } + + if (print_name) { + print_name = FALSE; + if (rsc == NULL) { + print_as("Orphan resource: %s", rsc_id); + } else { + print_rsc_summary(data_set, node, rsc, TRUE); + } + } + + print_as(" + (%s) %s:", call, task); + if (safe_str_neq(interval, "0")) { + print_as(" interval=%sms", interval); + } + + if (print_timing) { + int int_value; + const char *attr = "last-rc-change"; + + value = crm_element_value(xml_op, attr); + if (value) { + int_value = crm_parse_int(value, NULL); + print_as(" %s=", attr); + print_date(int_value); + } + + attr = "last-run"; + value = crm_element_value(xml_op, attr); + if (value) { + int_value = crm_parse_int(value, NULL); + print_as(" %s=", attr); + print_date(int_value); + } + + attr = "exec-time"; + value = crm_element_value(xml_op, attr); + if (value) { + int_value = crm_parse_int(value, NULL); + print_as(" %s=%dms", attr, int_value); + } + + attr = "queue-time"; + value = crm_element_value(xml_op, attr); + if (value) { + int_value = crm_parse_int(value, NULL); + print_as(" %s=%dms", attr, int_value); + } + } + + print_as(" rc=%s (%s)\n", op_rc, execra_code2string(rc)); } - + /* no need to free the contents */ g_list_free(sorted_op_list); } -static void print_attr_msg(node_t *node, GListPtr rsc_list, const char *attrname, const char *attrvalue) +static void +print_attr_msg(node_t * node, GListPtr rsc_list, const char *attrname, const char *attrvalue) { GListPtr gIter = NULL; - for(gIter = rsc_list; gIter != NULL; gIter = gIter->next) { - resource_t *rsc = (resource_t*)gIter->data; - const char *type = g_hash_table_lookup(rsc->meta, "type"); - if(rsc->children != NULL) { - print_attr_msg(node, rsc->children, attrname, attrvalue); - } - - if(safe_str_eq(type, "ping") || safe_str_eq(type, "pingd")) { - const char *name = "pingd"; - const char *multiplier = NULL; - char **host_list = NULL; - int host_list_num = 0; - int expected_score = 0; - - if(g_hash_table_lookup(rsc->meta, "name") != NULL) { - name = g_hash_table_lookup(rsc->meta, "name"); - } - - /* To identify the resource with the attribute name. */ - if(safe_str_eq(name, attrname)) { - int value = crm_parse_int(attrvalue, "0"); - multiplier = g_hash_table_lookup(rsc->meta, "multiplier"); - host_list = g_strsplit(g_hash_table_lookup(rsc->meta, "host_list"), " ", 0); - host_list_num = g_strv_length(host_list); - g_strfreev(host_list); - /* pingd multiplier is the same as the default value. */ - expected_score = host_list_num * crm_parse_int(multiplier, "1"); - - /* pingd is abnormal score. */ - if(value <= 0) { - print_as("\t: Connectivity is lost"); - } else if(value < expected_score) { - print_as("\t: Connectivity is degraded (Expected=%d)", expected_score); - } - } - } + + for (gIter = rsc_list; gIter != NULL; gIter = gIter->next) { + resource_t *rsc = (resource_t *) gIter->data; + const char *type = g_hash_table_lookup(rsc->meta, "type"); + + if (rsc->children != NULL) { + print_attr_msg(node, rsc->children, attrname, attrvalue); + } + + if (safe_str_eq(type, "ping") || safe_str_eq(type, "pingd")) { + const char *name = "pingd"; + const char *multiplier = NULL; + char **host_list = NULL; + int host_list_num = 0; + int expected_score = 0; + + if (g_hash_table_lookup(rsc->meta, "name") != NULL) { + name = g_hash_table_lookup(rsc->meta, "name"); + } + + /* To identify the resource with the attribute name. */ + if (safe_str_eq(name, attrname)) { + int value = crm_parse_int(attrvalue, "0"); + + multiplier = g_hash_table_lookup(rsc->meta, "multiplier"); + host_list = g_strsplit(g_hash_table_lookup(rsc->meta, "host_list"), " ", 0); + host_list_num = g_strv_length(host_list); + g_strfreev(host_list); + /* pingd multiplier is the same as the default value. */ + expected_score = host_list_num * crm_parse_int(multiplier, "1"); + + /* pingd is abnormal score. */ + if (value <= 0) { + print_as("\t: Connectivity is lost"); + } else if (value < expected_score) { + print_as("\t: Connectivity is degraded (Expected=%d)", expected_score); + } + } + } } } static int compare_attribute(gconstpointer a, gconstpointer b) { int rc; - rc = strcmp((const char*)a, (const char*)b); + rc = strcmp((const char *)a, (const char *)b); return rc; } static void create_attr_list(gpointer name, gpointer value, gpointer data) { int i; const char *filt_str[] = FILTER_STR; - + CRM_CHECK(name != NULL, return); /* filtering automatic attributes */ - for(i = 0; filt_str[i] != NULL; i++) { - if(g_str_has_prefix(name, filt_str[i])) { - return; - } + for (i = 0; filt_str[i] != NULL; i++) { + if (g_str_has_prefix(name, filt_str[i])) { + return; + } } attr_list = g_list_insert_sorted(attr_list, name, compare_attribute); } static void print_node_attribute(gpointer name, gpointer node_data) { const char *value = NULL; - node_t *node = (node_t *)node_data; + node_t *node = (node_t *) node_data; value = g_hash_table_lookup(node->details->attrs, name); print_as(" + %-32s\t: %-10s", (char *)name, value); print_attr_msg(node, node->details->running_rsc, name, value); print_as("\n"); } -static void print_node_summary(pe_working_set_t *data_set, gboolean operations) +static void +print_node_summary(pe_working_set_t * data_set, gboolean operations) { xmlNode *lrm_rsc = NULL; xmlNode *rsc_entry = NULL; xmlNode *node_state = NULL; xmlNode *cib_status = get_object_root(XML_CIB_TAG_STATUS, data_set->input); - if(operations) { - print_as("\nOperations:\n"); + if (operations) { + print_as("\nOperations:\n"); } else { - print_as("\nMigration summary:\n"); + print_as("\nMigration summary:\n"); } - - for(node_state = __xml_first_child(cib_status); node_state != NULL; node_state = __xml_next(node_state)) { - if(crm_str_eq((const char *)node_state->name, XML_CIB_TAG_STATE, TRUE)) { - node_t *node = pe_find_node_id(data_set->nodes, ID(node_state)); - if(node == NULL || node->details->online == FALSE){ - continue; - } - - print_as("* Node %s: ", crm_element_value(node_state, XML_ATTR_UNAME)); - print_as("\n"); - - lrm_rsc = find_xml_node(node_state, XML_CIB_TAG_LRM, FALSE); - lrm_rsc = find_xml_node(lrm_rsc, XML_LRM_TAG_RESOURCES, FALSE); - - for(rsc_entry = __xml_first_child(lrm_rsc); rsc_entry != NULL; rsc_entry = __xml_next(rsc_entry)) { - if(crm_str_eq((const char *)rsc_entry->name, XML_LRM_TAG_RESOURCE, TRUE)) { - if(operations) { - print_rsc_history(data_set, node, rsc_entry); - - } else { - const char *rsc_id = crm_element_value(rsc_entry, XML_ATTR_ID); - resource_t *rsc = pe_find_resource(data_set->resources, rsc_id); - if(rsc) { - print_rsc_summary(data_set, node, rsc, FALSE); - } else { - print_as(" %s: orphan\n", rsc_id); - } - } - } - } - } + + for (node_state = __xml_first_child(cib_status); node_state != NULL; + node_state = __xml_next(node_state)) { + if (crm_str_eq((const char *)node_state->name, XML_CIB_TAG_STATE, TRUE)) { + node_t *node = pe_find_node_id(data_set->nodes, ID(node_state)); + + if (node == NULL || node->details->online == FALSE) { + continue; + } + + print_as("* Node %s: ", crm_element_value(node_state, XML_ATTR_UNAME)); + print_as("\n"); + + lrm_rsc = find_xml_node(node_state, XML_CIB_TAG_LRM, FALSE); + lrm_rsc = find_xml_node(lrm_rsc, XML_LRM_TAG_RESOURCES, FALSE); + + for (rsc_entry = __xml_first_child(lrm_rsc); rsc_entry != NULL; + rsc_entry = __xml_next(rsc_entry)) { + if (crm_str_eq((const char *)rsc_entry->name, XML_LRM_TAG_RESOURCE, TRUE)) { + if (operations) { + print_rsc_history(data_set, node, rsc_entry); + + } else { + const char *rsc_id = crm_element_value(rsc_entry, XML_ATTR_ID); + resource_t *rsc = pe_find_resource(data_set->resources, rsc_id); + + if (rsc) { + print_rsc_summary(data_set, node, rsc, FALSE); + } else { + print_as(" %s: orphan\n", rsc_id); + } + } + } + } + } } } static char * -add_list_element(char *list, const char *value) +add_list_element(char *list, const char *value) { int len = 0; int last = 0; - if(value == NULL) { - return list; + if (value == NULL) { + return list; } - if(list) { - last = strlen(list); + if (list) { + last = strlen(list); } - len = last + 2; /* +1 space, +1 EOS */ + len = last + 2; /* +1 space, +1 EOS */ len += strlen(value); crm_realloc(list, len); sprintf(list + last, " %s", value); return list; } static int -print_status(pe_working_set_t *data_set) +print_status(pe_working_set_t * data_set) { static int updates = 0; GListPtr gIter = NULL; node_t *dc = NULL; char *since_epoch = NULL; char *online_nodes = NULL; char *offline_nodes = NULL; xmlNode *dc_version = NULL; xmlNode *quorum_node = NULL; xmlNode *stack = NULL; time_t a_time = time(NULL); int print_opts = pe_print_ncurses; const char *quorum_votes = "unknown"; - if(as_console) { - blank_screen(); + if (as_console) { + blank_screen(); } else { - print_opts = pe_print_printf; + print_opts = pe_print_printf; } updates++; dc = data_set->dc_node; print_as("============\n"); - if(a_time == (time_t)-1) { - crm_perror(LOG_ERR,"set_node_tstamp(): Invalid time returned"); - return 1; + if (a_time == (time_t) - 1) { + crm_perror(LOG_ERR, "set_node_tstamp(): Invalid time returned"); + return 1; } - + since_epoch = ctime(&a_time); - if(since_epoch != NULL && print_last_updated) { - print_as("Last updated: %s", since_epoch); - } - - if(print_last_change) { - const char *last_written = crm_element_value(data_set->input, XML_CIB_ATTR_WRITTEN); - const char *user = crm_element_value(data_set->input, XML_ATTR_UPDATE_USER); - const char *client = crm_element_value(data_set->input, XML_ATTR_UPDATE_CLIENT); - const char *origin = crm_element_value(data_set->input, XML_ATTR_UPDATE_ORIG); - - print_as("Last change: %s", last_written?last_written:""); - if(user) { - print_as(" by %s", user); - } - if(client) { - print_as(" via %s", client); - } - if(origin) { - print_as(" on %s", origin); - } - print_as("\n"); - } - - stack = get_xpath_object("//nvpair[@name='cluster-infrastructure']", data_set->input, LOG_DEBUG); - if(stack) { - print_as("Stack: %s\n", crm_element_value(stack, XML_NVPAIR_ATTR_VALUE)); - } - - dc_version = get_xpath_object("//nvpair[@name='dc-version']", data_set->input, LOG_DEBUG); - if(dc == NULL) { - print_as("Current DC: NONE\n"); + if (since_epoch != NULL && print_last_updated) { + print_as("Last updated: %s", since_epoch); + } + + if (print_last_change) { + const char *last_written = crm_element_value(data_set->input, XML_CIB_ATTR_WRITTEN); + const char *user = crm_element_value(data_set->input, XML_ATTR_UPDATE_USER); + const char *client = crm_element_value(data_set->input, XML_ATTR_UPDATE_CLIENT); + const char *origin = crm_element_value(data_set->input, XML_ATTR_UPDATE_ORIG); + + print_as("Last change: %s", last_written ? last_written : ""); + if (user) { + print_as(" by %s", user); + } + if (client) { + print_as(" via %s", client); + } + if (origin) { + print_as(" on %s", origin); + } + print_as("\n"); + } + + stack = + get_xpath_object("//nvpair[@name='cluster-infrastructure']", data_set->input, LOG_DEBUG); + if (stack) { + print_as("Stack: %s\n", crm_element_value(stack, XML_NVPAIR_ATTR_VALUE)); + } + + dc_version = get_xpath_object("//nvpair[@name='dc-version']", data_set->input, LOG_DEBUG); + if (dc == NULL) { + print_as("Current DC: NONE\n"); } else { - const char *quorum = crm_element_value(data_set->input, XML_ATTR_HAVE_QUORUM); - if(safe_str_neq(dc->details->uname, dc->details->id)) { - print_as("Current DC: %s (%s)", - dc->details->uname, dc->details->id); - } else { - print_as("Current DC: %s", dc->details->uname); - } - print_as(" - partition %s quorum\n", - crm_is_true(quorum)?"with":"WITHOUT"); - if(dc_version) { - print_as("Version: %s\n", crm_element_value(dc_version, XML_NVPAIR_ATTR_VALUE)); - } - } - - quorum_node = get_xpath_object("//nvpair[@name='"XML_ATTR_EXPECTED_VOTES"']", data_set->input, LOG_DEBUG); - if(quorum_node) { - quorum_votes = crm_element_value(quorum_node, XML_NVPAIR_ATTR_VALUE); - } - - print_as("%d Nodes configured, %s expected votes\n", g_list_length(data_set->nodes), quorum_votes); + const char *quorum = crm_element_value(data_set->input, XML_ATTR_HAVE_QUORUM); + + if (safe_str_neq(dc->details->uname, dc->details->id)) { + print_as("Current DC: %s (%s)", dc->details->uname, dc->details->id); + } else { + print_as("Current DC: %s", dc->details->uname); + } + print_as(" - partition %s quorum\n", crm_is_true(quorum) ? "with" : "WITHOUT"); + if (dc_version) { + print_as("Version: %s\n", crm_element_value(dc_version, XML_NVPAIR_ATTR_VALUE)); + } + } + + quorum_node = + get_xpath_object("//nvpair[@name='" XML_ATTR_EXPECTED_VOTES "']", data_set->input, + LOG_DEBUG); + if (quorum_node) { + quorum_votes = crm_element_value(quorum_node, XML_NVPAIR_ATTR_VALUE); + } + + print_as("%d Nodes configured, %s expected votes\n", g_list_length(data_set->nodes), + quorum_votes); print_as("%d Resources configured.\n", count_resources(data_set, NULL)); print_as("============\n\n"); - for(gIter = data_set->nodes; gIter != NULL; gIter = gIter->next) { - node_t *node = (node_t*)gIter->data; - const char *node_mode = NULL; - - if(node->details->unclean) { - if(node->details->online && node->details->unclean) { - node_mode = "UNCLEAN (online)"; - - } else if(node->details->pending) { - node_mode = "UNCLEAN (pending)"; - - } else { - node_mode = "UNCLEAN (offline)"; - } - - } else if(node->details->pending) { - node_mode = "pending"; - - } else if(node->details->standby_onfail && node->details->online) { - node_mode = "standby (on-fail)"; - - } else if(node->details->standby) { - if(node->details->online) { - node_mode = "standby"; - } else { - node_mode = "OFFLINE (standby)"; - } - - } else if(node->details->online) { - node_mode = "online"; - if(group_by_node == FALSE) { - online_nodes = add_list_element(online_nodes, node->details->uname); - continue; - } - - } else { - node_mode = "OFFLINE"; - if(group_by_node == FALSE) { - offline_nodes = add_list_element(offline_nodes, node->details->uname); - continue; - } - } - - if(safe_str_eq(node->details->uname, node->details->id)) { - print_as("Node %s: %s\n", - node->details->uname, node_mode); - } else { - print_as("Node %s (%s): %s\n", - node->details->uname, node->details->id, - node_mode); - } - - if(group_by_node) { - GListPtr gIter2 = NULL; - for(gIter2 = node->details->running_rsc; gIter2 != NULL; gIter2 = gIter2->next) { - resource_t *rsc = (resource_t*)gIter2->data; - rsc->fns->print(rsc, "\t", print_opts|pe_print_rsconly, stdout); - } - } - } - - if(online_nodes) { - print_as("Online: [%s ]\n", online_nodes); - crm_free(online_nodes); - } - if(offline_nodes) { - print_as("OFFLINE: [%s ]\n", offline_nodes); - crm_free(offline_nodes); + for (gIter = data_set->nodes; gIter != NULL; gIter = gIter->next) { + node_t *node = (node_t *) gIter->data; + const char *node_mode = NULL; + + if (node->details->unclean) { + if (node->details->online && node->details->unclean) { + node_mode = "UNCLEAN (online)"; + + } else if (node->details->pending) { + node_mode = "UNCLEAN (pending)"; + + } else { + node_mode = "UNCLEAN (offline)"; + } + + } else if (node->details->pending) { + node_mode = "pending"; + + } else if (node->details->standby_onfail && node->details->online) { + node_mode = "standby (on-fail)"; + + } else if (node->details->standby) { + if (node->details->online) { + node_mode = "standby"; + } else { + node_mode = "OFFLINE (standby)"; + } + + } else if (node->details->online) { + node_mode = "online"; + if (group_by_node == FALSE) { + online_nodes = add_list_element(online_nodes, node->details->uname); + continue; + } + + } else { + node_mode = "OFFLINE"; + if (group_by_node == FALSE) { + offline_nodes = add_list_element(offline_nodes, node->details->uname); + continue; + } + } + + if (safe_str_eq(node->details->uname, node->details->id)) { + print_as("Node %s: %s\n", node->details->uname, node_mode); + } else { + print_as("Node %s (%s): %s\n", node->details->uname, node->details->id, node_mode); + } + + if (group_by_node) { + GListPtr gIter2 = NULL; + + for (gIter2 = node->details->running_rsc; gIter2 != NULL; gIter2 = gIter2->next) { + resource_t *rsc = (resource_t *) gIter2->data; + + rsc->fns->print(rsc, "\t", print_opts | pe_print_rsconly, stdout); + } + } + } + + if (online_nodes) { + print_as("Online: [%s ]\n", online_nodes); + crm_free(online_nodes); + } + if (offline_nodes) { + print_as("OFFLINE: [%s ]\n", offline_nodes); + crm_free(offline_nodes); + } + + if (group_by_node == FALSE && inactive_resources) { + print_as("\nFull list of resources:\n"); + + } else if (inactive_resources) { + print_as("\nInactive resources:\n"); + } + + if (group_by_node == FALSE || inactive_resources) { + print_as("\n"); + for (gIter = data_set->resources; gIter != NULL; gIter = gIter->next) { + resource_t *rsc = (resource_t *) gIter->data; + + gboolean is_active = rsc->fns->active(rsc, TRUE); + gboolean partially_active = rsc->fns->active(rsc, FALSE); + + if (is_set(rsc->flags, pe_rsc_orphan) && is_active == FALSE) { + continue; + + } else if (group_by_node == FALSE) { + if (partially_active || inactive_resources) { + rsc->fns->print(rsc, NULL, print_opts, stdout); + } + + } else if (is_active == FALSE && inactive_resources) { + rsc->fns->print(rsc, NULL, print_opts, stdout); + } + } + } + + if (print_nodes_attr) { + print_as("\nNode Attributes:\n"); + for (gIter = data_set->nodes; gIter != NULL; gIter = gIter->next) { + node_t *node = (node_t *) gIter->data; + + if (node == NULL || node->details->online == FALSE) { + continue; + } + attr_list = NULL; + print_as("* Node %s:\n", node->details->uname); + g_hash_table_foreach(node->details->attrs, create_attr_list, NULL); + g_list_foreach(attr_list, print_node_attribute, node); + } + } + + if (print_operations || print_failcount) { + print_node_summary(data_set, print_operations); + } + + if (xml_has_children(data_set->failed)) { + xmlNode *xml_op = NULL; + + print_as("\nFailed actions:\n"); + for (xml_op = __xml_first_child(data_set->failed); xml_op != NULL; + xml_op = __xml_next(xml_op)) { + int val = 0; + const char *id = ID(xml_op); + const char *op_key = crm_element_value(xml_op, XML_LRM_ATTR_TASK_KEY); + const char *last = crm_element_value(xml_op, "last_run"); + const char *node = crm_element_value(xml_op, XML_ATTR_UNAME); + const char *call = crm_element_value(xml_op, XML_LRM_ATTR_CALLID); + const char *rc = crm_element_value(xml_op, XML_LRM_ATTR_RC); + const char *status = crm_element_value(xml_op, XML_LRM_ATTR_OPSTATUS); + + val = crm_parse_int(status, "0"); + print_as(" %s (node=%s, call=%s, rc=%s, status=%s", + op_key ? op_key : id, node, call, rc, op_status2text(val)); + + if (last) { + time_t run_at = crm_parse_int(last, "0"); + + print_as(", last-run=%s, queued=%sms, exec=%sms\n", + ctime(&run_at), + crm_element_value(xml_op, "exec_time"), + crm_element_value(xml_op, "queue_time")); + } + + val = crm_parse_int(rc, "0"); + print_as("): %s\n", execra_code2string(val)); + } } - - if(group_by_node == FALSE && inactive_resources) { - print_as("\nFull list of resources:\n"); - - } else if(inactive_resources) { - print_as("\nInactive resources:\n"); - } - - if(group_by_node == FALSE || inactive_resources) { - print_as("\n"); - for(gIter = data_set->resources; gIter != NULL; gIter = gIter->next) { - resource_t *rsc = (resource_t*)gIter->data; - - gboolean is_active = rsc->fns->active(rsc, TRUE); - gboolean partially_active = rsc->fns->active(rsc, FALSE); - if(is_set(rsc->flags, pe_rsc_orphan) && is_active == FALSE) { - continue; - - } else if(group_by_node == FALSE) { - if(partially_active || inactive_resources) { - rsc->fns->print(rsc, NULL, print_opts, stdout); - } - - } else if(is_active == FALSE && inactive_resources) { - rsc->fns->print(rsc, NULL, print_opts, stdout); - } - } - } - - if(print_nodes_attr) { - print_as("\nNode Attributes:\n"); - for(gIter = data_set->nodes; gIter != NULL; gIter = gIter->next) { - node_t *node = (node_t*)gIter->data; - - if(node == NULL || node->details->online == FALSE){ - continue; - } - attr_list = NULL; - print_as("* Node %s:\n", node->details->uname); - g_hash_table_foreach(node->details->attrs, create_attr_list, NULL); - g_list_foreach(attr_list, print_node_attribute, node); - } - } - - if(print_operations || print_failcount) { - print_node_summary(data_set, print_operations); - } - - if(xml_has_children(data_set->failed)) { - xmlNode *xml_op = NULL; - print_as("\nFailed actions:\n"); - for(xml_op = __xml_first_child(data_set->failed); xml_op != NULL; xml_op = __xml_next(xml_op)) { - int val = 0; - const char *id = ID(xml_op); - const char *op_key = crm_element_value(xml_op, XML_LRM_ATTR_TASK_KEY); - const char *last = crm_element_value(xml_op, "last_run"); - const char *node = crm_element_value(xml_op, XML_ATTR_UNAME); - const char *call = crm_element_value(xml_op, XML_LRM_ATTR_CALLID); - const char *rc = crm_element_value(xml_op, XML_LRM_ATTR_RC); - const char *status = crm_element_value(xml_op, XML_LRM_ATTR_OPSTATUS); - - val = crm_parse_int(status, "0"); - print_as(" %s (node=%s, call=%s, rc=%s, status=%s", - op_key?op_key:id, node, call, rc, op_status2text(val)); - - if(last) { - time_t run_at = crm_parse_int(last, "0"); - print_as(", last-run=%s, queued=%sms, exec=%sms\n", - ctime(&run_at), - crm_element_value(xml_op, "exec_time"), - crm_element_value(xml_op, "queue_time")); - } - - val = crm_parse_int(rc, "0"); - print_as("): %s\n", execra_code2string(val)); - } - } - #if CURSES_ENABLED - if(as_console) { - refresh(); + if (as_console) { + refresh(); } #endif return 0; } static int -print_html_status(pe_working_set_t *data_set, const char *filename, gboolean web_cgi) +print_html_status(pe_working_set_t * data_set, const char *filename, gboolean web_cgi) { FILE *stream; GListPtr gIter = NULL; node_t *dc = NULL; static int updates = 0; char *filename_tmp = NULL; if (web_cgi) { - stream=stdout; - fprintf(stream, "Content-type: text/html\n\n"); + stream = stdout; + fprintf(stream, "Content-type: text/html\n\n"); } else { - filename_tmp = crm_concat(filename, "tmp", '.'); - stream = fopen(filename_tmp, "w"); - if(stream == NULL) { - crm_perror(LOG_ERR,"Cannot open %s for writing", filename_tmp); - crm_free(filename_tmp); - return -1; - } + filename_tmp = crm_concat(filename, "tmp", '.'); + stream = fopen(filename_tmp, "w"); + if (stream == NULL) { + crm_perror(LOG_ERR, "Cannot open %s for writing", filename_tmp); + crm_free(filename_tmp); + return -1; + } } updates++; dc = data_set->dc_node; fprintf(stream, ""); fprintf(stream, ""); fprintf(stream, "Cluster status"); /* content="%d;url=http://webdesign.about.com" */ - fprintf(stream, - "", reconnect_msec/1000); + fprintf(stream, "", reconnect_msec / 1000); fprintf(stream, ""); /*** SUMMARY ***/ fprintf(stream, "

Cluster summary

"); { - char *now_str = NULL; - time_t now = time(NULL); - now_str = ctime(&now); - now_str[24] = EOS; /* replace the newline */ - fprintf(stream, "Last updated: %s
\n", now_str); - } - - if(dc == NULL) { - fprintf(stream, "Current DC: NONE
"); + char *now_str = NULL; + time_t now = time(NULL); + + now_str = ctime(&now); + now_str[24] = EOS; /* replace the newline */ + fprintf(stream, "Last updated: %s
\n", now_str); + } + + if (dc == NULL) { + fprintf(stream, "Current DC: NONE
"); } else { - fprintf(stream, "Current DC: %s (%s)
", - dc->details->uname, dc->details->id); + fprintf(stream, "Current DC: %s (%s)
", dc->details->uname, dc->details->id); } fprintf(stream, "%d Nodes configured.
", g_list_length(data_set->nodes)); fprintf(stream, "%d Resources configured.
", count_resources(data_set, NULL)); /*** CONFIG ***/ - + fprintf(stream, "

Config Options

\n"); fprintf(stream, "\n"); fprintf(stream, "\n", - is_set(data_set->flags, pe_flag_stonith_enabled)?"enabled":"disabled"); + is_set(data_set->flags, pe_flag_stonith_enabled) ? "enabled" : "disabled"); fprintf(stream, "\n", - is_set(data_set->flags, pe_flag_symmetric_cluster)?"":"a-"); - + is_set(data_set->flags, pe_flag_symmetric_cluster) ? "" : "a-"); + fprintf(stream, "\n
STONITH of failed nodes:%s
Cluster is:%ssymmetric
No Quorum Policy:"); switch (data_set->no_quorum_policy) { - case no_quorum_freeze: - fprintf(stream, "Freeze resources"); - break; - case no_quorum_stop: - fprintf(stream, "Stop ALL resources"); - break; - case no_quorum_ignore: - fprintf(stream, "Ignore"); - break; - case no_quorum_suicide: - fprintf(stream, "Suicide"); - break; + case no_quorum_freeze: + fprintf(stream, "Freeze resources"); + break; + case no_quorum_stop: + fprintf(stream, "Stop ALL resources"); + break; + case no_quorum_ignore: + fprintf(stream, "Ignore"); + break; + case no_quorum_suicide: + fprintf(stream, "Suicide"); + break; } fprintf(stream, "\n
\n"); /*** NODE LIST ***/ - + fprintf(stream, "

Node List

\n"); fprintf(stream, "
    \n"); - for(gIter = data_set->nodes; gIter != NULL; gIter = gIter->next) { - node_t *node = (node_t*)gIter->data; - - fprintf(stream, "
  • "); - if(node->details->standby_onfail && node->details->online) { - fprintf(stream, "Node: %s (%s): %s",node->details->uname, node->details->id,"standby (on-fail)\n"); - } else if(node->details->standby && node->details->online) { - fprintf(stream, "Node: %s (%s): %s",node->details->uname, node->details->id,"standby\n"); - } else if(node->details->standby) { - fprintf(stream, "Node: %s (%s): %s",node->details->uname, node->details->id,"OFFLINE (standby)\n"); - } else if(node->details->online) { - fprintf(stream, "Node: %s (%s): %s",node->details->uname, node->details->id,"online\n"); - } else { - fprintf(stream, "Node: %s (%s): %s",node->details->uname, node->details->id,"OFFLINE\n"); - } - if(group_by_node) { - GListPtr lpc2 = NULL; - fprintf(stream, "
      \n"); - for(lpc2 = node->details->running_rsc; lpc2 != NULL; lpc2 = lpc2->next) { - resource_t *rsc = (resource_t*)lpc2->data; - - fprintf(stream, "
    • "); - rsc->fns->print(rsc, NULL, pe_print_html|pe_print_rsconly, stream); - fprintf(stream, "
    • \n"); - } - fprintf(stream, "
    \n"); - } - fprintf(stream, "
  • \n"); + for (gIter = data_set->nodes; gIter != NULL; gIter = gIter->next) { + node_t *node = (node_t *) gIter->data; + + fprintf(stream, "
  • "); + if (node->details->standby_onfail && node->details->online) { + fprintf(stream, "Node: %s (%s): %s", node->details->uname, node->details->id, + "standby (on-fail)\n"); + } else if (node->details->standby && node->details->online) { + fprintf(stream, "Node: %s (%s): %s", node->details->uname, node->details->id, + "standby\n"); + } else if (node->details->standby) { + fprintf(stream, "Node: %s (%s): %s", node->details->uname, node->details->id, + "OFFLINE (standby)\n"); + } else if (node->details->online) { + fprintf(stream, "Node: %s (%s): %s", node->details->uname, node->details->id, + "online\n"); + } else { + fprintf(stream, "Node: %s (%s): %s", node->details->uname, node->details->id, + "OFFLINE\n"); + } + if (group_by_node) { + GListPtr lpc2 = NULL; + + fprintf(stream, "
      \n"); + for (lpc2 = node->details->running_rsc; lpc2 != NULL; lpc2 = lpc2->next) { + resource_t *rsc = (resource_t *) lpc2->data; + + fprintf(stream, "
    • "); + rsc->fns->print(rsc, NULL, pe_print_html | pe_print_rsconly, stream); + fprintf(stream, "
    • \n"); + } + fprintf(stream, "
    \n"); + } + fprintf(stream, "
  • \n"); } fprintf(stream, "
\n"); - - if(group_by_node && inactive_resources) { - fprintf(stream, "

Inactive Resources

\n"); - - } else if(group_by_node == FALSE) { - fprintf(stream, "

Resource List

\n"); - } - - if(group_by_node == FALSE || inactive_resources) { - for(gIter = data_set->resources; gIter != NULL; gIter = gIter->next) { - resource_t *rsc = (resource_t*)gIter->data; - gboolean is_active = rsc->fns->active(rsc, TRUE); - gboolean partially_active = rsc->fns->active(rsc, FALSE); - if(is_set(rsc->flags, pe_rsc_orphan) && is_active == FALSE) { - continue; - - } else if(group_by_node == FALSE) { - if(partially_active || inactive_resources) { - rsc->fns->print(rsc, NULL, pe_print_html, stream); - } - - } else if(is_active == FALSE && inactive_resources) { - rsc->fns->print(rsc, NULL, pe_print_html, stream); - } - } + + if (group_by_node && inactive_resources) { + fprintf(stream, "

Inactive Resources

\n"); + + } else if (group_by_node == FALSE) { + fprintf(stream, "

Resource List

\n"); + } + + if (group_by_node == FALSE || inactive_resources) { + for (gIter = data_set->resources; gIter != NULL; gIter = gIter->next) { + resource_t *rsc = (resource_t *) gIter->data; + gboolean is_active = rsc->fns->active(rsc, TRUE); + gboolean partially_active = rsc->fns->active(rsc, FALSE); + + if (is_set(rsc->flags, pe_rsc_orphan) && is_active == FALSE) { + continue; + + } else if (group_by_node == FALSE) { + if (partially_active || inactive_resources) { + rsc->fns->print(rsc, NULL, pe_print_html, stream); + } + + } else if (is_active == FALSE && inactive_resources) { + rsc->fns->print(rsc, NULL, pe_print_html, stream); + } + } } fprintf(stream, ""); fflush(stream); fclose(stream); if (!web_cgi) { - if(rename(filename_tmp, filename) != 0) { - crm_perror(LOG_ERR,"Unable to rename %s->%s", filename_tmp, filename); - } - crm_free(filename_tmp); + if (rename(filename_tmp, filename) != 0) { + crm_perror(LOG_ERR, "Unable to rename %s->%s", filename_tmp, filename); + } + crm_free(filename_tmp); } return 0; } #if ENABLE_SNMP -#include -#include -#include -#include -#include -#include - -#define add_snmp_field(list, oid_string, value) do { \ +# include +# include +# include +# include +# include +# include + +# define add_snmp_field(list, oid_string, value) do { \ oid name[MAX_OID_LEN]; \ size_t name_length = MAX_OID_LEN; \ if (snmp_parse_oid(oid_string, name, &name_length)) { \ int s_rc = snmp_add_var(list, name, name_length, 's', (value)); \ if(s_rc != 0) { \ crm_err("Could not add %s=%s rc=%d", oid_string, value, s_rc); \ } else { \ crm_debug_2("Added %s=%s", oid_string, value); \ } \ } else { \ crm_err("Could not parse OID: %s", oid_string); \ } \ } while(0) \ -#define add_snmp_field_int(list, oid_string, value) do { \ +# define add_snmp_field_int(list, oid_string, value) do { \ oid name[MAX_OID_LEN]; \ size_t name_length = MAX_OID_LEN; \ if (snmp_parse_oid(oid_string, name, &name_length)) { \ if(NULL == snmp_pdu_add_variable( \ list, name, name_length, ASN_INTEGER, \ (u_char *) & value, sizeof(value))) { \ crm_err("Could not add %s=%d", oid_string, value); \ } else { \ crm_debug_2("Added %s=%d", oid_string, value); \ } \ } else { \ crm_err("Could not parse OID: %s", oid_string); \ } \ } while(0) \ - -static int snmp_input(int operation, netsnmp_session *session, - int reqid, netsnmp_pdu *pdu, void *magic) + +static int +snmp_input(int operation, netsnmp_session * session, int reqid, netsnmp_pdu * pdu, void *magic) { return 1; } -static netsnmp_session *crm_snmp_init(const char *target, char *community) +static netsnmp_session * +crm_snmp_init(const char *target, char *community) { static netsnmp_session *session = NULL; -#ifdef NETSNMPV53 + +# ifdef NETSNMPV53 char target53[128]; + snprintf(target53, sizeof(target53), "%s:162", target); -#endif +# endif - if(session) { - return session; + if (session) { + return session; } - if(target == NULL) { - return NULL; + if (target == NULL) { + return NULL; } - - if(crm_log_level > LOG_INFO) { - char *debug_tokens = crm_strdup("run:shell,snmptrap,tdomain"); - debug_register_tokens(debug_tokens); - snmp_set_do_debugging(1); + + if (crm_log_level > LOG_INFO) { + char *debug_tokens = crm_strdup("run:shell,snmptrap,tdomain"); + + debug_register_tokens(debug_tokens); + snmp_set_do_debugging(1); } crm_malloc0(session, sizeof(netsnmp_session)); snmp_sess_init(session); session->version = SNMP_VERSION_2c; session->callback = snmp_input; session->callback_magic = NULL; - if(community) { - session->community_len = strlen(community); - session->community = (unsigned char*)community; + if (community) { + session->community_len = strlen(community); + session->community = (unsigned char *)community; } session = snmp_add(session, -#ifdef NETSNMPV53 - netsnmp_tdomain_transport(target53, 0, "udp"), -#else - netsnmp_transport_open_client("snmptrap", target), -#endif - NULL, NULL); +# ifdef NETSNMPV53 + netsnmp_tdomain_transport(target53, 0, "udp"), +# else + netsnmp_transport_open_client("snmptrap", target), +# endif + NULL, NULL); if (session == NULL) { snmp_sess_perror("Could not create snmp transport", session); } return session; } - #endif static int -send_snmp_trap(const char *node, const char *rsc, const char *task, int target_rc, int rc, int status, const char *desc) +send_snmp_trap(const char *node, const char *rsc, const char *task, int target_rc, int rc, + int status, const char *desc) { int ret = 1; + #if ENABLE_SNMP - static oid snmptrap_oid[] = { 1,3,6,1,6,3,1,1,4,1,0 }; - static oid sysuptime_oid[] = { 1,3,6,1,2,1,1,3,0 }; + static oid snmptrap_oid[] = { 1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0 }; + static oid sysuptime_oid[] = { 1, 3, 6, 1, 2, 1, 1, 3, 0 }; netsnmp_pdu *trap_pdu; netsnmp_session *session = crm_snmp_init(snmp_target, snmp_community); trap_pdu = snmp_pdu_create(SNMP_MSG_TRAP2); - if ( !trap_pdu ) { - crm_err("Failed to create SNMP notification"); - return SNMPERR_GENERR; + if (!trap_pdu) { + crm_err("Failed to create SNMP notification"); + return SNMPERR_GENERR; } - if(1) { - /* send uptime */ + if (1) { + /* send uptime */ char csysuptime[20]; - time_t now = time(NULL); - sprintf(csysuptime, "%ld", now); - snmp_add_var(trap_pdu, sysuptime_oid, sizeof(sysuptime_oid) / sizeof(oid), 't', csysuptime); + time_t now = time(NULL); + + sprintf(csysuptime, "%ld", now); + snmp_add_var(trap_pdu, sysuptime_oid, sizeof(sysuptime_oid) / sizeof(oid), 't', csysuptime); } - + /* Indicate what the trap is by setting snmpTrapOid.0 */ - ret = snmp_add_var(trap_pdu, snmptrap_oid, sizeof(snmptrap_oid) / sizeof(oid), 'o', snmp_crm_trap_oid); + ret = + snmp_add_var(trap_pdu, snmptrap_oid, sizeof(snmptrap_oid) / sizeof(oid), 'o', + snmp_crm_trap_oid); if (ret != 0) { - crm_err("Failed set snmpTrapOid.0=%s", snmp_crm_trap_oid); - return ret; + crm_err("Failed set snmpTrapOid.0=%s", snmp_crm_trap_oid); + return ret; } /* Add extries to the trap */ - add_snmp_field(trap_pdu, snmp_crm_oid_rsc, rsc); + add_snmp_field(trap_pdu, snmp_crm_oid_rsc, rsc); add_snmp_field(trap_pdu, snmp_crm_oid_node, node); add_snmp_field(trap_pdu, snmp_crm_oid_task, task); add_snmp_field(trap_pdu, snmp_crm_oid_desc, desc); - add_snmp_field_int(trap_pdu, snmp_crm_oid_rc, rc); + add_snmp_field_int(trap_pdu, snmp_crm_oid_rc, rc); add_snmp_field_int(trap_pdu, snmp_crm_oid_trc, target_rc); add_snmp_field_int(trap_pdu, snmp_crm_oid_status, status); /* Send and cleanup */ ret = snmp_send(session, trap_pdu); - if(ret == 0) { - /* error */ - snmp_sess_perror("Could not send SNMP trap", session); - snmp_free_pdu(trap_pdu); - ret = SNMPERR_GENERR; + if (ret == 0) { + /* error */ + snmp_sess_perror("Could not send SNMP trap", session); + snmp_free_pdu(trap_pdu); + ret = SNMPERR_GENERR; } else { - ret = SNMPERR_SUCCESS; + ret = SNMPERR_SUCCESS; } #else crm_err("Sending SNMP traps is not supported by this installation"); #endif return ret; } #if ENABLE_ESMTP -#include -#include +# include +# include -static void print_recipient_status( - smtp_recipient_t recipient, const char *mailbox, void *arg) +static void +print_recipient_status(smtp_recipient_t recipient, const char *mailbox, void *arg) { const smtp_status_t *status; - status = smtp_recipient_status (recipient); - printf ("%s: %d %s", mailbox, status->code, status->text); + status = smtp_recipient_status(recipient); + printf("%s: %d %s", mailbox, status->code, status->text); } -static void event_cb (smtp_session_t session, int event_no, void *arg, ...) +static void +event_cb(smtp_session_t session, int event_no, void *arg, ...) { int *ok; va_list alist; va_start(alist, arg); - switch(event_no) { - case SMTP_EV_CONNECT: - case SMTP_EV_MAILSTATUS: - case SMTP_EV_RCPTSTATUS: - case SMTP_EV_MESSAGEDATA: - case SMTP_EV_MESSAGESENT: - case SMTP_EV_DISCONNECT: - break; - - case SMTP_EV_WEAK_CIPHER: { - int bits = va_arg(alist, long); - ok = va_arg(alist, int*); - crm_debug("SMTP_EV_WEAK_CIPHER, bits=%d - accepted.", bits); - *ok = 1; break; - } - case SMTP_EV_STARTTLS_OK: - crm_debug("SMTP_EV_STARTTLS_OK - TLS started here."); - break; - - case SMTP_EV_INVALID_PEER_CERTIFICATE: { - long vfy_result = va_arg(alist, long); - ok = va_arg(alist, int*); - - /* There is a table in handle_invalid_peer_certificate() of mail-file.c */ - crm_err("SMTP_EV_INVALID_PEER_CERTIFICATE: %ld", vfy_result); - *ok = 1; break; - } - case SMTP_EV_NO_PEER_CERTIFICATE: - ok = va_arg(alist, int*); - crm_debug("SMTP_EV_NO_PEER_CERTIFICATE - accepted."); - *ok = 1; - break; - case SMTP_EV_WRONG_PEER_CERTIFICATE: - ok = va_arg(alist, int*); - crm_debug("SMTP_EV_WRONG_PEER_CERTIFICATE - accepted."); - *ok = 1; - break; - case SMTP_EV_NO_CLIENT_CERTIFICATE: - ok = va_arg(alist, int*); - crm_debug("SMTP_EV_NO_CLIENT_CERTIFICATE - accepted."); - *ok = 1; - break; - default: - crm_debug("Got event: %d - ignored.\n", event_no); + switch (event_no) { + case SMTP_EV_CONNECT: + case SMTP_EV_MAILSTATUS: + case SMTP_EV_RCPTSTATUS: + case SMTP_EV_MESSAGEDATA: + case SMTP_EV_MESSAGESENT: + case SMTP_EV_DISCONNECT: + break; + + case SMTP_EV_WEAK_CIPHER:{ + int bits = va_arg(alist, long); + ok = va_arg(alist, int *); + + crm_debug("SMTP_EV_WEAK_CIPHER, bits=%d - accepted.", bits); + *ok = 1; + break; + } + case SMTP_EV_STARTTLS_OK: + crm_debug("SMTP_EV_STARTTLS_OK - TLS started here."); + break; + + case SMTP_EV_INVALID_PEER_CERTIFICATE:{ + long vfy_result = va_arg(alist, long); + ok = va_arg(alist, int *); + + /* There is a table in handle_invalid_peer_certificate() of mail-file.c */ + crm_err("SMTP_EV_INVALID_PEER_CERTIFICATE: %ld", vfy_result); + *ok = 1; + break; + } + case SMTP_EV_NO_PEER_CERTIFICATE: + ok = va_arg(alist, int *); + + crm_debug("SMTP_EV_NO_PEER_CERTIFICATE - accepted."); + *ok = 1; + break; + case SMTP_EV_WRONG_PEER_CERTIFICATE: + ok = va_arg(alist, int *); + + crm_debug("SMTP_EV_WRONG_PEER_CERTIFICATE - accepted."); + *ok = 1; + break; + case SMTP_EV_NO_CLIENT_CERTIFICATE: + ok = va_arg(alist, int *); + + crm_debug("SMTP_EV_NO_CLIENT_CERTIFICATE - accepted."); + *ok = 1; + break; + default: + crm_debug("Got event: %d - ignored.\n", event_no); } va_end(alist); } #endif #define BODY_MAX 2048 #if ENABLE_ESMTP static void -crm_smtp_debug (const char *buf, int buflen, int writing, void *arg) +crm_smtp_debug(const char *buf, int buflen, int writing, void *arg) { char type = 0; - int lpc = 0, last = 0, level = *(int*)arg; + int lpc = 0, last = 0, level = *(int *)arg; if (writing == SMTP_CB_HEADERS) { - type = 'H'; - } else if(writing) { - type = 'C'; + type = 'H'; + } else if (writing) { + type = 'C'; } else { - type = 'S'; - } - - for(; lpc < buflen; lpc++) { - switch(buf[lpc]) { - case 0: - case '\n': - if(last > 0) { - do_crm_log(level, " %.*s", lpc-last, buf+last); - } else { - do_crm_log(level, "%c: %.*s", type, lpc-last, buf+last); - } - last = lpc + 1; - break; - } + type = 'S'; + } + + for (; lpc < buflen; lpc++) { + switch (buf[lpc]) { + case 0: + case '\n': + if (last > 0) { + do_crm_log(level, " %.*s", lpc - last, buf + last); + } else { + do_crm_log(level, "%c: %.*s", type, lpc - last, buf + last); + } + last = lpc + 1; + break; + } } } #endif static int -send_custom_trap(const char *node, const char *rsc, const char *task, int target_rc, int rc, int status, const char *desc) +send_custom_trap(const char *node, const char *rsc, const char *task, int target_rc, int rc, + int status, const char *desc) { pid_t pid; - /*setenv needs chars, these are ints*/ + + /*setenv needs chars, these are ints */ char *rc_s = crm_itoa(rc); char *status_s = crm_itoa(status); char *target_rc_s = crm_itoa(target_rc); crm_debug("Sending external notification to '%s' via '%s'", external_recipient, external_agent); - setenv("CRM_notify_recipient",external_recipient,1); - setenv("CRM_notify_node",node,1); - setenv("CRM_notify_rsc",rsc,1); - setenv("CRM_notify_task",task,1); - setenv("CRM_notify_desc",desc,1); - setenv("CRM_notify_rc",rc_s,1); - setenv("CRM_notify_target_rc",target_rc_s,1); - setenv("CRM_notify_status",status_s,1); + setenv("CRM_notify_recipient", external_recipient, 1); + setenv("CRM_notify_node", node, 1); + setenv("CRM_notify_rsc", rsc, 1); + setenv("CRM_notify_task", task, 1); + setenv("CRM_notify_desc", desc, 1); + setenv("CRM_notify_rc", rc_s, 1); + setenv("CRM_notify_target_rc", target_rc_s, 1); + setenv("CRM_notify_status", status_s, 1); - pid=fork(); - if(pid == -1) { - cl_perror("notification fork() failed."); + pid = fork(); + if (pid == -1) { + cl_perror("notification fork() failed."); } - if(pid == 0) { - /* crm_debug("notification: I am the child. Executing the nofitication program."); */ - execl(external_agent,external_agent,NULL); + if (pid == 0) { + /* crm_debug("notification: I am the child. Executing the nofitication program."); */ + execl(external_agent, external_agent, NULL); } - crm_debug_2("Finished running custom notification program '%s'.",external_agent); + crm_debug_2("Finished running custom notification program '%s'.", external_agent); crm_free(target_rc_s); crm_free(status_s); crm_free(rc_s); return 0; } static int -send_smtp_trap(const char *node, const char *rsc, const char *task, int target_rc, int rc, int status, const char *desc) +send_smtp_trap(const char *node, const char *rsc, const char *task, int target_rc, int rc, + int status, const char *desc) { #if ENABLE_ESMTP smtp_session_t session; smtp_message_t message; auth_context_t authctx; struct sigaction sa; - + int len = 20; int noauth = 1; int smtp_debug = LOG_DEBUG; char crm_mail_body[BODY_MAX]; char *crm_mail_subject = NULL; - - if(node == NULL) { - node = "-"; + + if (node == NULL) { + node = "-"; } - if(rsc == NULL) { - rsc = "-"; + if (rsc == NULL) { + rsc = "-"; } - if(desc == NULL) { - desc = "-"; + if (desc == NULL) { + desc = "-"; } - - if(crm_mail_to == NULL) { - return 1; + + if (crm_mail_to == NULL) { + return 1; } - - if(crm_mail_host == NULL) { - crm_mail_host = "localhost:25"; + + if (crm_mail_host == NULL) { + crm_mail_host = "localhost:25"; } - if(crm_mail_prefix == NULL) { - crm_mail_prefix = "Cluster notification"; + if (crm_mail_prefix == NULL) { + crm_mail_prefix = "Cluster notification"; } - + crm_debug("Sending '%s' mail to %s via %s", crm_mail_prefix, crm_mail_to, crm_mail_host); len += strlen(crm_mail_prefix); len += strlen(task); len += strlen(rsc); len += strlen(node); len += strlen(desc); len++; - + crm_malloc0(crm_mail_subject, len); - snprintf(crm_mail_subject, len, "%s - %s event for %s on %s: %s\r\n", crm_mail_prefix, task, rsc, node, desc); + snprintf(crm_mail_subject, len, "%s - %s event for %s on %s: %s\r\n", crm_mail_prefix, task, + rsc, node, desc); len = 0; - len += snprintf(crm_mail_body+len, BODY_MAX-len, "\r\n%s\r\n", crm_mail_prefix); - len += snprintf(crm_mail_body+len, BODY_MAX-len, "====\r\n\r\n"); - if(rc==target_rc) { - len += snprintf(crm_mail_body+len, BODY_MAX-len, - "Completed operation %s for resource %s on %s\r\n", task, rsc, node); + len += snprintf(crm_mail_body + len, BODY_MAX - len, "\r\n%s\r\n", crm_mail_prefix); + len += snprintf(crm_mail_body + len, BODY_MAX - len, "====\r\n\r\n"); + if (rc == target_rc) { + len += snprintf(crm_mail_body + len, BODY_MAX - len, + "Completed operation %s for resource %s on %s\r\n", task, rsc, node); } else { - len += snprintf(crm_mail_body+len, BODY_MAX-len, - "Operation %s for resource %s on %s failed: %s\r\n", task, rsc, node, desc); + len += snprintf(crm_mail_body + len, BODY_MAX - len, + "Operation %s for resource %s on %s failed: %s\r\n", task, rsc, node, desc); } - len += snprintf(crm_mail_body+len, BODY_MAX-len, "\r\nDetails:\r\n"); - len += snprintf(crm_mail_body+len, BODY_MAX-len, - "\toperation status: (%d) %s\r\n", status, op_status2text(status)); - if(status == LRM_OP_DONE) { - len += snprintf(crm_mail_body+len, BODY_MAX-len, - "\tscript returned: (%d) %s\r\n", rc, execra_code2string(rc)); - len += snprintf(crm_mail_body+len, BODY_MAX-len, - "\texpected return value: (%d) %s\r\n", target_rc, execra_code2string(target_rc)); + len += snprintf(crm_mail_body + len, BODY_MAX - len, "\r\nDetails:\r\n"); + len += snprintf(crm_mail_body + len, BODY_MAX - len, + "\toperation status: (%d) %s\r\n", status, op_status2text(status)); + if (status == LRM_OP_DONE) { + len += snprintf(crm_mail_body + len, BODY_MAX - len, + "\tscript returned: (%d) %s\r\n", rc, execra_code2string(rc)); + len += snprintf(crm_mail_body + len, BODY_MAX - len, + "\texpected return value: (%d) %s\r\n", target_rc, + execra_code2string(target_rc)); } - + auth_client_init(); session = smtp_create_session(); message = smtp_add_message(session); - smtp_starttls_enable (session, Starttls_ENABLED); - + smtp_starttls_enable(session, Starttls_ENABLED); + sa.sa_handler = SIG_IGN; - sigemptyset (&sa.sa_mask); + sigemptyset(&sa.sa_mask); sa.sa_flags = 0; - sigaction (SIGPIPE, &sa, NULL); + sigaction(SIGPIPE, &sa, NULL); - smtp_set_server (session, crm_mail_host); + smtp_set_server(session, crm_mail_host); - authctx = auth_create_context (); - auth_set_mechanism_flags (authctx, AUTH_PLUGIN_PLAIN, 0); + authctx = auth_create_context(); + auth_set_mechanism_flags(authctx, AUTH_PLUGIN_PLAIN, 0); smtp_set_eventcb(session, event_cb, NULL); /* Now tell libESMTP it can use the SMTP AUTH extension. */ if (!noauth) { - crm_debug("Adding authentication context"); - smtp_auth_set_context (session, authctx); + crm_debug("Adding authentication context"); + smtp_auth_set_context(session, authctx); } - - if(crm_mail_from == NULL) { - struct utsname us; - char auto_from[BODY_MAX]; - - CRM_ASSERT(uname(&us) == 0); - snprintf(auto_from, BODY_MAX, "crm_mon@%s", us.nodename); - smtp_set_reverse_path (message, auto_from); + + if (crm_mail_from == NULL) { + struct utsname us; + char auto_from[BODY_MAX]; + + CRM_ASSERT(uname(&us) == 0); + snprintf(auto_from, BODY_MAX, "crm_mon@%s", us.nodename); + smtp_set_reverse_path(message, auto_from); } else { - /* NULL is ok */ - smtp_set_reverse_path (message, crm_mail_from); + /* NULL is ok */ + smtp_set_reverse_path(message, crm_mail_from); } - - smtp_set_header (message, "To", NULL/*phrase*/, NULL/*addr*/); /* "Phrase" */ - smtp_add_recipient (message, crm_mail_to); - + + smtp_set_header(message, "To", NULL /*phrase */ , NULL /*addr */ ); /* "Phrase" */ + smtp_add_recipient(message, crm_mail_to); + /* Set the Subject: header and override any subject line in the message headers. */ - smtp_set_header (message, "Subject", crm_mail_subject); - smtp_set_header_option (message, "Subject", Hdr_OVERRIDE, 1); + smtp_set_header(message, "Subject", crm_mail_subject); + smtp_set_header_option(message, "Subject", Hdr_OVERRIDE, 1); smtp_set_message_str(message, crm_mail_body); - smtp_set_monitorcb (session, crm_smtp_debug, &smtp_debug, 1); + smtp_set_monitorcb(session, crm_smtp_debug, &smtp_debug, 1); + + if (smtp_start_session(session)) { + char buf[128]; + int rc = smtp_errno(); - if (smtp_start_session (session)) { - char buf[128]; - int rc = smtp_errno(); - crm_err("SMTP server problem: %s (%d)", smtp_strerror (rc, buf, sizeof buf), rc); + crm_err("SMTP server problem: %s (%d)", smtp_strerror(rc, buf, sizeof buf), rc); } else { - char buf[128]; - int rc = smtp_errno(); - const smtp_status_t *smtp_status = smtp_message_transfer_status(message); - if(rc != 0) { - crm_err("SMTP server problem: %s (%d)", smtp_strerror (rc, buf, sizeof buf), rc); - } - crm_info("Send status: %d %s", smtp_status->code, crm_str(smtp_status->text)); - smtp_enumerate_recipients (message, print_recipient_status, NULL); + char buf[128]; + int rc = smtp_errno(); + const smtp_status_t *smtp_status = smtp_message_transfer_status(message); + + if (rc != 0) { + crm_err("SMTP server problem: %s (%d)", smtp_strerror(rc, buf, sizeof buf), rc); + } + crm_info("Send status: %d %s", smtp_status->code, crm_str(smtp_status->text)); + smtp_enumerate_recipients(message, print_recipient_status, NULL); } smtp_destroy_session(session); auth_destroy_context(authctx); auth_client_exit(); #endif return 0; } -static void handle_rsc_op(xmlNode *rsc_op) +static void +handle_rsc_op(xmlNode * rsc_op) { int rc = -1; int status = -1; int action = -1; int interval = 0; int target_rc = -1; int transition_num = -1; gboolean notify = TRUE; - + char *rsc = NULL; char *task = NULL; const char *desc = NULL; - const char *node = NULL; - const char *magic = NULL; - const char *id = crm_element_value(rsc_op, XML_LRM_ATTR_TASK_KEY); + const char *node = NULL; + const char *magic = NULL; + const char *id = crm_element_value(rsc_op, XML_LRM_ATTR_TASK_KEY); char *update_te_uuid = NULL; xmlNode *n = rsc_op; - if(id == NULL) { - /* Compatability with <= 1.1.5 */ - id = ID(rsc_op); + if (id == NULL) { + /* Compatability with <= 1.1.5 */ + id = ID(rsc_op); } - + magic = crm_element_value(rsc_op, XML_ATTR_TRANSITION_MAGIC); - if(magic == NULL) { - /* non-change */ - return; + if (magic == NULL) { + /* non-change */ + return; } - - if(FALSE == decode_transition_magic( - magic, &update_te_uuid, &transition_num, &action, - &status, &rc, &target_rc)) { - crm_err("Invalid event %s detected for %s", magic, id); - return; + + if (FALSE == decode_transition_magic(magic, &update_te_uuid, &transition_num, &action, + &status, &rc, &target_rc)) { + crm_err("Invalid event %s detected for %s", magic, id); + return; } - - if(parse_op_key(id, &rsc, &task, &interval) == FALSE) { - crm_err("Invalid event detected for %s", id); - goto bail; + + if (parse_op_key(id, &rsc, &task, &interval) == FALSE) { + crm_err("Invalid event detected for %s", id); + goto bail; } - while(n != NULL && safe_str_neq(XML_CIB_TAG_STATE, TYPE(n))) { - n = n->parent; + while (n != NULL && safe_str_neq(XML_CIB_TAG_STATE, TYPE(n))) { + n = n->parent; } node = crm_element_value(n, XML_ATTR_UNAME); - if(node == NULL) { - node = ID(n); + if (node == NULL) { + node = ID(n); } - if(node == NULL) { - crm_err("No node detected for event %s (%s)", magic, id); - goto bail; + if (node == NULL) { + crm_err("No node detected for event %s (%s)", magic, id); + goto bail; } /* look up where we expected it to be? */ desc = cib_error2string(cib_ok); - if(status == LRM_OP_DONE && target_rc == rc) { - crm_notice("%s of %s on %s completed: %s", task, rsc, node, desc); - if(rc == EXECRA_NOT_RUNNING) { - notify = FALSE; - } - - } else if(status == LRM_OP_DONE) { - desc = execra_code2string(rc); - crm_warn("%s of %s on %s failed: %s", task, rsc, node, desc); - + if (status == LRM_OP_DONE && target_rc == rc) { + crm_notice("%s of %s on %s completed: %s", task, rsc, node, desc); + if (rc == EXECRA_NOT_RUNNING) { + notify = FALSE; + } + + } else if (status == LRM_OP_DONE) { + desc = execra_code2string(rc); + crm_warn("%s of %s on %s failed: %s", task, rsc, node, desc); + } else { - desc = op_status2text(status); - crm_warn("%s of %s on %s failed: %s", task, rsc, node, desc); + desc = op_status2text(status); + crm_warn("%s of %s on %s failed: %s", task, rsc, node, desc); } - if(notify && snmp_target) { - send_snmp_trap(node, rsc, task, target_rc, rc, status, desc); + if (notify && snmp_target) { + send_snmp_trap(node, rsc, task, target_rc, rc, status, desc); } - if(notify && crm_mail_to) { - send_smtp_trap(node, rsc, task, target_rc, rc, status, desc); + if (notify && crm_mail_to) { + send_smtp_trap(node, rsc, task, target_rc, rc, status, desc); } - if(notify && external_agent) { - send_custom_trap(node, rsc, task, target_rc, rc, status, desc); + if (notify && external_agent) { + send_custom_trap(node, rsc, task, target_rc, rc, status, desc); } bail: crm_free(update_te_uuid); crm_free(rsc); crm_free(task); } void -crm_diff_update(const char *event, xmlNode *msg) +crm_diff_update(const char *event, xmlNode * msg) { int rc = -1; long now = time(NULL); const char *op = NULL; unsigned int log_level = LOG_INFO; xmlNode *diff = NULL; xmlNode *cib_last = NULL; xmlNode *update = get_message_xml(msg, F_CIB_UPDATE); print_dot(); - - if(msg == NULL) { - crm_err("NULL update"); - return; + + if (msg == NULL) { + crm_err("NULL update"); + return; } - - crm_element_value_int(msg, F_CIB_RC, &rc); + + crm_element_value_int(msg, F_CIB_RC, &rc); op = crm_element_value(msg, F_CIB_OPERATION); diff = get_message_xml(msg, F_CIB_UPDATE_RESULT); - if(rc < cib_ok) { - log_level = LOG_WARNING; - do_crm_log(log_level, "[%s] %s ABORTED: %s", - event, op, cib_error2string(rc)); - return; - } - - if(current_cib != NULL) { - cib_last = current_cib; current_cib = NULL; - rc = cib_process_diff(op, cib_force_diff, NULL, NULL, diff, cib_last, ¤t_cib, NULL); - - if(rc != cib_ok) { - crm_debug("Update didn't apply, requesting full copy: %s", cib_error2string(rc)); - free_xml(current_cib); - current_cib = NULL; - } + if (rc < cib_ok) { + log_level = LOG_WARNING; + do_crm_log(log_level, "[%s] %s ABORTED: %s", event, op, cib_error2string(rc)); + return; } - - if(current_cib == NULL) { - current_cib = get_cib_copy(cib); + + if (current_cib != NULL) { + cib_last = current_cib; + current_cib = NULL; + rc = cib_process_diff(op, cib_force_diff, NULL, NULL, diff, cib_last, ¤t_cib, NULL); + + if (rc != cib_ok) { + crm_debug("Update didn't apply, requesting full copy: %s", cib_error2string(rc)); + free_xml(current_cib); + current_cib = NULL; + } } - if(log_diffs && diff) { - log_cib_diff(LOG_DEBUG, diff, op); + if (current_cib == NULL) { + current_cib = get_cib_copy(cib); } - - if(log_updates && update != NULL) { - do_crm_log_xml(LOG_DEBUG, "raw_update", update); - } - - if(diff && (crm_mail_to || snmp_target || external_agent)) { - /* Process operation updates */ - xmlXPathObject *xpathObj = xpath_search( - diff, "//"F_CIB_UPDATE_RESULT"//"XML_TAG_DIFF_ADDED"//"XML_LRM_TAG_RSC_OP); - if(xpathObj && xpathObj->nodesetval->nodeNr > 0) { - int lpc = 0, max = xpathObj->nodesetval->nodeNr; - for(lpc = 0; lpc < max; lpc++) { - xmlNode *rsc_op = getXpathResult(xpathObj, lpc); - handle_rsc_op(rsc_op); - } - } - if (xpathObj) { - xmlXPathFreeObject(xpathObj); - } - } - - if((now - last_refresh) > (reconnect_msec/1000)) { - /* Force a refresh */ - mon_refresh_display(NULL); - + + if (log_diffs && diff) { + log_cib_diff(LOG_DEBUG, diff, op); + } + + if (log_updates && update != NULL) { + do_crm_log_xml(LOG_DEBUG, "raw_update", update); + } + + if (diff && (crm_mail_to || snmp_target || external_agent)) { + /* Process operation updates */ + xmlXPathObject *xpathObj = + xpath_search(diff, + "//" F_CIB_UPDATE_RESULT "//" XML_TAG_DIFF_ADDED "//" XML_LRM_TAG_RSC_OP); + if (xpathObj && xpathObj->nodesetval->nodeNr > 0) { + int lpc = 0, max = xpathObj->nodesetval->nodeNr; + + for (lpc = 0; lpc < max; lpc++) { + xmlNode *rsc_op = getXpathResult(xpathObj, lpc); + + handle_rsc_op(rsc_op); + } + } + if (xpathObj) { + xmlXPathFreeObject(xpathObj); + } + } + + if ((now - last_refresh) > (reconnect_msec / 1000)) { + /* Force a refresh */ + mon_refresh_display(NULL); + } else { - mainloop_set_trigger(refresh_trigger); + mainloop_set_trigger(refresh_trigger); } free_xml(cib_last); } gboolean -mon_refresh_display(gpointer user_data) +mon_refresh_display(gpointer user_data) { xmlNode *cib_copy = copy_xml(current_cib); pe_working_set_t data_set; last_refresh = time(NULL); - - if(cli_config_update(&cib_copy, NULL, FALSE) == FALSE) { - if(cib) { - cib->cmds->signoff(cib); - } - print_as("Upgrade failed: %s", cib_error2string(cib_dtd_validation)); - if(as_console) { sleep(2); } - clean_up(LSB_EXIT_GENERIC); - return FALSE; + + if (cli_config_update(&cib_copy, NULL, FALSE) == FALSE) { + if (cib) { + cib->cmds->signoff(cib); + } + print_as("Upgrade failed: %s", cib_error2string(cib_dtd_validation)); + if (as_console) { + sleep(2); + } + clean_up(LSB_EXIT_GENERIC); + return FALSE; } set_working_set_defaults(&data_set); data_set.input = cib_copy; - cluster_status(&data_set); + cluster_status(&data_set); + + if (as_html_file || web_cgi) { + if (print_html_status(&data_set, as_html_file, web_cgi) != 0) { + fprintf(stderr, "Critical: Unable to output html file\n"); + clean_up(LSB_EXIT_GENERIC); + } - if(as_html_file || web_cgi) { - if (print_html_status(&data_set, as_html_file, web_cgi) != 0) { - fprintf(stderr, "Critical: Unable to output html file\n"); - clean_up(LSB_EXIT_GENERIC); - } - - } else if(daemonize) { - /* do nothing */ + } else if (daemonize) { + /* do nothing */ } else if (simple_status) { - print_simple_status(&data_set); - if (has_warnings) { - clean_up(LSB_EXIT_GENERIC); - } - + print_simple_status(&data_set); + if (has_warnings) { + clean_up(LSB_EXIT_GENERIC); + } + } else { - print_status(&data_set); + print_status(&data_set); } - + cleanup_calculations(&data_set); return TRUE; } /* * De-init ncurses, signoff from the CIB and deallocate memory. */ -void clean_up(int rc) +void +clean_up(int rc) { #if ENABLE_SNMP netsnmp_session *session = crm_snmp_init(NULL, NULL); - if(session) { - snmp_close(session); - snmp_shutdown("snmpapp"); + + if (session) { + snmp_close(session); + snmp_shutdown("snmpapp"); } -#endif +#endif #if CURSES_ENABLED - if(as_console) { - as_console = FALSE; - echo(); - nocbreak(); - endwin(); + if (as_console) { + as_console = FALSE; + echo(); + nocbreak(); + endwin(); } #endif if (cib != NULL) { - cib->cmds->signoff(cib); - cib_delete(cib); - cib = NULL; + cib->cmds->signoff(cib); + cib_delete(cib); + cib = NULL; } crm_free(as_html_file); crm_free(xml_file); crm_free(pid_file); - if(rc >= 0) { - exit(rc); + if (rc >= 0) { + exit(rc); } return; } diff --git a/tools/crm_resource.c b/tools/crm_resource.c index c252049190..77c5a1a9d4 100644 --- a/tools/crm_resource.c +++ b/tools/crm_resource.c @@ -1,1699 +1,1693 @@ /* * Copyright (C) 2004 Andrew Beekhof * * 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 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 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 */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include gboolean do_force = FALSE; gboolean BE_QUIET = FALSE; const char *attr_set_type = XML_TAG_ATTR_SETS; char *host_id = NULL; const char *rsc_id = NULL; const char *host_uname = NULL; const char *prop_name = NULL; const char *prop_value = NULL; const char *rsc_type = NULL; const char *prop_id = NULL; const char *prop_set = NULL; char *move_lifetime = NULL; char rsc_cmd = 'L'; char *our_pid = NULL; IPC_Channel *crmd_channel = NULL; char *xml_file = NULL; int cib_options = cib_sync_call; int crmd_replies_needed = 0; GMainLoop *mainloop = NULL; -extern void cleanup_alloc_calculations(pe_working_set_t *data_set); +extern void cleanup_alloc_calculations(pe_working_set_t * data_set); #define CMD_ERR(fmt, args...) do { \ crm_warn(fmt, ##args); \ fprintf(stderr, fmt, ##args); \ } while(0) #define message_timeout_ms 60*1000 static gboolean resource_ipc_timeout(gpointer data) { fprintf(stderr, "No messages received in %d seconds.. aborting\n", - (int)message_timeout_ms/1000); - crm_err("No messages received in %d seconds", - (int)message_timeout_ms/1000); + (int)message_timeout_ms / 1000); + crm_err("No messages received in %d seconds", (int)message_timeout_ms / 1000); exit(-1); } static void resource_ipc_connection_destroy(gpointer user_data) { crm_info("Connection to CRMd was terminated"); exit(1); } static void -start_mainloop(void) +start_mainloop(void) { mainloop = g_main_new(FALSE); - crmd_replies_needed++; /* The welcome message */ + crmd_replies_needed++; /* The welcome message */ fprintf(stderr, "Waiting for %d replies from the CRMd", crmd_replies_needed); crm_debug("Waiting for %d replies from the CRMd", crmd_replies_needed); - + g_timeout_add(message_timeout_ms, resource_ipc_timeout, NULL); g_main_run(mainloop); } static gboolean resource_ipc_callback(IPC_Channel * server, void *private_data) { int lpc = 0; xmlNode *msg = NULL; gboolean stay_connected = TRUE; - - while(IPC_ISRCONN(server)) { - if(server->ops->is_message_pending(server) == 0) { - break; - } - - msg = xmlfromIPC(server, MAX_IPC_DELAY); - if (msg == NULL) { - break; - } - - lpc++; - fprintf(stderr, "."); - crm_log_xml(LOG_DEBUG_2, "[inbound]", msg); - - crmd_replies_needed--; - if(crmd_replies_needed == 0) { - fprintf(stderr, " OK\n"); - crm_debug("Got all the replies we expected"); - crm_xml_cleanup(); - exit(0); - } - - free_xml(msg); - msg = NULL; - - if(server->ch_status != IPC_CONNECT) { - break; - } - } - + + while (IPC_ISRCONN(server)) { + if (server->ops->is_message_pending(server) == 0) { + break; + } + + msg = xmlfromIPC(server, MAX_IPC_DELAY); + if (msg == NULL) { + break; + } + + lpc++; + fprintf(stderr, "."); + crm_log_xml(LOG_DEBUG_2, "[inbound]", msg); + + crmd_replies_needed--; + if (crmd_replies_needed == 0) { + fprintf(stderr, " OK\n"); + crm_debug("Got all the replies we expected"); + crm_xml_cleanup(); + exit(0); + } + + free_xml(msg); + msg = NULL; + + if (server->ch_status != IPC_CONNECT) { + break; + } + } + crm_debug_2("Processed %d messages (%d)", lpc, server->ch_status); - + if (server->ch_status != IPC_CONNECT) { - stay_connected = FALSE; + stay_connected = FALSE; } return stay_connected; } static int -do_find_resource(const char *rsc, resource_t *the_rsc, pe_working_set_t *data_set) +do_find_resource(const char *rsc, resource_t * the_rsc, pe_working_set_t * data_set) { int found = 0; GListPtr lpc = NULL; - if(the_rsc == NULL) { - the_rsc = pe_find_resource(data_set->resources, rsc); + if (the_rsc == NULL) { + the_rsc = pe_find_resource(data_set->resources, rsc); } - - if(the_rsc == NULL) { - return cib_NOTEXISTS; + + if (the_rsc == NULL) { + return cib_NOTEXISTS; } - if(the_rsc->variant > pe_clone) { - GListPtr gIter = the_rsc->children; - for(; gIter != NULL; gIter = gIter->next) { - found += do_find_resource(rsc, gIter->data, data_set); - } - return found; + if (the_rsc->variant > pe_clone) { + GListPtr gIter = the_rsc->children; + + for (; gIter != NULL; gIter = gIter->next) { + found += do_find_resource(rsc, gIter->data, data_set); + } + return found; } - - for(lpc = the_rsc->running_on; lpc != NULL; lpc = lpc->next) { - node_t *node = (node_t*)lpc->data; - - crm_debug_3("resource %s is running on: %s", - rsc, node->details->uname); - if(BE_QUIET) { - fprintf(stdout, "%s\n", node->details->uname); - } else { - const char *state = ""; - if(the_rsc->variant == pe_native && the_rsc->role == RSC_ROLE_MASTER) { - state = "Master"; - } - fprintf(stdout, "resource %s is running on: %s %s\n", - rsc, node->details->uname, state); - } - - found++; - } - - if(BE_QUIET == FALSE && found == 0) { - fprintf(stderr, "resource %s is NOT running\n", rsc); - } - + + for (lpc = the_rsc->running_on; lpc != NULL; lpc = lpc->next) { + node_t *node = (node_t *) lpc->data; + + crm_debug_3("resource %s is running on: %s", rsc, node->details->uname); + if (BE_QUIET) { + fprintf(stdout, "%s\n", node->details->uname); + } else { + const char *state = ""; + + if (the_rsc->variant == pe_native && the_rsc->role == RSC_ROLE_MASTER) { + state = "Master"; + } + fprintf(stdout, "resource %s is running on: %s %s\n", rsc, node->details->uname, state); + } + + found++; + } + + if (BE_QUIET == FALSE && found == 0) { + fprintf(stderr, "resource %s is NOT running\n", rsc); + } + return 0; } #define cons_string(x) x?x:"NA" static void -print_cts_constraints(pe_working_set_t *data_set) +print_cts_constraints(pe_working_set_t * data_set) { xmlNode *xml_obj = NULL; xmlNode *lifetime = NULL; xmlNode *cib_constraints = get_object_root(XML_CIB_TAG_CONSTRAINTS, data_set->input); - for(xml_obj = __xml_first_child(cib_constraints); xml_obj != NULL; xml_obj = __xml_next(xml_obj)) { - const char *id = crm_element_value(xml_obj, XML_ATTR_ID); - if(id == NULL) { - continue; - } - - lifetime = first_named_child(xml_obj, "lifetime"); - - if(test_ruleset(lifetime, NULL, data_set->now) == FALSE) { - continue; - } - - if(safe_str_eq(XML_CONS_TAG_RSC_DEPEND, crm_element_name(xml_obj))) { - printf("Constraint %s %s %s %s %s %s %s\n", - crm_element_name(xml_obj), - cons_string(crm_element_value(xml_obj, XML_ATTR_ID)), - cons_string(crm_element_value(xml_obj, XML_COLOC_ATTR_SOURCE)), - cons_string(crm_element_value(xml_obj, XML_COLOC_ATTR_TARGET)), - cons_string(crm_element_value(xml_obj, XML_RULE_ATTR_SCORE)), - cons_string(crm_element_value(xml_obj, XML_COLOC_ATTR_SOURCE_ROLE)), - cons_string(crm_element_value(xml_obj, XML_COLOC_ATTR_TARGET_ROLE))); - - } else if(safe_str_eq(XML_CONS_TAG_RSC_LOCATION, crm_element_name(xml_obj))) { - /* unpack_rsc_location(xml_obj, data_set); */ - } + + for (xml_obj = __xml_first_child(cib_constraints); xml_obj != NULL; + xml_obj = __xml_next(xml_obj)) { + const char *id = crm_element_value(xml_obj, XML_ATTR_ID); + + if (id == NULL) { + continue; + } + + lifetime = first_named_child(xml_obj, "lifetime"); + + if (test_ruleset(lifetime, NULL, data_set->now) == FALSE) { + continue; + } + + if (safe_str_eq(XML_CONS_TAG_RSC_DEPEND, crm_element_name(xml_obj))) { + printf("Constraint %s %s %s %s %s %s %s\n", + crm_element_name(xml_obj), + cons_string(crm_element_value(xml_obj, XML_ATTR_ID)), + cons_string(crm_element_value(xml_obj, XML_COLOC_ATTR_SOURCE)), + cons_string(crm_element_value(xml_obj, XML_COLOC_ATTR_TARGET)), + cons_string(crm_element_value(xml_obj, XML_RULE_ATTR_SCORE)), + cons_string(crm_element_value(xml_obj, XML_COLOC_ATTR_SOURCE_ROLE)), + cons_string(crm_element_value(xml_obj, XML_COLOC_ATTR_TARGET_ROLE))); + + } else if (safe_str_eq(XML_CONS_TAG_RSC_LOCATION, crm_element_name(xml_obj))) { + /* unpack_rsc_location(xml_obj, data_set); */ + } } } static void -print_cts_rsc(resource_t *rsc) +print_cts_rsc(resource_t * rsc) { GListPtr lpc = NULL; const char *host = NULL; gboolean needs_quorum = TRUE; const char *rtype = crm_element_value(rsc->xml, XML_ATTR_TYPE); const char *rprov = crm_element_value(rsc->xml, XML_AGENT_ATTR_PROVIDER); const char *rclass = crm_element_value(rsc->xml, XML_AGENT_ATTR_CLASS); - if(safe_str_eq(rclass, "stonith")) { - xmlNode *op = NULL; - needs_quorum = FALSE; + if (safe_str_eq(rclass, "stonith")) { + xmlNode *op = NULL; + + needs_quorum = FALSE; + + for (op = __xml_first_child(rsc->ops_xml); op != NULL; op = __xml_next(op)) { + if (crm_str_eq((const char *)op->name, "op", TRUE)) { + const char *name = crm_element_value(op, "name"); + + if (safe_str_neq(name, CRMD_ACTION_START)) { + const char *value = crm_element_value(op, "requires"); - for(op = __xml_first_child(rsc->ops_xml); op != NULL; op = __xml_next(op)) { - if(crm_str_eq((const char *)op->name, "op", TRUE)) { - const char *name = crm_element_value(op, "name"); - if(safe_str_neq(name, CRMD_ACTION_START)) { - const char *value = crm_element_value(op, "requires"); - if(safe_str_eq(value, "nothing")) { - needs_quorum = FALSE; - } - break; - } - } - } + if (safe_str_eq(value, "nothing")) { + needs_quorum = FALSE; + } + break; + } + } + } } - if(rsc->running_on != NULL && g_list_length(rsc->running_on) == 1) { - node_t *tmp = rsc->running_on->data; - host = tmp->details->uname; + if (rsc->running_on != NULL && g_list_length(rsc->running_on) == 1) { + node_t *tmp = rsc->running_on->data; + + host = tmp->details->uname; } printf("Resource: %s %s %s %s %s %s %s %s %d %lld 0x%.16llx\n", - crm_element_name(rsc->xml), rsc->id, - rsc->clone_name?rsc->clone_name:rsc->id, rsc->parent?rsc->parent->id:"NA", - rprov?rprov:"NA", rclass, rtype, host?host:"NA", needs_quorum, rsc->flags, rsc->flags); + crm_element_name(rsc->xml), rsc->id, + rsc->clone_name ? rsc->clone_name : rsc->id, rsc->parent ? rsc->parent->id : "NA", + rprov ? rprov : "NA", rclass, rtype, host ? host : "NA", needs_quorum, rsc->flags, + rsc->flags); - for(lpc = rsc->children; lpc != NULL; lpc = lpc->next) { - resource_t *child = (resource_t*)lpc->data; - - print_cts_rsc(child); + for (lpc = rsc->children; lpc != NULL; lpc = lpc->next) { + resource_t *child = (resource_t *) lpc->data; + + print_cts_rsc(child); } } - static void -print_raw_rsc(resource_t *rsc) +print_raw_rsc(resource_t * rsc) { GListPtr lpc = NULL; GListPtr children = rsc->children; - if(children == NULL) { - printf("%s\n", rsc->id); + if (children == NULL) { + printf("%s\n", rsc->id); } - - for(lpc = children; lpc != NULL; lpc = lpc->next) { - resource_t *child = (resource_t*)lpc->data; - - print_raw_rsc(child); + + for (lpc = children; lpc != NULL; lpc = lpc->next) { + resource_t *child = (resource_t *) lpc->data; + + print_raw_rsc(child); } } - static int -do_find_resource_list(pe_working_set_t *data_set, gboolean raw) +do_find_resource_list(pe_working_set_t * data_set, gboolean raw) { int found = 0; - + GListPtr lpc = NULL; - for(lpc = data_set->resources; lpc != NULL; lpc = lpc->next) { - resource_t *rsc = (resource_t*)lpc->data; - - if(is_set(rsc->flags, pe_rsc_orphan) - && rsc->fns->active(rsc, TRUE) == FALSE) { - continue; - } - rsc->fns->print( - rsc, NULL, pe_print_printf|pe_print_rsconly, stdout); - found++; + + for (lpc = data_set->resources; lpc != NULL; lpc = lpc->next) { + resource_t *rsc = (resource_t *) lpc->data; + + if (is_set(rsc->flags, pe_rsc_orphan) + && rsc->fns->active(rsc, TRUE) == FALSE) { + continue; + } + rsc->fns->print(rsc, NULL, pe_print_printf | pe_print_rsconly, stdout); + found++; } - if(found == 0) { - printf("NO resources configured\n"); - return cib_NOTEXISTS; + if (found == 0) { + printf("NO resources configured\n"); + return cib_NOTEXISTS; } return 0; } - -static resource_t *find_rsc_or_clone(const char *rsc, pe_working_set_t *data_set) +static resource_t * +find_rsc_or_clone(const char *rsc, pe_working_set_t * data_set) { resource_t *the_rsc = pe_find_resource(data_set->resources, rsc); - if(the_rsc == NULL) { - char *as_clone = crm_concat(rsc, "0", ':'); - the_rsc = pe_find_resource(data_set->resources, as_clone); - crm_free(as_clone); + + if (the_rsc == NULL) { + char *as_clone = crm_concat(rsc, "0", ':'); + + the_rsc = pe_find_resource(data_set->resources, as_clone); + crm_free(as_clone); } return the_rsc; } static int -dump_resource(const char *rsc, pe_working_set_t *data_set, gboolean expanded) +dump_resource(const char *rsc, pe_working_set_t * data_set, gboolean expanded) { char *rsc_xml = NULL; resource_t *the_rsc = find_rsc_or_clone(rsc, data_set); - if(the_rsc == NULL) { - return cib_NOTEXISTS; + if (the_rsc == NULL) { + return cib_NOTEXISTS; } the_rsc->fns->print(the_rsc, NULL, pe_print_printf, stdout); - if(expanded) { - rsc_xml = dump_xml_formatted(the_rsc->xml); + if (expanded) { + rsc_xml = dump_xml_formatted(the_rsc->xml); } else { - if(the_rsc->orig_xml) { - rsc_xml = dump_xml_formatted(the_rsc->orig_xml); - } else { - rsc_xml = dump_xml_formatted(the_rsc->xml); - } + if (the_rsc->orig_xml) { + rsc_xml = dump_xml_formatted(the_rsc->orig_xml); + } else { + rsc_xml = dump_xml_formatted(the_rsc->xml); + } } - fprintf(stdout, "%sxml:\n%s\n", expanded?"":"raw ", rsc_xml); - + fprintf(stdout, "%sxml:\n%s\n", expanded ? "" : "raw ", rsc_xml); + crm_free(rsc_xml); - + return 0; } static int -dump_resource_attr( - const char *rsc, const char *attr, pe_working_set_t *data_set) +dump_resource_attr(const char *rsc, const char *attr, pe_working_set_t * data_set) { int rc = cib_NOTEXISTS; node_t *current = NULL; GHashTable *params = NULL; resource_t *the_rsc = find_rsc_or_clone(rsc, data_set); const char *value = NULL; - if(the_rsc == NULL) { - return cib_NOTEXISTS; + if (the_rsc == NULL) { + return cib_NOTEXISTS; } - if(g_list_length(the_rsc->running_on) == 1) { - current = the_rsc->running_on->data; + if (g_list_length(the_rsc->running_on) == 1) { + current = the_rsc->running_on->data; - } else if(g_list_length(the_rsc->running_on) > 1) { - CMD_ERR("%s is active on more than one node," - " returning the default value for %s\n", - the_rsc->id, crm_str(value)); - } + } else if (g_list_length(the_rsc->running_on) > 1) { + CMD_ERR("%s is active on more than one node," + " returning the default value for %s\n", the_rsc->id, crm_str(value)); + } - params = g_hash_table_new_full( - crm_str_hash, g_str_equal, - g_hash_destroy_str, g_hash_destroy_str); + params = g_hash_table_new_full(crm_str_hash, g_str_equal, + g_hash_destroy_str, g_hash_destroy_str); - if(safe_str_eq(attr_set_type, XML_TAG_ATTR_SETS)) { - get_rsc_attributes(params, the_rsc, current, data_set); - } else if(safe_str_eq(attr_set_type, XML_TAG_META_SETS)) { - get_meta_attributes(params, the_rsc, current, data_set); + if (safe_str_eq(attr_set_type, XML_TAG_ATTR_SETS)) { + get_rsc_attributes(params, the_rsc, current, data_set); + } else if (safe_str_eq(attr_set_type, XML_TAG_META_SETS)) { + get_meta_attributes(params, the_rsc, current, data_set); } else { - unpack_instance_attributes(data_set->input, the_rsc->xml, XML_TAG_UTILIZATION, NULL, - params, NULL, FALSE, data_set->now); + unpack_instance_attributes(data_set->input, the_rsc->xml, XML_TAG_UTILIZATION, NULL, + params, NULL, FALSE, data_set->now); } - + crm_debug("Looking up %s in %s", attr, the_rsc->id); value = g_hash_table_lookup(params, attr); - if(value != NULL) { - fprintf(stdout, "%s\n", value); - rc = 0; + if (value != NULL) { + fprintf(stdout, "%s\n", value); + rc = 0; } g_hash_table_destroy(params); return rc; } -static int find_resource_attr( - cib_t *the_cib, const char *attr, const char *rsc, const char *set_type, const char *set_name, - const char *attr_id, const char *attr_name, char **value) +static int +find_resource_attr(cib_t * the_cib, const char *attr, const char *rsc, const char *set_type, + const char *set_name, const char *attr_id, const char *attr_name, char **value) { int offset = 0; static int xpath_max = 1024; enum cib_errors rc = cib_ok; xmlNode *xml_search = NULL; char *xpath_string = NULL; CRM_ASSERT(value != NULL); *value = NULL; - + crm_malloc0(xpath_string, xpath_max); - offset += snprintf(xpath_string + offset, xpath_max - offset, "%s", get_object_path("resources")); + offset += + snprintf(xpath_string + offset, xpath_max - offset, "%s", get_object_path("resources")); offset += snprintf(xpath_string + offset, xpath_max - offset, "//*[@id=\"%s\"]", rsc); - if(set_type) { - offset += snprintf(xpath_string + offset, xpath_max - offset, "/%s", set_type); - if(set_name) { - offset += snprintf(xpath_string + offset, xpath_max - offset, "[@id=\"%s\"]", set_name); - } + if (set_type) { + offset += snprintf(xpath_string + offset, xpath_max - offset, "/%s", set_type); + if (set_name) { + offset += snprintf(xpath_string + offset, xpath_max - offset, "[@id=\"%s\"]", set_name); + } } - + offset += snprintf(xpath_string + offset, xpath_max - offset, "//nvpair["); - if(attr_id) { - offset += snprintf(xpath_string + offset, xpath_max - offset, "@id=\"%s\"", attr_id); + if (attr_id) { + offset += snprintf(xpath_string + offset, xpath_max - offset, "@id=\"%s\"", attr_id); + } + + if (attr_name) { + if (attr_id) { + offset += snprintf(xpath_string + offset, xpath_max - offset, " and "); + } + offset += snprintf(xpath_string + offset, xpath_max - offset, "@name=\"%s\"", attr_name); } - - if(attr_name) { - if(attr_id) { - offset += snprintf(xpath_string + offset, xpath_max - offset, " and "); - } - offset += snprintf(xpath_string + offset, xpath_max - offset, "@name=\"%s\"", attr_name); - } offset += snprintf(xpath_string + offset, xpath_max - offset, "]"); - rc = the_cib->cmds->query( - the_cib, xpath_string, &xml_search, cib_sync_call|cib_scope_local|cib_xpath); - - if(rc != cib_ok) { - goto bail; + rc = the_cib->cmds->query(the_cib, xpath_string, &xml_search, + cib_sync_call | cib_scope_local | cib_xpath); + + if (rc != cib_ok) { + goto bail; } crm_log_xml_debug(xml_search, "Match"); - if(xml_has_children(xml_search)) { - xmlNode *child = NULL; - rc = cib_missing_data; - printf("Multiple attributes match name=%s\n", attr_name); - - for(child = __xml_first_child(xml_search); child != NULL; child = __xml_next(child)) { - printf(" Value: %s \t(id=%s)\n", - crm_element_value(child, XML_NVPAIR_ATTR_VALUE), ID(child)); - } + if (xml_has_children(xml_search)) { + xmlNode *child = NULL; + + rc = cib_missing_data; + printf("Multiple attributes match name=%s\n", attr_name); + + for (child = __xml_first_child(xml_search); child != NULL; child = __xml_next(child)) { + printf(" Value: %s \t(id=%s)\n", + crm_element_value(child, XML_NVPAIR_ATTR_VALUE), ID(child)); + } } else { - const char *tmp = crm_element_value(xml_search, attr); - if(tmp) { - *value = crm_strdup(tmp); - } + const char *tmp = crm_element_value(xml_search, attr); + + if (tmp) { + *value = crm_strdup(tmp); + } } bail: crm_free(xpath_string); free_xml(xml_search); return rc; } static int set_resource_attr(const char *rsc_id, const char *attr_set, const char *attr_id, - const char *attr_name, const char *attr_value, - cib_t *cib, pe_working_set_t *data_set) + const char *attr_name, const char *attr_value, + cib_t * cib, pe_working_set_t * data_set) { int rc = cib_ok; - + char *local_attr_id = NULL; char *local_attr_set = NULL; - + xmlNode *xml_top = NULL; xmlNode *xml_obj = NULL; gboolean use_attributes_tag = FALSE; resource_t *rsc = find_rsc_or_clone(rsc_id, data_set); - if(rsc == NULL) { - return cib_NOTEXISTS; + if (rsc == NULL) { + return cib_NOTEXISTS; } - if(safe_str_eq(attr_set_type, XML_TAG_ATTR_SETS)) { - rc = find_resource_attr( - cib, XML_ATTR_ID, rsc_id, XML_TAG_META_SETS, attr_set, attr_id, attr_name, &local_attr_id); - if(rc == cib_ok) { - printf("WARNING: There is already a meta attribute called %s (id=%s)\n", attr_name, local_attr_id); - } + if (safe_str_eq(attr_set_type, XML_TAG_ATTR_SETS)) { + rc = find_resource_attr(cib, XML_ATTR_ID, rsc_id, XML_TAG_META_SETS, attr_set, attr_id, + attr_name, &local_attr_id); + if (rc == cib_ok) { + printf("WARNING: There is already a meta attribute called %s (id=%s)\n", attr_name, + local_attr_id); + } } - rc = find_resource_attr( - cib, XML_ATTR_ID, rsc_id, attr_set_type, attr_set, attr_id, attr_name, &local_attr_id); + rc = find_resource_attr(cib, XML_ATTR_ID, rsc_id, attr_set_type, attr_set, attr_id, attr_name, + &local_attr_id); - if(rc == cib_ok) { - crm_debug("Found a match for name=%s: id=%s", attr_name, local_attr_id); - attr_id = local_attr_id; + if (rc == cib_ok) { + crm_debug("Found a match for name=%s: id=%s", attr_name, local_attr_id); + attr_id = local_attr_id; - } else if(rc != cib_NOTEXISTS) { - crm_free(local_attr_id); - return rc; + } else if (rc != cib_NOTEXISTS) { + crm_free(local_attr_id); + return rc; } else { - const char *value = NULL; - xmlNode *cib_top = NULL; - const char *tag = crm_element_name(rsc->xml); - - rc = cib->cmds->query(cib, "/cib", &cib_top, cib_sync_call|cib_scope_local|cib_xpath|cib_no_children); - value = crm_element_value(cib_top, "ignore_dtd"); - if(value != NULL) { - use_attributes_tag = TRUE; - - } else { - value = crm_element_value(cib_top, XML_ATTR_VALIDATION); - if(value && strstr(value, "-0.6")) { - use_attributes_tag = TRUE; - } - } - free_xml(cib_top); - - if(attr_set == NULL) { - local_attr_set = crm_concat(rsc_id, attr_set_type, '-'); - attr_set = local_attr_set; - } - if(attr_id == NULL) { - local_attr_id = crm_concat(attr_set, attr_name, '-'); - attr_id = local_attr_id; - } - - if(use_attributes_tag && safe_str_eq(tag, XML_CIB_TAG_MASTER)) { - tag = "master_slave"; /* use the old name */ - } - - xml_top = create_xml_node(NULL, tag); - crm_xml_add(xml_top, XML_ATTR_ID, rsc_id); - - xml_obj = create_xml_node(xml_top, attr_set_type); - crm_xml_add(xml_obj, XML_ATTR_ID, attr_set); - - if(use_attributes_tag) { - xml_obj = create_xml_node(xml_obj, XML_TAG_ATTRS); - } - } - + const char *value = NULL; + xmlNode *cib_top = NULL; + const char *tag = crm_element_name(rsc->xml); + + rc = cib->cmds->query(cib, "/cib", &cib_top, + cib_sync_call | cib_scope_local | cib_xpath | cib_no_children); + value = crm_element_value(cib_top, "ignore_dtd"); + if (value != NULL) { + use_attributes_tag = TRUE; + + } else { + value = crm_element_value(cib_top, XML_ATTR_VALIDATION); + if (value && strstr(value, "-0.6")) { + use_attributes_tag = TRUE; + } + } + free_xml(cib_top); + + if (attr_set == NULL) { + local_attr_set = crm_concat(rsc_id, attr_set_type, '-'); + attr_set = local_attr_set; + } + if (attr_id == NULL) { + local_attr_id = crm_concat(attr_set, attr_name, '-'); + attr_id = local_attr_id; + } + + if (use_attributes_tag && safe_str_eq(tag, XML_CIB_TAG_MASTER)) { + tag = "master_slave"; /* use the old name */ + } + + xml_top = create_xml_node(NULL, tag); + crm_xml_add(xml_top, XML_ATTR_ID, rsc_id); + + xml_obj = create_xml_node(xml_top, attr_set_type); + crm_xml_add(xml_obj, XML_ATTR_ID, attr_set); + + if (use_attributes_tag) { + xml_obj = create_xml_node(xml_obj, XML_TAG_ATTRS); + } + } + xml_obj = create_xml_node(xml_obj, XML_CIB_TAG_NVPAIR); - if(xml_top == NULL) { - xml_top = xml_obj; + if (xml_top == NULL) { + xml_top = xml_obj; } - + crm_xml_add(xml_obj, XML_ATTR_ID, attr_id); crm_xml_add(xml_obj, XML_NVPAIR_ATTR_NAME, attr_name); crm_xml_add(xml_obj, XML_NVPAIR_ATTR_VALUE, attr_value); - + crm_log_xml_debug(xml_top, "Update"); - + rc = cib->cmds->modify(cib, XML_CIB_TAG_RESOURCES, xml_top, cib_options); free_xml(xml_top); crm_free(local_attr_id); crm_free(local_attr_set); return rc; } static int -delete_resource_attr( - const char *rsc_id, const char *attr_set, const char *attr_id, - const char *attr_name, cib_t *cib, pe_working_set_t *data_set) +delete_resource_attr(const char *rsc_id, const char *attr_set, const char *attr_id, + const char *attr_name, cib_t * cib, pe_working_set_t * data_set) { xmlNode *xml_obj = NULL; int rc = cib_ok; char *local_attr_id = NULL; resource_t *rsc = find_rsc_or_clone(rsc_id, data_set); - if(rsc == NULL) { - return cib_NOTEXISTS; + if (rsc == NULL) { + return cib_NOTEXISTS; } - rc = find_resource_attr( - cib, XML_ATTR_ID, rsc_id, attr_set_type, attr_set, attr_id, attr_name, &local_attr_id); + rc = find_resource_attr(cib, XML_ATTR_ID, rsc_id, attr_set_type, attr_set, attr_id, attr_name, + &local_attr_id); - if(rc == cib_NOTEXISTS) { - return cib_ok; + if (rc == cib_NOTEXISTS) { + return cib_ok; - } else if(rc != cib_ok) { - return rc; + } else if (rc != cib_ok) { + return rc; } - - if(attr_id == NULL) { - attr_id = local_attr_id; + + if (attr_id == NULL) { + attr_id = local_attr_id; } xml_obj = create_xml_node(NULL, XML_CIB_TAG_NVPAIR); crm_xml_add(xml_obj, XML_ATTR_ID, attr_id); crm_xml_add(xml_obj, XML_NVPAIR_ATTR_NAME, attr_name); - + crm_log_xml_debug(xml_obj, "Delete"); - + rc = cib->cmds->delete(cib, XML_CIB_TAG_RESOURCES, xml_obj, cib_options); - if(rc == cib_ok) { - printf("Deleted %s option: id=%s%s%s%s%s\n", rsc_id, local_attr_id, - attr_set?" set=":"", attr_set?attr_set:"", - attr_name?" name=":"", attr_name?attr_name:""); + if (rc == cib_ok) { + printf("Deleted %s option: id=%s%s%s%s%s\n", rsc_id, local_attr_id, + attr_set ? " set=" : "", attr_set ? attr_set : "", + attr_name ? " name=" : "", attr_name ? attr_name : ""); } free_xml(xml_obj); crm_free(local_attr_id); return rc; } static int -dump_resource_prop( - const char *rsc, const char *attr, pe_working_set_t *data_set) +dump_resource_prop(const char *rsc, const char *attr, pe_working_set_t * data_set) { const char *value = NULL; resource_t *the_rsc = pe_find_resource(data_set->resources, rsc); - if(the_rsc == NULL) { - return cib_NOTEXISTS; + if (the_rsc == NULL) { + return cib_NOTEXISTS; } value = crm_element_value(the_rsc->xml, attr); - if(value != NULL) { - fprintf(stdout, "%s\n", value); - return 0; + if (value != NULL) { + fprintf(stdout, "%s\n", value); + return 0; } return cib_NOTEXISTS; } static int -send_lrm_rsc_op(IPC_Channel *crmd_channel, const char *op, - const char *host_uname, const char *rsc_id, - gboolean only_failed, pe_working_set_t *data_set) +send_lrm_rsc_op(IPC_Channel * crmd_channel, const char *op, + const char *host_uname, const char *rsc_id, + gboolean only_failed, pe_working_set_t * data_set) { char *key = NULL; int rc = cib_send_failed; xmlNode *cmd = NULL; xmlNode *xml_rsc = NULL; const char *value = NULL; xmlNode *params = NULL; xmlNode *msg_data = NULL; resource_t *rsc = pe_find_resource(data_set->resources, rsc_id); - if(rsc == NULL) { - CMD_ERR("Resource %s not found\n", rsc_id); - return cib_NOTEXISTS; + if (rsc == NULL) { + CMD_ERR("Resource %s not found\n", rsc_id); + return cib_NOTEXISTS; - } else if(rsc->variant != pe_native) { - CMD_ERR("We can only process primitive resources, not %s\n", rsc_id); - return cib_invalid_argument; + } else if (rsc->variant != pe_native) { + CMD_ERR("We can only process primitive resources, not %s\n", rsc_id); + return cib_invalid_argument; - } else if(host_uname == NULL) { - CMD_ERR("Please supply a hostname with -H\n"); - return cib_invalid_argument; + } else if (host_uname == NULL) { + CMD_ERR("Please supply a hostname with -H\n"); + return cib_invalid_argument; } - + key = crm_concat("0:0:crm-resource", our_pid, '-'); - + msg_data = create_xml_node(NULL, XML_GRAPH_TAG_RSC_OP); crm_xml_add(msg_data, XML_ATTR_TRANSITION_KEY, key); crm_free(key); - + xml_rsc = create_xml_node(msg_data, XML_CIB_TAG_RESOURCE); - if(rsc->clone_name) { - crm_xml_add(xml_rsc, XML_ATTR_ID, rsc->clone_name); - crm_xml_add(xml_rsc, XML_ATTR_ID_LONG, rsc->id); - + if (rsc->clone_name) { + crm_xml_add(xml_rsc, XML_ATTR_ID, rsc->clone_name); + crm_xml_add(xml_rsc, XML_ATTR_ID_LONG, rsc->id); + } else { - crm_xml_add(xml_rsc, XML_ATTR_ID, rsc->id); - crm_xml_add(xml_rsc, XML_ATTR_ID_LONG, rsc->long_name); + crm_xml_add(xml_rsc, XML_ATTR_ID, rsc->id); + crm_xml_add(xml_rsc, XML_ATTR_ID_LONG, rsc->long_name); } - + value = crm_element_value(rsc->xml, XML_ATTR_TYPE); crm_xml_add(xml_rsc, XML_ATTR_TYPE, value); - if(value == NULL) { - CMD_ERR("%s has no type! Aborting...\n", rsc_id); - return cib_NOTEXISTS; + if (value == NULL) { + CMD_ERR("%s has no type! Aborting...\n", rsc_id); + return cib_NOTEXISTS; } value = crm_element_value(rsc->xml, XML_AGENT_ATTR_CLASS); crm_xml_add(xml_rsc, XML_AGENT_ATTR_CLASS, value); - if(value == NULL) { - CMD_ERR("%s has no class! Aborting...\n", rsc_id); - return cib_NOTEXISTS; + if (value == NULL) { + CMD_ERR("%s has no class! Aborting...\n", rsc_id); + return cib_NOTEXISTS; } value = crm_element_value(rsc->xml, XML_AGENT_ATTR_PROVIDER); crm_xml_add(xml_rsc, XML_AGENT_ATTR_PROVIDER, value); params = create_xml_node(msg_data, XML_TAG_ATTRS); crm_xml_add(params, XML_ATTR_CRM_VERSION, CRM_FEATURE_SET); key = crm_meta_name(XML_LRM_ATTR_INTERVAL); - crm_xml_add(params, key, "60000"); /* 1 minute */ + crm_xml_add(params, key, "60000"); /* 1 minute */ crm_free(key); - - cmd = create_request(op, msg_data, host_uname, - CRM_SYSTEM_CRMD, crm_system_name, our_pid); -/* crm_log_xml_warn(cmd, "send_lrm_rsc_op"); */ + cmd = create_request(op, msg_data, host_uname, CRM_SYSTEM_CRMD, crm_system_name, our_pid); + +/* crm_log_xml_warn(cmd, "send_lrm_rsc_op"); */ free_xml(msg_data); - if(send_ipc_message(crmd_channel, cmd)) { - rc = 0; + if (send_ipc_message(crmd_channel, cmd)) { + rc = 0; } else { - CMD_ERR("Could not send %s op to the crmd", op); - rc = cib_connection; + CMD_ERR("Could not send %s op to the crmd", op); + rc = cib_connection; } - + free_xml(cmd); return rc; } - static int -delete_lrm_rsc(IPC_Channel *crmd_channel, const char *host_uname, - resource_t *rsc, pe_working_set_t *data_set) +delete_lrm_rsc(IPC_Channel * crmd_channel, const char *host_uname, + resource_t * rsc, pe_working_set_t * data_set) { int rc = cib_ok; - - if(rsc == NULL) { - return cib_NOTEXISTS; - - } else if(rsc->children) { - GListPtr lpc = NULL; - for(lpc = rsc->children; lpc != NULL; lpc = lpc->next) { - resource_t *child = (resource_t*)lpc->data; - - delete_lrm_rsc(crmd_channel, host_uname, child, data_set); - } - return cib_ok; - - } else if(host_uname == NULL) { - GListPtr lpc = NULL; - for(lpc = data_set->nodes; lpc != NULL; lpc = lpc->next) { - node_t *node = (node_t*)lpc->data; - - if(node->details->online) { - delete_lrm_rsc(crmd_channel, node->details->uname, rsc, data_set); - } - } - - return cib_ok; + + if (rsc == NULL) { + return cib_NOTEXISTS; + + } else if (rsc->children) { + GListPtr lpc = NULL; + + for (lpc = rsc->children; lpc != NULL; lpc = lpc->next) { + resource_t *child = (resource_t *) lpc->data; + + delete_lrm_rsc(crmd_channel, host_uname, child, data_set); + } + return cib_ok; + + } else if (host_uname == NULL) { + GListPtr lpc = NULL; + + for (lpc = data_set->nodes; lpc != NULL; lpc = lpc->next) { + node_t *node = (node_t *) lpc->data; + + if (node->details->online) { + delete_lrm_rsc(crmd_channel, node->details->uname, rsc, data_set); + } + } + + return cib_ok; } printf("Cleaning up %s on %s\n", rsc->id, host_uname); rc = send_lrm_rsc_op(crmd_channel, CRM_OP_LRM_DELETE, host_uname, rsc->id, TRUE, data_set); - if(rc == cib_ok) { - char *attr_name = NULL; - const char *id = rsc->id; - - crmd_replies_needed++; - if(rsc->clone_name) { - id = rsc->clone_name; - } - - attr_name = crm_concat("fail-count", id, '-'); - attrd_lazy_update('D', host_uname, attr_name, NULL, XML_CIB_TAG_STATUS, NULL, NULL); - crm_free(attr_name); + if (rc == cib_ok) { + char *attr_name = NULL; + const char *id = rsc->id; + + crmd_replies_needed++; + if (rsc->clone_name) { + id = rsc->clone_name; + } + + attr_name = crm_concat("fail-count", id, '-'); + attrd_lazy_update('D', host_uname, attr_name, NULL, XML_CIB_TAG_STATUS, NULL, NULL); + crm_free(attr_name); } return rc; } static int -fail_lrm_rsc(IPC_Channel *crmd_channel, const char *host_uname, - const char *rsc_id, pe_working_set_t *data_set) +fail_lrm_rsc(IPC_Channel * crmd_channel, const char *host_uname, + const char *rsc_id, pe_working_set_t * data_set) { crm_warn("Failing: %s", rsc_id); #if HAVE_STRUCT_LRM_OPS_FAIL_RSC crmd_replies_needed++; #endif - return send_lrm_rsc_op(crmd_channel, CRM_OP_LRM_FAIL, host_uname, rsc_id, FALSE, data_set); + return send_lrm_rsc_op(crmd_channel, CRM_OP_LRM_FAIL, host_uname, rsc_id, FALSE, data_set); } static int -refresh_lrm(IPC_Channel *crmd_channel, const char *host_uname) +refresh_lrm(IPC_Channel * crmd_channel, const char *host_uname) { xmlNode *cmd = NULL; int rc = cib_send_failed; - + cmd = create_request(CRM_OP_LRM_REFRESH, NULL, host_uname, - CRM_SYSTEM_CRMD, crm_system_name, our_pid); - - if(send_ipc_message(crmd_channel, cmd)) { - rc = 0; + CRM_SYSTEM_CRMD, crm_system_name, our_pid); + + if (send_ipc_message(crmd_channel, cmd)) { + rc = 0; } free_xml(cmd); return rc; } static int -move_resource( - const char *rsc_id, - const char *existing_node, const char *preferred_node, - cib_t * cib_conn) +move_resource(const char *rsc_id, + const char *existing_node, const char *preferred_node, cib_t * cib_conn) { char *later_s = NULL; enum cib_errors rc = cib_ok; char *id = NULL; xmlNode *rule = NULL; xmlNode *expr = NULL; xmlNode *constraints = NULL; xmlNode *fragment = NULL; - + xmlNode *can_run = NULL; xmlNode *dont_run = NULL; fragment = create_xml_node(NULL, XML_CIB_TAG_CONSTRAINTS); constraints = fragment; id = crm_concat("cli-prefer", rsc_id, '-'); can_run = create_xml_node(NULL, XML_CONS_TAG_RSC_LOCATION); crm_xml_add(can_run, XML_ATTR_ID, id); crm_free(id); id = crm_concat("cli-standby", rsc_id, '-'); dont_run = create_xml_node(NULL, XML_CONS_TAG_RSC_LOCATION); crm_xml_add(dont_run, XML_ATTR_ID, id); crm_free(id); - if(move_lifetime) { - char *life = crm_strdup(move_lifetime); - char *life_mutable = life; - - ha_time_t *now = NULL; - ha_time_t *later = NULL; - ha_time_t *duration = parse_time_duration(&life_mutable); - - if(duration == NULL) { - CMD_ERR("Invalid duration specified: %s\n", - move_lifetime); - CMD_ERR("Please refer to" - " http://en.wikipedia.org/wiki/ISO_8601#Duration" - " for examples of valid durations\n"); - crm_free(life); - return cib_invalid_argument; - } - now = new_ha_date(TRUE); - later = add_time(now, duration); - log_date(LOG_INFO, "now ", now, ha_log_date|ha_log_time); - log_date(LOG_INFO, "later ", later, ha_log_date|ha_log_time); - log_date(LOG_INFO, "duration", duration, ha_log_date|ha_log_time|ha_log_local); - later_s = date_to_string(later, ha_log_date|ha_log_time); - printf("Migration will take effect until: %s\n", later_s); - - free_ha_date(duration); - free_ha_date(later); - free_ha_date(now); - crm_free(life); - } - - if(existing_node == NULL) { - crm_log_xml_notice(can_run, "Deleting"); - rc = cib_conn->cmds->delete( - cib_conn, XML_CIB_TAG_CONSTRAINTS, dont_run, cib_options); - if(rc == cib_NOTEXISTS) { - rc = cib_ok; - - } else if(rc != cib_ok) { - goto bail; - } + if (move_lifetime) { + char *life = crm_strdup(move_lifetime); + char *life_mutable = life; + + ha_time_t *now = NULL; + ha_time_t *later = NULL; + ha_time_t *duration = parse_time_duration(&life_mutable); + + if (duration == NULL) { + CMD_ERR("Invalid duration specified: %s\n", move_lifetime); + CMD_ERR("Please refer to" + " http://en.wikipedia.org/wiki/ISO_8601#Duration" + " for examples of valid durations\n"); + crm_free(life); + return cib_invalid_argument; + } + now = new_ha_date(TRUE); + later = add_time(now, duration); + log_date(LOG_INFO, "now ", now, ha_log_date | ha_log_time); + log_date(LOG_INFO, "later ", later, ha_log_date | ha_log_time); + log_date(LOG_INFO, "duration", duration, ha_log_date | ha_log_time | ha_log_local); + later_s = date_to_string(later, ha_log_date | ha_log_time); + printf("Migration will take effect until: %s\n", later_s); + + free_ha_date(duration); + free_ha_date(later); + free_ha_date(now); + crm_free(life); + } + + if (existing_node == NULL) { + crm_log_xml_notice(can_run, "Deleting"); + rc = cib_conn->cmds->delete(cib_conn, XML_CIB_TAG_CONSTRAINTS, dont_run, cib_options); + if (rc == cib_NOTEXISTS) { + rc = cib_ok; + + } else if (rc != cib_ok) { + goto bail; + } } else { - if(BE_QUIET == FALSE) { - fprintf(stderr, - "WARNING: Creating rsc_location constraint '%s'" - " with a score of -INFINITY for resource %s" - " on %s.\n", - ID(dont_run), rsc_id, existing_node); - CMD_ERR("\tThis will prevent %s from running" - " on %s until the constraint is removed using" - " the 'crm_resource -U' command or manually" - " with cibadmin\n", rsc_id, existing_node); - CMD_ERR("\tThis will be the case even if %s is" - " the last node in the cluster\n", existing_node); - CMD_ERR("\tThis message can be disabled with -Q\n"); - } - - crm_xml_add(dont_run, "rsc", rsc_id); - - rule = create_xml_node(dont_run, XML_TAG_RULE); - expr = create_xml_node(rule, XML_TAG_EXPRESSION); - id = crm_concat("cli-standby-rule", rsc_id, '-'); - crm_xml_add(rule, XML_ATTR_ID, id); - crm_free(id); - - crm_xml_add(rule, XML_RULE_ATTR_SCORE, MINUS_INFINITY_S); - crm_xml_add(rule, XML_RULE_ATTR_BOOLEAN_OP, "and"); - - id = crm_concat("cli-standby-expr", rsc_id, '-'); - crm_xml_add(expr, XML_ATTR_ID, id); - crm_free(id); - - crm_xml_add(expr, XML_EXPR_ATTR_ATTRIBUTE, "#uname"); - crm_xml_add(expr, XML_EXPR_ATTR_OPERATION, "eq"); - crm_xml_add(expr, XML_EXPR_ATTR_VALUE, existing_node); - crm_xml_add(expr, XML_EXPR_ATTR_TYPE, "string"); - - if(later_s) { - expr = create_xml_node(rule, "date_expression"); - id = crm_concat("cli-standby-lifetime-end",rsc_id,'-'); - crm_xml_add(expr, XML_ATTR_ID, id); - crm_free(id); - - crm_xml_add(expr, "operation", "lt"); - crm_xml_add(expr, "end", later_s); - } - - add_node_copy(constraints, dont_run); - } - - if(preferred_node == NULL) { - crm_log_xml_notice(can_run, "Deleting"); - rc = cib_conn->cmds->delete( - cib_conn, XML_CIB_TAG_CONSTRAINTS, can_run, cib_options); - if(rc == cib_NOTEXISTS) { - rc = cib_ok; - - } else if(rc != cib_ok) { - goto bail; - } + if (BE_QUIET == FALSE) { + fprintf(stderr, + "WARNING: Creating rsc_location constraint '%s'" + " with a score of -INFINITY for resource %s" + " on %s.\n", ID(dont_run), rsc_id, existing_node); + CMD_ERR("\tThis will prevent %s from running" + " on %s until the constraint is removed using" + " the 'crm_resource -U' command or manually" + " with cibadmin\n", rsc_id, existing_node); + CMD_ERR("\tThis will be the case even if %s is" + " the last node in the cluster\n", existing_node); + CMD_ERR("\tThis message can be disabled with -Q\n"); + } + + crm_xml_add(dont_run, "rsc", rsc_id); + + rule = create_xml_node(dont_run, XML_TAG_RULE); + expr = create_xml_node(rule, XML_TAG_EXPRESSION); + id = crm_concat("cli-standby-rule", rsc_id, '-'); + crm_xml_add(rule, XML_ATTR_ID, id); + crm_free(id); + + crm_xml_add(rule, XML_RULE_ATTR_SCORE, MINUS_INFINITY_S); + crm_xml_add(rule, XML_RULE_ATTR_BOOLEAN_OP, "and"); + + id = crm_concat("cli-standby-expr", rsc_id, '-'); + crm_xml_add(expr, XML_ATTR_ID, id); + crm_free(id); + + crm_xml_add(expr, XML_EXPR_ATTR_ATTRIBUTE, "#uname"); + crm_xml_add(expr, XML_EXPR_ATTR_OPERATION, "eq"); + crm_xml_add(expr, XML_EXPR_ATTR_VALUE, existing_node); + crm_xml_add(expr, XML_EXPR_ATTR_TYPE, "string"); + + if (later_s) { + expr = create_xml_node(rule, "date_expression"); + id = crm_concat("cli-standby-lifetime-end", rsc_id, '-'); + crm_xml_add(expr, XML_ATTR_ID, id); + crm_free(id); + + crm_xml_add(expr, "operation", "lt"); + crm_xml_add(expr, "end", later_s); + } + + add_node_copy(constraints, dont_run); + } + + if (preferred_node == NULL) { + crm_log_xml_notice(can_run, "Deleting"); + rc = cib_conn->cmds->delete(cib_conn, XML_CIB_TAG_CONSTRAINTS, can_run, cib_options); + if (rc == cib_NOTEXISTS) { + rc = cib_ok; + + } else if (rc != cib_ok) { + goto bail; + } } else { - crm_xml_add(can_run, "rsc", rsc_id); - - rule = create_xml_node(can_run, XML_TAG_RULE); - expr = create_xml_node(rule, XML_TAG_EXPRESSION); - id = crm_concat("cli-prefer-rule", rsc_id, '-'); - crm_xml_add(rule, XML_ATTR_ID, id); - crm_free(id); - - crm_xml_add(rule, XML_RULE_ATTR_SCORE, INFINITY_S); - crm_xml_add(rule, XML_RULE_ATTR_BOOLEAN_OP, "and"); - - id = crm_concat("cli-prefer-expr", rsc_id, '-'); - crm_xml_add(expr, XML_ATTR_ID, id); - crm_free(id); - - crm_xml_add(expr, XML_EXPR_ATTR_ATTRIBUTE, "#uname"); - crm_xml_add(expr, XML_EXPR_ATTR_OPERATION, "eq"); - crm_xml_add(expr, XML_EXPR_ATTR_VALUE, preferred_node); - crm_xml_add(expr, XML_EXPR_ATTR_TYPE, "string"); - - if(later_s) { - expr = create_xml_node(rule, "date_expression"); - id = crm_concat("cli-prefer-lifetime-end", rsc_id, '-'); - crm_xml_add(expr, XML_ATTR_ID, id); - crm_free(id); - - crm_xml_add(expr, "operation", "lt"); - crm_xml_add(expr, "end", later_s); - } - - add_node_copy(constraints, can_run); - } - - if(preferred_node != NULL || existing_node != NULL) { - crm_log_xml_notice(fragment, "CLI Update"); - rc = cib_conn->cmds->update( - cib_conn, XML_CIB_TAG_CONSTRAINTS, fragment, cib_options); + crm_xml_add(can_run, "rsc", rsc_id); + + rule = create_xml_node(can_run, XML_TAG_RULE); + expr = create_xml_node(rule, XML_TAG_EXPRESSION); + id = crm_concat("cli-prefer-rule", rsc_id, '-'); + crm_xml_add(rule, XML_ATTR_ID, id); + crm_free(id); + + crm_xml_add(rule, XML_RULE_ATTR_SCORE, INFINITY_S); + crm_xml_add(rule, XML_RULE_ATTR_BOOLEAN_OP, "and"); + + id = crm_concat("cli-prefer-expr", rsc_id, '-'); + crm_xml_add(expr, XML_ATTR_ID, id); + crm_free(id); + + crm_xml_add(expr, XML_EXPR_ATTR_ATTRIBUTE, "#uname"); + crm_xml_add(expr, XML_EXPR_ATTR_OPERATION, "eq"); + crm_xml_add(expr, XML_EXPR_ATTR_VALUE, preferred_node); + crm_xml_add(expr, XML_EXPR_ATTR_TYPE, "string"); + + if (later_s) { + expr = create_xml_node(rule, "date_expression"); + id = crm_concat("cli-prefer-lifetime-end", rsc_id, '-'); + crm_xml_add(expr, XML_ATTR_ID, id); + crm_free(id); + + crm_xml_add(expr, "operation", "lt"); + crm_xml_add(expr, "end", later_s); + } + + add_node_copy(constraints, can_run); + } + + if (preferred_node != NULL || existing_node != NULL) { + crm_log_xml_notice(fragment, "CLI Update"); + rc = cib_conn->cmds->update(cib_conn, XML_CIB_TAG_CONSTRAINTS, fragment, cib_options); } bail: free_xml(fragment); free_xml(dont_run); free_xml(can_run); crm_free(later_s); return rc; } static int -list_resource_operations( - const char *rsc_id, const char *host_uname, gboolean active, pe_working_set_t *data_set) +list_resource_operations(const char *rsc_id, const char *host_uname, gboolean active, + pe_working_set_t * data_set) { resource_t *rsc = NULL; - int opts = pe_print_printf|pe_print_rsconly|pe_print_suppres_nl; + int opts = pe_print_printf | pe_print_rsconly | pe_print_suppres_nl; GListPtr ops = find_operations(rsc_id, host_uname, active, data_set); GListPtr lpc = NULL; - for(lpc = ops; lpc != NULL; lpc = lpc->next) { - xmlNode *xml_op = (xmlNode*)lpc->data; - - const char *op_rsc = crm_element_value(xml_op, "resource"); - const char *last = crm_element_value(xml_op, "last_run"); - const char *status_s = crm_element_value(xml_op, XML_LRM_ATTR_OPSTATUS); - const char *op_key = crm_element_value(xml_op, XML_LRM_ATTR_TASK_KEY); - int status = crm_parse_int(status_s, "0"); - - rsc = pe_find_resource(data_set->resources, op_rsc); - rsc->fns->print(rsc, "", opts, stdout); - - fprintf(stdout, ": %s (node=%s, call=%s, rc=%s", - op_key?op_key:ID(xml_op), - crm_element_value(xml_op, XML_ATTR_UNAME), - crm_element_value(xml_op, XML_LRM_ATTR_CALLID), - crm_element_value(xml_op, XML_LRM_ATTR_RC)); - if(last) { - time_t run_at = crm_parse_int(last, "0"); - fprintf(stdout, ", last-run=%s, exec=%sms\n", - ctime(&run_at), crm_element_value(xml_op, "exec_time")); - } - fprintf(stdout, "): %s\n", op_status2text(status)); + + for (lpc = ops; lpc != NULL; lpc = lpc->next) { + xmlNode *xml_op = (xmlNode *) lpc->data; + + const char *op_rsc = crm_element_value(xml_op, "resource"); + const char *last = crm_element_value(xml_op, "last_run"); + const char *status_s = crm_element_value(xml_op, XML_LRM_ATTR_OPSTATUS); + const char *op_key = crm_element_value(xml_op, XML_LRM_ATTR_TASK_KEY); + int status = crm_parse_int(status_s, "0"); + + rsc = pe_find_resource(data_set->resources, op_rsc); + rsc->fns->print(rsc, "", opts, stdout); + + fprintf(stdout, ": %s (node=%s, call=%s, rc=%s", + op_key ? op_key : ID(xml_op), + crm_element_value(xml_op, XML_ATTR_UNAME), + crm_element_value(xml_op, XML_LRM_ATTR_CALLID), + crm_element_value(xml_op, XML_LRM_ATTR_RC)); + if (last) { + time_t run_at = crm_parse_int(last, "0"); + + fprintf(stdout, ", last-run=%s, exec=%sms\n", + ctime(&run_at), crm_element_value(xml_op, "exec_time")); + } + fprintf(stdout, "): %s\n", op_status2text(status)); } return cib_ok; } #include "../pengine/pengine.h" -static void show_location(resource_t *rsc, const char *prefix) +static void +show_location(resource_t * rsc, const char *prefix) { GListPtr lpc = NULL; GListPtr list = rsc->rsc_location; int offset = 0; - if(prefix) { - offset = strlen(prefix) - 2; + + if (prefix) { + offset = strlen(prefix) - 2; } - - for(lpc = list; lpc != NULL; lpc = lpc->next) { - rsc_to_node_t *cons = (rsc_to_node_t*)lpc->data; - - GListPtr lpc2 = NULL; - for(lpc2 = cons->node_list_rh; lpc2 != NULL; lpc2 = lpc2->next) { - node_t *node = (node_t*)lpc2->data; - char *score = score2char(node->weight); - fprintf(stdout, "%s: Node %-*s (score=%s, id=%s)\n", - prefix?prefix:" ", 71-offset, node->details->uname, score, cons->id); - crm_free(score); - } + + for (lpc = list; lpc != NULL; lpc = lpc->next) { + rsc_to_node_t *cons = (rsc_to_node_t *) lpc->data; + + GListPtr lpc2 = NULL; + + for (lpc2 = cons->node_list_rh; lpc2 != NULL; lpc2 = lpc2->next) { + node_t *node = (node_t *) lpc2->data; + char *score = score2char(node->weight); + + fprintf(stdout, "%s: Node %-*s (score=%s, id=%s)\n", + prefix ? prefix : " ", 71 - offset, node->details->uname, score, cons->id); + crm_free(score); + } } } - -static void show_colocation(resource_t *rsc, gboolean dependants, gboolean recursive, int offset) +static void +show_colocation(resource_t * rsc, gboolean dependants, gboolean recursive, int offset) { char *prefix = NULL; GListPtr lpc = NULL; GListPtr list = rsc->rsc_cons; - crm_malloc0(prefix, (offset*4) + 1); - memset(prefix, ' ', offset*4); + crm_malloc0(prefix, (offset * 4) + 1); + memset(prefix, ' ', offset * 4); - if(dependants) { - list = rsc->rsc_cons_lhs; + if (dependants) { + list = rsc->rsc_cons_lhs; } - - if(is_set(rsc->flags, pe_rsc_allocating)) { - /* Break colocation loops */ - printf("loop %s\n", rsc->id); - crm_free(prefix); - return; + + if (is_set(rsc->flags, pe_rsc_allocating)) { + /* Break colocation loops */ + printf("loop %s\n", rsc->id); + crm_free(prefix); + return; } - + set_bit(rsc->flags, pe_rsc_allocating); - for(lpc = list; lpc != NULL; lpc = lpc->next) { - rsc_colocation_t *cons = (rsc_colocation_t*)lpc->data; - - char *score = NULL; - resource_t *peer = cons->rsc_rh; - - if(dependants) { - peer = cons->rsc_lh; - } - - if(is_set(peer->flags, pe_rsc_allocating)) { - if(dependants == FALSE) { - fprintf(stdout, "%s%-*s (id=%s - loop)\n", prefix, 80-(4*offset), peer->id, cons->id); - } - continue; - } - - if(dependants && recursive) { - show_colocation(peer, dependants, recursive, offset+1); - } - - score = score2char(cons->score); - if(cons->role_rh > RSC_ROLE_STARTED) { - fprintf(stdout, "%s%-*s (score=%s, %s role=%s, id=%s)\n", prefix, 80-(4*offset), - peer->id, score, dependants?"needs":"with", role2text(cons->role_rh), cons->id); - } else { - fprintf(stdout, "%s%-*s (score=%s, id=%s)\n", prefix, 80-(4*offset), - peer->id, score, cons->id); - } - show_location(peer, prefix); - crm_free(score); - - if(!dependants && recursive) { - show_colocation(peer, dependants, recursive, offset+1); - } + for (lpc = list; lpc != NULL; lpc = lpc->next) { + rsc_colocation_t *cons = (rsc_colocation_t *) lpc->data; + + char *score = NULL; + resource_t *peer = cons->rsc_rh; + + if (dependants) { + peer = cons->rsc_lh; + } + + if (is_set(peer->flags, pe_rsc_allocating)) { + if (dependants == FALSE) { + fprintf(stdout, "%s%-*s (id=%s - loop)\n", prefix, 80 - (4 * offset), peer->id, + cons->id); + } + continue; + } + + if (dependants && recursive) { + show_colocation(peer, dependants, recursive, offset + 1); + } + + score = score2char(cons->score); + if (cons->role_rh > RSC_ROLE_STARTED) { + fprintf(stdout, "%s%-*s (score=%s, %s role=%s, id=%s)\n", prefix, 80 - (4 * offset), + peer->id, score, dependants ? "needs" : "with", role2text(cons->role_rh), + cons->id); + } else { + fprintf(stdout, "%s%-*s (score=%s, id=%s)\n", prefix, 80 - (4 * offset), + peer->id, score, cons->id); + } + show_location(peer, prefix); + crm_free(score); + + if (!dependants && recursive) { + show_colocation(peer, dependants, recursive, offset + 1); + } } crm_free(prefix); -} +} /* *INDENT-OFF* */ static struct crm_option long_options[] = { /* Top-level Options */ {"help", 0, 0, '?', "\t\tThis text"}, {"version", 0, 0, '$', "\t\tVersion information" }, {"verbose", 0, 0, 'V', "\t\tIncrease debug output"}, {"quiet", 0, 0, 'Q', "\t\tPrint only the value on stdout\n"}, {"resource", 1, 0, 'r', "\tResource ID" }, {"-spacer-",1, 0, '-', "\nQueries:"}, {"list", 0, 0, 'L', "\t\tList all resources"}, {"list-raw", 0, 0, 'l', "\tList the IDs of all instantiated resources (no groups/clones/...)"}, {"list-cts", 0, 0, 'c', NULL, 1}, {"list-operations", 0, 0, 'O', "\tList active resource operations. Optionally filtered by resource (-r) and/or node (-N)"}, {"list-all-operations", 0, 0, 'o', "List all resource operations. Optionally filtered by resource (-r) and/or node (-N)\n"}, {"query-xml", 0, 0, 'q', "\tQuery the definition of a resource (template expanded)"}, {"query-xml-raw", 0, 0, 'w', "\tQuery the definition of a resource (raw xml)"}, {"locate", 0, 0, 'W', "\t\tDisplay the current location(s) of a resource"}, {"stack", 0, 0, 'A', "\t\tDisplay the prerequisites and dependents of a resource"}, {"constraints",0, 0, 'a', "\tDisplay the (co)location constraints that apply to a resource"}, {"-spacer-", 1, 0, '-', "\nCommands:"}, {"set-parameter", 1, 0, 'p', "Set the named parameter for a resource. See also -m, --meta"}, {"get-parameter", 1, 0, 'g', "Display the named parameter for a resource. See also -m, --meta"}, {"delete-parameter",1, 0, 'd', "Delete the named parameter for a resource. See also -m, --meta"}, {"get-property", 1, 0, 'G', "Display the 'class', 'type' or 'provider' of a resource", 1}, {"set-property", 1, 0, 'S', "(Advanced) Set the class, type or provider of a resource", 1}, {"move", 0, 0, 'M', "\t\tMove a resource from its current location, optionally specifying a destination (-N) and/or a period for which it should take effect (-u)" "\n\t\t\t\tIf -N is not specified, the cluster will force the resource to move by creating a rule for the current location and a score of -INFINITY" "\n\t\t\t\tNOTE: This will prevent the resource from running on this node until the constraint is removed with -U"}, {"un-move", 0, 0, 'U', "\tRemove all constraints created by a move command"}, {"-spacer-", 1, 0, '-', "\nAdvanced Commands:"}, {"delete", 0, 0, 'D', "\t\tDelete a resource from the CIB"}, {"fail", 0, 0, 'F', "\t\tTell the cluster this resource has failed"}, {"refresh", 0, 0, 'R', "\t\t(Advanced) Refresh the CIB from the LRM"}, {"cleanup", 0, 0, 'C', "\t\t(Advanced) Delete a resource from the LRM"}, {"reprobe", 0, 0, 'P', "\t\t(Advanced) Re-check for resources started outside of the CRM\n"}, {"-spacer-", 1, 0, '-', "\nAdditional Options:"}, {"node", 1, 0, 'N', "\tHost uname"}, {"resource-type", 1, 0, 't', "Resource type (primitive, clone, group, ...)"}, {"parameter-value", 1, 0, 'v', "Value to use with -p, -g or -d"}, {"lifetime", 1, 0, 'u', "\tLifespan of migration constraints\n"}, {"meta", 0, 0, 'm', "\t\tModify a resource's configuration option rather than one which is passed to the resource agent script. For use with -p, -g, -d"}, {"utilization", 0, 0, 'z', "\tModify a resource's utilization attribute. For use with -p, -g, -d"}, {"set-name", 1, 0, 's', "\t(Advanced) ID of the instance_attributes object to change"}, {"nvpair", 1, 0, 'i', "\t(Advanced) ID of the nvpair object to change/delete"}, {"force", 0, 0, 'f', "\n" /* Is this actually true anymore? "\t\tForce the resource to move by creating a rule for the current location and a score of -INFINITY" "\n\t\tThis should be used if the resource's stickiness and constraint scores total more than INFINITY (Currently 100,000)" "\n\t\tNOTE: This will prevent the resource from running on this node until the constraint is removed with -U or the --lifetime duration expires\n"*/ }, {"xml-file", 1, 0, 'x', NULL, 1},\ /* legacy options */ {"host-uname", 1, 0, 'H', NULL, 1}, {"migrate", 0, 0, 'M', NULL, 1}, {"un-migrate", 0, 0, 'U', NULL, 1}, {"-spacer-", 1, 0, '-', "\nExamples:", pcmk_option_paragraph}, {"-spacer-", 1, 0, '-', "List the configured resources:", pcmk_option_paragraph}, {"-spacer-", 1, 0, '-', " crm_resource --list", pcmk_option_example}, {"-spacer-", 1, 0, '-', "Display the current location of 'myResource':", pcmk_option_paragraph}, {"-spacer-", 1, 0, '-', " crm_resource --resource myResource --locate", pcmk_option_example}, {"-spacer-", 1, 0, '-', "Move 'myResource' to another machine:", pcmk_option_paragraph}, {"-spacer-", 1, 0, '-', " crm_resource --resource myResource --move", pcmk_option_example}, {"-spacer-", 1, 0, '-', "Move 'myResource' to a specific machine:", pcmk_option_paragraph}, {"-spacer-", 1, 0, '-', " crm_resource --resource myResource --move --node altNode", pcmk_option_example}, {"-spacer-", 1, 0, '-', "Allow (but not force) 'myResource' to move back to its original location:", pcmk_option_paragraph}, {"-spacer-", 1, 0, '-', " crm_resource --resource myResource --un-move", pcmk_option_example}, {"-spacer-", 1, 0, '-', "Tell the cluster that 'myResource' failed:", pcmk_option_paragraph}, {"-spacer-", 1, 0, '-', " crm_resource --resource myResource --fail", pcmk_option_example}, {"-spacer-", 1, 0, '-', "Stop a 'myResource' (and anything that depends on it):", pcmk_option_paragraph}, {"-spacer-", 1, 0, '-', " crm_resource --resource myResource --set-parameter target-role --meta --parameter-value Stopped", pcmk_option_example}, {"-spacer-", 1, 0, '-', "Tell the cluster not to manage 'myResource':", pcmk_option_paragraph}, {"-spacer-", 1, 0, '-', "The cluster will not attempt to start or stop the resource under any circumstances."}, {"-spacer-", 1, 0, '-', "Useful when performing maintenance tasks on a resource.", pcmk_option_paragraph}, {"-spacer-", 1, 0, '-', " crm_resource --resource myResource --set-parameter is-managed --meta --parameter-value false", pcmk_option_example}, {"-spacer-", 1, 0, '-', "Erase the operation history of 'myResource' on 'aNode':", pcmk_option_paragraph}, {"-spacer-", 1, 0, '-', "The cluster will 'forget' the existing resource state (including any errors) and attempt to recover the resource."}, {"-spacer-", 1, 0, '-', "Useful when a resource had failed permanently and has been repaired by an administrator.", pcmk_option_paragraph}, {"-spacer-", 1, 0, '-', " crm_resource --resource myResource --cleanup --node aNode", pcmk_option_example}, {0, 0, 0, 0} }; /* *INDENT-ON* */ int main(int argc, char **argv) { pe_working_set_t data_set; xmlNode *cib_xml_copy = NULL; - cib_t * cib_conn = NULL; + cib_t *cib_conn = NULL; enum cib_errors rc = cib_ok; gboolean need_cib = TRUE; int option_index = 0; int argerr = 0; int flag; crm_log_init(NULL, LOG_ERR, FALSE, FALSE, argc, argv); crm_set_options(NULL, "(query|command) [options]", long_options, - "Perform tasks related to cluster resources.\n Allows resources to be queried (definition and location), modified, and moved around the cluster.\n"); + "Perform tasks related to cluster resources.\n Allows resources to be queried (definition and location), modified, and moved around the cluster.\n"); - if(argc < 2) { - crm_help('?', LSB_EXIT_EINVAL); + if (argc < 2) { + crm_help('?', LSB_EXIT_EINVAL); } while (1) { - flag = crm_get_option(argc, argv, &option_index); - if (flag == -1) - break; - - switch(flag) { - case 'V': - cl_log_enable_stderr(TRUE); - alter_debug(DEBUG_INC); - break; - case '$': - case '?': - crm_help(flag, LSB_EXIT_OK); - break; - case 'x': - xml_file = crm_strdup(optarg); - break; - case 'Q': - BE_QUIET = TRUE; - break; - case 'm': - attr_set_type = XML_TAG_META_SETS; - break; - case 'z': - attr_set_type = XML_TAG_UTILIZATION; - break; - case 'u': - move_lifetime = crm_strdup(optarg); - break; - case 'f': - do_force = TRUE; - break; - case 'i': - prop_id = optarg; - break; - case 's': - prop_set = optarg; - break; - case 'r': - rsc_id = optarg; - break; - case 'v': - prop_value = optarg; - break; - case 't': - rsc_type = optarg; - break; - case 'R': - case 'P': - need_cib = FALSE; - rsc_cmd = flag; - break; - case 'L': - case 'c': - case 'l': - case 'q': - case 'w': - case 'D': - case 'F': - case 'C': - case 'W': - case 'M': - case 'U': - case 'O': - case 'o': - case 'A': - case 'a': - rsc_cmd = flag; - break; - case 'p': - case 'g': - case 'd': - case 'S': - case 'G': - prop_name = optarg; - rsc_cmd = flag; - break; - case 'h': - case 'H': - case 'N': - crm_debug_2("Option %c => %s", flag, optarg); - host_uname = optarg; - break; - - default: - CMD_ERR("Argument code 0%o (%c) is not (?yet?) supported\n", flag, flag); - ++argerr; - break; - } + flag = crm_get_option(argc, argv, &option_index); + if (flag == -1) + break; + + switch (flag) { + case 'V': + cl_log_enable_stderr(TRUE); + alter_debug(DEBUG_INC); + break; + case '$': + case '?': + crm_help(flag, LSB_EXIT_OK); + break; + case 'x': + xml_file = crm_strdup(optarg); + break; + case 'Q': + BE_QUIET = TRUE; + break; + case 'm': + attr_set_type = XML_TAG_META_SETS; + break; + case 'z': + attr_set_type = XML_TAG_UTILIZATION; + break; + case 'u': + move_lifetime = crm_strdup(optarg); + break; + case 'f': + do_force = TRUE; + break; + case 'i': + prop_id = optarg; + break; + case 's': + prop_set = optarg; + break; + case 'r': + rsc_id = optarg; + break; + case 'v': + prop_value = optarg; + break; + case 't': + rsc_type = optarg; + break; + case 'R': + case 'P': + need_cib = FALSE; + rsc_cmd = flag; + break; + case 'L': + case 'c': + case 'l': + case 'q': + case 'w': + case 'D': + case 'F': + case 'C': + case 'W': + case 'M': + case 'U': + case 'O': + case 'o': + case 'A': + case 'a': + rsc_cmd = flag; + break; + case 'p': + case 'g': + case 'd': + case 'S': + case 'G': + prop_name = optarg; + rsc_cmd = flag; + break; + case 'h': + case 'H': + case 'N': + crm_debug_2("Option %c => %s", flag, optarg); + host_uname = optarg; + break; + + default: + CMD_ERR("Argument code 0%o (%c) is not (?yet?) supported\n", flag, flag); + ++argerr; + break; + } } if (optind < argc && argv[optind] != NULL) { - CMD_ERR("non-option ARGV-elements: "); - while (optind < argc && argv[optind] != NULL) { - CMD_ERR("%s ", argv[optind++]); - ++argerr; - } - CMD_ERR("\n"); + CMD_ERR("non-option ARGV-elements: "); + while (optind < argc && argv[optind] != NULL) { + CMD_ERR("%s ", argv[optind++]); + ++argerr; + } + CMD_ERR("\n"); } if (optind > argc) { - ++argerr; + ++argerr; } if (argerr) { - crm_help('?', LSB_EXIT_GENERIC); + crm_help('?', LSB_EXIT_GENERIC); } crm_malloc0(our_pid, 11); - if(our_pid != NULL) { - snprintf(our_pid, 10, "%d", getpid()); - our_pid[10] = '\0'; + if (our_pid != NULL) { + snprintf(our_pid, 10, "%d", getpid()); + our_pid[10] = '\0'; } - if(do_force) { - crm_debug("Forcing..."); - cib_options |= cib_quorum_override; + if (do_force) { + crm_debug("Forcing..."); + cib_options |= cib_quorum_override; } set_working_set_defaults(&data_set); - if(need_cib) { - resource_t *rsc = NULL; - if(xml_file != NULL) { - cib_xml_copy = filename2xml(xml_file); - - } else { - cib_conn = cib_new(); - rc = cib_conn->cmds->signon( - cib_conn, crm_system_name, cib_command); - if(rc != cib_ok) { - CMD_ERR("Error signing on to the CIB service: %s\n", - cib_error2string(rc)); - return rc; - } - - cib_xml_copy = get_cib_copy(cib_conn); - } - - if(cli_config_update(&cib_xml_copy, NULL, FALSE) == FALSE) { - rc = cib_STALE; - goto bail; - } - - data_set.input = cib_xml_copy; - data_set.now = new_ha_date(TRUE); - - cluster_status(&data_set); - if(rsc_id) { - rsc = find_rsc_or_clone(rsc_id, &data_set); - } - if(rsc == NULL) { - rc = cib_NOTEXISTS; - } - } - - if(rsc_cmd == 'R' - || rsc_cmd == 'C' - || rsc_cmd == 'F' - || rsc_cmd == 'P') { - GCHSource *src = NULL; - src = init_client_ipc_comms(CRM_SYSTEM_CRMD, resource_ipc_callback, - NULL, &crmd_channel); - - if(src == NULL) { - CMD_ERR("Error signing on to the CRMd service\n"); - rc = cib_connection; - goto bail; - } - - send_hello_message( - crmd_channel, our_pid, crm_system_name, "0", "1"); - - set_IPC_Channel_dnotify(src, resource_ipc_connection_destroy); - } - - if(rsc_cmd == 'L') { - rc = cib_ok; - do_find_resource_list(&data_set, FALSE); - - } else if(rsc_cmd == 'l') { - int found = 0; - GListPtr lpc = NULL; - rc = cib_ok; - for(lpc = data_set.resources; lpc != NULL; lpc = lpc->next) { - resource_t *rsc = (resource_t*)lpc->data; - - found++; - print_raw_rsc(rsc); - } - - if(found == 0) { - printf("NO resources configured\n"); - rc = cib_NOTEXISTS; - goto bail; - } - - } else if(rsc_cmd == 'A' || rsc_cmd == 'a') { - GListPtr lpc = NULL; - resource_t *rsc = pe_find_resource(data_set.resources, rsc_id); - xmlNode * cib_constraints = get_object_root(XML_CIB_TAG_CONSTRAINTS, data_set.input); - if(rsc == NULL) { - CMD_ERR("Must supply a resource id with -r\n"); - rc = cib_NOTEXISTS; - goto bail; - } - - unpack_constraints(cib_constraints, &data_set); - - for(lpc = data_set.resources; lpc != NULL; lpc = lpc->next) { - resource_t *r = (resource_t*)lpc->data; - clear_bit(r->flags, pe_rsc_allocating); - } - - show_colocation(rsc, TRUE, rsc_cmd=='A', 1); - - fprintf(stdout, "* %s\n", rsc->id); - show_location(rsc, NULL); - - for(lpc = data_set.resources; lpc != NULL; lpc = lpc->next) { - resource_t *r = (resource_t*)lpc->data; - clear_bit(r->flags, pe_rsc_allocating); - } - - show_colocation(rsc, FALSE, rsc_cmd=='A', 1); - - } else if(rsc_cmd == 'c') { - int found = 0; - GListPtr lpc = NULL; - rc = cib_ok; - for(lpc = data_set.resources; lpc != NULL; lpc = lpc->next) { - resource_t *rsc = (resource_t*)lpc->data; - print_cts_rsc(rsc); - found++; - } - print_cts_constraints(&data_set); - - } else if(rsc_cmd == 'C') { - resource_t *rsc = pe_find_resource(data_set.resources, rsc_id); - rc = delete_lrm_rsc(crmd_channel, host_uname, rsc, &data_set); - if(rc == cib_ok) { - start_mainloop(); - } - - } else if(rsc_cmd == 'F') { - rc = fail_lrm_rsc(crmd_channel, host_uname, rsc_id, &data_set); - if(rc == cib_ok) { - start_mainloop(); - } - - } else if(rsc_cmd == 'O') { - rc = list_resource_operations(rsc_id, host_uname, TRUE, &data_set); - - } else if(rsc_cmd == 'o') { - rc = list_resource_operations(rsc_id, host_uname, FALSE, &data_set); - - } else if(rc == cib_NOTEXISTS) { - CMD_ERR("Resource %s not found: %s\n", - crm_str(rsc_id), cib_error2string(rc)); - - } else if(rsc_cmd == 'W') { - if(rsc_id == NULL) { - CMD_ERR("Must supply a resource id with -r\n"); - rc = cib_NOTEXISTS; - goto bail; - } - rc = do_find_resource(rsc_id, NULL, &data_set); - - } else if(rsc_cmd == 'q') { - if(rsc_id == NULL) { - CMD_ERR("Must supply a resource id with -r\n"); - rc = cib_NOTEXISTS; - goto bail; - } - rc = dump_resource(rsc_id, &data_set, TRUE); - - } else if(rsc_cmd == 'w') { - if(rsc_id == NULL) { - CMD_ERR("Must supply a resource id with -r\n"); - rc = cib_NOTEXISTS; - goto bail; - } - rc = dump_resource(rsc_id, &data_set, FALSE); - - } else if(rsc_cmd == 'U') { - if(rsc_id == NULL) { - CMD_ERR("Must supply a resource id with -r\n"); - rc = cib_NOTEXISTS; - goto bail; - } - rc = move_resource(rsc_id, NULL, NULL, cib_conn); - - } else if(rsc_cmd == 'M') { - node_t *dest = NULL; - node_t *current = NULL; - const char *current_uname = NULL; - resource_t *rsc = pe_find_resource(data_set.resources, rsc_id); - if(rsc != NULL && rsc->running_on != NULL) { - current = rsc->running_on->data; - if(current != NULL) { - current_uname = current->details->uname; - } - } - - if(host_uname != NULL) { - dest = pe_find_node(data_set.nodes, host_uname); - } - - if(rsc == NULL) { - CMD_ERR("Resource %s not moved:" - " not found\n", rsc_id); - - } else if(rsc->variant == pe_native - && g_list_length(rsc->running_on) > 1) { - CMD_ERR("Resource %s not moved:" - " active on multiple nodes\n", rsc_id); - - } else if(host_uname != NULL && dest == NULL) { - CMD_ERR("Error performing operation: " - "%s is not a known node\n", host_uname); - rc = cib_NOTEXISTS; - - } else if(host_uname != NULL - && safe_str_eq(current_uname, host_uname)) { - CMD_ERR("Error performing operation: " - "%s is already active on %s\n", - rsc_id, host_uname); - - } else if(current_uname != NULL - && (do_force || host_uname == NULL)) { - rc = move_resource(rsc_id, current_uname, - host_uname, cib_conn); - - - } else if(host_uname != NULL) { - rc = move_resource( - rsc_id, NULL, host_uname, cib_conn); - - } else { - CMD_ERR("Resource %s not moved: " - "not-active and no preferred location" - " specified.\n", rsc_id); - rc = cib_missing; - } - - } else if(rsc_cmd == 'G') { - if(rsc_id == NULL) { - CMD_ERR("Must supply a resource id with -r\n"); - rc = cib_NOTEXISTS; - goto bail; - } - rc = dump_resource_prop(rsc_id, prop_name, &data_set); - - } else if(rsc_cmd == 'S') { - xmlNode *msg_data = NULL; - if(prop_value == NULL || strlen(prop_value) == 0) { - CMD_ERR("You need to supply a value with the -v option\n"); - rc = CIBRES_MISSING_FIELD; - goto bail; - - } else if(cib_conn == NULL) { - rc = cib_connection; - goto bail; - } - - if(rsc_id == NULL) { - CMD_ERR("Must supply a resource id with -r\n"); - rc = cib_NOTEXISTS; - goto bail; - } - CRM_LOG_ASSERT(rsc_type != NULL); - CRM_LOG_ASSERT(prop_name != NULL); - CRM_LOG_ASSERT(prop_value != NULL); - - msg_data = create_xml_node(NULL, rsc_type); - crm_xml_add(msg_data, XML_ATTR_ID, rsc_id); - crm_xml_add(msg_data, prop_name, prop_value); - - rc = cib_conn->cmds->modify( - cib_conn, XML_CIB_TAG_RESOURCES, msg_data, cib_options); - free_xml(msg_data); - - } else if(rsc_cmd == 'g') { - if(rsc_id == NULL) { - CMD_ERR("Must supply a resource id with -r\n"); - rc = cib_NOTEXISTS; - goto bail; - } - rc = dump_resource_attr(rsc_id, prop_name, &data_set); - - } else if(rsc_cmd == 'p') { - if(rsc_id == NULL) { - CMD_ERR("Must supply a resource id with -r\n"); - rc = cib_NOTEXISTS; - goto bail; - } - if(prop_value == NULL || strlen(prop_value) == 0) { - CMD_ERR("You need to supply a value with the -v option\n"); - rc = CIBRES_MISSING_FIELD; - goto bail; - } - rc = set_resource_attr(rsc_id, prop_set, prop_id, prop_name, - prop_value, cib_conn, &data_set); - - } else if(rsc_cmd == 'd') { - if(rsc_id == NULL) { - CMD_ERR("Must supply a resource id with -r\n"); - rc = cib_NOTEXISTS; - goto bail; - } - rc = delete_resource_attr(rsc_id, prop_set, prop_id, prop_name, - cib_conn, &data_set); - - } else if(rsc_cmd == 'P') { - xmlNode *cmd = NULL; - - cmd = create_request(CRM_OP_REPROBE, NULL, host_uname, - CRM_SYSTEM_CRMD, crm_system_name, our_pid); - if(send_ipc_message(crmd_channel, cmd)) { - start_mainloop(); - } - - free_xml(cmd); - - } else if(rsc_cmd == 'R') { - rc = refresh_lrm(crmd_channel, host_uname); - if(rc == cib_ok) { - start_mainloop(); - } - - } else if(rsc_cmd == 'D') { - xmlNode *msg_data = NULL; - - if(rsc_id == NULL) { - CMD_ERR("Must supply a resource id with -r\n"); - rc = cib_NOTEXISTS; - goto bail; - - } - if(rsc_type == NULL) { - CMD_ERR("You need to specify a resource type with -t"); - rc = cib_NOTEXISTS; - goto bail; - - } else if(cib_conn == NULL) { - rc = cib_connection; - goto bail; - } - - msg_data = create_xml_node(NULL, rsc_type); - crm_xml_add(msg_data, XML_ATTR_ID, rsc_id); - - rc = cib_conn->cmds->delete( - cib_conn, XML_CIB_TAG_RESOURCES, msg_data, cib_options); - free_xml(msg_data); + if (need_cib) { + resource_t *rsc = NULL; + + if (xml_file != NULL) { + cib_xml_copy = filename2xml(xml_file); + + } else { + cib_conn = cib_new(); + rc = cib_conn->cmds->signon(cib_conn, crm_system_name, cib_command); + if (rc != cib_ok) { + CMD_ERR("Error signing on to the CIB service: %s\n", cib_error2string(rc)); + return rc; + } + + cib_xml_copy = get_cib_copy(cib_conn); + } + + if (cli_config_update(&cib_xml_copy, NULL, FALSE) == FALSE) { + rc = cib_STALE; + goto bail; + } + + data_set.input = cib_xml_copy; + data_set.now = new_ha_date(TRUE); + + cluster_status(&data_set); + if (rsc_id) { + rsc = find_rsc_or_clone(rsc_id, &data_set); + } + if (rsc == NULL) { + rc = cib_NOTEXISTS; + } + } + + if (rsc_cmd == 'R' || rsc_cmd == 'C' || rsc_cmd == 'F' || rsc_cmd == 'P') { + GCHSource *src = NULL; + + src = init_client_ipc_comms(CRM_SYSTEM_CRMD, resource_ipc_callback, NULL, &crmd_channel); + + if (src == NULL) { + CMD_ERR("Error signing on to the CRMd service\n"); + rc = cib_connection; + goto bail; + } + + send_hello_message(crmd_channel, our_pid, crm_system_name, "0", "1"); + + set_IPC_Channel_dnotify(src, resource_ipc_connection_destroy); + } + + if (rsc_cmd == 'L') { + rc = cib_ok; + do_find_resource_list(&data_set, FALSE); + + } else if (rsc_cmd == 'l') { + int found = 0; + GListPtr lpc = NULL; + + rc = cib_ok; + for (lpc = data_set.resources; lpc != NULL; lpc = lpc->next) { + resource_t *rsc = (resource_t *) lpc->data; + + found++; + print_raw_rsc(rsc); + } + + if (found == 0) { + printf("NO resources configured\n"); + rc = cib_NOTEXISTS; + goto bail; + } + + } else if (rsc_cmd == 'A' || rsc_cmd == 'a') { + GListPtr lpc = NULL; + resource_t *rsc = pe_find_resource(data_set.resources, rsc_id); + xmlNode *cib_constraints = get_object_root(XML_CIB_TAG_CONSTRAINTS, data_set.input); + + if (rsc == NULL) { + CMD_ERR("Must supply a resource id with -r\n"); + rc = cib_NOTEXISTS; + goto bail; + } + + unpack_constraints(cib_constraints, &data_set); + + for (lpc = data_set.resources; lpc != NULL; lpc = lpc->next) { + resource_t *r = (resource_t *) lpc->data; + + clear_bit(r->flags, pe_rsc_allocating); + } + + show_colocation(rsc, TRUE, rsc_cmd == 'A', 1); + + fprintf(stdout, "* %s\n", rsc->id); + show_location(rsc, NULL); + + for (lpc = data_set.resources; lpc != NULL; lpc = lpc->next) { + resource_t *r = (resource_t *) lpc->data; + + clear_bit(r->flags, pe_rsc_allocating); + } + + show_colocation(rsc, FALSE, rsc_cmd == 'A', 1); + + } else if (rsc_cmd == 'c') { + int found = 0; + GListPtr lpc = NULL; + + rc = cib_ok; + for (lpc = data_set.resources; lpc != NULL; lpc = lpc->next) { + resource_t *rsc = (resource_t *) lpc->data; + + print_cts_rsc(rsc); + found++; + } + print_cts_constraints(&data_set); + + } else if (rsc_cmd == 'C') { + resource_t *rsc = pe_find_resource(data_set.resources, rsc_id); + + rc = delete_lrm_rsc(crmd_channel, host_uname, rsc, &data_set); + if (rc == cib_ok) { + start_mainloop(); + } + + } else if (rsc_cmd == 'F') { + rc = fail_lrm_rsc(crmd_channel, host_uname, rsc_id, &data_set); + if (rc == cib_ok) { + start_mainloop(); + } + + } else if (rsc_cmd == 'O') { + rc = list_resource_operations(rsc_id, host_uname, TRUE, &data_set); + + } else if (rsc_cmd == 'o') { + rc = list_resource_operations(rsc_id, host_uname, FALSE, &data_set); + + } else if (rc == cib_NOTEXISTS) { + CMD_ERR("Resource %s not found: %s\n", crm_str(rsc_id), cib_error2string(rc)); + + } else if (rsc_cmd == 'W') { + if (rsc_id == NULL) { + CMD_ERR("Must supply a resource id with -r\n"); + rc = cib_NOTEXISTS; + goto bail; + } + rc = do_find_resource(rsc_id, NULL, &data_set); + + } else if (rsc_cmd == 'q') { + if (rsc_id == NULL) { + CMD_ERR("Must supply a resource id with -r\n"); + rc = cib_NOTEXISTS; + goto bail; + } + rc = dump_resource(rsc_id, &data_set, TRUE); + + } else if (rsc_cmd == 'w') { + if (rsc_id == NULL) { + CMD_ERR("Must supply a resource id with -r\n"); + rc = cib_NOTEXISTS; + goto bail; + } + rc = dump_resource(rsc_id, &data_set, FALSE); + + } else if (rsc_cmd == 'U') { + if (rsc_id == NULL) { + CMD_ERR("Must supply a resource id with -r\n"); + rc = cib_NOTEXISTS; + goto bail; + } + rc = move_resource(rsc_id, NULL, NULL, cib_conn); + + } else if (rsc_cmd == 'M') { + node_t *dest = NULL; + node_t *current = NULL; + const char *current_uname = NULL; + resource_t *rsc = pe_find_resource(data_set.resources, rsc_id); + + if (rsc != NULL && rsc->running_on != NULL) { + current = rsc->running_on->data; + if (current != NULL) { + current_uname = current->details->uname; + } + } + + if (host_uname != NULL) { + dest = pe_find_node(data_set.nodes, host_uname); + } + + if (rsc == NULL) { + CMD_ERR("Resource %s not moved:" " not found\n", rsc_id); + + } else if (rsc->variant == pe_native && g_list_length(rsc->running_on) > 1) { + CMD_ERR("Resource %s not moved:" " active on multiple nodes\n", rsc_id); + + } else if (host_uname != NULL && dest == NULL) { + CMD_ERR("Error performing operation: " "%s is not a known node\n", host_uname); + rc = cib_NOTEXISTS; + + } else if (host_uname != NULL && safe_str_eq(current_uname, host_uname)) { + CMD_ERR("Error performing operation: " + "%s is already active on %s\n", rsc_id, host_uname); + + } else if (current_uname != NULL && (do_force || host_uname == NULL)) { + rc = move_resource(rsc_id, current_uname, host_uname, cib_conn); + + } else if (host_uname != NULL) { + rc = move_resource(rsc_id, NULL, host_uname, cib_conn); + + } else { + CMD_ERR("Resource %s not moved: " + "not-active and no preferred location" " specified.\n", rsc_id); + rc = cib_missing; + } + + } else if (rsc_cmd == 'G') { + if (rsc_id == NULL) { + CMD_ERR("Must supply a resource id with -r\n"); + rc = cib_NOTEXISTS; + goto bail; + } + rc = dump_resource_prop(rsc_id, prop_name, &data_set); + + } else if (rsc_cmd == 'S') { + xmlNode *msg_data = NULL; + + if (prop_value == NULL || strlen(prop_value) == 0) { + CMD_ERR("You need to supply a value with the -v option\n"); + rc = CIBRES_MISSING_FIELD; + goto bail; + + } else if (cib_conn == NULL) { + rc = cib_connection; + goto bail; + } + + if (rsc_id == NULL) { + CMD_ERR("Must supply a resource id with -r\n"); + rc = cib_NOTEXISTS; + goto bail; + } + CRM_LOG_ASSERT(rsc_type != NULL); + CRM_LOG_ASSERT(prop_name != NULL); + CRM_LOG_ASSERT(prop_value != NULL); + + msg_data = create_xml_node(NULL, rsc_type); + crm_xml_add(msg_data, XML_ATTR_ID, rsc_id); + crm_xml_add(msg_data, prop_name, prop_value); + + rc = cib_conn->cmds->modify(cib_conn, XML_CIB_TAG_RESOURCES, msg_data, cib_options); + free_xml(msg_data); + + } else if (rsc_cmd == 'g') { + if (rsc_id == NULL) { + CMD_ERR("Must supply a resource id with -r\n"); + rc = cib_NOTEXISTS; + goto bail; + } + rc = dump_resource_attr(rsc_id, prop_name, &data_set); + + } else if (rsc_cmd == 'p') { + if (rsc_id == NULL) { + CMD_ERR("Must supply a resource id with -r\n"); + rc = cib_NOTEXISTS; + goto bail; + } + if (prop_value == NULL || strlen(prop_value) == 0) { + CMD_ERR("You need to supply a value with the -v option\n"); + rc = CIBRES_MISSING_FIELD; + goto bail; + } + rc = set_resource_attr(rsc_id, prop_set, prop_id, prop_name, + prop_value, cib_conn, &data_set); + + } else if (rsc_cmd == 'd') { + if (rsc_id == NULL) { + CMD_ERR("Must supply a resource id with -r\n"); + rc = cib_NOTEXISTS; + goto bail; + } + rc = delete_resource_attr(rsc_id, prop_set, prop_id, prop_name, cib_conn, &data_set); + + } else if (rsc_cmd == 'P') { + xmlNode *cmd = NULL; + + cmd = create_request(CRM_OP_REPROBE, NULL, host_uname, + CRM_SYSTEM_CRMD, crm_system_name, our_pid); + if (send_ipc_message(crmd_channel, cmd)) { + start_mainloop(); + } + + free_xml(cmd); + + } else if (rsc_cmd == 'R') { + rc = refresh_lrm(crmd_channel, host_uname); + if (rc == cib_ok) { + start_mainloop(); + } + + } else if (rsc_cmd == 'D') { + xmlNode *msg_data = NULL; + + if (rsc_id == NULL) { + CMD_ERR("Must supply a resource id with -r\n"); + rc = cib_NOTEXISTS; + goto bail; + + } + if (rsc_type == NULL) { + CMD_ERR("You need to specify a resource type with -t"); + rc = cib_NOTEXISTS; + goto bail; + + } else if (cib_conn == NULL) { + rc = cib_connection; + goto bail; + } + + msg_data = create_xml_node(NULL, rsc_type); + crm_xml_add(msg_data, XML_ATTR_ID, rsc_id); + + rc = cib_conn->cmds->delete(cib_conn, XML_CIB_TAG_RESOURCES, msg_data, cib_options); + free_xml(msg_data); } else { - CMD_ERR("Unknown command: %c\n", rsc_cmd); + CMD_ERR("Unknown command: %c\n", rsc_cmd); } bail: - - if(cib_conn != NULL) { - cleanup_alloc_calculations(&data_set); - cib_conn->cmds->signoff(cib_conn); - cib_delete(cib_conn); + + if (cib_conn != NULL) { + cleanup_alloc_calculations(&data_set); + cib_conn->cmds->signoff(cib_conn); + cib_delete(cib_conn); } crm_xml_cleanup(); - - if(rc == cib_no_quorum) { - CMD_ERR("Error performing operation: %s\n", - cib_error2string(rc)); - CMD_ERR("Try using -f\n"); - } else if(rc != cib_ok) { - CMD_ERR("Error performing operation: %s\n", - cib_error2string(rc)); + if (rc == cib_no_quorum) { + CMD_ERR("Error performing operation: %s\n", cib_error2string(rc)); + CMD_ERR("Try using -f\n"); + + } else if (rc != cib_ok) { + CMD_ERR("Error performing operation: %s\n", cib_error2string(rc)); } - + return rc; } - diff --git a/tools/crm_uuid.c b/tools/crm_uuid.c index 7a95747c27..5a6112f35a 100644 --- a/tools/crm_uuid.c +++ b/tools/crm_uuid.c @@ -1,185 +1,184 @@ /* * Copyright (C) 2004 Andrew Beekhof * * 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 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 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 */ #include #include #include #include #include #include #ifdef HAVE_STRING_H -#include +# include #endif #include #include #include #include #include #include #ifdef HAVE_GETOPT_H # include #endif #define UUID_LEN 16 #define OPTARGS "?rw:" int read_local_hb_uuid(void); int write_local_hb_uuid(const char *buffer); -static void usage(int rc) +static void +usage(int rc) { - FILE *stream = rc != 0 ? stderr : stdout; - fprintf(stream, "crm_uuid [-r|-w new_ascii_value]\n"); - exit(rc); + FILE *stream = rc != 0 ? stderr : stdout; + + fprintf(stream, "crm_uuid [-r|-w new_ascii_value]\n"); + exit(rc); } int main(int argc, char **argv) { - int flag; - int rc = 0; - - if(argc == 1) { - /* no arguments specified, default to read */ - rc = read_local_hb_uuid(); - return rc; - } - - cl_log_args(argc, argv); - - while (1) { - flag = getopt(argc, argv, OPTARGS); - if (flag == -1) { - break; - } - switch(flag) { - case 'r': - rc = read_local_hb_uuid(); - break; - case 'w': - rc = write_local_hb_uuid(optarg); - break; - case '?': - usage(LSB_EXIT_OK); - break; - default: - usage(LSB_EXIT_GENERIC); - break; - } - } - return rc; + int flag; + int rc = 0; + + if (argc == 1) { + /* no arguments specified, default to read */ + rc = read_local_hb_uuid(); + return rc; + } + + cl_log_args(argc, argv); + + while (1) { + flag = getopt(argc, argv, OPTARGS); + if (flag == -1) { + break; + } + switch (flag) { + case 'r': + rc = read_local_hb_uuid(); + break; + case 'w': + rc = write_local_hb_uuid(optarg); + break; + case '?': + usage(LSB_EXIT_OK); + break; + default: + usage(LSB_EXIT_GENERIC); + break; + } + } + return rc; } int -read_local_hb_uuid(void) +read_local_hb_uuid(void) { - int rc = 0; - cl_uuid_t uuid; - char *buffer = NULL; - long start = 0, read_len = 0; - - FILE *input = fopen(UUID_FILE, "r"); - - if(input == NULL) { - cl_perror("Could not open UUID file %s\n", UUID_FILE); - return 1; - } - - /* see how big the file is */ - start = ftell(input); - fseek(input, 0L, SEEK_END); - if(UUID_LEN != ftell(input)) { - fprintf(stderr, "%s must contain exactly %d bytes\n", - UUID_FILE, UUID_LEN); - abort(); - } - - fseek(input, 0L, start); - - if(start != ftell(input)) { - fprintf(stderr, "fseek not behaving: %ld vs. %ld\n", - start, ftell(input)); - rc = 2; - goto bail; - } + int rc = 0; + cl_uuid_t uuid; + char *buffer = NULL; + long start = 0, read_len = 0; + + FILE *input = fopen(UUID_FILE, "r"); + + if (input == NULL) { + cl_perror("Could not open UUID file %s\n", UUID_FILE); + return 1; + } + + /* see how big the file is */ + start = ftell(input); + fseek(input, 0L, SEEK_END); + if (UUID_LEN != ftell(input)) { + fprintf(stderr, "%s must contain exactly %d bytes\n", UUID_FILE, UUID_LEN); + abort(); + } + + fseek(input, 0L, start); + + if (start != ftell(input)) { + fprintf(stderr, "fseek not behaving: %ld vs. %ld\n", start, ftell(input)); + rc = 2; + goto bail; + } /* fprintf(stderr, "Reading %d bytes from: %s\n", UUID_LEN, UUID_FILE); */ - buffer = malloc(50); - read_len = fread(uuid.uuid, 1, UUID_LEN, input); - if(read_len != UUID_LEN) { - fprintf(stderr, "Expected and read bytes differ: %d vs. %ld\n", - UUID_LEN, read_len); - rc = 3; - goto bail; - - } else if(buffer != NULL) { - cl_uuid_unparse(&uuid, buffer); - fprintf(stdout, "%s\n", buffer); - - } else { - fprintf(stderr, "No buffer to unparse\n"); - rc = 4; - } - - bail: - free(buffer); - fclose(input); - - return rc; + buffer = malloc(50); + read_len = fread(uuid.uuid, 1, UUID_LEN, input); + if (read_len != UUID_LEN) { + fprintf(stderr, "Expected and read bytes differ: %d vs. %ld\n", UUID_LEN, read_len); + rc = 3; + goto bail; + + } else if (buffer != NULL) { + cl_uuid_unparse(&uuid, buffer); + fprintf(stdout, "%s\n", buffer); + + } else { + fprintf(stderr, "No buffer to unparse\n"); + rc = 4; + } + + bail: + free(buffer); + fclose(input); + + return rc; } int -write_local_hb_uuid(const char *new_value) +write_local_hb_uuid(const char *new_value) { - int fd; - int rc = 0; - cl_uuid_t uuid; - char *buffer = strdup(new_value); - rc = cl_uuid_parse(buffer, &uuid); - if(rc != 0) { - fprintf(stderr, "Invalid ASCII UUID supplied: [%s]\n", new_value); - fprintf(stderr, "ASCII UUIDs must be of the form" - " XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" - " and contain only letters and digits\n"); - return 5; - } - - if ((fd = open(UUID_FILE, O_WRONLY|O_SYNC|O_CREAT, 0644)) < 0) { - cl_perror("Could not open %s", UUID_FILE); - return 6; - } - - if (write(fd, uuid.uuid, UUID_LEN) != UUID_LEN) { - cl_perror("Could not write UUID to %s", UUID_FILE); - rc=7; - } - - if (close(fd) < 0) { - cl_perror("Could not close %s", UUID_FILE); - rc=8; - } - return rc; + int fd; + int rc = 0; + cl_uuid_t uuid; + char *buffer = strdup(new_value); + + rc = cl_uuid_parse(buffer, &uuid); + if (rc != 0) { + fprintf(stderr, "Invalid ASCII UUID supplied: [%s]\n", new_value); + fprintf(stderr, "ASCII UUIDs must be of the form" + " XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" " and contain only letters and digits\n"); + return 5; + } + + if ((fd = open(UUID_FILE, O_WRONLY | O_SYNC | O_CREAT, 0644)) < 0) { + cl_perror("Could not open %s", UUID_FILE); + return 6; + } + + if (write(fd, uuid.uuid, UUID_LEN) != UUID_LEN) { + cl_perror("Could not write UUID to %s", UUID_FILE); + rc = 7; + } + + if (close(fd) < 0) { + cl_perror("Could not close %s", UUID_FILE); + rc = 8; + } + return rc; } diff --git a/tools/crm_verify.c b/tools/crm_verify.c index e2ee4e922b..d684aad4f0 100644 --- a/tools/crm_verify.c +++ b/tools/crm_verify.c @@ -1,293 +1,287 @@ /* * Copyright (C) 2004 Andrew Beekhof * * 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 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 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 */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include gboolean USE_LIVE_CIB = FALSE; char *cib_save = NULL; void usage(const char *cmd, int exit_status); -extern gboolean stage0(pe_working_set_t *data_set); -extern void cleanup_alloc_calculations(pe_working_set_t *data_set); -extern xmlNode * do_calculations( - pe_working_set_t *data_set, xmlNode *xml_input, ha_time_t *now); +extern gboolean stage0(pe_working_set_t * data_set); +extern void cleanup_alloc_calculations(pe_working_set_t * data_set); +extern xmlNode *do_calculations(pe_working_set_t * data_set, xmlNode * xml_input, ha_time_t * now); /* *INDENT-OFF* */ static struct crm_option long_options[] = { /* Top-level Options */ {"help", 0, 0, '?', "\tThis text"}, {"version", 0, 0, '$', "\tVersion information" }, {"verbose", 0, 0, 'V', "\tIncrease debug output\n"}, {"-spacer-", 1, 0, '-', "\nData sources:"}, {"live-check", 0, 0, 'L', "Check the configuration used by the running cluster\n"}, {"xml-file", 1, 0, 'x', "Check the configuration in the named file"}, {"xml-text", 1, 0, 'X', "Check the configuration in the supplied string"}, {"xml-pipe", 0, 0, 'p', "Check the configuration piped in via stdin"}, {"-spacer-", 1, 0, '-', "\nAdditional Options:"}, {"save-xml", 1, 0, 'S', "Save the verified XML to the named file. Most useful with -L"}, {"-spacer-", 1, 0, '-', "\nExamples:", pcmk_option_paragraph}, {"-spacer-", 1, 0, '-', "Check the consistency of the configuration in the running cluster:", pcmk_option_paragraph}, {"-spacer-", 1, 0, '-', " crm_verify --live-check", pcmk_option_example}, {"-spacer-", 1, 0, '-', "Check the consistency of the configuration in a given file and produce verbose output:", pcmk_option_paragraph}, {"-spacer-", 1, 0, '-', " crm_verify --xml-file file.xml --verbose", pcmk_option_example}, {F_CRM_DATA, 1, 0, 'X', NULL, 1}, /* legacy */ {0, 0, 0, 0} }; /* *INDENT-ON* */ int main(int argc, char **argv) { xmlNode *cib_object = NULL; xmlNode *status = NULL; int argerr = 0; int flag; int option_index = 0; - + pe_working_set_t data_set; - cib_t * cib_conn = NULL; + cib_t *cib_conn = NULL; int rc = cib_ok; - + gboolean xml_stdin = FALSE; const char *xml_tag = NULL; const char *xml_file = NULL; const char *xml_string = NULL; - + g_log_set_handler(NULL, - G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL - | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_MESSAGE - | G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG - | G_LOG_FLAG_RECURSION | G_LOG_FLAG_FATAL, - cl_glib_msg_handler, NULL); + G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL + | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_MESSAGE + | G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG + | G_LOG_FLAG_RECURSION | G_LOG_FLAG_FATAL, cl_glib_msg_handler, NULL); /* and for good measure... - this enum is a bit field (!) */ - g_log_set_always_fatal((GLogLevelFlags)0); /*value out of range*/ + g_log_set_always_fatal((GLogLevelFlags) 0); /*value out of range */ crm_log_init_quiet(NULL, LOG_ERR, FALSE, TRUE, argc, argv); crm_set_options(NULL, "[modifiers] data_source", long_options, - "Check a (complete) confiuration for syntax and common conceptual errors." - "\n\nChecks the well-formedness of an XML configuration, its conformance to the configured DTD/schema and for the presence of common misconfigurations." - "\n\nIt reports two classes of problems, errors and warnings." - " Errors must be fixed before the cluster will work properly." - " However, it is left up to the administrator to decide if the warnings should also be fixed."); - + "Check a (complete) confiuration for syntax and common conceptual errors." + "\n\nChecks the well-formedness of an XML configuration, its conformance to the configured DTD/schema and for the presence of common misconfigurations." + "\n\nIt reports two classes of problems, errors and warnings." + " Errors must be fixed before the cluster will work properly." + " However, it is left up to the administrator to decide if the warnings should also be fixed."); + while (1) { - flag = crm_get_option(argc, argv, &option_index); - if (flag == -1) - break; - - switch(flag) { + flag = crm_get_option(argc, argv, &option_index); + if (flag == -1) + break; + + switch (flag) { #ifdef HAVE_GETOPT_H - case 0: - printf("option %s", long_options[option_index].name); - if (optarg) - printf(" with arg %s", optarg); - printf("\n"); - - break; + case 0: + printf("option %s", long_options[option_index].name); + if (optarg) + printf(" with arg %s", optarg); + printf("\n"); + + break; #endif - - case 'X': - crm_debug_2("Option %c => %s", flag, optarg); - xml_string = crm_strdup(optarg); - break; - case 'x': - crm_debug_2("Option %c => %s", flag, optarg); - xml_file = crm_strdup(optarg); - break; - case 'p': - xml_stdin = TRUE; - break; - case 'S': - cib_save = crm_strdup(optarg); - break; - case 'V': - alter_debug(DEBUG_INC); - break; - case 'L': - USE_LIVE_CIB = TRUE; - break; - case '$': - case '?': - crm_help(flag, LSB_EXIT_OK); - break; - default: - fprintf(stderr, "Option -%c is not yet supported\n", flag); - ++argerr; - break; - } + + case 'X': + crm_debug_2("Option %c => %s", flag, optarg); + xml_string = crm_strdup(optarg); + break; + case 'x': + crm_debug_2("Option %c => %s", flag, optarg); + xml_file = crm_strdup(optarg); + break; + case 'p': + xml_stdin = TRUE; + break; + case 'S': + cib_save = crm_strdup(optarg); + break; + case 'V': + alter_debug(DEBUG_INC); + break; + case 'L': + USE_LIVE_CIB = TRUE; + break; + case '$': + case '?': + crm_help(flag, LSB_EXIT_OK); + break; + default: + fprintf(stderr, "Option -%c is not yet supported\n", flag); + ++argerr; + break; + } } - + if (optind < argc) { - printf("non-option ARGV-elements: "); - while (optind < argc) { - printf("%s ", argv[optind++]); - } - printf("\n"); + printf("non-option ARGV-elements: "); + while (optind < argc) { + printf("%s ", argv[optind++]); + } + printf("\n"); } - + if (optind > argc) { - ++argerr; + ++argerr; } - + if (argerr) { - crm_err("%d errors in option parsing", argerr); - crm_help(flag, LSB_EXIT_GENERIC); + crm_err("%d errors in option parsing", argerr); + crm_help(flag, LSB_EXIT_GENERIC); } - + crm_info("=#=#=#=#= Getting XML =#=#=#=#="); - if(USE_LIVE_CIB) { - cib_conn = cib_new(); - rc = cib_conn->cmds->signon(cib_conn, crm_system_name, cib_command); + if (USE_LIVE_CIB) { + cib_conn = cib_new(); + rc = cib_conn->cmds->signon(cib_conn, crm_system_name, cib_command); } - - - if(USE_LIVE_CIB) { - if(rc == cib_ok) { - int options = cib_scope_local|cib_sync_call; - crm_info("Reading XML from: live cluster"); - rc = cib_conn->cmds->query( - cib_conn, NULL, &cib_object, options); - } - - - if(rc != cib_ok) { - fprintf(stderr, "Live CIB query failed: %s\n", - cib_error2string(rc)); - return 3; - } - if(cib_object == NULL) { - fprintf(stderr, "Live CIB query failed: empty result\n"); - return 3; - } - - } else if(xml_file != NULL) { - cib_object = filename2xml(xml_file); - if(cib_object == NULL) { - fprintf(stderr, - "Couldn't parse input file: %s\n", xml_file); - return 4; - } - - } else if(xml_string != NULL) { - cib_object = string2xml(xml_string); - if(cib_object == NULL) { - fprintf(stderr, - "Couldn't parse input string: %s\n", xml_string); - return 4; - } - } else if(xml_stdin) { - cib_object = stdin2xml(); - if(cib_object == NULL) { - fprintf(stderr, "Couldn't parse input from STDIN.\n"); - return 4; - } + + if (USE_LIVE_CIB) { + if (rc == cib_ok) { + int options = cib_scope_local | cib_sync_call; + + crm_info("Reading XML from: live cluster"); + rc = cib_conn->cmds->query(cib_conn, NULL, &cib_object, options); + } + + if (rc != cib_ok) { + fprintf(stderr, "Live CIB query failed: %s\n", cib_error2string(rc)); + return 3; + } + if (cib_object == NULL) { + fprintf(stderr, "Live CIB query failed: empty result\n"); + return 3; + } + + } else if (xml_file != NULL) { + cib_object = filename2xml(xml_file); + if (cib_object == NULL) { + fprintf(stderr, "Couldn't parse input file: %s\n", xml_file); + return 4; + } + + } else if (xml_string != NULL) { + cib_object = string2xml(xml_string); + if (cib_object == NULL) { + fprintf(stderr, "Couldn't parse input string: %s\n", xml_string); + return 4; + } + } else if (xml_stdin) { + cib_object = stdin2xml(); + if (cib_object == NULL) { + fprintf(stderr, "Couldn't parse input from STDIN.\n"); + return 4; + } } else { - fprintf(stderr, "No configuration source specified." - " Use --help for usage information.\n"); - return 5; + fprintf(stderr, "No configuration source specified." + " Use --help for usage information.\n"); + return 5; } xml_tag = crm_element_name(cib_object); - if(safe_str_neq(xml_tag, XML_TAG_CIB)) { - fprintf(stderr, "This tool can only check complete configurations (ie. those starting with ).\n"); - return 6; + if (safe_str_neq(xml_tag, XML_TAG_CIB)) { + fprintf(stderr, + "This tool can only check complete configurations (ie. those starting with ).\n"); + return 6; } - - if(cib_save != NULL) { - write_xml_file(cib_object, cib_save, FALSE); + + if (cib_save != NULL) { + write_xml_file(cib_object, cib_save, FALSE); } - + status = get_object_root(XML_CIB_TAG_STATUS, cib_object); - if(status == NULL) { - create_xml_node(cib_object, XML_CIB_TAG_STATUS); + if (status == NULL) { + create_xml_node(cib_object, XML_CIB_TAG_STATUS); } - - if(validate_xml(cib_object, NULL, FALSE) == FALSE) { - crm_config_err("CIB did not pass DTD/schema validation"); - free_xml(cib_object); - cib_object = NULL; - - } else if(cli_config_update(&cib_object, NULL, FALSE) == FALSE) { - crm_config_error = TRUE; - free_xml(cib_object); cib_object = NULL; - fprintf(stderr, "The cluster will NOT be able to use this configuration.\n"); - fprintf(stderr, "Please manually update the configuration to conform to the %s syntax.\n", - LATEST_SCHEMA_VERSION); + + if (validate_xml(cib_object, NULL, FALSE) == FALSE) { + crm_config_err("CIB did not pass DTD/schema validation"); + free_xml(cib_object); + cib_object = NULL; + + } else if (cli_config_update(&cib_object, NULL, FALSE) == FALSE) { + crm_config_error = TRUE; + free_xml(cib_object); + cib_object = NULL; + fprintf(stderr, "The cluster will NOT be able to use this configuration.\n"); + fprintf(stderr, "Please manually update the configuration to conform to the %s syntax.\n", + LATEST_SCHEMA_VERSION); } - + set_working_set_defaults(&data_set); - if(cib_object == NULL) { - } else if(USE_LIVE_CIB) { - /* we will always have a status section and can do a full simulation */ - do_calculations(&data_set, cib_object, NULL); - cleanup_alloc_calculations(&data_set); + if (cib_object == NULL) { + } else if (USE_LIVE_CIB) { + /* we will always have a status section and can do a full simulation */ + do_calculations(&data_set, cib_object, NULL); + cleanup_alloc_calculations(&data_set); } else { - data_set.now = new_ha_date(TRUE); - data_set.input = cib_object; - stage0(&data_set); - cleanup_alloc_calculations(&data_set); + data_set.now = new_ha_date(TRUE); + data_set.input = cib_object; + stage0(&data_set); + cleanup_alloc_calculations(&data_set); } - - - if(crm_config_error) { - fprintf(stderr, "Errors found during check: config not valid\n"); - if(crm_log_level < LOG_WARNING) { - fprintf(stderr, " -V may provide more details\n"); - } - rc = 2; - - } else if(crm_config_warning) { - fprintf(stderr, "Warnings found during check: config may not be valid\n"); - if(crm_log_level < LOG_WARNING) { - fprintf(stderr, " Use -V for more details\n"); - } - rc = 1; + + if (crm_config_error) { + fprintf(stderr, "Errors found during check: config not valid\n"); + if (crm_log_level < LOG_WARNING) { + fprintf(stderr, " -V may provide more details\n"); + } + rc = 2; + + } else if (crm_config_warning) { + fprintf(stderr, "Warnings found during check: config may not be valid\n"); + if (crm_log_level < LOG_WARNING) { + fprintf(stderr, " Use -V for more details\n"); + } + rc = 1; + } + + if (USE_LIVE_CIB) { + cib_conn->cmds->signoff(cib_conn); + cib_delete(cib_conn); } - - if(USE_LIVE_CIB) { - cib_conn->cmds->signoff(cib_conn); - cib_delete(cib_conn); - } return rc; } diff --git a/tools/crmadmin.c b/tools/crmadmin.c index eca9560713..74f7b0fdc5 100644 --- a/tools/crmadmin.c +++ b/tools/crmadmin.c @@ -1,603 +1,586 @@ /* * Copyright (C) 2004 Andrew Beekhof * * 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 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 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 */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include int message_timer_id = -1; -int message_timeout_ms = 30*1000; +int message_timeout_ms = 30 * 1000; GMainLoop *mainloop = NULL; IPC_Channel *crmd_channel = NULL; char *admin_uuid = NULL; void usage(const char *cmd, int exit_status); gboolean do_init(void); int do_work(void); void crmadmin_ipc_connection_destroy(gpointer user_data); gboolean admin_msg_callback(IPC_Channel * source_data, void *private_data); char *pluralSection(const char *a_section); xmlNode *handleCibMod(void); -int do_find_node_list(xmlNode *xml_node); +int do_find_node_list(xmlNode * xml_node); gboolean admin_message_timeout(gpointer data); -gboolean is_node_online(xmlNode *node_state); +gboolean is_node_online(xmlNode * node_state); enum debug { debug_none, debug_dec, debug_inc }; gboolean BE_VERBOSE = FALSE; int expected_responses = 1; -gboolean BASH_EXPORT = FALSE; -gboolean DO_HEALTH = FALSE; -gboolean DO_RESET = FALSE; -gboolean DO_RESOURCE = FALSE; -gboolean DO_ELECT_DC = FALSE; -gboolean DO_WHOIS_DC = FALSE; -gboolean DO_NODE_LIST = FALSE; -gboolean BE_SILENT = FALSE; +gboolean BASH_EXPORT = FALSE; +gboolean DO_HEALTH = FALSE; +gboolean DO_RESET = FALSE; +gboolean DO_RESOURCE = FALSE; +gboolean DO_ELECT_DC = FALSE; +gboolean DO_WHOIS_DC = FALSE; +gboolean DO_NODE_LIST = FALSE; +gboolean BE_SILENT = FALSE; gboolean DO_RESOURCE_LIST = FALSE; -enum debug DO_DEBUG = debug_none; +enum debug DO_DEBUG = debug_none; const char *crmd_operation = NULL; xmlNode *msg_options = NULL; const char *standby_on_off = "on"; const char *admin_verbose = XML_BOOLEAN_FALSE; char *id = NULL; char *disconnect = NULL; -char *dest_node = NULL; -char *rsc_name = NULL; +char *dest_node = NULL; +char *rsc_name = NULL; char *crm_option = NULL; int operation_status = 0; const char *sys_to = NULL; /* *INDENT-OFF* */ static struct crm_option long_options[] = { /* Top-level Options */ {"help", 0, 0, '?', "\tThis text"}, {"version", 0, 0, '$', "\tVersion information" }, {"quiet", 0, 0, 'q', "\tDisplay only the essential query information"}, {"verbose", 0, 0, 'V', "\tIncrease debug output"}, {"-spacer-", 1, 0, '-', "\nCommands:"}, /* daemon options */ {"debug_inc", 1, 0, 'i', "Increase the crmd's debug level on the specified host"}, {"debug_dec", 1, 0, 'd', "Decrease the crmd's debug level on the specified host"}, {"status", 1, 0, 'S', "Display the status of the specified node." }, {"-spacer-", 1, 0, '-', "\n\tResult is the node's internal FSM state which can be useful for debugging\n"}, {"dc_lookup", 0, 0, 'D', "Display the uname of the node co-ordinating the cluster."}, {"-spacer-", 1, 0, '-', "\n\tThis is an internal detail and is rarely useful to administrators except when deciding on which node to examine the logs.\n"}, {"nodes", 0, 0, 'N', "\tDisplay the uname of all member nodes"}, {"election", 0, 0, 'E', "(Advanced) Start an election for the cluster co-ordinator"}, {"kill", 1, 0, 'K', "(Advanced) Shut down the crmd (not the rest of the clusterstack ) on the specified node"}, {"health", 0, 0, 'H', NULL, 1}, {"-spacer-", 1, 0, '-', "\nAdditional Options:"}, {XML_ATTR_TIMEOUT, 1, 0, 't', "Time (in milliseconds) to wait before declaring the operation failed"}, {"bash-export", 0, 0, 'B', "Create Bash export entries of the form 'export uname=uuid'\n"}, {"-spacer-", 1, 0, '-', "Notes:"}, {"-spacer-", 1, 0, '-', " The -i,-d,-K and -E commands are rarely used and may be removed in future versions."}, {0, 0, 0, 0} }; /* *INDENT-ON* */ int main(int argc, char **argv) { int option_index = 0; int argerr = 0; int flag; crm_log_init(NULL, LOG_ERR, FALSE, TRUE, argc, argv); crm_set_options(NULL, "command [options]", long_options, - "Development tool for performing some crmd-specific commands." - "\n Likely to be replaced by crm_node in the future" ); - if(argc < 2) { - crm_help('?', LSB_EXIT_EINVAL); + "Development tool for performing some crmd-specific commands." + "\n Likely to be replaced by crm_node in the future"); + if (argc < 2) { + crm_help('?', LSB_EXIT_EINVAL); } - + while (1) { - flag = crm_get_option(argc, argv, &option_index); - if (flag == -1) - break; - - switch(flag) { - case 'V': - BE_VERBOSE = TRUE; - admin_verbose = XML_BOOLEAN_TRUE; - cl_log_enable_stderr(TRUE); - alter_debug(DEBUG_INC); - break; - case 't': - message_timeout_ms = atoi(optarg); - if(message_timeout_ms < 1) { - message_timeout_ms = 30*1000; - } - break; - - case '$': - case '?': - crm_help(flag, LSB_EXIT_OK); - break; - case 'D': - DO_WHOIS_DC = TRUE; - break; - case 'B': - BASH_EXPORT = TRUE; - break; - case 'K': - DO_RESET = TRUE; - crm_debug_2("Option %c => %s", flag, optarg); - dest_node = crm_strdup(optarg); - crmd_operation = CRM_OP_LOCAL_SHUTDOWN; - break; - case 'q': - BE_SILENT = TRUE; - break; - case 'i': - DO_DEBUG = debug_inc; - crm_debug_2("Option %c => %s", flag, optarg); - dest_node = crm_strdup(optarg); - break; - case 'd': - DO_DEBUG = debug_dec; - crm_debug_2("Option %c => %s", flag, optarg); - dest_node = crm_strdup(optarg); - break; - case 'S': - DO_HEALTH = TRUE; - crm_debug_2("Option %c => %s", flag, optarg); - dest_node = crm_strdup(optarg); - break; - case 'E': - DO_ELECT_DC = TRUE; - break; - case 'N': - DO_NODE_LIST = TRUE; - break; - case 'H': - DO_HEALTH = TRUE; - break; - default: - printf("Argument code 0%o (%c) is not (?yet?) supported\n", flag, flag); - ++argerr; - break; - } + flag = crm_get_option(argc, argv, &option_index); + if (flag == -1) + break; + + switch (flag) { + case 'V': + BE_VERBOSE = TRUE; + admin_verbose = XML_BOOLEAN_TRUE; + cl_log_enable_stderr(TRUE); + alter_debug(DEBUG_INC); + break; + case 't': + message_timeout_ms = atoi(optarg); + if (message_timeout_ms < 1) { + message_timeout_ms = 30 * 1000; + } + break; + + case '$': + case '?': + crm_help(flag, LSB_EXIT_OK); + break; + case 'D': + DO_WHOIS_DC = TRUE; + break; + case 'B': + BASH_EXPORT = TRUE; + break; + case 'K': + DO_RESET = TRUE; + crm_debug_2("Option %c => %s", flag, optarg); + dest_node = crm_strdup(optarg); + crmd_operation = CRM_OP_LOCAL_SHUTDOWN; + break; + case 'q': + BE_SILENT = TRUE; + break; + case 'i': + DO_DEBUG = debug_inc; + crm_debug_2("Option %c => %s", flag, optarg); + dest_node = crm_strdup(optarg); + break; + case 'd': + DO_DEBUG = debug_dec; + crm_debug_2("Option %c => %s", flag, optarg); + dest_node = crm_strdup(optarg); + break; + case 'S': + DO_HEALTH = TRUE; + crm_debug_2("Option %c => %s", flag, optarg); + dest_node = crm_strdup(optarg); + break; + case 'E': + DO_ELECT_DC = TRUE; + break; + case 'N': + DO_NODE_LIST = TRUE; + break; + case 'H': + DO_HEALTH = TRUE; + 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"); + printf("non-option ARGV-elements: "); + while (optind < argc) + printf("%s ", argv[optind++]); + printf("\n"); } if (optind > argc) { - ++argerr; + ++argerr; } if (argerr) { - crm_help('?', LSB_EXIT_GENERIC); + crm_help('?', LSB_EXIT_GENERIC); } if (do_init()) { - int res = 0; - res = do_work(); - if (res > 0) { - /* wait for the reply by creating a mainloop and running it until - * the callbacks are invoked... - */ - mainloop = g_main_new(FALSE); - expected_responses++; - crm_debug_2("Waiting for %d replies from the local CRM", expected_responses); - - message_timer_id = g_timeout_add( - message_timeout_ms, admin_message_timeout, NULL); - - g_main_run(mainloop); - - } else if(res < 0) { - crm_err("No message to send"); - operation_status = -1; - } + int res = 0; + + res = do_work(); + if (res > 0) { + /* wait for the reply by creating a mainloop and running it until + * the callbacks are invoked... + */ + mainloop = g_main_new(FALSE); + expected_responses++; + crm_debug_2("Waiting for %d replies from the local CRM", expected_responses); + + message_timer_id = g_timeout_add(message_timeout_ms, admin_message_timeout, NULL); + + g_main_run(mainloop); + + } else if (res < 0) { + crm_err("No message to send"); + operation_status = -1; + } } else { - crm_warn("Init failed, could not perform requested operations"); - operation_status = -2; + crm_warn("Init failed, could not perform requested operations"); + operation_status = -2; } crm_debug_2("%s exiting normally", crm_system_name); return operation_status; } - - int do_work(void) { int ret = 1; + /* construct the request */ xmlNode *msg_data = NULL; gboolean all_is_good = TRUE; - + msg_options = create_xml_node(NULL, XML_TAG_OPTIONS); crm_xml_add(msg_options, XML_ATTR_VERBOSE, admin_verbose); crm_xml_add(msg_options, XML_ATTR_TIMEOUT, "0"); if (DO_HEALTH == TRUE) { - crm_debug_2("Querying the system"); - - sys_to = CRM_SYSTEM_DC; - - if (dest_node != NULL) { - sys_to = CRM_SYSTEM_CRMD; - crmd_operation = CRM_OP_PING; - - if (BE_VERBOSE) { - expected_responses = 1; - } - - crm_xml_add(msg_options, XML_ATTR_TIMEOUT, "0"); - - } else { - crm_info("Cluster-wide health not available yet"); - all_is_good = FALSE; - } - - } else if(DO_ELECT_DC) { - /* tell the local node to initiate an election */ - - sys_to = CRM_SYSTEM_CRMD; - crmd_operation = CRM_OP_VOTE; - - crm_xml_add(msg_options, XML_ATTR_TIMEOUT, "0"); - - dest_node = NULL; - - ret = 0; /* no return message */ - - } else if(DO_WHOIS_DC) { - sys_to = CRM_SYSTEM_DC; - crmd_operation = CRM_OP_PING; - - crm_xml_add(msg_options, XML_ATTR_TIMEOUT, "0"); - - dest_node = NULL; - - } else if(DO_NODE_LIST) { - - cib_t * the_cib = cib_new(); - xmlNode *output = NULL; - - enum cib_errors rc = the_cib->cmds->signon( - the_cib, crm_system_name, cib_command); - - if(rc != cib_ok) { - return -1; - } - - output = get_cib_copy(the_cib); - do_find_node_list(output); - - free_xml(output); - the_cib->cmds->signoff(the_cib); - exit(rc); - - } else if(DO_RESET) { - /* tell dest_node to initiate the shutdown proceedure - * - * if dest_node is NULL, the request will be sent to the - * local node - */ - sys_to = CRM_SYSTEM_CRMD; - crm_xml_add(msg_options, XML_ATTR_TIMEOUT, "0"); - - ret = 0; /* no return message */ - - } else if(DO_DEBUG == debug_inc) { - /* tell dest_node to increase its debug level - * - * if dest_node is NULL, the request will be sent to the - * local node - */ - sys_to = CRM_SYSTEM_CRMD; - crmd_operation = CRM_OP_DEBUG_UP; - - ret = 0; /* no return message */ - - } else if(DO_DEBUG == debug_dec) { - /* tell dest_node to increase its debug level - * - * if dest_node is NULL, the request will be sent to the - * local node - */ - sys_to = CRM_SYSTEM_CRMD; - crmd_operation = CRM_OP_DEBUG_DOWN; - - ret = 0; /* no return message */ - + crm_debug_2("Querying the system"); + + sys_to = CRM_SYSTEM_DC; + + if (dest_node != NULL) { + sys_to = CRM_SYSTEM_CRMD; + crmd_operation = CRM_OP_PING; + + if (BE_VERBOSE) { + expected_responses = 1; + } + + crm_xml_add(msg_options, XML_ATTR_TIMEOUT, "0"); + + } else { + crm_info("Cluster-wide health not available yet"); + all_is_good = FALSE; + } + + } else if (DO_ELECT_DC) { + /* tell the local node to initiate an election */ + + sys_to = CRM_SYSTEM_CRMD; + crmd_operation = CRM_OP_VOTE; + + crm_xml_add(msg_options, XML_ATTR_TIMEOUT, "0"); + + dest_node = NULL; + + ret = 0; /* no return message */ + + } else if (DO_WHOIS_DC) { + sys_to = CRM_SYSTEM_DC; + crmd_operation = CRM_OP_PING; + + crm_xml_add(msg_options, XML_ATTR_TIMEOUT, "0"); + + dest_node = NULL; + + } else if (DO_NODE_LIST) { + + cib_t *the_cib = cib_new(); + xmlNode *output = NULL; + + enum cib_errors rc = the_cib->cmds->signon(the_cib, crm_system_name, cib_command); + + if (rc != cib_ok) { + return -1; + } + + output = get_cib_copy(the_cib); + do_find_node_list(output); + + free_xml(output); + the_cib->cmds->signoff(the_cib); + exit(rc); + + } else if (DO_RESET) { + /* tell dest_node to initiate the shutdown proceedure + * + * if dest_node is NULL, the request will be sent to the + * local node + */ + sys_to = CRM_SYSTEM_CRMD; + crm_xml_add(msg_options, XML_ATTR_TIMEOUT, "0"); + + ret = 0; /* no return message */ + + } else if (DO_DEBUG == debug_inc) { + /* tell dest_node to increase its debug level + * + * if dest_node is NULL, the request will be sent to the + * local node + */ + sys_to = CRM_SYSTEM_CRMD; + crmd_operation = CRM_OP_DEBUG_UP; + + ret = 0; /* no return message */ + + } else if (DO_DEBUG == debug_dec) { + /* tell dest_node to increase its debug level + * + * if dest_node is NULL, the request will be sent to the + * local node + */ + sys_to = CRM_SYSTEM_CRMD; + crmd_operation = CRM_OP_DEBUG_DOWN; + + ret = 0; /* no return message */ + } else { - crm_err("Unknown options"); - all_is_good = FALSE; + crm_err("Unknown options"); + all_is_good = FALSE; } - - if(all_is_good == FALSE) { - crm_err("Creation of request failed. No message to send"); - return -1; + if (all_is_good == FALSE) { + crm_err("Creation of request failed. No message to send"); + return -1; } /* send it */ if (crmd_channel == NULL) { - crm_err("The IPC connection is not valid, cannot send anything"); - return -1; + crm_err("The IPC connection is not valid, cannot send anything"); + return -1; } - if(sys_to == NULL) { - if (dest_node != NULL) { - sys_to = CRM_SYSTEM_CRMD; - } else { - sys_to = CRM_SYSTEM_DC; - } + if (sys_to == NULL) { + if (dest_node != NULL) { + sys_to = CRM_SYSTEM_CRMD; + } else { + sys_to = CRM_SYSTEM_DC; + } } - + { - xmlNode *cmd = create_request( - crmd_operation, msg_data, dest_node, sys_to, - crm_system_name, admin_uuid); + xmlNode *cmd = create_request(crmd_operation, msg_data, dest_node, sys_to, + crm_system_name, admin_uuid); - send_ipc_message(crmd_channel, cmd); - free_xml(cmd); + send_ipc_message(crmd_channel, cmd); + free_xml(cmd); } - + return ret; } void crmadmin_ipc_connection_destroy(gpointer user_data) { crm_err("Connection to CRMd was terminated"); - if(mainloop) { - g_main_quit(mainloop); + if (mainloop) { + g_main_quit(mainloop); } else { - exit(1); + exit(1); } } - gboolean do_init(void) { GCHSource *src = NULL; - + crm_malloc0(admin_uuid, 11); - if(admin_uuid != NULL) { - snprintf(admin_uuid, 10, "%d", getpid()); - admin_uuid[10] = '\0'; + if (admin_uuid != NULL) { + snprintf(admin_uuid, 10, "%d", getpid()); + admin_uuid[10] = '\0'; + } + + src = init_client_ipc_comms(CRM_SYSTEM_CRMD, admin_msg_callback, NULL, &crmd_channel); + + if (DO_RESOURCE || DO_RESOURCE_LIST || DO_NODE_LIST) { + return TRUE; + + } else if (crmd_channel != NULL) { + send_hello_message(crmd_channel, admin_uuid, crm_system_name, "0", "1"); + + set_IPC_Channel_dnotify(src, crmadmin_ipc_connection_destroy); + + return TRUE; } - - src = init_client_ipc_comms( - CRM_SYSTEM_CRMD, admin_msg_callback, NULL, &crmd_channel); - - if(DO_RESOURCE || DO_RESOURCE_LIST || DO_NODE_LIST) { - return TRUE; - - } else if(crmd_channel != NULL) { - send_hello_message( - crmd_channel, admin_uuid, crm_system_name,"0", "1"); - - set_IPC_Channel_dnotify(src, crmadmin_ipc_connection_destroy); - - return TRUE; - } return FALSE; } gboolean admin_msg_callback(IPC_Channel * server, void *private_data) { int rc = 0; int lpc = 0; xmlNode *xml = NULL; IPC_Message *msg = NULL; gboolean hack_return_good = TRUE; static int received_responses = 0; const char *result = NULL; g_source_remove(message_timer_id); - while (server->ch_status != IPC_DISCONNECT - && server->ops->is_message_pending(server) == TRUE) { - rc = server->ops->recv(server, &msg); - if (rc != IPC_OK) { - crm_perror(LOG_ERR,"Receive failure (%d)", rc); - return !hack_return_good; - } - - if (msg == NULL) { - crm_debug_4("No message this time"); - continue; - } - - lpc++; - received_responses++; - - xml = convert_ipc_message(msg, __FUNCTION__); - msg->msg_done(msg); - crm_log_xml(LOG_MSG, "ipc", xml); - - if (xml == NULL) { - crm_info("XML in IPC message was not valid... " - "discarding."); - goto cleanup; - - } else if (validate_crm_message( - xml, crm_system_name, admin_uuid, - XML_ATTR_RESPONSE) == FALSE) { - crm_debug_2("Message was not a CRM response. Discarding."); - goto cleanup; - } - - result = crm_element_value(xml, XML_ATTR_RESULT); - if(result == NULL || strcasecmp(result, "ok") == 0) { - result = "pass"; - } else { - result = "fail"; - } - - if(DO_HEALTH) { - xmlNode *data = get_message_xml(xml, F_CRM_DATA); - const char *state = crm_element_value(data, "crmd_state"); - - printf("Status of %s@%s: %s (%s)\n", - crm_element_value(data,XML_PING_ATTR_SYSFROM), - crm_element_value(xml, F_CRM_HOST_FROM), - state, - crm_element_value(data,XML_PING_ATTR_STATUS)); - - if(BE_SILENT && state != NULL) { - fprintf(stderr, "%s\n", state); - } - - } else if(DO_WHOIS_DC) { - const char *dc = crm_element_value(xml, F_CRM_HOST_FROM); - - printf("Designated Controller is: %s\n", dc); - if(BE_SILENT && dc != NULL) { - fprintf(stderr, "%s\n", dc); - } - } - - cleanup: - free_xml(xml); - xml = NULL; + while (server->ch_status != IPC_DISCONNECT && server->ops->is_message_pending(server) == TRUE) { + rc = server->ops->recv(server, &msg); + if (rc != IPC_OK) { + crm_perror(LOG_ERR, "Receive failure (%d)", rc); + return !hack_return_good; + } + + if (msg == NULL) { + crm_debug_4("No message this time"); + continue; + } + + lpc++; + received_responses++; + + xml = convert_ipc_message(msg, __FUNCTION__); + msg->msg_done(msg); + crm_log_xml(LOG_MSG, "ipc", xml); + + if (xml == NULL) { + crm_info("XML in IPC message was not valid... " "discarding."); + goto cleanup; + + } else if (validate_crm_message(xml, crm_system_name, admin_uuid, + XML_ATTR_RESPONSE) == FALSE) { + crm_debug_2("Message was not a CRM response. Discarding."); + goto cleanup; + } + + result = crm_element_value(xml, XML_ATTR_RESULT); + if (result == NULL || strcasecmp(result, "ok") == 0) { + result = "pass"; + } else { + result = "fail"; + } + + if (DO_HEALTH) { + xmlNode *data = get_message_xml(xml, F_CRM_DATA); + const char *state = crm_element_value(data, "crmd_state"); + + printf("Status of %s@%s: %s (%s)\n", + crm_element_value(data, XML_PING_ATTR_SYSFROM), + crm_element_value(xml, F_CRM_HOST_FROM), + state, crm_element_value(data, XML_PING_ATTR_STATUS)); + + if (BE_SILENT && state != NULL) { + fprintf(stderr, "%s\n", state); + } + + } else if (DO_WHOIS_DC) { + const char *dc = crm_element_value(xml, F_CRM_HOST_FROM); + + printf("Designated Controller is: %s\n", dc); + if (BE_SILENT && dc != NULL) { + fprintf(stderr, "%s\n", dc); + } + } + + cleanup: + free_xml(xml); + xml = NULL; } if (server->ch_status == IPC_DISCONNECT) { - crm_debug_2("admin_msg_callback: received HUP"); - return !hack_return_good; + crm_debug_2("admin_msg_callback: received HUP"); + return !hack_return_good; } if (received_responses >= expected_responses) { - crm_debug_2( - "Received expected number (%d) of messages from Heartbeat." - " Exiting normally.", expected_responses); - exit(0); + crm_debug_2("Received expected number (%d) of messages from Heartbeat." + " Exiting normally.", expected_responses); + exit(0); } - message_timer_id = g_timeout_add( - message_timeout_ms, admin_message_timeout, NULL); - - + message_timer_id = g_timeout_add(message_timeout_ms, admin_message_timeout, NULL); + return hack_return_good; } gboolean admin_message_timeout(gpointer data) { fprintf(stderr, "No messages received in %d seconds.. aborting\n", - (int)message_timeout_ms/1000); - crm_err("No messages received in %d seconds", - (int)message_timeout_ms/1000); + (int)message_timeout_ms / 1000); + crm_err("No messages received in %d seconds", (int)message_timeout_ms / 1000); operation_status = -3; g_main_quit(mainloop); return FALSE; } - gboolean -is_node_online(xmlNode *node_state) +is_node_online(xmlNode * node_state) { - const char *uname = crm_element_value(node_state,XML_ATTR_UNAME); - const char *join_state = crm_element_value(node_state,XML_CIB_ATTR_JOINSTATE); - const char *exp_state = crm_element_value(node_state,XML_CIB_ATTR_EXPSTATE); - const char *crm_state = crm_element_value(node_state,XML_CIB_ATTR_CRMDSTATE); - const char *ha_state = crm_element_value(node_state,XML_CIB_ATTR_HASTATE); - const char *ccm_state = crm_element_value(node_state,XML_CIB_ATTR_INCCM); - - if(safe_str_neq(join_state, CRMD_JOINSTATE_DOWN) - && (ha_state == NULL || safe_str_eq(ha_state, "active")) - && crm_is_true(ccm_state) - && safe_str_eq(crm_state, "online")) { - crm_debug_3("Node %s is online", uname); - return TRUE; + const char *uname = crm_element_value(node_state, XML_ATTR_UNAME); + const char *join_state = crm_element_value(node_state, XML_CIB_ATTR_JOINSTATE); + const char *exp_state = crm_element_value(node_state, XML_CIB_ATTR_EXPSTATE); + const char *crm_state = crm_element_value(node_state, XML_CIB_ATTR_CRMDSTATE); + const char *ha_state = crm_element_value(node_state, XML_CIB_ATTR_HASTATE); + const char *ccm_state = crm_element_value(node_state, XML_CIB_ATTR_INCCM); + + if (safe_str_neq(join_state, CRMD_JOINSTATE_DOWN) + && (ha_state == NULL || safe_str_eq(ha_state, "active")) + && crm_is_true(ccm_state) + && safe_str_eq(crm_state, "online")) { + crm_debug_3("Node %s is online", uname); + return TRUE; } crm_debug_3("Node %s: ha=%s ccm=%s join=%s exp=%s crm=%s", - uname, crm_str(ha_state), crm_str(ccm_state), - crm_str(join_state), crm_str(exp_state), - crm_str(crm_state)); + uname, crm_str(ha_state), crm_str(ccm_state), + crm_str(join_state), crm_str(exp_state), crm_str(crm_state)); crm_debug_3("Node %s is offline", uname); return FALSE; } int -do_find_node_list(xmlNode *xml_node) +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 = __xml_first_child(nodes); node != NULL; node = __xml_next(node)) { - if(crm_str_eq((const char *)node->name, XML_CIB_TAG_NODE, TRUE)) { - - if(BASH_EXPORT) { - printf("export %s=%s\n", - crm_element_value(node, XML_ATTR_UNAME), - crm_element_value(node, XML_ATTR_ID)); - } else { - printf("%s node: %s (%s)\n", - crm_element_value(node, XML_ATTR_TYPE), - crm_element_value(node, XML_ATTR_UNAME), - crm_element_value(node, XML_ATTR_ID)); - } - found++; - } + for (node = __xml_first_child(nodes); node != NULL; node = __xml_next(node)) { + if (crm_str_eq((const char *)node->name, XML_CIB_TAG_NODE, TRUE)) { + + if (BASH_EXPORT) { + printf("export %s=%s\n", + crm_element_value(node, XML_ATTR_UNAME), + crm_element_value(node, XML_ATTR_ID)); + } else { + printf("%s node: %s (%s)\n", + crm_element_value(node, XML_ATTR_TYPE), + crm_element_value(node, XML_ATTR_UNAME), + crm_element_value(node, XML_ATTR_ID)); + } + found++; + } } - - if(found == 0) { - printf("NO nodes configured\n"); + + if (found == 0) { + printf("NO nodes configured\n"); } - + return found; } diff --git a/tools/ipmiservicelogd.c b/tools/ipmiservicelogd.c index bf4a2b8c77..1170157995 100644 --- a/tools/ipmiservicelogd.c +++ b/tools/ipmiservicelogd.c @@ -1,628 +1,607 @@ /* * ipmiservicelogd.c * * A program that listens to IPMI events and writes them * out to servicelog. * * Author: International Business Machines, IBM * Mark Hamzy * Author: Intel Corporation * Jeff Zheng * * Copyright 2009 International Business Machines, IBM * * 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 PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* gcc -o ipmiservicelogd -g `pkg-config --cflags --libs OpenIPMI OpenIPMIposix servicelog-1` ipmiservicelogd.c */ /* ./ipmiservicelogd smi 0 */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define COMPLEX 1 static os_handler_t *os_hnd; -char *getStringExecOutput (char *args[]); -char *getSerialNumber (void); -char *getProductName (void); -static void con_usage (const char *name, const char *help, void *cb_data); -static void usage (const char *progname); -void ipmi2servicelog (struct sl_data_bmc *bmc_data); -static int sensor_threshold_event_handler (ipmi_sensor_t *sensor, enum ipmi_event_dir_e dir, enum ipmi_thresh_e threshold, enum ipmi_event_value_dir_e high_low, enum ipmi_value_present_e value_present, unsigned int raw_value, double value, void *cb_data, ipmi_event_t *event); -static int sensor_discrete_event_handler (ipmi_sensor_t *sensor, enum ipmi_event_dir_e dir, int offset, int severity, int prev_severity, void *cb_data, ipmi_event_t *event); -static void sensor_change (enum ipmi_update_e op, ipmi_entity_t *ent, ipmi_sensor_t *sensor, void *cb_data); -static void entity_change (enum ipmi_update_e op, ipmi_domain_t *domain, ipmi_entity_t *entity, void *cb_data); -void setup_done (ipmi_domain_t *domain, int err, unsigned int conn_num, unsigned int port_num, int still_connected, void *user_data); +char *getStringExecOutput(char *args[]); +char *getSerialNumber(void); +char *getProductName(void); +static void con_usage(const char *name, const char *help, void *cb_data); +static void usage(const char *progname); +void ipmi2servicelog(struct sl_data_bmc *bmc_data); +static int sensor_threshold_event_handler(ipmi_sensor_t * sensor, enum ipmi_event_dir_e dir, + enum ipmi_thresh_e threshold, + enum ipmi_event_value_dir_e high_low, + enum ipmi_value_present_e value_present, + unsigned int raw_value, double value, void *cb_data, + ipmi_event_t * event); +static int sensor_discrete_event_handler(ipmi_sensor_t * sensor, enum ipmi_event_dir_e dir, + int offset, int severity, int prev_severity, void *cb_data, + ipmi_event_t * event); +static void sensor_change(enum ipmi_update_e op, ipmi_entity_t * ent, ipmi_sensor_t * sensor, + void *cb_data); +static void entity_change(enum ipmi_update_e op, ipmi_domain_t * domain, ipmi_entity_t * entity, + void *cb_data); +void setup_done(ipmi_domain_t * domain, int err, unsigned int conn_num, unsigned int port_num, + int still_connected, void *user_data); char * -getStringExecOutput (char *args[]) +getStringExecOutput(char *args[]) { - int rc; - pid_t pid; - int pipefd[2]; + int rc; + pid_t pid; + int pipefd[2]; - rc = pipe2 (pipefd, 0); + rc = pipe2(pipefd, 0); - if (rc == -1) { + if (rc == -1) { - crm_err ("Error: pipe errno = %d", errno); + crm_err("Error: pipe errno = %d", errno); - return NULL; - } + return NULL; + } - pid = fork (); + pid = fork(); - if (0 < pid) { + if (0 < pid) { - /* Parent */ - int childExitStatus; - char serialNumber[256]; - ssize_t sizeRead; + /* Parent */ + int childExitStatus; + char serialNumber[256]; + ssize_t sizeRead; - /* close write end of pipe */ - rc = close (pipefd[1]); - if (rc == -1) { - crm_err ("Error: parent close (pipefd[1]) = %d", errno); - } + /* close write end of pipe */ + rc = close(pipefd[1]); + if (rc == -1) { + crm_err("Error: parent close (pipefd[1]) = %d", errno); + } - /* make 0 same as read-from end of pipe */ - rc = dup2 (pipefd[0], 0); - if (rc == -1) { - crm_err ("Error: parent dup2 (pipefd[0]) = %d", errno); - } + /* make 0 same as read-from end of pipe */ + rc = dup2(pipefd[0], 0); + if (rc == -1) { + crm_err("Error: parent dup2 (pipefd[0]) = %d", errno); + } - /* close excess fildes */ - rc = close (pipefd[0]); - if (rc == -1) { - crm_err ("Error: parent close (pipefd[0]) = %d", errno); - } + /* close excess fildes */ + rc = close(pipefd[0]); + if (rc == -1) { + crm_err("Error: parent close (pipefd[0]) = %d", errno); + } - waitpid (pid, &childExitStatus, 0); + waitpid(pid, &childExitStatus, 0); - if (!WIFEXITED(childExitStatus)) { + if (!WIFEXITED(childExitStatus)) { - crm_err ("waitpid() exited with an error: status = %d", WEXITSTATUS(childExitStatus)); + crm_err("waitpid() exited with an error: status = %d", WEXITSTATUS(childExitStatus)); - return NULL; + return NULL; - } else if (WIFSIGNALED(childExitStatus)) { + } else if (WIFSIGNALED(childExitStatus)) { - crm_err ("waitpid() exited due to a signal = %d", WTERMSIG(childExitStatus)); + crm_err("waitpid() exited due to a signal = %d", WTERMSIG(childExitStatus)); - return NULL; + return NULL; - } + } - memset (serialNumber, 0, sizeof (serialNumber)); + memset(serialNumber, 0, sizeof(serialNumber)); - sizeRead = read (0, serialNumber, sizeof (serialNumber) - 1); + sizeRead = read(0, serialNumber, sizeof(serialNumber) - 1); - if (sizeRead > 0) { + if (sizeRead > 0) { - char *end = serialNumber + strlen (serialNumber) - 1; - char *retSerialNumber = NULL; + char *end = serialNumber + strlen(serialNumber) - 1; + char *retSerialNumber = NULL; - while ( end > serialNumber - && (*end == '\n' || *end == '\r' || *end == '\t' || *end == ' ') - ) { - *end = '\0'; - end--; - } + while (end > serialNumber + && (*end == '\n' || *end == '\r' || *end == '\t' || *end == ' ') + ) { + *end = '\0'; + end--; + } - retSerialNumber = malloc (strlen (serialNumber) + 1); + retSerialNumber = malloc(strlen(serialNumber) + 1); - if (retSerialNumber) { + if (retSerialNumber) { - strcpy (retSerialNumber, serialNumber); + strcpy(retSerialNumber, serialNumber); - } + } - return retSerialNumber; + return retSerialNumber; - } + } - return NULL; + return NULL; - } else if (pid == 0) { + } else if (pid == 0) { - /* Child */ + /* Child */ - /* close read end of pipe */ - rc = close (pipefd[0]); - if (rc == -1) { - crm_err ("Error: child close (pipefd[0]) = %d", errno); - } + /* close read end of pipe */ + rc = close(pipefd[0]); + if (rc == -1) { + crm_err("Error: child close (pipefd[0]) = %d", errno); + } - /* make 1 same as write-to end of pipe */ - rc = dup2 (pipefd[1], 1); - if (rc == -1) { - crm_err ("Error: child dup2 (pipefd[1]) = %d", errno); - } + /* make 1 same as write-to end of pipe */ + rc = dup2(pipefd[1], 1); + if (rc == -1) { + crm_err("Error: child dup2 (pipefd[1]) = %d", errno); + } - /* close excess fildes */ - rc = close (pipefd[1]); - if (rc == -1) { - crm_err ("Error: child close (pipefd[1]) = %d", errno); - } + /* close excess fildes */ + rc = close(pipefd[1]); + if (rc == -1) { + crm_err("Error: child close (pipefd[1]) = %d", errno); + } - rc = execvp (args[0], args); + rc = execvp(args[0], args); - if (rc == -1) { - crm_err ("Error: child execvp = %d", errno); - } + if (rc == -1) { + crm_err("Error: child execvp = %d", errno); + } - /* In case of error */ - return NULL; + /* In case of error */ + return NULL; - } else { + } else { - /* Error */ - crm_err ("fork errno = %d", errno); + /* Error */ + crm_err("fork errno = %d", errno); - return NULL; - } + return NULL; + } - return NULL; + return NULL; } char * -getSerialNumber (void) +getSerialNumber(void) { - char *dmiArgs[] = { - "dmidecode", - "--string", - "system-serial-number", - NULL - }; - - return getStringExecOutput (dmiArgs); + char *dmiArgs[] = { + "dmidecode", + "--string", + "system-serial-number", + NULL + }; + + return getStringExecOutput(dmiArgs); } char * -getProductName (void) +getProductName(void) { - char *dmiArgs[] = { - "dmidecode", - "--string", - "system-product-name", - NULL - }; - - return getStringExecOutput (dmiArgs); + char *dmiArgs[] = { + "dmidecode", + "--string", + "system-product-name", + NULL + }; + + return getStringExecOutput(dmiArgs); } static void -con_usage (const char *name, const char *help, void *cb_data) +con_usage(const char *name, const char *help, void *cb_data) { printf("\n%s%s", name, help); } static void usage(const char *progname) { printf("Usage:\n"); printf(" %s \n", progname); printf(" Where is one of:"); ipmi_parse_args_iter_help(con_usage, NULL); } void -ipmi2servicelog (struct sl_data_bmc *bmc_data) +ipmi2servicelog(struct sl_data_bmc *bmc_data) { - servicelog *slog = NULL; - struct sl_event sl_event; - uint64_t new_id = 0; - struct utsname name; - char *serial_number = NULL; - char *product_name = NULL; - int rc; - - if (uname (&name) == -1) - { - crm_err ("Error: uname failed"); - return; + servicelog *slog = NULL; + struct sl_event sl_event; + uint64_t new_id = 0; + struct utsname name; + char *serial_number = NULL; + char *product_name = NULL; + int rc; + + if (uname(&name) == -1) { + crm_err("Error: uname failed"); + return; } - rc = servicelog_open (&slog, 0); /* flags is one of SL_FLAG_xxx */ + rc = servicelog_open(&slog, 0); /* flags is one of SL_FLAG_xxx */ - if (!slog) - { - crm_err ("Error: servicelog_open failed, rc = %d", rc); - return; + if (!slog) { + crm_err("Error: servicelog_open failed, rc = %d", rc); + return; } - serial_number = getSerialNumber (); + serial_number = getSerialNumber(); if (serial_number) { - if (strlen (serial_number) > 20) { - serial_number[20] = '\0'; - } + if (strlen(serial_number) > 20) { + serial_number[20] = '\0'; + } } - product_name = getProductName (); + product_name = getProductName(); if (product_name) { - if (strlen (product_name) > 20) { - product_name[20] = '\0'; - } + if (strlen(product_name) > 20) { + product_name[20] = '\0'; + } } - memset (&sl_event, 0, sizeof (sl_event)); + memset(&sl_event, 0, sizeof(sl_event)); /* *INDENT-OFF* */ sl_event.next = NULL; /* only used if in a linked list */ sl_event.id = 0; /* unique identifier - filled in by API call */ sl_event.time_logged = time (NULL); sl_event.time_event = time (NULL); sl_event.time_last_update = time (NULL); sl_event.type = SL_TYPE_BMC; /* one of SL_TYPE_* */ sl_event.severity = SL_SEV_WARNING; /* one of SL_SEV_* */ sl_event.platform = name.machine; /* ppc64, etc */ sl_event.machine_serial = serial_number; sl_event.machine_model = product_name; /* it may not have the serial # within the first 20 chars */ sl_event.nodename = name.nodename; sl_event.refcode = "ipmi"; sl_event.description = "ipmi event"; sl_event.serviceable = 1; /* 1 or 0 */ sl_event.predictive = 0; /* 1 or 0 */ sl_event.disposition = SL_DISP_RECOVERABLE; /* one of SL_DISP_* */ sl_event.call_home_status = SL_CALLHOME_NONE; /* one of SL_CALLHOME_*, only valid if serviceable */ sl_event.closed = 1; /* 1 or 0, only valid if serviceable */ sl_event.repair = 0; /* id of repairing repair_action */ sl_event.callouts = NULL; sl_event.raw_data_len = 0; sl_event.raw_data = NULL; sl_event.addl_data = &bmc_data; /* pointer to an sl_data_* struct */ /* *INDENT-ON* */ - rc = servicelog_event_log (slog, &sl_event, &new_id); + rc = servicelog_event_log(slog, &sl_event, &new_id); - if (rc != 0) - { - crm_err ("Error: servicelog_event_log, rc = %d (\"%s\")", rc, servicelog_error (slog)); - } - else - { - crm_debug ("Sending to servicelog database"); + if (rc != 0) { + crm_err("Error: servicelog_event_log, rc = %d (\"%s\")", rc, servicelog_error(slog)); + } else { + crm_debug("Sending to servicelog database"); } - free (serial_number); - free (product_name); + free(serial_number); + free(product_name); - servicelog_close (slog); + servicelog_close(slog); } static int -sensor_threshold_event_handler(ipmi_sensor_t *sensor, - enum ipmi_event_dir_e dir, - enum ipmi_thresh_e threshold, - enum ipmi_event_value_dir_e high_low, - enum ipmi_value_present_e value_present, - unsigned int raw_value, - double value, - void *cb_data, - ipmi_event_t *event) +sensor_threshold_event_handler(ipmi_sensor_t * sensor, + enum ipmi_event_dir_e dir, + enum ipmi_thresh_e threshold, + enum ipmi_event_value_dir_e high_low, + enum ipmi_value_present_e value_present, + unsigned int raw_value, + double value, void *cb_data, ipmi_event_t * event) { - ipmi_entity_t *ent = ipmi_sensor_get_entity(sensor); - int id, - instance; - char name[IPMI_ENTITY_NAME_LEN]; - struct sl_data_bmc bmc_data; - uint32_t sel_id; - uint32_t sel_type; - uint16_t generator; - uint8_t version; - uint8_t sensor_type; - int sensor_lun; - int sensor_number; - uint8_t event_class; - uint8_t event_type; - int direction; + ipmi_entity_t *ent = ipmi_sensor_get_entity(sensor); + int id, instance; + char name[IPMI_ENTITY_NAME_LEN]; + struct sl_data_bmc bmc_data; + uint32_t sel_id; + uint32_t sel_type; + uint16_t generator; + uint8_t version; + uint8_t sensor_type; + int sensor_lun; + int sensor_number; + uint8_t event_class; + uint8_t event_type; + int direction; id = ipmi_entity_get_entity_id(ent); instance = ipmi_entity_get_entity_instance(ent); - ipmi_sensor_get_id(sensor, name, sizeof (name)); - - ipmi_sensor_get_num (sensor, &sensor_lun, &sensor_number); - - sel_id = ipmi_entity_get_entity_id (ent); - sel_type = ipmi_entity_get_type (ent); - generator = ipmi_entity_get_slave_address (ent) | (sensor_lun << 5); /* LUN (2 bits) | SLAVE ADDRESS (5 bits) */ - version = 0x04; - sensor_type = ipmi_sensor_get_sensor_type (sensor); - event_class = 0; /* @TBD - where does this come from? */ - event_type = ipmi_event_get_type (event); - direction = dir; - - memset (&bmc_data, 0, sizeof (bmc_data)); - - bmc_data.sel_id = sel_id; - bmc_data.sel_type = sel_type; - bmc_data.generator = generator; - bmc_data.version = version; - bmc_data.sensor_type = sensor_type; - bmc_data.sensor_number = sensor_number; - bmc_data.event_class = event_class; - bmc_data.event_type = event_type; - bmc_data.direction = direction; - - crm_debug ("Writing bmc_data (%08x, %08x, %04x, %02x, %02x, %02x, %02x, %02x, %d)\n", - bmc_data.sel_id, - bmc_data.sel_type, - bmc_data.generator, - bmc_data.version, - bmc_data.sensor_type, - bmc_data.sensor_number, - bmc_data.event_class, - bmc_data.event_type, - bmc_data.direction); - - ipmi2servicelog (&bmc_data); + ipmi_sensor_get_id(sensor, name, sizeof(name)); + + ipmi_sensor_get_num(sensor, &sensor_lun, &sensor_number); + + sel_id = ipmi_entity_get_entity_id(ent); + sel_type = ipmi_entity_get_type(ent); + generator = ipmi_entity_get_slave_address(ent) | (sensor_lun << 5); /* LUN (2 bits) | SLAVE ADDRESS (5 bits) */ + version = 0x04; + sensor_type = ipmi_sensor_get_sensor_type(sensor); + event_class = 0; /* @TBD - where does this come from? */ + event_type = ipmi_event_get_type(event); + direction = dir; + + memset(&bmc_data, 0, sizeof(bmc_data)); + + bmc_data.sel_id = sel_id; + bmc_data.sel_type = sel_type; + bmc_data.generator = generator; + bmc_data.version = version; + bmc_data.sensor_type = sensor_type; + bmc_data.sensor_number = sensor_number; + bmc_data.event_class = event_class; + bmc_data.event_type = event_type; + bmc_data.direction = direction; + + crm_debug("Writing bmc_data (%08x, %08x, %04x, %02x, %02x, %02x, %02x, %02x, %d)\n", + bmc_data.sel_id, + bmc_data.sel_type, + bmc_data.generator, + bmc_data.version, + bmc_data.sensor_type, + bmc_data.sensor_number, + bmc_data.event_class, bmc_data.event_type, bmc_data.direction); + + ipmi2servicelog(&bmc_data); /* This passes the event on to the main event handler, which does not exist in this program. */ return IPMI_EVENT_NOT_HANDLED; } static int -sensor_discrete_event_handler(ipmi_sensor_t *sensor, - enum ipmi_event_dir_e dir, - int offset, - int severity, - int prev_severity, - void *cb_data, - ipmi_event_t *event) +sensor_discrete_event_handler(ipmi_sensor_t * sensor, + enum ipmi_event_dir_e dir, + int offset, + int severity, int prev_severity, void *cb_data, ipmi_event_t * event) { - ipmi_entity_t *ent = ipmi_sensor_get_entity(sensor); - int id, - instance; - char name[IPMI_ENTITY_NAME_LEN]; - struct sl_data_bmc bmc_data; - uint32_t sel_id; - uint32_t sel_type; - uint16_t generator; - uint8_t version; - uint8_t sensor_type; - int sensor_lun; - int sensor_number; - uint8_t event_class; - uint8_t event_type; - int direction; + ipmi_entity_t *ent = ipmi_sensor_get_entity(sensor); + int id, instance; + char name[IPMI_ENTITY_NAME_LEN]; + struct sl_data_bmc bmc_data; + uint32_t sel_id; + uint32_t sel_type; + uint16_t generator; + uint8_t version; + uint8_t sensor_type; + int sensor_lun; + int sensor_number; + uint8_t event_class; + uint8_t event_type; + int direction; id = ipmi_entity_get_entity_id(ent); instance = ipmi_entity_get_entity_instance(ent); - ipmi_sensor_get_id(sensor, name, sizeof (name)); + ipmi_sensor_get_id(sensor, name, sizeof(name)); - sel_id = ipmi_entity_get_entity_id (ent); - sel_type = ipmi_entity_get_type (ent); - generator = ipmi_entity_get_slave_address (ent) | (sensor_lun << 5); /* LUN (2 bits) | SLAVE ADDRESS (5 bits) */ - version = 0x04; - sensor_type = ipmi_sensor_get_sensor_type (sensor); + sel_id = ipmi_entity_get_entity_id(ent); + sel_type = ipmi_entity_get_type(ent); + generator = ipmi_entity_get_slave_address(ent) | (sensor_lun << 5); /* LUN (2 bits) | SLAVE ADDRESS (5 bits) */ + version = 0x04; + sensor_type = ipmi_sensor_get_sensor_type(sensor); - ipmi_sensor_get_num (sensor, &sensor_lun, &sensor_number); + ipmi_sensor_get_num(sensor, &sensor_lun, &sensor_number); - event_class = 0; /* @TBD - where does this come from? */ - event_type = ipmi_event_get_type (event); - direction = dir; + event_class = 0; /* @TBD - where does this come from? */ + event_type = ipmi_event_get_type(event); + direction = dir; - memset (&bmc_data, 0, sizeof (bmc_data)); + memset(&bmc_data, 0, sizeof(bmc_data)); - bmc_data.sel_id = sel_id; - bmc_data.sel_type = sel_type; - bmc_data.generator = generator; - bmc_data.version = version; - bmc_data.sensor_type = sensor_type; + bmc_data.sel_id = sel_id; + bmc_data.sel_type = sel_type; + bmc_data.generator = generator; + bmc_data.version = version; + bmc_data.sensor_type = sensor_type; bmc_data.sensor_number = sensor_number; - bmc_data.event_class = event_class; - bmc_data.event_type = event_type; - bmc_data.direction = direction; - - crm_debug ("Writing bmc_data (%08x, %08x, %04x, %02x, %02x, %02x, %02x, %02x, %d)\n", - bmc_data.sel_id, - bmc_data.sel_type, - bmc_data.generator, - bmc_data.version, - bmc_data.sensor_type, - bmc_data.sensor_number, - bmc_data.event_class, - bmc_data.event_type, - bmc_data.direction); - - ipmi2servicelog (&bmc_data); + bmc_data.event_class = event_class; + bmc_data.event_type = event_type; + bmc_data.direction = direction; + + crm_debug("Writing bmc_data (%08x, %08x, %04x, %02x, %02x, %02x, %02x, %02x, %d)\n", + bmc_data.sel_id, + bmc_data.sel_type, + bmc_data.generator, + bmc_data.version, + bmc_data.sensor_type, + bmc_data.sensor_number, + bmc_data.event_class, bmc_data.event_type, bmc_data.direction); + + ipmi2servicelog(&bmc_data); /* This passes the event on to the main event handler, which does not exist in this program. */ return IPMI_EVENT_NOT_HANDLED; } /* Whenever the status of a sensor changes, the function is called We display the information of the sensor if we find a new sensor */ static void -sensor_change(enum ipmi_update_e op, - ipmi_entity_t *ent, - ipmi_sensor_t *sensor, - void *cb_data) +sensor_change(enum ipmi_update_e op, ipmi_entity_t * ent, ipmi_sensor_t * sensor, void *cb_data) { int rv; if (op == IPMI_ADDED) { - if (ipmi_sensor_get_event_reading_type(sensor) == IPMI_EVENT_READING_TYPE_THRESHOLD) - rv = ipmi_sensor_add_threshold_event_handler (sensor, - sensor_threshold_event_handler, - NULL); - else - rv = ipmi_sensor_add_discrete_event_handler (sensor, - sensor_discrete_event_handler, - NULL); - if (rv) - crm_err ("Unable to add the sensor event handler: %x", rv); + if (ipmi_sensor_get_event_reading_type(sensor) == IPMI_EVENT_READING_TYPE_THRESHOLD) + rv = ipmi_sensor_add_threshold_event_handler(sensor, + sensor_threshold_event_handler, NULL); + else + rv = ipmi_sensor_add_discrete_event_handler(sensor, + sensor_discrete_event_handler, NULL); + if (rv) + crm_err("Unable to add the sensor event handler: %x", rv); } } /* Whenever the status of an entity changes, the function is called When a new entity is created, we search all sensors that belong to the entity */ static void -entity_change(enum ipmi_update_e op, - ipmi_domain_t *domain, - ipmi_entity_t *entity, - void *cb_data) +entity_change(enum ipmi_update_e op, ipmi_domain_t * domain, ipmi_entity_t * entity, void *cb_data) { int rv; int id, instance; id = ipmi_entity_get_entity_id(entity); instance = ipmi_entity_get_entity_instance(entity); if (op == IPMI_ADDED) { - /* Register callback so that when the status of a - sensor changes, sensor_change is called */ - rv = ipmi_entity_add_sensor_update_handler(entity, - sensor_change, - entity); - if (rv) { - crm_err ("ipmi_entity_set_sensor_update_handler: 0x%x", rv); - exit(1); - } + /* Register callback so that when the status of a + sensor changes, sensor_change is called */ + rv = ipmi_entity_add_sensor_update_handler(entity, sensor_change, entity); + if (rv) { + crm_err("ipmi_entity_set_sensor_update_handler: 0x%x", rv); + exit(1); + } } } /* After we have established connection to domain, this function get called At this time, we can do whatever things we want to do. Herr we want to - search all entities in the system */ + search all entities in the system */ void -setup_done(ipmi_domain_t *domain, - int err, - unsigned int conn_num, - unsigned int port_num, - int still_connected, - void *user_data) +setup_done(ipmi_domain_t * domain, + int err, + unsigned int conn_num, unsigned int port_num, int still_connected, void *user_data) { int rv; /* Register a callback functin entity_change. When a new entities is created, entity_change is called */ rv = ipmi_domain_add_entity_update_handler(domain, entity_change, domain); - if (rv) { - crm_err ("ipmi_domain_add_entity_update_handler return error: %d", rv); - return; + if (rv) { + crm_err("ipmi_domain_add_entity_update_handler return error: %d", rv); + return; } } int main(int argc, char *argv[]) { - int rv; - int curr_arg = 1; + int rv; + int curr_arg = 1; ipmi_args_t *args; - ipmi_con_t *con; + ipmi_con_t *con; /* OS handler allocated first. */ os_hnd = ipmi_posix_setup_os_handler(); if (!os_hnd) { - crm_err ("ipmi_smi_setup_con: Unable to allocate os handler"); - exit(1); + crm_err("ipmi_smi_setup_con: Unable to allocate os handler"); + exit(1); } /* Initialize the OpenIPMI library. */ ipmi_init(os_hnd); #ifdef COMPLEX rv = ipmi_parse_args2(&curr_arg, argc, argv, &args); if (rv) { - crm_err ("Error parsing command arguments, argument %d: %s", - curr_arg, strerror(rv)); - usage(argv[0]); - exit(1); + crm_err("Error parsing command arguments, argument %d: %s", curr_arg, strerror(rv)); + usage(argv[0]); + exit(1); } #endif - crm_make_daemon ("ipmiservicelogd", TRUE, "/var/run/ipmiservicelogd.pid0"); + crm_make_daemon("ipmiservicelogd", TRUE, "/var/run/ipmiservicelogd.pid0"); - crm_log_init ("ipmiservicelogd", LOG_INFO, FALSE, TRUE, argc, argv); + crm_log_init("ipmiservicelogd", LOG_INFO, FALSE, TRUE, argc, argv); #ifdef COMPLEX rv = ipmi_args_setup_con(args, os_hnd, NULL, &con); if (rv) { - crm_err ("ipmi_ip_setup_con: %s", strerror(rv)); - crm_err ("Error: Is IPMI configured correctly?"); - exit(1); + crm_err("ipmi_ip_setup_con: %s", strerror(rv)); + crm_err("Error: Is IPMI configured correctly?"); + exit(1); } #else /* If all you need is an SMI connection, this is all the code you need. */ /* Establish connections to domain through system interface. This function connect domain, selector and OS handler together. When there is response message from domain, the status of file descriptor in selector is changed and predefined callback is called. After the connection is established, setup_done will be called. */ rv = ipmi_smi_setup_con(0, os_hnd, NULL, &con); if (rv) { - crm_err ("ipmi_smi_setup_con: %s", strerror(rv)); - crm_err ("Error: Is IPMI configured correctly?"); - exit(1); + crm_err("ipmi_smi_setup_con: %s", strerror(rv)); + crm_err("Error: Is IPMI configured correctly?"); + exit(1); } #endif - rv = ipmi_open_domain("", &con, 1, setup_done, NULL, NULL, NULL, - NULL, 0, NULL); + rv = ipmi_open_domain("", &con, 1, setup_done, NULL, NULL, NULL, NULL, 0, NULL); if (rv) { - crm_err ("ipmi_init_domain: %s", strerror(rv)); - exit(1); + crm_err("ipmi_init_domain: %s", strerror(rv)); + exit(1); } /* This is the main loop of the event-driven program. - Try to exit the program */ + Try to exit the program */ /* Let the selector code run the select loop. */ os_hnd->operation_loop(os_hnd); /* Technically, we can't get here, but this is an example. */ os_hnd->free_os_handler(os_hnd); } diff --git a/tools/notifyServicelogEvent.c b/tools/notifyServicelogEvent.c index 25ebbcf59e..d9c367f4c3 100644 --- a/tools/notifyServicelogEvent.c +++ b/tools/notifyServicelogEvent.c @@ -1,218 +1,196 @@ /* * Copyright (C) 2009 International Business Machines, IBM, Mark Hamzy * * 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 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 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 */ /* gcc -o notifyServicelogEvent `pkg-config --cflags servicelog-1` `pkg-config --libs servicelog-1` notifyServicelogEvent.c */ #include #include #include #include #include #include #include #include #include #include #include -typedef enum {STATUS_GREEN = 1, STATUS_YELLOW, STATUS_RED} STATUS; +typedef enum { STATUS_GREEN = 1, STATUS_YELLOW, STATUS_RED } STATUS; -const char * status2char (STATUS status); -STATUS event2status (struct sl_event *event); +const char *status2char(STATUS status); +STATUS event2status(struct sl_event *event); const char * -status2char (STATUS status) +status2char(STATUS status) { - switch (status) - { - default: - case STATUS_GREEN: - return "green"; - case STATUS_YELLOW: - return "yellow"; - case STATUS_RED: - return "red"; + switch (status) { + default: + case STATUS_GREEN: + return "green"; + case STATUS_YELLOW: + return "yellow"; + case STATUS_RED: + return "red"; } } STATUS -event2status (struct sl_event *event) +event2status(struct sl_event * event) { STATUS status = STATUS_GREEN; - crm_debug ("Severity = %d, Disposition = %d", event->severity, event->disposition); + crm_debug("Severity = %d, Disposition = %d", event->severity, event->disposition); /* @TBD */ - if (event->severity == SL_SEV_WARNING) - { - status = STATUS_YELLOW; + if (event->severity == SL_SEV_WARNING) { + status = STATUS_YELLOW; } - if (event->disposition == SL_DISP_UNRECOVERABLE) - { - status = STATUS_RED; + if (event->disposition == SL_DISP_UNRECOVERABLE) { + status = STATUS_RED; } return status; } static struct crm_option long_options[] = { /* Top-level Options */ - {"help", 0, 0, '?', "\tThis text"}, - {"version", 0, 0, '$', "\tVersion information" }, - {"-spacer-",0, 0, '-', "\nUsage: notifyServicelogEvent event_id"}, - {"-spacer-",0, 0, '-', "\nWhere event_id is unique unsigned event identifier which is then passed into servicelog"}, - + {"help", 0, 0, '?', "\tThis text"}, + {"version", 0, 0, '$', "\tVersion information"}, + {"-spacer-", 0, 0, '-', "\nUsage: notifyServicelogEvent event_id"}, + {"-spacer-", 0, 0, '-', + "\nWhere event_id is unique unsigned event identifier which is then passed into servicelog"}, + {0, 0, 0, 0} }; int -main (int argc, char *argv[]) +main(int argc, char *argv[]) { - int argerr = 0; - int flag; - int index = 0; - int rc = 0; - servicelog *slog = NULL; - struct sl_event *event = NULL; - uint64_t event_id = 0; - + int argerr = 0; + int flag; + int index = 0; + int rc = 0; + servicelog *slog = NULL; + struct sl_event *event = NULL; + uint64_t event_id = 0; + crm_log_init_quiet("notifyServicelogEvent", LOG_INFO, FALSE, TRUE, argc, argv); - crm_set_options(NULL, "event_id ", long_options, "Gets called upon events written to servicelog database"); - + crm_set_options(NULL, "event_id ", long_options, + "Gets called upon events written to servicelog database"); + if (argc < 2) { - argerr++; + argerr++; } while (1) { - flag = crm_get_option(argc, argv, &index); - if (flag == -1) - break; - - switch(flag) { - case '?': - case '$': - crm_help(flag, 0); - break; - default: - ++argerr; - break; + flag = crm_get_option(argc, argv, &index); + if (flag == -1) + break; + + switch (flag) { + case '?': + case '$': + crm_help(flag, 0); + break; + default: + ++argerr; + break; } } if (argc - optind != 1) { - ++argerr; + ++argerr; } if (argerr) { - crm_help('?', 1); + crm_help('?', 1); } - openlog ("notifyServicelogEvent", LOG_NDELAY, LOG_USER); + openlog("notifyServicelogEvent", LOG_NDELAY, LOG_USER); - if (sscanf (argv[optind], U64T, &event_id) != 1) - { - crm_err ("Error: could not read event_id from args!"); + if (sscanf(argv[optind], U64T, &event_id) != 1) { + crm_err("Error: could not read event_id from args!"); rc = 1; - goto cleanup; + goto cleanup; } - if (event_id == 0) - { - crm_err ("Error: event_id is 0!"); + if (event_id == 0) { + crm_err("Error: event_id is 0!"); rc = 1; - goto cleanup; + goto cleanup; } - rc = servicelog_open (&slog, 0); /* flags is one of SL_FLAG_xxx */ + rc = servicelog_open(&slog, 0); /* flags is one of SL_FLAG_xxx */ - if (!slog) - { - crm_err ("Error: servicelog_open failed, rc = %d", rc); + if (!slog) { + crm_err("Error: servicelog_open failed, rc = %d", rc); rc = 1; - goto cleanup; + goto cleanup; } - if (slog) - { - rc = servicelog_event_get (slog, event_id, &event); + if (slog) { + rc = servicelog_event_get(slog, event_id, &event); } - if (rc == 0) - { - STATUS status = STATUS_GREEN; - const char *health_component = "#health-ipmi"; - const char *health_status = NULL; - - crm_debug ("Event id = "U64T", Log timestamp = %s, Event timestamp = %s", - event_id, - ctime (&(event->time_logged)), - ctime (&(event->time_event))); - - status = event2status (event); - - health_status = status2char (status); - - if (health_status) - { - gboolean rc; - - rc = attrd_update_no_mainloop (NULL, - 'v', - NULL, - health_component, - health_status, - NULL, - NULL, - NULL); - - crm_debug ("attrd_update_no_mainloop ('%s', '%s') = %d", - health_component, - health_status, - rc); - } - else - { - crm_err ("Error: status2char failed, status = %d", status); - rc = 1; - } - } - else - { - crm_err ("Error: servicelog_event_get failed, rc = %d", rc); + if (rc == 0) { + STATUS status = STATUS_GREEN; + const char *health_component = "#health-ipmi"; + const char *health_status = NULL; + + crm_debug("Event id = " U64T ", Log timestamp = %s, Event timestamp = %s", + event_id, ctime(&(event->time_logged)), ctime(&(event->time_event))); + + status = event2status(event); + + health_status = status2char(status); + + if (health_status) { + gboolean rc; + + rc = attrd_update_no_mainloop(NULL, + 'v', + NULL, health_component, health_status, NULL, NULL, NULL); + + crm_debug("attrd_update_no_mainloop ('%s', '%s') = %d", + health_component, health_status, rc); + } else { + crm_err("Error: status2char failed, status = %d", status); + rc = 1; + } + } else { + crm_err("Error: servicelog_event_get failed, rc = %d", rc); } -cleanup: - if (event) - { - servicelog_event_free (event); + cleanup: + if (event) { + servicelog_event_free(event); } - if (slog) - { - servicelog_close (slog); + if (slog) { + servicelog_close(slog); } - closelog (); + closelog(); return rc; } diff --git a/tools/pingd.c b/tools/pingd.c index e8084a1737..9195a55106 100644 --- a/tools/pingd.c +++ b/tools/pingd.c @@ -1,1406 +1,1404 @@ /* * Copyright (C) 2004 Andrew Beekhof * * 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 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 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 */ #include #include #include #include #include #include #include #include #include #ifdef HAVE_SYS_SOCKET_H -# include +# include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef ON_LINUX -#include -#include -# ifndef ICMP_FILTER -# define ICMP_FILTER 1 +# include +# include +# ifndef ICMP_FILTER +# define ICMP_FILTER 1 struct icmp_filter { - uint32_t data; + uint32_t data; }; -# endif +# endif #endif #include #include #include #if SUPPORT_HEARTBEAT # include ll_cluster_t *pingd_cluster = NULL; -void do_node_walk(ll_cluster_t *hb_cluster); +void do_node_walk(ll_cluster_t * hb_cluster); #endif /* GMainLoop *mainloop = NULL; */ GListPtr ping_list = NULL; -GMainLoop* mainloop = NULL; +GMainLoop *mainloop = NULL; GHashTable *ping_nodes = NULL; const char *pingd_attr = "pingd"; gboolean do_filter = FALSE; gboolean need_shutdown = FALSE; gboolean stand_alone = FALSE; gboolean do_updates = TRUE; const char *attr_set = NULL; const char *attr_section = NULL; -int attr_dampen = 5000; /* 5s */ +int attr_dampen = 5000; /* 5s */ int attr_multiplier = 1; int pings_per_host = 2; int ping_timeout = 2; -int re_ping_interval = 1000; /* 1s */ +int re_ping_interval = 1000; /* 1s */ -int ident; /* our pid */ +int ident; /* our pid */ unsigned char cmsgbuf[4096]; int cmsglen = 0; typedef struct ping_node_s { - int fd; /* ping socket */ - uint16_t iseq; /* sequence number */ - gboolean type; - gboolean extra_filters; - union { - struct sockaddr raw; - struct sockaddr_in v4; /* ipv4 ping addr */ - struct sockaddr_in6 v6; /* ipv6 ping addr */ - } addr; - char dest[256]; - char *host; + int fd; /* ping socket */ + uint16_t iseq; /* sequence number */ + gboolean type; + gboolean extra_filters; + union { + struct sockaddr raw; + struct sockaddr_in v4; /* ipv4 ping addr */ + struct sockaddr_in6 v6; /* ipv6 ping addr */ + } addr; + char dest[256]; + char *host; } ping_node; -void pingd_nstatus_callback( - const char *node, const char *status, void *private_data); -void pingd_lstatus_callback( - const char *node, const char *link, const char *status, - void *private_data); +void pingd_nstatus_callback(const char *node, const char *status, void *private_data); +void pingd_lstatus_callback(const char *node, const char *link, const char *status, + void *private_data); void send_update(int active); -int process_icmp6_error(ping_node *node, struct sockaddr_in6 *whereto); -int process_icmp4_error(ping_node *node, struct sockaddr_in *whereto); +int process_icmp6_error(ping_node * node, struct sockaddr_in6 *whereto); +int process_icmp4_error(ping_node * node, struct sockaddr_in *whereto); /* * in_cksum -- * Checksum routine for Internet Protocol family headers (C Version) * This function taken from Mike Muuss' ping program. */ static int -in_cksum (u_short *addr, size_t len) +in_cksum(u_short * addr, size_t len) { - size_t nleft = len; - u_short * w = addr; - int sum = 0; - u_short answer = 0; - - /* - * The IP checksum algorithm is simple: using a 32 bit accumulator (sum) - * add sequential 16 bit words to it, and at the end, folding back all - * the carry bits from the top 16 bits into the lower 16 bits. - */ - while (nleft > 1) { - sum += *w++; - nleft -= 2; - } - - /* Mop up an odd byte, if necessary */ - if (nleft == 1) { - sum += *(u_char*)w; - } - - /* Add back carry bits from top 16 bits to low 16 bits */ - - sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ - sum += (sum >> 16); /* add carry */ - answer = ~sum; /* truncate to 16 bits */ - - return answer; + size_t nleft = len; + u_short *w = addr; + int sum = 0; + u_short answer = 0; + + /* + * The IP checksum algorithm is simple: using a 32 bit accumulator (sum) + * add sequential 16 bit words to it, and at the end, folding back all + * the carry bits from the top 16 bits into the lower 16 bits. + */ + while (nleft > 1) { + sum += *w++; + nleft -= 2; + } + + /* Mop up an odd byte, if necessary */ + if (nleft == 1) { + sum += *(u_char *) w; + } + + /* Add back carry bits from top 16 bits to low 16 bits */ + + sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ + sum += (sum >> 16); /* add carry */ + answer = ~sum; /* truncate to 16 bits */ + + return answer; } -static const char *ping_desc(gboolean family, uint8_t type, uint8_t code) +static const char * +ping_desc(gboolean family, uint8_t type, uint8_t code) { - if(family == AF_INET6) { - switch(type) { - case ICMP6_DST_UNREACH: - switch(code) { - case ICMP6_DST_UNREACH_NOROUTE: - return "No Route to Destination"; - case ICMP6_DST_UNREACH_ADMIN: - return "Destination Administratively Unreachable"; + if (family == AF_INET6) { + switch (type) { + case ICMP6_DST_UNREACH: + switch (code) { + case ICMP6_DST_UNREACH_NOROUTE: + return "No Route to Destination"; + case ICMP6_DST_UNREACH_ADMIN: + return "Destination Administratively Unreachable"; #ifdef ICMP6_DST_UNREACH_BEYONDSCOPE - case ICMP6_DST_UNREACH_BEYONDSCOPE: - return "Destination Unreachable Beyond Scope"; + case ICMP6_DST_UNREACH_BEYONDSCOPE: + return "Destination Unreachable Beyond Scope"; #endif - case ICMP6_DST_UNREACH_ADDR: - return "Destination Address Unreachable"; - case ICMP6_DST_UNREACH_NOPORT: - return "Destination Port Unreachable"; - default: - crm_err("Unreachable: Unknown subtype: %d", code); - return "Unreachable: Unknown Subtype"; - } - case ICMP6_PACKET_TOO_BIG: - return "Packet too big"; - case ICMP6_TIME_EXCEEDED: - switch(code) { - case ICMP6_TIME_EXCEED_TRANSIT: - return "Time to live exceeded"; - case ICMP6_TIME_EXCEED_REASSEMBLY: - return "Frag reassembly time exceeded"; - default: - crm_err("Timeout: Unknown subtype: %d", code); - return "Timeout: Unknown Subtype"; - } - case ICMP6_PARAM_PROB: - switch(code) { - case ICMP6_PARAMPROB_HEADER: - return "Parameter problem: Erroneous Header"; - case ICMP6_PARAMPROB_NEXTHEADER: - return "Parameter problem: Unknown Nextheader"; - case ICMP6_PARAMPROB_OPTION: - return "Parameter problem: Unrecognized Option"; - default: - crm_err("Invalid header: Unknown subtype: %d", code); - return "Invalid header: Unknown Subtype"; - } - case ICMP6_ECHO_REQUEST: - return "Echo Request"; - case ICMP6_ECHO_REPLY: - return "Echo Reply"; + case ICMP6_DST_UNREACH_ADDR: + return "Destination Address Unreachable"; + case ICMP6_DST_UNREACH_NOPORT: + return "Destination Port Unreachable"; + default: + crm_err("Unreachable: Unknown subtype: %d", code); + return "Unreachable: Unknown Subtype"; + } + case ICMP6_PACKET_TOO_BIG: + return "Packet too big"; + case ICMP6_TIME_EXCEEDED: + switch (code) { + case ICMP6_TIME_EXCEED_TRANSIT: + return "Time to live exceeded"; + case ICMP6_TIME_EXCEED_REASSEMBLY: + return "Frag reassembly time exceeded"; + default: + crm_err("Timeout: Unknown subtype: %d", code); + return "Timeout: Unknown Subtype"; + } + case ICMP6_PARAM_PROB: + switch (code) { + case ICMP6_PARAMPROB_HEADER: + return "Parameter problem: Erroneous Header"; + case ICMP6_PARAMPROB_NEXTHEADER: + return "Parameter problem: Unknown Nextheader"; + case ICMP6_PARAMPROB_OPTION: + return "Parameter problem: Unrecognized Option"; + default: + crm_err("Invalid header: Unknown subtype: %d", code); + return "Invalid header: Unknown Subtype"; + } + case ICMP6_ECHO_REQUEST: + return "Echo Request"; + case ICMP6_ECHO_REPLY: + return "Echo Reply"; #ifdef MLD_LISTENER_QUERY - case MLD_LISTENER_QUERY: - return "Multicast Listener Query"; + case MLD_LISTENER_QUERY: + return "Multicast Listener Query"; #endif #ifdef MLD_LISTENER_REPORT - case MLD_LISTENER_REPORT: - return "Multicast Listener Report"; + case MLD_LISTENER_REPORT: + return "Multicast Listener Report"; #endif #ifdef MLD_LISTENER_REDUCTION - case MLD_LISTENER_REDUCTION: - return "Multicast Listener Done"; + case MLD_LISTENER_REDUCTION: + return "Multicast Listener Done"; #endif - case ND_ROUTER_SOLICIT: - return "Router Solicitation"; - case ND_ROUTER_ADVERT: - return "Router Advertisement"; - case ND_NEIGHBOR_SOLICIT: - return "Neighbor Solicitation"; - case ND_NEIGHBOR_ADVERT: - return "Neighbor Advertisement"; - case ND_REDIRECT: - return "Redirect"; + case ND_ROUTER_SOLICIT: + return "Router Solicitation"; + case ND_ROUTER_ADVERT: + return "Router Advertisement"; + case ND_NEIGHBOR_SOLICIT: + return "Neighbor Solicitation"; + case ND_NEIGHBOR_ADVERT: + return "Neighbor Advertisement"; + case ND_REDIRECT: + return "Redirect"; #ifdef ICMP6_ROUTER_RENUMBERING - case ICMP6_ROUTER_RENUMBERING: - return "Router renumbering"; + case ICMP6_ROUTER_RENUMBERING: + return "Router renumbering"; #endif - default: - crm_err("Unknown type: %d", type); - return "Unknown type"; - } - } else { - switch(type) { - case ICMP_ECHOREPLY: - return "Echo Reply"; - case ICMP_ECHO: - return "Echo Request"; - case ICMP_PARAMPROB: - return "Bad Parameter"; - case ICMP_SOURCEQUENCH: - return "Packet lost, slow down"; - case ICMP_TSTAMP: - return "Timestamp Request"; - case ICMP_TSTAMPREPLY: - return "Timestamp Reply"; - case ICMP_IREQ: - return "Information Request"; - case ICMP_IREQREPLY: - return "Information Reply"; - - case ICMP_UNREACH: - switch(code) { - case ICMP_UNREACH_NET: - return "Unreachable Network"; - case ICMP_UNREACH_HOST: - return "Unreachable Host"; - case ICMP_UNREACH_PROTOCOL: - return "Unreachable Protocol"; - case ICMP_UNREACH_PORT: - return "Unreachable Port"; - case ICMP_UNREACH_NEEDFRAG: - return "Unreachable: Fragmentation needed"; - case ICMP_UNREACH_SRCFAIL: - return "Unreachable Source Route"; - case ICMP_UNREACH_NET_UNKNOWN: - return "Unknown Network"; - case ICMP_UNREACH_HOST_UNKNOWN: - return "Unknown Host"; - case ICMP_UNREACH_ISOLATED: - return "Unreachable: Isolated"; - case ICMP_UNREACH_NET_PROHIB: - return "Prohibited network"; - case ICMP_UNREACH_HOST_PROHIB: - return "Prohibited host"; - case ICMP_UNREACH_FILTER_PROHIB: - return "Unreachable: Prohibited filter"; - case ICMP_UNREACH_TOSNET: - return "Unreachable: Type of Service and Network"; - case ICMP_UNREACH_TOSHOST: - return "Unreachable: Type of Service and Host"; - case ICMP_UNREACH_HOST_PRECEDENCE: - return "Unreachable: Prec vio"; - case ICMP_UNREACH_PRECEDENCE_CUTOFF: - return "Unreachable: Prec cutoff"; - default: - crm_err("Unreachable: Unknown subtype: %d", code); - return "Unreachable: Unknown Subtype"; - } - break; - - case ICMP_REDIRECT: - switch(code) { - case ICMP_REDIRECT_NET: - return "Redirect: Network"; - case ICMP_REDIRECT_HOST: - return "Redirect: Host"; - case ICMP_REDIRECT_TOSNET: - return "Redirect: Type of Service and Network"; - case ICMP_REDIRECT_TOSHOST: - return "Redirect: Type of Service and Host"; - default: - crm_err("Redirect: Unknown subtype: %d", code); - return "Redirect: Unknown Subtype"; - } - - case ICMP_TIMXCEED: - switch(code) { - case ICMP_TIMXCEED_INTRANS: - return "Timeout: TTL"; - case ICMP_TIMXCEED_REASS: - return "Timeout: Fragmentation reassembly"; - default: - crm_err("Timeout: Unknown subtype: %d", code); - return "Timeout: Unknown Subtype"; - } - break; - - default: - crm_err("Unknown type: %d", type); - return "Unknown type"; - } - } + default: + crm_err("Unknown type: %d", type); + return "Unknown type"; + } + } else { + switch (type) { + case ICMP_ECHOREPLY: + return "Echo Reply"; + case ICMP_ECHO: + return "Echo Request"; + case ICMP_PARAMPROB: + return "Bad Parameter"; + case ICMP_SOURCEQUENCH: + return "Packet lost, slow down"; + case ICMP_TSTAMP: + return "Timestamp Request"; + case ICMP_TSTAMPREPLY: + return "Timestamp Reply"; + case ICMP_IREQ: + return "Information Request"; + case ICMP_IREQREPLY: + return "Information Reply"; + + case ICMP_UNREACH: + switch (code) { + case ICMP_UNREACH_NET: + return "Unreachable Network"; + case ICMP_UNREACH_HOST: + return "Unreachable Host"; + case ICMP_UNREACH_PROTOCOL: + return "Unreachable Protocol"; + case ICMP_UNREACH_PORT: + return "Unreachable Port"; + case ICMP_UNREACH_NEEDFRAG: + return "Unreachable: Fragmentation needed"; + case ICMP_UNREACH_SRCFAIL: + return "Unreachable Source Route"; + case ICMP_UNREACH_NET_UNKNOWN: + return "Unknown Network"; + case ICMP_UNREACH_HOST_UNKNOWN: + return "Unknown Host"; + case ICMP_UNREACH_ISOLATED: + return "Unreachable: Isolated"; + case ICMP_UNREACH_NET_PROHIB: + return "Prohibited network"; + case ICMP_UNREACH_HOST_PROHIB: + return "Prohibited host"; + case ICMP_UNREACH_FILTER_PROHIB: + return "Unreachable: Prohibited filter"; + case ICMP_UNREACH_TOSNET: + return "Unreachable: Type of Service and Network"; + case ICMP_UNREACH_TOSHOST: + return "Unreachable: Type of Service and Host"; + case ICMP_UNREACH_HOST_PRECEDENCE: + return "Unreachable: Prec vio"; + case ICMP_UNREACH_PRECEDENCE_CUTOFF: + return "Unreachable: Prec cutoff"; + default: + crm_err("Unreachable: Unknown subtype: %d", code); + return "Unreachable: Unknown Subtype"; + } + break; + + case ICMP_REDIRECT: + switch (code) { + case ICMP_REDIRECT_NET: + return "Redirect: Network"; + case ICMP_REDIRECT_HOST: + return "Redirect: Host"; + case ICMP_REDIRECT_TOSNET: + return "Redirect: Type of Service and Network"; + case ICMP_REDIRECT_TOSHOST: + return "Redirect: Type of Service and Host"; + default: + crm_err("Redirect: Unknown subtype: %d", code); + return "Redirect: Unknown Subtype"; + } + + case ICMP_TIMXCEED: + switch (code) { + case ICMP_TIMXCEED_INTRANS: + return "Timeout: TTL"; + case ICMP_TIMXCEED_REASS: + return "Timeout: Fragmentation reassembly"; + default: + crm_err("Timeout: Unknown subtype: %d", code); + return "Timeout: Unknown Subtype"; + } + break; + + default: + crm_err("Unknown type: %d", type); + return "Unknown type"; + } + } } #ifdef ON_LINUX # define MAX_HOST 1024 -int process_icmp6_error(ping_node *node, struct sockaddr_in6 *whereto) +int +process_icmp6_error(ping_node * node, struct sockaddr_in6 *whereto) { int rc = 0; char buf[512]; - struct iovec iov; + struct iovec iov; struct msghdr msg; struct icmp6_hdr icmph; struct sockaddr_in6 target; struct cmsghdr *cmsg = NULL; struct sock_extended_err *s_err = NULL; iov.iov_base = &icmph; iov.iov_len = sizeof(icmph); - msg.msg_name = (void*)⌖ + msg.msg_name = (void *)⌖ msg.msg_namelen = sizeof(target); msg.msg_iov = &iov; msg.msg_iovlen = 1; msg.msg_flags = 0; msg.msg_control = buf; msg.msg_controllen = sizeof(buf); - rc = recvmsg(node->fd, &msg, MSG_ERRQUEUE|MSG_DONTWAIT); + rc = recvmsg(node->fd, &msg, MSG_ERRQUEUE | MSG_DONTWAIT); if (rc < 0 || rc < sizeof(icmph)) { - crm_perror(LOG_DEBUG, "No error message: %d", rc); - return 0; + crm_perror(LOG_DEBUG, "No error message: %d", rc); + return 0; } for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) { - if (cmsg->cmsg_level == SOL_IPV6 && cmsg->cmsg_type == IPV6_RECVERR) { - s_err = (struct sock_extended_err *)CMSG_DATA(cmsg); - } + if (cmsg->cmsg_level == SOL_IPV6 && cmsg->cmsg_type == IPV6_RECVERR) { + s_err = (struct sock_extended_err *)CMSG_DATA(cmsg); + } } CRM_ASSERT(s_err != NULL); if (s_err->ee_origin == SO_EE_ORIGIN_LOCAL) { - if (s_err->ee_errno == EMSGSIZE) { - crm_info("local error: Message too long, mtu=%u", s_err->ee_info); - } else { - crm_info("local error: %s", strerror(s_err->ee_errno)); - } - return 0; + if (s_err->ee_errno == EMSGSIZE) { + crm_info("local error: Message too long, mtu=%u", s_err->ee_info); + } else { + crm_info("local error: %s", strerror(s_err->ee_errno)); + } + return 0; } else if (s_err->ee_origin == SO_EE_ORIGIN_ICMP6) { - struct sockaddr_in6 *sin = (struct sockaddr_in6*)(s_err+1); - const char *ping_result = ping_desc(node->type, s_err->ee_type, s_err->ee_code); - static char target_s[64], whereto_s[64], ping_host_s[64]; - inet_ntop(AF_INET6, (struct in6_addr *)&(target.sin6_addr), target_s, sizeof(target_s)); - inet_ntop(AF_INET6, (struct in6_addr *)&(whereto->sin6_addr), whereto_s, sizeof(whereto_s)); - - if (ntohs(icmph.icmp6_id) != ident) { - /* Result was not for us */ - crm_debug("Not our error (ident): %d %d", ntohs(icmph.icmp6_id), ident); - return -1; - - } else if (memcmp(&target.sin6_addr, &whereto->sin6_addr, 16)) { - /* Result was not for us */ - crm_debug("Not our error (addr): %s %s", target_s, whereto_s); - return -1; - - } else if (icmph.icmp6_type != ICMP6_ECHO_REQUEST) { - /* Not an error */ - crm_info("Not an error: %d", icmph.icmp6_type); - return -1; - } - - inet_ntop(AF_INET6, (struct in6_addr *)&(sin->sin6_addr), ping_host_s, sizeof(ping_host_s)); - crm_debug("From %s icmp_seq=%u %s", ping_host_s, ntohs(icmph.icmp6_seq), ping_result); + struct sockaddr_in6 *sin = (struct sockaddr_in6 *)(s_err + 1); + const char *ping_result = ping_desc(node->type, s_err->ee_type, s_err->ee_code); + static char target_s[64], whereto_s[64], ping_host_s[64]; + + inet_ntop(AF_INET6, (struct in6_addr *)&(target.sin6_addr), target_s, sizeof(target_s)); + inet_ntop(AF_INET6, (struct in6_addr *)&(whereto->sin6_addr), whereto_s, sizeof(whereto_s)); + + if (ntohs(icmph.icmp6_id) != ident) { + /* Result was not for us */ + crm_debug("Not our error (ident): %d %d", ntohs(icmph.icmp6_id), ident); + return -1; + + } else if (memcmp(&target.sin6_addr, &whereto->sin6_addr, 16)) { + /* Result was not for us */ + crm_debug("Not our error (addr): %s %s", target_s, whereto_s); + return -1; + + } else if (icmph.icmp6_type != ICMP6_ECHO_REQUEST) { + /* Not an error */ + crm_info("Not an error: %d", icmph.icmp6_type); + return -1; + } + + inet_ntop(AF_INET6, (struct in6_addr *)&(sin->sin6_addr), ping_host_s, sizeof(ping_host_s)); + crm_debug("From %s icmp_seq=%u %s", ping_host_s, ntohs(icmph.icmp6_seq), ping_result); } else { - crm_debug("else: %d", s_err->ee_origin); + crm_debug("else: %d", s_err->ee_origin); } return 0; } -int process_icmp4_error(ping_node *node, struct sockaddr_in *whereto) +int +process_icmp4_error(ping_node * node, struct sockaddr_in *whereto) { int rc = 0; char buf[512]; - struct iovec iov; + struct iovec iov; struct msghdr msg; struct icmphdr icmph; struct sockaddr_in target; struct cmsghdr *cmsg = NULL; struct sock_extended_err *s_err = NULL; iov.iov_base = &icmph; iov.iov_len = sizeof(icmph); - msg.msg_name = (void*)⌖ + msg.msg_name = (void *)⌖ msg.msg_namelen = sizeof(target); msg.msg_iov = &iov; msg.msg_iovlen = 1; msg.msg_flags = 0; msg.msg_control = buf; msg.msg_controllen = sizeof(buf); - - rc = recvmsg(node->fd, &msg, MSG_ERRQUEUE|MSG_DONTWAIT); + + rc = recvmsg(node->fd, &msg, MSG_ERRQUEUE | MSG_DONTWAIT); if (rc < 0 || rc < sizeof(icmph)) { - crm_perror(LOG_DEBUG, "No error message: %d", rc); - return 0; + crm_perror(LOG_DEBUG, "No error message: %d", rc); + return 0; } - + for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) { - if (cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_RECVERR) { - s_err = (struct sock_extended_err *)CMSG_DATA(cmsg); - } + if (cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_RECVERR) { + s_err = (struct sock_extended_err *)CMSG_DATA(cmsg); + } } CRM_ASSERT(s_err != NULL); - + if (s_err->ee_origin == SO_EE_ORIGIN_LOCAL) { - if (s_err->ee_errno == EMSGSIZE) { - crm_info("local error: Message too long, mtu=%u", s_err->ee_info); - } else { - crm_info("local error: %s", strerror(s_err->ee_errno)); - } - return 0; - + if (s_err->ee_errno == EMSGSIZE) { + crm_info("local error: Message too long, mtu=%u", s_err->ee_info); + } else { + crm_info("local error: %s", strerror(s_err->ee_errno)); + } + return 0; + } else if (s_err->ee_origin == SO_EE_ORIGIN_ICMP) { - char ping_host[MAX_HOST]; - struct sockaddr_in *sin = (struct sockaddr_in*)(s_err+1); - const char *ping_result = ping_desc(node->type, s_err->ee_type, s_err->ee_code); - char *target_s = inet_ntoa(*(struct in_addr *)&(target.sin_addr.s_addr)); - char *whereto_s = inet_ntoa(*(struct in_addr *)&(whereto->sin_addr.s_addr)); - - if (ntohs(icmph.un.echo.id) != ident) { - /* Result was not for us */ - crm_debug("Not our error (ident): %d %d", ntohs(icmph.un.echo.id), ident); - return -1; - - } else if (safe_str_neq(target_s, whereto_s)) { - /* Result was not for us */ - crm_debug("Not our error (addr): %s %s", target_s, whereto_s); - return -1; - - } else if (icmph.type != ICMP_ECHO) { - /* Not an error */ - crm_info("Not an error: %d", icmph.type); - return -1; - } - - /* snprintf(ping_host, MAX_HOST, "%s", inet_ntoa(*(struct in_addr *)&(sin->sin_addr.s_addr))); */ - snprintf(ping_host, MAX_HOST, "%s", inet_ntoa(sin->sin_addr)); - - if (node->extra_filters == FALSE) { - /* Now that we got some sort of reply, add extra filters to - * ensure we keep getting the _right_ replies for dead hosts - */ - struct icmp_filter filt; - crm_debug("Installing additional ICMP filters"); - node->extra_filters = TRUE; /* only try once */ - - filt.data = ~((1<fd, SOL_RAW, ICMP_FILTER, (char*)&filt, sizeof(filt)) == -1) { - crm_perror(LOG_WARNING, "setsockopt failed: Cannot install ICMP filters for %s", ping_host); - } - } - - crm_debug("From %s icmp_seq=%u %s", ping_host, ntohs(icmph.un.echo.sequence), ping_result); + char ping_host[MAX_HOST]; + struct sockaddr_in *sin = (struct sockaddr_in *)(s_err + 1); + const char *ping_result = ping_desc(node->type, s_err->ee_type, s_err->ee_code); + char *target_s = inet_ntoa(*(struct in_addr *)&(target.sin_addr.s_addr)); + char *whereto_s = inet_ntoa(*(struct in_addr *)&(whereto->sin_addr.s_addr)); + + if (ntohs(icmph.un.echo.id) != ident) { + /* Result was not for us */ + crm_debug("Not our error (ident): %d %d", ntohs(icmph.un.echo.id), ident); + return -1; + + } else if (safe_str_neq(target_s, whereto_s)) { + /* Result was not for us */ + crm_debug("Not our error (addr): %s %s", target_s, whereto_s); + return -1; + + } else if (icmph.type != ICMP_ECHO) { + /* Not an error */ + crm_info("Not an error: %d", icmph.type); + return -1; + } + + /* snprintf(ping_host, MAX_HOST, "%s", inet_ntoa(*(struct in_addr *)&(sin->sin_addr.s_addr))); */ + snprintf(ping_host, MAX_HOST, "%s", inet_ntoa(sin->sin_addr)); + + if (node->extra_filters == FALSE) { + /* Now that we got some sort of reply, add extra filters to + * ensure we keep getting the _right_ replies for dead hosts + */ + struct icmp_filter filt; + + crm_debug("Installing additional ICMP filters"); + node->extra_filters = TRUE; /* only try once */ + + filt.data = ~((1 << ICMP_SOURCE_QUENCH) | (1 << ICMP_REDIRECT) | (1 << ICMP_ECHOREPLY)); + if (setsockopt(node->fd, SOL_RAW, ICMP_FILTER, (char *)&filt, sizeof(filt)) == -1) { + crm_perror(LOG_WARNING, "setsockopt failed: Cannot install ICMP filters for %s", + ping_host); + } + } + + crm_debug("From %s icmp_seq=%u %s", ping_host, ntohs(icmph.un.echo.sequence), ping_result); } else { - crm_debug("else: %d", s_err->ee_origin); + crm_debug("else: %d", s_err->ee_origin); } - + return 0; } #else -int process_icmp6_error(ping_node *node, struct sockaddr_in6 *whereto) +int +process_icmp6_error(ping_node * node, struct sockaddr_in6 *whereto) { /* dummy function */ return 0; } -int process_icmp4_error(ping_node *node, struct sockaddr_in *whereto) +int +process_icmp4_error(ping_node * node, struct sockaddr_in *whereto) { /* dummy function */ return 0; } #endif -static ping_node *ping_new(const char *host) +static ping_node * +ping_new(const char *host) { ping_node *node; - + crm_malloc0(node, sizeof(ping_node)); - if(strstr(host, ":")) { - node->type = AF_INET6; + if (strstr(host, ":")) { + node->type = AF_INET6; } else { - node->type = AF_INET; + node->type = AF_INET; } - + node->host = crm_strdup(host); - + return node; } -static gboolean ping_open(ping_node *node) +static gboolean +ping_open(ping_node * node) { int ret_ga = 0; char *hostname = NULL; struct addrinfo *res = NULL; struct addrinfo hints; char *addr = NULL; char *cp = NULL; /* getaddrinfo */ bzero(&hints, sizeof(struct addrinfo)); hints.ai_flags = AI_CANONNAME; hints.ai_family = node->type; hints.ai_socktype = SOCK_RAW; - if(node->type == AF_INET6) { - hints.ai_protocol = IPPROTO_ICMPV6; + if (node->type == AF_INET6) { + hints.ai_protocol = IPPROTO_ICMPV6; } else { - hints.ai_protocol = IPPROTO_ICMP; + hints.ai_protocol = IPPROTO_ICMP; } - + addr = crm_strdup(node->host); if ((cp = strchr(addr, '%'))) { - *cp = 0; + *cp = 0; } crm_debug("node->host[%s], addr[%s]", node->host, addr); ret_ga = getaddrinfo(addr, NULL, &hints, &res); crm_free(addr); if (ret_ga) { - crm_warn("getaddrinfo: %s", gai_strerror(ret_ga)); - goto bail; + crm_warn("getaddrinfo: %s", gai_strerror(ret_ga)); + goto bail; } - + if (res->ai_canonname) { - hostname = res->ai_canonname; + hostname = res->ai_canonname; } else { - hostname = node->host; + hostname = node->host; } - + crm_debug_2("Got address %s for %s", hostname, node->host); - - if(!res->ai_addr) { - crm_warn("getaddrinfo failed: no address"); - goto bail; + + if (!res->ai_addr) { + crm_warn("getaddrinfo failed: no address"); + goto bail; } - + memcpy(&(node->addr.raw), res->ai_addr, res->ai_addrlen); node->fd = socket(hints.ai_family, hints.ai_socktype, hints.ai_protocol); /* node->fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); */ - if(node->fd < 0) { - crm_perror(LOG_WARNING, "Can't open socket to %s", hostname); - goto bail; + if (node->fd < 0) { + crm_perror(LOG_WARNING, "Can't open socket to %s", hostname); + goto bail; } - if(node->type == AF_INET6) { - int sockopt; + if (node->type == AF_INET6) { + int sockopt; + + inet_ntop(node->type, &node->addr.v6.sin6_addr, node->dest, sizeof(node->dest)); - inet_ntop(node->type, &node->addr.v6.sin6_addr, node->dest, sizeof(node->dest)); - - /* set recv buf for broadcast pings */ - sockopt = 48 * 1024; - setsockopt(node->fd, SOL_SOCKET, SO_RCVBUF, (char *) &sockopt, sizeof(sockopt)); + /* set recv buf for broadcast pings */ + sockopt = 48 * 1024; + setsockopt(node->fd, SOL_SOCKET, SO_RCVBUF, (char *)&sockopt, sizeof(sockopt)); } else { - inet_ntop(node->type, &node->addr.v4.sin_addr, node->dest, sizeof(node->dest)); + inet_ntop(node->type, &node->addr.v4.sin_addr, node->dest, sizeof(node->dest)); } - if(ping_timeout > 0) { - struct timeval timeout_opt; + if (ping_timeout > 0) { + struct timeval timeout_opt; - timeout_opt.tv_sec = ping_timeout; - timeout_opt.tv_usec = 0; - - setsockopt(node->fd, SOL_SOCKET, SO_RCVTIMEO, (char *) &timeout_opt, sizeof(timeout_opt)); - } + timeout_opt.tv_sec = ping_timeout; + timeout_opt.tv_usec = 0; + setsockopt(node->fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout_opt, sizeof(timeout_opt)); + } #ifdef ON_LINUX { - int dummy = 1; - - memset(&cmsgbuf, 0, sizeof(cmsgbuf)); - cmsglen = 0; - - if(node->type == AF_INET6) { - struct icmp6_filter filt; - - ICMP6_FILTER_SETBLOCKALL(&filt); - ICMP6_FILTER_SETPASS(ICMP6_ECHO_REPLY, &filt); - - if (setsockopt(node->fd, IPPROTO_ICMPV6, ICMP6_FILTER, (char*)&filt, sizeof(filt)) == -1) { - crm_perror(LOG_WARNING, "setsockopt failed: Cannot install ICMP6 filters for %s", node->dest); - } - setsockopt(node->fd, SOL_IPV6, IPV6_RECVERR, (char *)&dummy, sizeof(dummy)); - - if ((cp = strchr(node->host, '%'))) { - struct ifreq ifr; - struct cmsghdr *cmsg; - struct in6_pktinfo *ipi; - - memset(&ifr, 0, sizeof(ifr)); - cp++; - crm_debug("set interface: [%s]", cp); - strncpy(ifr.ifr_name, cp, IFNAMSIZ-1); - - if (ioctl(node->fd, SIOCGIFINDEX, &ifr) >= 0) { - cmsg = (struct cmsghdr*)cmsgbuf; - cmsglen = CMSG_SPACE(sizeof(*ipi)); - cmsg->cmsg_len = CMSG_LEN(sizeof(*ipi)); - cmsg->cmsg_level = SOL_IPV6; - cmsg->cmsg_type = IPV6_PKTINFO; - - ipi = (struct in6_pktinfo*)CMSG_DATA(cmsg); - memset(ipi, 0, sizeof(*ipi)); - ipi->ipi6_ifindex = ifr.ifr_ifindex; - } else { - crm_warn("unknown interface %s specified", cp); - } - } - } else { - struct icmp_filter filt; - filt.data = ~((1<fd, SOL_RAW, ICMP_FILTER, (char*)&filt, sizeof(filt)) == -1) { - crm_perror(LOG_WARNING, "setsockopt failed: Cannot install ICMP filters for %s", node->dest); - } - setsockopt(node->fd, SOL_IP, IP_RECVERR, (char *)&dummy, sizeof(dummy)); - - if ((cp = strchr(node->host, '%'))) { - struct ifreq ifr; - struct cmsghdr *cmsg; - struct in_pktinfo *ipi; - - memset(&ifr, 0, sizeof(ifr)); - cp++; - crm_debug("set interface: [%s]", cp); - strncpy(ifr.ifr_name, cp, IFNAMSIZ-1); - - if (ioctl(node->fd, SIOCGIFINDEX, &ifr) >= 0) { - cmsg = (struct cmsghdr*)cmsgbuf; - cmsglen = CMSG_SPACE(sizeof(*ipi)); - cmsg->cmsg_len = CMSG_LEN(sizeof(*ipi)); - cmsg->cmsg_level = SOL_IP; - cmsg->cmsg_type = IP_PKTINFO; - - ipi = (struct in_pktinfo*)CMSG_DATA(cmsg); - memset(ipi, 0, sizeof(*ipi)); - ipi->ipi_ifindex = ifr.ifr_ifindex; - } else { - crm_warn("unknown interface %s specified", cp); - } - } - } + int dummy = 1; + + memset(&cmsgbuf, 0, sizeof(cmsgbuf)); + cmsglen = 0; + + if (node->type == AF_INET6) { + struct icmp6_filter filt; + + ICMP6_FILTER_SETBLOCKALL(&filt); + ICMP6_FILTER_SETPASS(ICMP6_ECHO_REPLY, &filt); + + if (setsockopt(node->fd, IPPROTO_ICMPV6, ICMP6_FILTER, (char *)&filt, sizeof(filt)) == + -1) { + crm_perror(LOG_WARNING, "setsockopt failed: Cannot install ICMP6 filters for %s", + node->dest); + } + setsockopt(node->fd, SOL_IPV6, IPV6_RECVERR, (char *)&dummy, sizeof(dummy)); + + if ((cp = strchr(node->host, '%'))) { + struct ifreq ifr; + struct cmsghdr *cmsg; + struct in6_pktinfo *ipi; + + memset(&ifr, 0, sizeof(ifr)); + cp++; + crm_debug("set interface: [%s]", cp); + strncpy(ifr.ifr_name, cp, IFNAMSIZ - 1); + + if (ioctl(node->fd, SIOCGIFINDEX, &ifr) >= 0) { + cmsg = (struct cmsghdr *)cmsgbuf; + cmsglen = CMSG_SPACE(sizeof(*ipi)); + cmsg->cmsg_len = CMSG_LEN(sizeof(*ipi)); + cmsg->cmsg_level = SOL_IPV6; + cmsg->cmsg_type = IPV6_PKTINFO; + + ipi = (struct in6_pktinfo *)CMSG_DATA(cmsg); + memset(ipi, 0, sizeof(*ipi)); + ipi->ipi6_ifindex = ifr.ifr_ifindex; + } else { + crm_warn("unknown interface %s specified", cp); + } + } + } else { + struct icmp_filter filt; + + filt.data = ~((1 << ICMP_SOURCE_QUENCH) | + (1 << ICMP_DEST_UNREACH) | + (1 << ICMP_TIME_EXCEEDED) | + (1 << ICMP_PARAMETERPROB) | (1 << ICMP_REDIRECT) | (1 << ICMP_ECHOREPLY)); + + if (setsockopt(node->fd, SOL_RAW, ICMP_FILTER, (char *)&filt, sizeof(filt)) == -1) { + crm_perror(LOG_WARNING, "setsockopt failed: Cannot install ICMP filters for %s", + node->dest); + } + setsockopt(node->fd, SOL_IP, IP_RECVERR, (char *)&dummy, sizeof(dummy)); + + if ((cp = strchr(node->host, '%'))) { + struct ifreq ifr; + struct cmsghdr *cmsg; + struct in_pktinfo *ipi; + + memset(&ifr, 0, sizeof(ifr)); + cp++; + crm_debug("set interface: [%s]", cp); + strncpy(ifr.ifr_name, cp, IFNAMSIZ - 1); + + if (ioctl(node->fd, SIOCGIFINDEX, &ifr) >= 0) { + cmsg = (struct cmsghdr *)cmsgbuf; + cmsglen = CMSG_SPACE(sizeof(*ipi)); + cmsg->cmsg_len = CMSG_LEN(sizeof(*ipi)); + cmsg->cmsg_level = SOL_IP; + cmsg->cmsg_type = IP_PKTINFO; + + ipi = (struct in_pktinfo *)CMSG_DATA(cmsg); + memset(ipi, 0, sizeof(*ipi)); + ipi->ipi_ifindex = ifr.ifr_ifindex; + } else { + crm_warn("unknown interface %s specified", cp); + } + } + } } -#endif - +#endif + crm_debug_2("Opened connection to %s", node->dest); freeaddrinfo(res); return TRUE; bail: - if(res) { - freeaddrinfo(res); + if (res) { + freeaddrinfo(res); } return FALSE; } -static gboolean ping_close(ping_node *node) +static gboolean +ping_close(ping_node * node) { int tmp_fd = node->fd; + node->fd = -1; - + if (tmp_fd >= 0) { - if(close(tmp_fd) < 0) { - crm_perror(LOG_ERR,"Could not close ping socket"); - } else { - tmp_fd = -1; - crm_debug_2("Closed connection to %s", node->dest); - } + if (close(tmp_fd) < 0) { + crm_perror(LOG_ERR, "Could not close ping socket"); + } else { + tmp_fd = -1; + crm_debug_2("Closed connection to %s", node->dest); + } } return (tmp_fd == -1); } #define MAXPACKETLEN 131072 -#define ICMP6ECHOLEN 8 /* icmp echo header len excluding time */ +#define ICMP6ECHOLEN 8 /* icmp echo header len excluding time */ #define ICMP6ECHOTMLEN 20 #define DEFDATALEN ICMP6ECHOTMLEN -#define EXTRA 256 /* for AH and various other headers. weird. */ +#define EXTRA 256 /* for AH and various other headers. weird. */ #define IP6LEN 40 static int -dump_v6_echo(ping_node *node, u_char *buf, int bytes, struct msghdr *hdr) +dump_v6_echo(ping_node * node, u_char * buf, int bytes, struct msghdr *hdr) { - int rc = -1; /* Try again */ - int fromlen; - char from_host[1024]; - - struct icmp6_hdr *icp; - struct sockaddr *from; - - if (!hdr || !hdr->msg_name || hdr->msg_namelen != sizeof(struct sockaddr_in6) - || ((struct sockaddr *)hdr->msg_name)->sa_family != AF_INET6) { - crm_warn("Invalid echo peer"); - return rc; - } - - fromlen = hdr->msg_namelen; - from = (struct sockaddr *)hdr->msg_name; - getnameinfo(from, fromlen, from_host, sizeof(from_host), NULL, 0, NI_NUMERICHOST | NI_NUMERICSERV); - - if (bytes < (int)sizeof(struct icmp6_hdr)) { - crm_warn("Invalid echo packet (too short: %d bytes) from %s", bytes, from_host); - return rc; - } - icp = (struct icmp6_hdr *)buf; - - if (icp->icmp6_type == ICMP6_ECHO_REPLY) { - if (ident == ntohs(icp->icmp6_id) - && node->iseq == ntohs(icp->icmp6_seq)) { - rc = 1; /* Alive */ - } - - } else if(icp->icmp6_type != ICMP6_ECHO_REQUEST) { - rc = process_icmp6_error(node, (struct sockaddr_in6*)&(node->addr)); - } - - do_crm_log(LOG_DEBUG_2, - "Echo from %s (exp=%d, seq=%d, id=%d, dest=%s, data=%s): %s", - from_host, node->iseq, ntohs(icp->icmp6_seq), - ntohs(icp->icmp6_id), node->dest, (char*)(buf + ICMP6ECHOLEN), - ping_desc(node->type, icp->icmp6_type, icp->icmp6_code)); - - return rc; + int rc = -1; /* Try again */ + int fromlen; + char from_host[1024]; + + struct icmp6_hdr *icp; + struct sockaddr *from; + + if (!hdr || !hdr->msg_name || hdr->msg_namelen != sizeof(struct sockaddr_in6) + || ((struct sockaddr *)hdr->msg_name)->sa_family != AF_INET6) { + crm_warn("Invalid echo peer"); + return rc; + } + + fromlen = hdr->msg_namelen; + from = (struct sockaddr *)hdr->msg_name; + getnameinfo(from, fromlen, from_host, sizeof(from_host), NULL, 0, + NI_NUMERICHOST | NI_NUMERICSERV); + + if (bytes < (int)sizeof(struct icmp6_hdr)) { + crm_warn("Invalid echo packet (too short: %d bytes) from %s", bytes, from_host); + return rc; + } + icp = (struct icmp6_hdr *)buf; + + if (icp->icmp6_type == ICMP6_ECHO_REPLY) { + if (ident == ntohs(icp->icmp6_id) + && node->iseq == ntohs(icp->icmp6_seq)) { + rc = 1; /* Alive */ + } + + } else if (icp->icmp6_type != ICMP6_ECHO_REQUEST) { + rc = process_icmp6_error(node, (struct sockaddr_in6 *)&(node->addr)); + } + + do_crm_log(LOG_DEBUG_2, + "Echo from %s (exp=%d, seq=%d, id=%d, dest=%s, data=%s): %s", + from_host, node->iseq, ntohs(icp->icmp6_seq), + ntohs(icp->icmp6_id), node->dest, (char *)(buf + ICMP6ECHOLEN), + ping_desc(node->type, icp->icmp6_type, icp->icmp6_code)); + + return rc; } static int -dump_v4_echo(ping_node *node, u_char *buf, int bytes, struct msghdr *hdr) +dump_v4_echo(ping_node * node, u_char * buf, int bytes, struct msghdr *hdr) { - int rc = -1; /* Try again */ - int iplen, fromlen; - char from_host[1024]; - - struct ip *ip; - struct icmp *icp; - struct sockaddr *from; - - if (hdr == NULL - || !hdr->msg_name - || hdr->msg_namelen != sizeof(struct sockaddr_in) - || ((struct sockaddr *)hdr->msg_name)->sa_family != AF_INET) { - crm_warn("Invalid echo peer"); - return rc; - } - - fromlen = hdr->msg_namelen; - from = (struct sockaddr *)hdr->msg_name; - getnameinfo(from, fromlen, from_host, sizeof(from_host), NULL, 0, NI_NUMERICHOST | NI_NUMERICSERV); - - ip = (struct ip*)buf; - iplen = ip->ip_hl * 4; - - if (bytes < (iplen + sizeof(struct icmp))) { - crm_warn("Invalid echo packet (too short: %d bytes) from %s", bytes, from_host); - return rc; - } - - /* Check the IP header */ - icp = (struct icmp*)(buf + iplen); - - if (icp->icmp_type == ICMP_ECHOREPLY) { - if (ident == ntohs(icp->icmp_id) - && node->iseq == ntohs(icp->icmp_seq)) { - rc = 1; /* Alive */ - } - - } else if(icp->icmp_type != ICMP_ECHO) { - rc = process_icmp4_error(node, (struct sockaddr_in*)from); - } - - /* TODO: Stop logging icmp_id once we're sure everything works */ - do_crm_log(LOG_DEBUG_2, - "Echo from %s (exp=%d, seq=%d, id=%d, dest=%s, data=%s): %s", - from_host, node->iseq, ntohs(icp->icmp_seq), - ntohs(icp->icmp_id), node->dest, icp->icmp_data, - ping_desc(node->type, icp->icmp_type, icp->icmp_code)); - - return rc; + int rc = -1; /* Try again */ + int iplen, fromlen; + char from_host[1024]; + + struct ip *ip; + struct icmp *icp; + struct sockaddr *from; + + if (hdr == NULL || !hdr->msg_name || hdr->msg_namelen != sizeof(struct sockaddr_in) + || ((struct sockaddr *)hdr->msg_name)->sa_family != AF_INET) { + crm_warn("Invalid echo peer"); + return rc; + } + + fromlen = hdr->msg_namelen; + from = (struct sockaddr *)hdr->msg_name; + getnameinfo(from, fromlen, from_host, sizeof(from_host), NULL, 0, + NI_NUMERICHOST | NI_NUMERICSERV); + + ip = (struct ip *)buf; + iplen = ip->ip_hl * 4; + + if (bytes < (iplen + sizeof(struct icmp))) { + crm_warn("Invalid echo packet (too short: %d bytes) from %s", bytes, from_host); + return rc; + } + + /* Check the IP header */ + icp = (struct icmp *)(buf + iplen); + + if (icp->icmp_type == ICMP_ECHOREPLY) { + if (ident == ntohs(icp->icmp_id) + && node->iseq == ntohs(icp->icmp_seq)) { + rc = 1; /* Alive */ + } + + } else if (icp->icmp_type != ICMP_ECHO) { + rc = process_icmp4_error(node, (struct sockaddr_in *)from); + } + + /* TODO: Stop logging icmp_id once we're sure everything works */ + do_crm_log(LOG_DEBUG_2, + "Echo from %s (exp=%d, seq=%d, id=%d, dest=%s, data=%s): %s", + from_host, node->iseq, ntohs(icp->icmp_seq), + ntohs(icp->icmp_id), node->dest, icp->icmp_data, + ping_desc(node->type, icp->icmp_type, icp->icmp_code)); + + return rc; } static int -ping_read(ping_node *node, int *lenp) +ping_read(ping_node * node, int *lenp) { int bytes; char fromaddr[128]; struct msghdr m; struct cmsghdr *cm; u_char buf[1024]; struct iovec iov[2]; int saved_errno = 0; struct timeval recv_start_time; struct timeval recv_time; int packlen; u_char *packet; gettimeofday(&recv_start_time, NULL); packlen = DEFDATALEN + IP6LEN + ICMP6ECHOLEN + EXTRA; crm_malloc0(packet, packlen); retry: m.msg_name = &fromaddr; m.msg_namelen = sizeof(fromaddr); memset(&iov, 0, sizeof(iov)); - iov[0].iov_base = (caddr_t)packet; + iov[0].iov_base = (caddr_t) packet; iov[0].iov_len = packlen; m.msg_iov = iov; m.msg_iovlen = 1; cm = (struct cmsghdr *)buf; - m.msg_control = (caddr_t)buf; + m.msg_control = (caddr_t) buf; m.msg_controllen = sizeof(buf); - bytes = recvmsg(node->fd, &m, 0); saved_errno = errno; crm_debug_2("Got %d bytes", bytes); - - if(bytes < 0) { - crm_perror(LOG_DEBUG, "Read failed"); - if (saved_errno != EAGAIN && saved_errno != EINTR) { - int rc = 0; - if(node->type == AF_INET6) { - rc = process_icmp6_error(node, (struct sockaddr_in6*)&(node->addr)); - } else { - rc = process_icmp4_error(node, (struct sockaddr_in*)&fromaddr); - } - - if(rc < 0) { - crm_info("Retrying..."); - goto retry; - } - } + + if (bytes < 0) { + crm_perror(LOG_DEBUG, "Read failed"); + if (saved_errno != EAGAIN && saved_errno != EINTR) { + int rc = 0; + + if (node->type == AF_INET6) { + rc = process_icmp6_error(node, (struct sockaddr_in6 *)&(node->addr)); + } else { + rc = process_icmp4_error(node, (struct sockaddr_in *)&fromaddr); + } + + if (rc < 0) { + crm_info("Retrying..."); + goto retry; + } + } } else if (bytes > 0) { - int rc = 0; - if(node->type == AF_INET6) { - rc = dump_v6_echo(node, packet, bytes, &m); - } else { - rc = dump_v4_echo(node, packet, bytes, &m); - } - - gettimeofday(&recv_time, NULL); - if ((recv_start_time.tv_sec + ping_timeout) < recv_time.tv_sec) { - crm_warn("failed to receive for timeout."); - crm_free(packet); - return FALSE; - } - - if(rc < 0) { - crm_info("Retrying..."); - goto retry; - - } else if(rc > 0) { - crm_free(packet); - return TRUE; - } - + int rc = 0; + + if (node->type == AF_INET6) { + rc = dump_v6_echo(node, packet, bytes, &m); + } else { + rc = dump_v4_echo(node, packet, bytes, &m); + } + + gettimeofday(&recv_time, NULL); + if ((recv_start_time.tv_sec + ping_timeout) < recv_time.tv_sec) { + crm_warn("failed to receive for timeout."); + crm_free(packet); + return FALSE; + } + + if (rc < 0) { + crm_info("Retrying..."); + goto retry; + + } else if (rc > 0) { + crm_free(packet); + return TRUE; + } + } else { - crm_err("Unexpected reply"); + crm_err("Unexpected reply"); } crm_free(packet); return FALSE; } static int -ping_write(ping_node *node, const char *data, size_t size) +ping_write(ping_node * node, const char *data, size_t size) { - struct iovec iov; - int rc, bytes, namelen; - /* static int ntransmitted = 9; */ - struct msghdr smsghdr; - u_char outpack[MAXPACKETLEN]; - memset(outpack, 0, MAXPACKETLEN); - - node->iseq++; - - if(node->type == AF_INET6) { - struct icmp6_hdr *icp; - namelen = sizeof(struct sockaddr_in6); - bytes = ICMP6ECHOLEN + DEFDATALEN; - - icp = (struct icmp6_hdr *)outpack; - - icp->icmp6_code = 0; - icp->icmp6_cksum = 0; - icp->icmp6_type = ICMP6_ECHO_REQUEST; - icp->icmp6_id = htons(ident); - icp->icmp6_seq = htons(node->iseq); - - /* Sanity check */ - if(ntohs(icp->icmp6_seq) != node->iseq) { - crm_debug("Wrapping at %u", node->iseq); - node->iseq = ntohs(icp->icmp6_seq); - } - - memcpy(&outpack[ICMP6ECHOLEN], "pingd-v6", 8); - - } else { - struct icmp *icp; - namelen = sizeof(struct sockaddr_in); - bytes = sizeof(struct icmp) + 11; - - icp = (struct icmp *)outpack; - - icp->icmp_code = 0; - icp->icmp_cksum = 0; - icp->icmp_type = ICMP_ECHO; - icp->icmp_id = htons(ident); - icp->icmp_seq = htons(node->iseq); - - /* Sanity check */ - if(ntohs(icp->icmp_seq) != node->iseq) { - crm_debug("Wrapping at %u", node->iseq); - node->iseq = ntohs(icp->icmp_seq); - } - - memcpy(icp->icmp_data, "pingd-v4", 8); - icp->icmp_cksum = in_cksum((u_short *)icp, bytes); - } - - memset(&iov, 0, sizeof(struct iovec)); - memset(&smsghdr, 0, sizeof(struct msghdr)); - - smsghdr.msg_name = (caddr_t)&(node->addr); - smsghdr.msg_namelen = namelen; - iov.iov_base = (caddr_t)outpack; - iov.iov_len = bytes; - smsghdr.msg_iov = &iov; - smsghdr.msg_iovlen = 1; - smsghdr.msg_control = cmsgbuf; - smsghdr.msg_controllen = cmsglen; - - rc = sendmsg(node->fd, &smsghdr, 0); - - if (rc < 0 || rc != bytes) { - crm_perror(LOG_WARNING, "Wrote %d of %d chars", rc, bytes); - return FALSE; - } - - crm_debug_2("Sent %d bytes to %s", rc, node->dest); - return TRUE; + struct iovec iov; + int rc, bytes, namelen; + + /* static int ntransmitted = 9; */ + struct msghdr smsghdr; + u_char outpack[MAXPACKETLEN]; + + memset(outpack, 0, MAXPACKETLEN); + + node->iseq++; + + if (node->type == AF_INET6) { + struct icmp6_hdr *icp; + + namelen = sizeof(struct sockaddr_in6); + bytes = ICMP6ECHOLEN + DEFDATALEN; + + icp = (struct icmp6_hdr *)outpack; + + icp->icmp6_code = 0; + icp->icmp6_cksum = 0; + icp->icmp6_type = ICMP6_ECHO_REQUEST; + icp->icmp6_id = htons(ident); + icp->icmp6_seq = htons(node->iseq); + + /* Sanity check */ + if (ntohs(icp->icmp6_seq) != node->iseq) { + crm_debug("Wrapping at %u", node->iseq); + node->iseq = ntohs(icp->icmp6_seq); + } + + memcpy(&outpack[ICMP6ECHOLEN], "pingd-v6", 8); + + } else { + struct icmp *icp; + + namelen = sizeof(struct sockaddr_in); + bytes = sizeof(struct icmp) + 11; + + icp = (struct icmp *)outpack; + + icp->icmp_code = 0; + icp->icmp_cksum = 0; + icp->icmp_type = ICMP_ECHO; + icp->icmp_id = htons(ident); + icp->icmp_seq = htons(node->iseq); + + /* Sanity check */ + if (ntohs(icp->icmp_seq) != node->iseq) { + crm_debug("Wrapping at %u", node->iseq); + node->iseq = ntohs(icp->icmp_seq); + } + + memcpy(icp->icmp_data, "pingd-v4", 8); + icp->icmp_cksum = in_cksum((u_short *) icp, bytes); + } + + memset(&iov, 0, sizeof(struct iovec)); + memset(&smsghdr, 0, sizeof(struct msghdr)); + + smsghdr.msg_name = (caddr_t) & (node->addr); + smsghdr.msg_namelen = namelen; + iov.iov_base = (caddr_t) outpack; + iov.iov_len = bytes; + smsghdr.msg_iov = &iov; + smsghdr.msg_iovlen = 1; + smsghdr.msg_control = cmsgbuf; + smsghdr.msg_controllen = cmsglen; + + rc = sendmsg(node->fd, &smsghdr, 0); + + if (rc < 0 || rc != bytes) { + crm_perror(LOG_WARNING, "Wrote %d of %d chars", rc, bytes); + return FALSE; + } + + crm_debug_2("Sent %d bytes to %s", rc, node->dest); + return TRUE; } static void pingd_shutdown(int nsig) { - need_shutdown = TRUE; - send_update(0); - - g_hash_table_destroy(ping_nodes); - slist_destroy(ping_node, p, ping_list, - crm_free(p->host); - crm_free(p); - ); - - exit(0); + need_shutdown = TRUE; + send_update(0); + + g_hash_table_destroy(ping_nodes); + slist_destroy(ping_node, p, ping_list, crm_free(p->host); crm_free(p);); + + exit(0); } #if SUPPORT_HEARTBEAT static gboolean -pingd_ha_dispatch(IPC_Channel *channel, gpointer user_data) +pingd_ha_dispatch(IPC_Channel * channel, gpointer user_data) { - gboolean stay_connected = TRUE; - - crm_debug_2("Invoked"); - - while(pingd_cluster != NULL && IPC_ISRCONN(channel)) { - if(pingd_cluster->llc_ops->msgready(pingd_cluster) == 0) { - crm_debug_2("no message ready yet"); - break; - } - /* invoke the callbacks but dont block */ - pingd_cluster->llc_ops->rcvmsg(pingd_cluster, 0); - } - - if (pingd_cluster == NULL || channel->ch_status != IPC_CONNECT) { - if(need_shutdown == FALSE) { - crm_crit("Lost connection to heartbeat service."); - } else { - crm_info("Lost connection to heartbeat service."); - } - stay_connected = FALSE; - } - - return stay_connected; -} + gboolean stay_connected = TRUE; + + crm_debug_2("Invoked"); + while (pingd_cluster != NULL && IPC_ISRCONN(channel)) { + if (pingd_cluster->llc_ops->msgready(pingd_cluster) == 0) { + crm_debug_2("no message ready yet"); + break; + } + /* invoke the callbacks but dont block */ + pingd_cluster->llc_ops->rcvmsg(pingd_cluster, 0); + } + + if (pingd_cluster == NULL || channel->ch_status != IPC_CONNECT) { + if (need_shutdown == FALSE) { + crm_crit("Lost connection to heartbeat service."); + } else { + crm_info("Lost connection to heartbeat service."); + } + stay_connected = FALSE; + } + + return stay_connected; +} static void pingd_ha_connection_destroy(gpointer user_data) { - crm_debug_3("Invoked"); - if(need_shutdown) { - /* we signed out, so this is expected */ - crm_info("Heartbeat disconnection complete"); - return; - } - - crm_crit("Lost connection to heartbeat service!"); + crm_debug_3("Invoked"); + if (need_shutdown) { + /* we signed out, so this is expected */ + crm_info("Heartbeat disconnection complete"); + return; + } + + crm_crit("Lost connection to heartbeat service!"); } static gboolean -register_with_ha(void) +register_with_ha(void) { - if(pingd_cluster == NULL) { - pingd_cluster = ll_cluster_new("heartbeat"); - } - if(pingd_cluster == NULL) { - crm_err("Cannot create heartbeat object"); - return FALSE; - } - - crm_debug("Signing in with Heartbeat"); - if (pingd_cluster->llc_ops->signon( - pingd_cluster, crm_system_name) != HA_OK) { - - crm_err("Cannot sign on with heartbeat: %s", - pingd_cluster->llc_ops->errmsg(pingd_cluster)); - crm_err("REASON: %s", pingd_cluster->llc_ops->errmsg(pingd_cluster)); - return FALSE; - } - - do_node_walk(pingd_cluster); - - crm_debug_3("Be informed of Node Status changes"); - if (HA_OK != pingd_cluster->llc_ops->set_nstatus_callback( - pingd_cluster, pingd_nstatus_callback, NULL)) { - - crm_err("Cannot set nstatus callback: %s", - pingd_cluster->llc_ops->errmsg(pingd_cluster)); - crm_err("REASON: %s", pingd_cluster->llc_ops->errmsg(pingd_cluster)); - return FALSE; - } - - if (pingd_cluster->llc_ops->set_ifstatus_callback( - pingd_cluster, pingd_lstatus_callback, NULL) != HA_OK) { - crm_err("Cannot set if status callback: %s", pingd_cluster->llc_ops->errmsg(pingd_cluster)); - return FALSE; - } - - crm_debug_3("Adding channel to mainloop"); - G_main_add_IPC_Channel( - G_PRIORITY_HIGH, pingd_cluster->llc_ops->ipcchan( - pingd_cluster), - FALSE, pingd_ha_dispatch, pingd_cluster, - pingd_ha_connection_destroy); - - return TRUE; + if (pingd_cluster == NULL) { + pingd_cluster = ll_cluster_new("heartbeat"); + } + if (pingd_cluster == NULL) { + crm_err("Cannot create heartbeat object"); + return FALSE; + } + + crm_debug("Signing in with Heartbeat"); + if (pingd_cluster->llc_ops->signon(pingd_cluster, crm_system_name) != HA_OK) { + + crm_err("Cannot sign on with heartbeat: %s", pingd_cluster->llc_ops->errmsg(pingd_cluster)); + crm_err("REASON: %s", pingd_cluster->llc_ops->errmsg(pingd_cluster)); + return FALSE; + } + + do_node_walk(pingd_cluster); + + crm_debug_3("Be informed of Node Status changes"); + if (HA_OK != + pingd_cluster->llc_ops->set_nstatus_callback(pingd_cluster, pingd_nstatus_callback, NULL)) { + + crm_err("Cannot set nstatus callback: %s", pingd_cluster->llc_ops->errmsg(pingd_cluster)); + crm_err("REASON: %s", pingd_cluster->llc_ops->errmsg(pingd_cluster)); + return FALSE; + } + + if (pingd_cluster->llc_ops-> + set_ifstatus_callback(pingd_cluster, pingd_lstatus_callback, NULL) != HA_OK) { + crm_err("Cannot set if status callback: %s", pingd_cluster->llc_ops->errmsg(pingd_cluster)); + return FALSE; + } + + crm_debug_3("Adding channel to mainloop"); + G_main_add_IPC_Channel(G_PRIORITY_HIGH, pingd_cluster->llc_ops->ipcchan(pingd_cluster), + FALSE, pingd_ha_dispatch, pingd_cluster, pingd_ha_connection_destroy); + + return TRUE; } void -do_node_walk(ll_cluster_t *hb_cluster) +do_node_walk(ll_cluster_t * hb_cluster) { - const char *ha_node = NULL; - - /* Async get client status information in the cluster */ - crm_debug_2("Invoked"); - crm_debug_3("Requesting an initial dump of CRMD client_status"); - hb_cluster->llc_ops->client_status( - hb_cluster, NULL, CRM_SYSTEM_CRMD, -1); - - crm_info("Requesting the list of configured nodes"); - hb_cluster->llc_ops->init_nodewalk(hb_cluster); - - do { - const char *ha_node_type = NULL; - const char *ha_node_status = NULL; - - ha_node = hb_cluster->llc_ops->nextnode(hb_cluster); - if(ha_node == NULL) { - continue; - } - - ha_node_type = hb_cluster->llc_ops->node_type( - hb_cluster, ha_node); - if(safe_str_neq("ping", ha_node_type)) { - crm_debug("Node %s: skipping '%s'", - ha_node, ha_node_type); - continue; - } - - if(do_filter - && g_hash_table_lookup(ping_nodes, ha_node) == NULL) { - crm_debug("Filtering: %s", ha_node); - continue; - } - - ha_node_status = hb_cluster->llc_ops->node_status( - hb_cluster, ha_node); - - crm_debug("Adding: %s=%s", ha_node, ha_node_status); - g_hash_table_replace(ping_nodes, crm_strdup(ha_node), - crm_strdup(ha_node_status)); - - } while(ha_node != NULL); - - hb_cluster->llc_ops->end_nodewalk(hb_cluster); - crm_debug_2("Complete"); - send_update(-1); + const char *ha_node = NULL; + + /* Async get client status information in the cluster */ + crm_debug_2("Invoked"); + crm_debug_3("Requesting an initial dump of CRMD client_status"); + hb_cluster->llc_ops->client_status(hb_cluster, NULL, CRM_SYSTEM_CRMD, -1); + + crm_info("Requesting the list of configured nodes"); + hb_cluster->llc_ops->init_nodewalk(hb_cluster); + + do { + const char *ha_node_type = NULL; + const char *ha_node_status = NULL; + + ha_node = hb_cluster->llc_ops->nextnode(hb_cluster); + if (ha_node == NULL) { + continue; + } + + ha_node_type = hb_cluster->llc_ops->node_type(hb_cluster, ha_node); + if (safe_str_neq("ping", ha_node_type)) { + crm_debug("Node %s: skipping '%s'", ha_node, ha_node_type); + continue; + } + + if (do_filter && g_hash_table_lookup(ping_nodes, ha_node) == NULL) { + crm_debug("Filtering: %s", ha_node); + continue; + } + + ha_node_status = hb_cluster->llc_ops->node_status(hb_cluster, ha_node); + + crm_debug("Adding: %s=%s", ha_node, ha_node_status); + g_hash_table_replace(ping_nodes, crm_strdup(ha_node), crm_strdup(ha_node_status)); + + } while (ha_node != NULL); + + hb_cluster->llc_ops->end_nodewalk(hb_cluster); + crm_debug_2("Complete"); + send_update(-1); } #endif -static gboolean stand_alone_ping(gpointer data) +static gboolean +stand_alone_ping(gpointer data) { int num_active = 0; GListPtr num = NULL; - + crm_debug_2("Checking connectivity"); - for(num = ping_list; num != NULL; num = num->next) { - ping_node *ping = (ping_node*)num->data; - if(ping_open(ping)) { - int lpc = 0; - for(;lpc < pings_per_host; lpc++) { - int len = 0; - if(ping_write(ping, "test", 4) == FALSE) { - crm_info("Node %s is unreachable (write)", ping->host); - - } else if(ping_read(ping, &len)) { - crm_debug("Node %s is alive", ping->host); - num_active++; - break; - } else { - crm_info("Node %s is unreachable (read)", ping->host); - } - sleep(1); - } - } - - ping_close(ping); + for (num = ping_list; num != NULL; num = num->next) { + ping_node *ping = (ping_node *) num->data; + + if (ping_open(ping)) { + int lpc = 0; + + for (; lpc < pings_per_host; lpc++) { + int len = 0; + + if (ping_write(ping, "test", 4) == FALSE) { + crm_info("Node %s is unreachable (write)", ping->host); + + } else if (ping_read(ping, &len)) { + crm_debug("Node %s is alive", ping->host); + num_active++; + break; + } else { + crm_info("Node %s is unreachable (read)", ping->host); + } + sleep(1); + } + } + + ping_close(ping); } send_update(num_active); return TRUE; } /* *INDENT-OFF* */ static struct crm_option long_options[] = { /* Top-level Options */ {"help", 0, 0, '?', "This text"}, {"version", 0, 0, '$', "Version information" }, {"verbose", 0, 0, 'V', "Increase debug output\n"}, {"daemonize", 0, 0, 'D', "\t\tRun in daemon mode"}, {"pid-file", 1, 0, 'p', "\tFile in which to store the process' PID\n"}, {"node", 1, 0, 'N', "\tDNS name or IP address of a host to check (can be specified more than once\n"}, {"attr-name", 1, 0, 'a', "\tName of the node attribute to set"}, {"attr-dampen", 1, 0, 'd', "How long to wait for no further changes to occur before updating the CIB with a changed attribute"}, {"attr-section", 1, 0, 'S', "(Advanced) Which part of the CIB to put the attribute in"}, {"attr-set", 1, 0, 's', "\t(Advanced) Name of the set in which to put the attribute\n"}, {"ping-interval", 1, 0, 'i', "How often, in seconds, to check for node liveliness (default=1)"}, {"ping-attempts", 1, 0, 'n', "Number of ping attempts, per host, before declaring it dead (default=2)"}, {"ping-timeout", 1, 0, 't', "How long, in seconds, to wait before declaring a ping lost (default=2)"}, {"ping-multiplier", 1, 0, 'm', "For every connected node, add to the value set in the CIB"}, {"no-updates", 0, 0, 'U', NULL, 1}, /* Legacy */ {"ping-host", 1, 0, 'h', NULL, 1}, {"value-multiplier", 1, 0, 'm', NULL, 1}, {"interval", 1, 0, 'i', NULL, 1}, {0, 0, 0, 0} }; /* *INDENT-ON* */ int main(int argc, char **argv) { - int argerr = 0; - int flag; - const char *pid_file = NULL; - gboolean daemonize = FALSE; - ping_node *p = NULL; - - int option_index = 0; - pid_file = "/tmp/pingd.pid"; - - mainloop_add_signal(SIGTERM, pingd_shutdown); - - ping_nodes = g_hash_table_new_full( - crm_str_hash, g_str_equal, - g_hash_destroy_str, g_hash_destroy_str); - - crm_log_init(NULL, LOG_INFO, TRUE, FALSE, argc, argv); - crm_set_options("V?$p:a:d:s:S:h:Dm:N:Ui:t:n:", NULL, long_options, - "Daemon for checking external connectivity and making the results available to the cluster"); - - while (1) { - flag = crm_get_option(argc, argv, &option_index); - if (flag == -1) - break; - - switch(flag) { - case 'V': - cl_log_enable_stderr(TRUE); - alter_debug(DEBUG_INC); - break; - case 'p': - pid_file = optarg; - break; - case 'a': - pingd_attr = optarg; - break; - case 'N': - case 'h': - stand_alone = TRUE; - crm_debug("Adding ping host %s", optarg); - p = ping_new(optarg); - ping_list = g_list_append(ping_list, p); - break; - case 's': - attr_set = crm_strdup(optarg); - break; - case 'm': - attr_multiplier = crm_parse_int(optarg, "1"); - break; - case 'S': - attr_section = crm_strdup(optarg); - break; - case 'd': - attr_dampen = crm_get_msec(optarg); - break; - case 'i': - re_ping_interval = crm_get_msec(optarg); - break; - case 'n': - pings_per_host = crm_atoi(optarg, NULL); - break; - case 't': - ping_timeout = crm_atoi(optarg, NULL); - break; - case 'D': - daemonize = TRUE; - break; - case 'U': - cl_log_enable_stderr(TRUE); - do_updates = FALSE; - break; - case '$': - case '?': - crm_help(flag, LSB_EXIT_OK); - break; - default: - printf("Argument code 0%o (%c) is not (?yet?) supported\n", flag, flag); - crm_err("Argument code 0%o (%c) is not (?yet?) supported\n", flag, flag); - ++argerr; - break; - } - } - - if (optind < argc) { - crm_err("non-option ARGV-elements: "); - printf("non-option ARGV-elements: "); - while (optind < argc) { - crm_err("%s ", argv[optind]); - printf("%s ", argv[optind++]); - } - printf("\n"); - } - if (argerr) { - crm_help(flag, LSB_EXIT_GENERIC); - } - - crm_make_daemon(crm_system_name, daemonize, pid_file); - ident = getpid(); - - if(do_updates == FALSE) { - goto start_ping; - } - + int argerr = 0; + int flag; + const char *pid_file = NULL; + gboolean daemonize = FALSE; + ping_node *p = NULL; + + int option_index = 0; + + pid_file = "/tmp/pingd.pid"; + + mainloop_add_signal(SIGTERM, pingd_shutdown); + + ping_nodes = g_hash_table_new_full(crm_str_hash, g_str_equal, + g_hash_destroy_str, g_hash_destroy_str); + + crm_log_init(NULL, LOG_INFO, TRUE, FALSE, argc, argv); + crm_set_options("V?$p:a:d:s:S:h:Dm:N:Ui:t:n:", NULL, long_options, + "Daemon for checking external connectivity and making the results available to the cluster"); + + while (1) { + flag = crm_get_option(argc, argv, &option_index); + if (flag == -1) + break; + + switch (flag) { + case 'V': + cl_log_enable_stderr(TRUE); + alter_debug(DEBUG_INC); + break; + case 'p': + pid_file = optarg; + break; + case 'a': + pingd_attr = optarg; + break; + case 'N': + case 'h': + stand_alone = TRUE; + crm_debug("Adding ping host %s", optarg); + p = ping_new(optarg); + ping_list = g_list_append(ping_list, p); + break; + case 's': + attr_set = crm_strdup(optarg); + break; + case 'm': + attr_multiplier = crm_parse_int(optarg, "1"); + break; + case 'S': + attr_section = crm_strdup(optarg); + break; + case 'd': + attr_dampen = crm_get_msec(optarg); + break; + case 'i': + re_ping_interval = crm_get_msec(optarg); + break; + case 'n': + pings_per_host = crm_atoi(optarg, NULL); + break; + case 't': + ping_timeout = crm_atoi(optarg, NULL); + break; + case 'D': + daemonize = TRUE; + break; + case 'U': + cl_log_enable_stderr(TRUE); + do_updates = FALSE; + break; + case '$': + case '?': + crm_help(flag, LSB_EXIT_OK); + break; + default: + printf("Argument code 0%o (%c) is not (?yet?) supported\n", flag, flag); + crm_err("Argument code 0%o (%c) is not (?yet?) supported\n", flag, flag); + ++argerr; + break; + } + } + + if (optind < argc) { + crm_err("non-option ARGV-elements: "); + printf("non-option ARGV-elements: "); + while (optind < argc) { + crm_err("%s ", argv[optind]); + printf("%s ", argv[optind++]); + } + printf("\n"); + } + if (argerr) { + crm_help(flag, LSB_EXIT_GENERIC); + } + + crm_make_daemon(crm_system_name, daemonize, pid_file); + ident = getpid(); + + if (do_updates == FALSE) { + goto start_ping; + } #if SUPPORT_COROSYNC - if(is_openais_cluster()) { - stand_alone = TRUE; - } + if (is_openais_cluster()) { + stand_alone = TRUE; + } #endif - + #if SUPPORT_HEARTBEAT - if(stand_alone == FALSE && register_with_ha() == FALSE) { - crm_err("HA registration failed"); - cl_flush_logs(); - exit(LSB_EXIT_GENERIC); - } + if (stand_alone == FALSE && register_with_ha() == FALSE) { + crm_err("HA registration failed"); + cl_flush_logs(); + exit(LSB_EXIT_GENERIC); + } #endif start_ping: - if(stand_alone && ping_list == NULL) { - crm_err("You must specify a list of hosts to monitor"); - exit(LSB_EXIT_GENERIC); - } - - crm_info("Starting %s", crm_system_name); - mainloop = g_main_new(FALSE); - - if(stand_alone) { - stand_alone_ping(NULL); - g_timeout_add(re_ping_interval, stand_alone_ping, NULL); - } - - g_main_run(mainloop); - - crm_info("Exiting %s", crm_system_name); - return 0; -} + if (stand_alone && ping_list == NULL) { + crm_err("You must specify a list of hosts to monitor"); + exit(LSB_EXIT_GENERIC); + } + + crm_info("Starting %s", crm_system_name); + mainloop = g_main_new(FALSE); + if (stand_alone) { + stand_alone_ping(NULL); + g_timeout_add(re_ping_interval, stand_alone_ping, NULL); + } -static void count_ping_nodes(gpointer key, gpointer value, gpointer user_data) + g_main_run(mainloop); + + crm_info("Exiting %s", crm_system_name); + return 0; +} + +static void +count_ping_nodes(gpointer key, gpointer value, gpointer user_data) { - int *num_active = user_data; - CRM_CHECK(num_active != NULL, return); - - if(need_shutdown) { - return; - } - - if(safe_str_eq(value, "ping")) { - (*num_active)++; - } else if(safe_str_eq(value, "up")) { - (*num_active)++; - } + int *num_active = user_data; + + CRM_CHECK(num_active != NULL, return); + + if (need_shutdown) { + return; + } + + if (safe_str_eq(value, "ping")) { + (*num_active)++; + } else if (safe_str_eq(value, "up")) { + (*num_active)++; + } } void -send_update(int num_active) +send_update(int num_active) { char *value = NULL; - char *damp = crm_itoa(attr_dampen/1000); + char *damp = crm_itoa(attr_dampen / 1000); - if(num_active < 0) { - num_active = 0; - g_hash_table_foreach(ping_nodes, count_ping_nodes, &num_active); + if (num_active < 0) { + num_active = 0; + g_hash_table_foreach(ping_nodes, count_ping_nodes, &num_active); } - - value = crm_itoa(attr_multiplier*num_active); + + value = crm_itoa(attr_multiplier * num_active); attrd_lazy_update('U', NULL, pingd_attr, value, attr_section, attr_set, damp); crm_free(value); crm_free(damp); } void -pingd_nstatus_callback( - const char *node, const char * status, void* private_data) +pingd_nstatus_callback(const char *node, const char *status, void *private_data) { - crm_notice("Status update: Ping node %s now has status [%s]", - node, status); - - if(g_hash_table_lookup(ping_nodes, node) != NULL) { - g_hash_table_replace( - ping_nodes, crm_strdup(node), crm_strdup(status)); - send_update(-1); - } + crm_notice("Status update: Ping node %s now has status [%s]", node, status); + + if (g_hash_table_lookup(ping_nodes, node) != NULL) { + g_hash_table_replace(ping_nodes, crm_strdup(node), crm_strdup(status)); + send_update(-1); + } } void -pingd_lstatus_callback(const char *node, const char *lnk, const char *status, - void *private) +pingd_lstatus_callback(const char *node, const char *lnk, const char *status, void *private) { - crm_notice("Status update: Ping node %s now has status [%s]", - node, status); - pingd_nstatus_callback(node, status, private); + crm_notice("Status update: Ping node %s now has status [%s]", node, status); + pingd_nstatus_callback(node, status, private); } - diff --git a/tools/test.iso8601.c b/tools/test.iso8601.c index a0bf760a93..2f1a53306f 100644 --- a/tools/test.iso8601.c +++ b/tools/test.iso8601.c @@ -1,144 +1,146 @@ /* * Copyright (C) 2005 Andrew Beekhof * * 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 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 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 */ #include #include #include char command = 0; /* *INDENT-OFF* */ static struct crm_option long_options[] = { /* Top-level Options */ {"help", 0, 0, '?', "\tThis text"}, {"version", 0, 0, '$', "\tVersion information" }, {"verbose", 0, 0, 'V', "\tIncrease debug output"}, {"-spacer-", 0, 0, '-', "\nCommands:"}, {"now", 0, 0, 'n', "\tDisplay the current date/time"}, {"date", 1, 0, 'd', "Parse an ISO8601 date/time. Eg. '2005-01-20 00:30:00 +01:00' or '2005-040'"}, {"period", 1, 0, 'p', "Parse an ISO8601 date/time with interval/period (wth start time). Eg. '2005-040/2005-043'"}, {"duration", 1, 0, 'D', "Parse an ISO8601 date/time with duration (wth start time). Eg. '2005-040/P1M'"}, {"-spacer-",0, 0, '-', "\nOutput Modifiers:"}, {"local", 0, 0, 'L', "\tShow result as a 'local' date/time"}, {"ordinal", 0, 0, 'O', "\tShow result as an 'ordinal' date/time"}, {"week", 0, 0, 'W', "\tShow result as an 'calendar week' date/time"}, {"-spacer-",0, 0, '-', "\nFor more information on the ISO8601 standard, see: http://en.wikipedia.org/wiki/ISO_8601"}, {0, 0, 0, 0} }; /* *INDENT-ON* */ int main(int argc, char **argv) { - int argerr = 0; - int flag; - int index = 0; - int print_options = 0; - char *input_s = NULL; - char *mutable_s = NULL; - - crm_log_init_quiet(NULL, LOG_INFO, FALSE, TRUE, argc, argv); - crm_set_options(NULL, "command [output modifier] ", long_options, "Display and parse ISO8601 dates and times"); - - if(argc < 2) { - argerr++; - } - - while (1) { - flag = crm_get_option(argc, argv, &index); - if (flag == -1) - break; - - switch(flag) { - case 'V': - cl_log_enable_stderr(TRUE); - alter_debug(DEBUG_INC); - break; - case '?': - case '$': - crm_help(flag, 0); - break; - case 'n': - command = flag; - break; - case 'd': - case 'p': - case 'D': - command = flag; - input_s = crm_strdup(optarg); - break; - case 'W': - print_options |= ha_date_weeks; - break; - case 'O': - print_options |= ha_date_ordinal; - break; - case 'L': - print_options |= ha_log_local; - break; - } - } - - if(input_s == NULL && command != 'n') { - crm_help('?', 1); - } - - mutable_s = input_s; - - if(command == 'd') { - ha_time_t *date_time = parse_date(&mutable_s); - if(date_time == NULL) { - fprintf(stderr, "Invalid date/time specified: %s\n", input_s); - crm_help('?',1); - } - log_date(LOG_INFO, "parsed", date_time, - print_options|ha_log_date|ha_log_time); - - } else if(command == 'p') { - ha_time_period_t *interval = parse_time_period(&mutable_s); - if(interval == NULL) { - fprintf(stderr, "Invalid interval specified: %s\n", input_s); - crm_help('?',1); - } - log_time_period(LOG_INFO, interval, - print_options|ha_log_date|ha_log_time); - - } else if(command == 'D') { - ha_time_t *duration = parse_time_duration(&mutable_s); - if(duration == NULL) { - fprintf(stderr, "Invalid duration specified: %s\n", input_s); - crm_help('?',1); - } - log_date(LOG_INFO, "Duration", duration, - print_options|ha_log_date|ha_log_time|ha_log_local); - - } else if(command == 'n') { - ha_time_t *now = new_ha_date(TRUE); - if(now == NULL) { - fprintf(stderr, "Internal error: couldnt determin 'now' !\n"); - crm_help('?',1); - } - log_date(LOG_INFO, "Current date/time", now, - print_options|ha_log_date|ha_log_time); - } - - return 0; + int argerr = 0; + int flag; + int index = 0; + int print_options = 0; + char *input_s = NULL; + char *mutable_s = NULL; + + crm_log_init_quiet(NULL, LOG_INFO, FALSE, TRUE, argc, argv); + crm_set_options(NULL, "command [output modifier] ", long_options, + "Display and parse ISO8601 dates and times"); + + if (argc < 2) { + argerr++; + } + + while (1) { + flag = crm_get_option(argc, argv, &index); + if (flag == -1) + break; + + switch (flag) { + case 'V': + cl_log_enable_stderr(TRUE); + alter_debug(DEBUG_INC); + break; + case '?': + case '$': + crm_help(flag, 0); + break; + case 'n': + command = flag; + break; + case 'd': + case 'p': + case 'D': + command = flag; + input_s = crm_strdup(optarg); + break; + case 'W': + print_options |= ha_date_weeks; + break; + case 'O': + print_options |= ha_date_ordinal; + break; + case 'L': + print_options |= ha_log_local; + break; + } + } + + if (input_s == NULL && command != 'n') { + crm_help('?', 1); + } + + mutable_s = input_s; + + if (command == 'd') { + ha_time_t *date_time = parse_date(&mutable_s); + + if (date_time == NULL) { + fprintf(stderr, "Invalid date/time specified: %s\n", input_s); + crm_help('?', 1); + } + log_date(LOG_INFO, "parsed", date_time, print_options | ha_log_date | ha_log_time); + + } else if (command == 'p') { + ha_time_period_t *interval = parse_time_period(&mutable_s); + + if (interval == NULL) { + fprintf(stderr, "Invalid interval specified: %s\n", input_s); + crm_help('?', 1); + } + log_time_period(LOG_INFO, interval, print_options | ha_log_date | ha_log_time); + + } else if (command == 'D') { + ha_time_t *duration = parse_time_duration(&mutable_s); + + if (duration == NULL) { + fprintf(stderr, "Invalid duration specified: %s\n", input_s); + crm_help('?', 1); + } + log_date(LOG_INFO, "Duration", duration, + print_options | ha_log_date | ha_log_time | ha_log_local); + + } else if (command == 'n') { + ha_time_t *now = new_ha_date(TRUE); + + if (now == NULL) { + fprintf(stderr, "Internal error: couldnt determin 'now' !\n"); + crm_help('?', 1); + } + log_date(LOG_INFO, "Current date/time", now, print_options | ha_log_date | ha_log_time); + } + + return 0; } diff --git a/tools/xml_diff.c b/tools/xml_diff.c index 1b3287585e..38a201c68b 100644 --- a/tools/xml_diff.c +++ b/tools/xml_diff.c @@ -1,232 +1,231 @@ /* * Copyright (C) 2004 Andrew Beekhof * * 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 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 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 */ #include #include #include #include #include #include #include #include #include #include #include #include #include /* *INDENT-OFF* */ static struct crm_option long_options[] = { /* Top-level Options */ {"help", 0, 0, '?', "\t\tThis text"}, {"version", 0, 0, '$', "\t\tVersion information" }, {"verbose", 0, 0, 'V', "\t\tIncrease debug output\n"}, {"-spacer-", 1, 0, '-', "\nOriginal XML:"}, {"original", 1, 0, 'o', "\tXML is contained in the named file"}, {"original-string", 1, 0, 'O', "XML is contained in the supplied string"}, {"-spacer-", 1, 0, '-', "\nOperation:"}, {"new", 1, 0, 'n', "\tCompare the original XML to the contents of the named file"}, {"new-string", 1, 0, 'N', "\tCompare the original XML to the contents of the supplied string"}, {"patch", 1, 0, 'p', "\tPatch the original XML with the contents of the named file"}, {"-spacer-", 1, 0, '-', "\nAdditional Options:"}, {"cib", 0, 0, 'c', "\t\tCompare/patch the inputs as a CIB (includes versions details)"}, {"filter", 0, 0, 'f', "\t\tSuppress irrelevant differences between the two inputs"}, {"stdin", 0, 0, 's', NULL, 1}, {"-spacer-", 1, 0, '-', "\nExamples:", pcmk_option_paragraph}, {"-spacer-", 1, 0, '-', "Obtain the two different configuration files by running cibadmin on the two cluster setups to compare:", pcmk_option_paragraph}, {"-spacer-", 1, 0, '-', " cibadmin --query > cib-old.xml", pcmk_option_example}, {"-spacer-", 1, 0, '-', " cibadmin --query > cib-new.xml", pcmk_option_example}, {"-spacer-", 1, 0, '-', "Calculate and save the difference between the two files:", pcmk_option_paragraph}, {"-spacer-", 1, 0, '-', " crm_diff --original cib-old.xml --new cib-new.xml > patch.xml", pcmk_option_example }, {"-spacer-", 1, 0, '-', "Apply the patch to the original file:", pcmk_option_paragraph }, {"-spacer-", 1, 0, '-', " crm_diff --original cib-old.xml --patch patch.xml > updated.xml", pcmk_option_example }, {"-spacer-", 1, 0, '-', "Apply the patch to the running cluster:", pcmk_option_paragraph }, {"-spacer-", 1, 0, '-', " cibadmin --patch patch.xml", pcmk_option_example }, {0, 0, 0, 0} }; /* *INDENT-ON* */ int main(int argc, char **argv) { - gboolean apply = FALSE; - gboolean raw_1 = FALSE; - gboolean raw_2 = FALSE; - gboolean filter = FALSE; - gboolean use_stdin = FALSE; - gboolean as_cib = FALSE; - int argerr = 0; - int flag; - xmlNode *object_1 = NULL; - xmlNode *object_2 = NULL; - xmlNode *output = NULL; - const char *xml_file_1 = NULL; - const char *xml_file_2 = NULL; - - int option_index = 0; - - crm_log_init_quiet(NULL, LOG_CRIT-1, FALSE, FALSE, argc, argv); - crm_set_options(NULL, "original_xml operation [options]", long_options, - "A tool for determining the differences between two xml files and/or applying the differences like a patch\n"); - - if(argc < 2) { - crm_help('?', LSB_EXIT_EINVAL); - } - - while (1) { - flag = crm_get_option(argc, argv, &option_index); - if (flag == -1) - break; - - switch(flag) { - case 'o': - xml_file_1 = optarg; - break; - case 'O': - xml_file_1 = optarg; - raw_1 = TRUE; - break; - case 'n': - xml_file_2 = optarg; - break; - case 'N': - xml_file_2 = optarg; - raw_2 = TRUE; - break; - case 'p': - xml_file_2 = optarg; - apply = TRUE; - break; - case 'f': - filter = TRUE; - break; - case 's': - use_stdin = TRUE; - break; - case 'c': - as_cib = TRUE; - break; - case 'V': - cl_log_enable_stderr(TRUE); - alter_debug(DEBUG_INC); - break; - case '?': - case '$': - crm_help(flag, LSB_EXIT_OK); - 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 (argerr) { - crm_help('?', LSB_EXIT_GENERIC); - } - - if(raw_1) { - object_1 = string2xml(xml_file_1); - - } else if(use_stdin) { - fprintf(stderr, "Input first XML fragment:"); - object_1 = stdin2xml(); - - } else if(xml_file_1 != NULL) { - object_1 = filename2xml(xml_file_1); - } - - if(raw_2) { - object_2 = string2xml(xml_file_2); - - } else if(use_stdin) { - fprintf(stderr, "Input second XML fragment:"); - object_2 = stdin2xml(); - - } else if(xml_file_2 != NULL) { - object_2 = filename2xml(xml_file_2); - } - - if(object_1 == NULL) { - fprintf(stderr, "Could not parse the first XML fragment"); - return 1; - } - if(object_2 == NULL) { - fprintf(stderr, "Could not parse the second XML fragment"); - return 1; - } - - if(apply) { - if(as_cib == FALSE) { - apply_xml_diff(object_1, object_2, &output); - } else { - apply_cib_diff(object_1, object_2, &output); - } - - } else { - if(as_cib == FALSE) { - output = diff_xml_object(object_1, object_2, filter); - } else { - output = diff_cib_object(object_1, object_2, filter); - } - } - - if(output != NULL) { - char *buffer = dump_xml_formatted(output); - fprintf(stdout, "%s\n", crm_str(buffer)); - crm_free(buffer); - - fflush(stdout); - - if(apply) { - buffer = calculate_xml_versioned_digest(output, FALSE, TRUE, CRM_FEATURE_SET); - crm_trace("Digest: %s\n", crm_str(buffer)); - crm_free(buffer); - } - } - - free_xml(object_1); - free_xml(object_2); - free_xml(output); - - if(apply == FALSE && output != NULL) { - return 1; - } - - return 0; + gboolean apply = FALSE; + gboolean raw_1 = FALSE; + gboolean raw_2 = FALSE; + gboolean filter = FALSE; + gboolean use_stdin = FALSE; + gboolean as_cib = FALSE; + int argerr = 0; + int flag; + xmlNode *object_1 = NULL; + xmlNode *object_2 = NULL; + xmlNode *output = NULL; + const char *xml_file_1 = NULL; + const char *xml_file_2 = NULL; + + int option_index = 0; + + crm_log_init_quiet(NULL, LOG_CRIT - 1, FALSE, FALSE, argc, argv); + crm_set_options(NULL, "original_xml operation [options]", long_options, + "A tool for determining the differences between two xml files and/or applying the differences like a patch\n"); + + if (argc < 2) { + crm_help('?', LSB_EXIT_EINVAL); + } + + while (1) { + flag = crm_get_option(argc, argv, &option_index); + if (flag == -1) + break; + + switch (flag) { + case 'o': + xml_file_1 = optarg; + break; + case 'O': + xml_file_1 = optarg; + raw_1 = TRUE; + break; + case 'n': + xml_file_2 = optarg; + break; + case 'N': + xml_file_2 = optarg; + raw_2 = TRUE; + break; + case 'p': + xml_file_2 = optarg; + apply = TRUE; + break; + case 'f': + filter = TRUE; + break; + case 's': + use_stdin = TRUE; + break; + case 'c': + as_cib = TRUE; + break; + case 'V': + cl_log_enable_stderr(TRUE); + alter_debug(DEBUG_INC); + break; + case '?': + case '$': + crm_help(flag, LSB_EXIT_OK); + 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 (argerr) { + crm_help('?', LSB_EXIT_GENERIC); + } + + if (raw_1) { + object_1 = string2xml(xml_file_1); + + } else if (use_stdin) { + fprintf(stderr, "Input first XML fragment:"); + object_1 = stdin2xml(); + + } else if (xml_file_1 != NULL) { + object_1 = filename2xml(xml_file_1); + } + + if (raw_2) { + object_2 = string2xml(xml_file_2); + + } else if (use_stdin) { + fprintf(stderr, "Input second XML fragment:"); + object_2 = stdin2xml(); + + } else if (xml_file_2 != NULL) { + object_2 = filename2xml(xml_file_2); + } + + if (object_1 == NULL) { + fprintf(stderr, "Could not parse the first XML fragment"); + return 1; + } + if (object_2 == NULL) { + fprintf(stderr, "Could not parse the second XML fragment"); + return 1; + } + + if (apply) { + if (as_cib == FALSE) { + apply_xml_diff(object_1, object_2, &output); + } else { + apply_cib_diff(object_1, object_2, &output); + } + + } else { + if (as_cib == FALSE) { + output = diff_xml_object(object_1, object_2, filter); + } else { + output = diff_cib_object(object_1, object_2, filter); + } + } + + if (output != NULL) { + char *buffer = dump_xml_formatted(output); + + fprintf(stdout, "%s\n", crm_str(buffer)); + crm_free(buffer); + + fflush(stdout); + + if (apply) { + buffer = calculate_xml_versioned_digest(output, FALSE, TRUE, CRM_FEATURE_SET); + crm_trace("Digest: %s\n", crm_str(buffer)); + crm_free(buffer); + } + } + + free_xml(object_1); + free_xml(object_2); + free_xml(output); + + if (apply == FALSE && output != NULL) { + return 1; + } + + return 0; }