diff --git a/_service b/_service index e0135b5..8b4c570 100644 --- a/_service +++ b/_service @@ -11,7 +11,7 @@ 1.1.10 --> 1.1.10+git%cd.%h - 3e8930190b8b53565ef4ca3fa00006c41511be9f + 96cd1941308be48fdf1e827b88ebd9410cf2010a diff --git a/bug-812269_pacemaker-fencing-update-cib.patch b/bug-812269_pacemaker-fencing-update-cib.patch deleted file mode 100644 index 02f0605..0000000 --- a/bug-812269_pacemaker-fencing-update-cib.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/fencing/main.c b/fencing/main.c -index 1a16b48..90787f8 100644 ---- a/fencing/main.c -+++ b/fencing/main.c -@@ -761,7 +761,7 @@ update_cib_cache_cb(const char *event, xmlNode * msg) - xmlNode *cib_last = local_cib; - - local_cib = NULL; -- rc = (*cib_apply_patch_event)(msg, cib_last, &local_cib, LOG_DEBUG); -+ /*rc = (*cib_apply_patch_event)(msg, cib_last, &local_cib, LOG_DEBUG);*/ - free_xml(cib_last); - - switch (rc) { diff --git a/pacemaker-1.1.10+git20140110.3e89301.tar.bz2 b/pacemaker-1.1.10+git20140110.3e89301.tar.bz2 deleted file mode 100644 index 93723d4..0000000 --- a/pacemaker-1.1.10+git20140110.3e89301.tar.bz2 +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c6dc260d69c6f82801be0b8f65bfea43ac2ff00e2424981a117bef30a627649a -size 9322352 diff --git a/pacemaker-1.1.10+git20140124.96cd194.tar.bz2 b/pacemaker-1.1.10+git20140124.96cd194.tar.bz2 new file mode 100644 index 0000000..791b905 --- /dev/null +++ b/pacemaker-1.1.10+git20140124.96cd194.tar.bz2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d9a2ba6bb2dece3d5ac383ce62fd1e9559493ea6cec9e62f2ce4443e855fe1a3 +size 9350450 diff --git a/pacemaker-Wno-cast-align.patch b/pacemaker-Wno-cast-align.patch index 8d25cfd..a970201 100644 --- a/pacemaker-Wno-cast-align.patch +++ b/pacemaker-Wno-cast-align.patch @@ -1,13 +1,102 @@ -Index: pacemaker/lib/common/Makefile.am -=================================================================== ---- pacemaker.orig/lib/common/Makefile.am -+++ pacemaker/lib/common/Makefile.am -@@ -32,6 +32,8 @@ lib_LTLIBRARIES = libcrmcommon.la +commit 5e0e36364e242029717ef5bd2061344b8e38e7d2 +Author: Gao,Yan +Date: Sat Jan 25 14:30:25 2014 +0800 + + Build: Suppress -Wcast-align warnings/errors on arm and ppc64le + +diff --git a/lib/common/ipc.c b/lib/common/ipc.c +index 3d34706..d7b525f 100644 +--- a/lib/common/ipc.c ++++ b/lib/common/ipc.c +@@ -894,7 +894,7 @@ crm_ipc_ready(crm_ipc_t * client) + static int + crm_ipc_decompress(crm_ipc_t * client) + { +- struct crm_ipc_response_header *header = (struct crm_ipc_response_header *)client->buffer; ++ struct crm_ipc_response_header *header = (struct crm_ipc_response_header *)(void *)client->buffer; - CFLAGS = $(CFLAGS_COPY:-Wcast-qual=) -fPIC + if (header->size_compressed) { + int rc = 0; +@@ -926,7 +926,7 @@ crm_ipc_decompress(crm_ipc_t * client) + CRM_ASSERT(size_u == header->size_uncompressed); + + memcpy(uncompressed, client->buffer, hdr_offset); /* Preserve the header */ +- header = (struct crm_ipc_response_header *)uncompressed; ++ header = (struct crm_ipc_response_header *)(void *)uncompressed; + + free(client->buffer); + client->buf_size = new_buf_size; +@@ -957,7 +957,7 @@ crm_ipc_read(crm_ipc_t * client) + return rc; + } + +- header = (struct crm_ipc_response_header *)client->buffer; ++ header = (struct crm_ipc_response_header *)(void *)client->buffer; + if(header->version > PCMK_IPC_VERSION) { + crm_err("Filtering incompatible v%d IPC message, we only support versions <= %d", + header->version, PCMK_IPC_VERSION); +@@ -1044,7 +1044,7 @@ internal_ipc_get_reply(crm_ipc_t * client, int request_id, int ms_timeout) + return rc; + } + +- hdr = (struct crm_ipc_response_header *)client->buffer; ++ hdr = (struct crm_ipc_response_header *)(void *)client->buffer; + if (hdr->qb.id == request_id) { + /* Got it */ + break; +@@ -1173,7 +1173,7 @@ crm_ipc_send(crm_ipc_t * client, xmlNode * message, enum crm_ipc_flags flags, in + } + + if (rc > 0) { +- struct crm_ipc_response_header *hdr = (struct crm_ipc_response_header *)client->buffer; ++ struct crm_ipc_response_header *hdr = (struct crm_ipc_response_header *)(void *)client->buffer; + + crm_trace("Received response %d, size=%d, rc=%ld, text: %.200s", hdr->qb.id, hdr->qb.size, + rc, crm_ipc_buffer(client)); +diff --git a/lib/common/remote.c b/lib/common/remote.c +index acffccb..02099e6 100644 +--- a/lib/common/remote.c ++++ b/lib/common/remote.c +@@ -353,7 +353,7 @@ crm_remote_send(crm_remote_t * remote, xmlNode * msg) + header->size_total = iov[0].iov_len + iov[1].iov_len; + + crm_trace("Sending len[0]=%d, start=%x\n", +- (int)iov[0].iov_len, *(int*)xml_text); ++ (int)iov[0].iov_len, *(int*)(void *)xml_text); + rc = crm_remote_sendv(remote, iov, 2); + if (rc < 0) { + crm_err("Failed to send remote msg, rc = %d", rc); +@@ -861,13 +861,13 @@ crm_remote_tcp_connect_async(const char *host, int port, int timeout, /*ms */ + + memset(buffer, 0, DIMOF(buffer)); + if (addr->sa_family == AF_INET6) { +- struct sockaddr_in6 *addr_in = (struct sockaddr_in6 *)addr; ++ struct sockaddr_in6 *addr_in = (struct sockaddr_in6 *)(void *)addr; + + addr_in->sin6_port = htons(port); + inet_ntop(addr->sa_family, &addr_in->sin6_addr, buffer, DIMOF(buffer)); + + } else { +- struct sockaddr_in *addr_in = (struct sockaddr_in *)addr; ++ struct sockaddr_in *addr_in = (struct sockaddr_in *)(void *)addr; + + addr_in->sin_port = htons(port); + inet_ntop(addr->sa_family, &addr_in->sin_addr, buffer, DIMOF(buffer)); +diff --git a/lrmd/tls_backend.c b/lrmd/tls_backend.c +index 1600353..32d761f 100644 +--- a/lrmd/tls_backend.c ++++ b/lrmd/tls_backend.c +@@ -264,11 +264,11 @@ bind_and_listen(struct addrinfo *addr) + char buffer[256] = { 0, }; + + if (addr->ai_family == AF_INET6) { +- struct sockaddr_in6 *addr_in = (struct sockaddr_in6 *)addr->ai_addr; ++ struct sockaddr_in6 *addr_in = (struct sockaddr_in6 *)(void *)addr->ai_addr; + inet_ntop(addr->ai_family, &addr_in->sin6_addr, buffer, DIMOF(buffer)); + + } else { +- struct sockaddr_in *addr_in = (struct sockaddr_in *)addr->ai_addr; ++ struct sockaddr_in *addr_in = (struct sockaddr_in *)(void *)addr->ai_addr; + inet_ntop(addr->ai_family, &addr_in->sin_addr, buffer, DIMOF(buffer)); + } -+ipc.lo remote.lo: CFLAGS += -Wno-cast-align -+ - libcrmcommon_la_SOURCES = ipc.c utils.c xml.c iso8601.c remote.c mainloop.c logging.c - if BUILD_CIBSECRETS - libcrmcommon_la_SOURCES += cib_secrets.c diff --git a/pacemaker-crm_mon-brief.patch b/pacemaker-crm_mon-brief.patch new file mode 100644 index 0000000..f3a09a9 --- /dev/null +++ b/pacemaker-crm_mon-brief.patch @@ -0,0 +1,374 @@ +commit 9584fca04fc5b7a72dba09cc44fcfbe917325737 +Author: Gao,Yan +Date: Fri Jan 24 16:11:36 2014 +0800 + + Feature: crm_mon: Display brief output if "-b/--brief" is supplied or 'b' is toggled + + It's very helpful if there are many same types of resources. + + If -b/--brief is supplied, the output is like: + + 6 (ocf::pacemaker:Dummy): Active node1 + + If -r/--inactive is also supplied: + + 6/10 (ocf::pacemaker:Dummy): Active node1 + 0/5 (ocf::heartbeat:Dummy): Active + + Output for a group is like: + Resource Group: group1 + 18/20 (ocf::pacemaker:Dummy): Active node1 + 12/15 (ocf::heartbeat:Dummy): Active node1 + + If -n/--group-by-node is also supplied, the output of the node is like: + + Node node1: online + 24 (ocf::pacemaker:Dummy): Active + 12 (ocf::heartbeat:Dummy): Active + +diff --git a/include/crm/pengine/common.h b/include/crm/pengine/common.h +index c1901ef..ddca95d 100644 +--- a/include/crm/pengine/common.h ++++ b/include/crm/pengine/common.h +@@ -98,6 +98,7 @@ enum pe_print_options { + pe_print_suppres_nl = 0x0200, + pe_print_xml = 0x0400, + pe_print_pending = 0x0800, ++ pe_print_brief = 0x1000, + }; + /* *INDENT-ON* */ + +diff --git a/include/crm/pengine/internal.h b/include/crm/pengine/internal.h +index 46e63c4..072c0a9 100644 +--- a/include/crm/pengine/internal.h ++++ b/include/crm/pengine/internal.h +@@ -265,4 +265,7 @@ gboolean is_baremetal_remote_node(node_t *node); + gboolean is_container_remote_node(node_t *node); + gboolean is_remote_node(node_t *node); + resource_t * rsc_contains_remote_node(pe_working_set_t * data_set, resource_t *rsc); ++ ++void print_rscs_brief(GListPtr rsc_list, const char * pre_text, long options, ++ void * print_data, gboolean print_all); + #endif +diff --git a/lib/pengine/group.c b/lib/pengine/group.c +index 885486e..831376c 100644 +--- a/lib/pengine/group.c ++++ b/lib/pengine/group.c +@@ -168,15 +168,20 @@ group_print(resource_t * rsc, const char *pre_text, long options, void *print_da + status_print("\n"); + } + +- for (; gIter != NULL; gIter = gIter->next) { +- resource_t *child_rsc = (resource_t *) gIter->data; ++ if (options & pe_print_brief) { ++ print_rscs_brief(rsc->children, child_text, options, print_data, TRUE); + +- if (options & pe_print_html) { +- status_print("
  • \n"); +- } +- child_rsc->fns->print(child_rsc, child_text, options, print_data); +- if (options & pe_print_html) { +- status_print("
  • \n"); ++ } else { ++ for (; gIter != NULL; gIter = gIter->next) { ++ resource_t *child_rsc = (resource_t *) gIter->data; ++ ++ if (options & pe_print_html) { ++ status_print("
  • \n"); ++ } ++ child_rsc->fns->print(child_rsc, child_text, options, print_data); ++ if (options & pe_print_html) { ++ status_print("
  • \n"); ++ } + } + } + +diff --git a/lib/pengine/native.c b/lib/pengine/native.c +index be95ba1..b223ab3 100644 +--- a/lib/pengine/native.c ++++ b/lib/pengine/native.c +@@ -687,3 +687,160 @@ native_location(resource_t * rsc, GListPtr * list, gboolean current) + g_list_free(result); + return one; + } ++ ++static void ++get_rscs_brief(GListPtr rsc_list, GHashTable * rsc_table, GHashTable * active_table) ++{ ++ GListPtr gIter = rsc_list; ++ ++ for (; gIter != NULL; gIter = gIter->next) { ++ resource_t *rsc = (resource_t *) gIter->data; ++ ++ const char *class = crm_element_value(rsc->xml, XML_AGENT_ATTR_CLASS); ++ const char *kind = crm_element_value(rsc->xml, XML_ATTR_TYPE); ++ ++ int offset = 0; ++ char buffer[LINE_MAX]; ++ ++ int *rsc_counter = NULL; ++ int *active_counter = NULL; ++ ++ if (rsc->variant != pe_native) { ++ continue; ++ } ++ ++ offset += snprintf(buffer + offset, LINE_MAX - offset, "%s", class); ++ if (safe_str_eq(class, "ocf")) { ++ const char *prov = crm_element_value(rsc->xml, XML_AGENT_ATTR_PROVIDER); ++ offset += snprintf(buffer + offset, LINE_MAX - offset, "::%s", prov); ++ } ++ offset += snprintf(buffer + offset, LINE_MAX - offset, ":%s", kind); ++ ++ if (rsc_table) { ++ rsc_counter = g_hash_table_lookup(rsc_table, buffer); ++ if (rsc_counter == NULL) { ++ rsc_counter = calloc(1, sizeof(int)); ++ *rsc_counter = 0; ++ g_hash_table_insert(rsc_table, strdup(buffer), rsc_counter); ++ } ++ (*rsc_counter)++; ++ } ++ ++ if (active_table) { ++ GListPtr gIter2 = rsc->running_on; ++ ++ for (; gIter2 != NULL; gIter2 = gIter2->next) { ++ node_t *node = (node_t *) gIter2->data; ++ GHashTable *node_table = NULL; ++ ++ if (node->details->unclean == FALSE && node->details->online == FALSE) { ++ continue; ++ } ++ ++ node_table = g_hash_table_lookup(active_table, node->details->uname); ++ if (node_table == NULL) { ++ node_table = g_hash_table_new_full(crm_str_hash, g_str_equal, free, free); ++ g_hash_table_insert(active_table, strdup(node->details->uname), node_table); ++ } ++ ++ active_counter = g_hash_table_lookup(node_table, buffer); ++ if (active_counter == NULL) { ++ active_counter = calloc(1, sizeof(int)); ++ *active_counter = 0; ++ g_hash_table_insert(node_table, strdup(buffer), active_counter); ++ } ++ (*active_counter)++; ++ } ++ } ++ } ++} ++ ++static void ++destroy_node_table(gpointer data) ++{ ++ GHashTable *node_table = data; ++ ++ if (node_table) { ++ g_hash_table_destroy(node_table); ++ } ++} ++ ++void ++print_rscs_brief(GListPtr rsc_list, const char *pre_text, long options, ++ void *print_data, gboolean print_all) ++{ ++ GHashTable *rsc_table = g_hash_table_new_full(crm_str_hash, g_str_equal, free, free); ++ GHashTable *active_table = g_hash_table_new_full(crm_str_hash, g_str_equal, ++ free, destroy_node_table); ++ GHashTableIter hash_iter; ++ char *type = NULL; ++ int *rsc_counter = NULL; ++ ++ get_rscs_brief(rsc_list, rsc_table, active_table); ++ ++ g_hash_table_iter_init(&hash_iter, rsc_table); ++ while (g_hash_table_iter_next(&hash_iter, (gpointer *)&type, (gpointer *)&rsc_counter)) { ++ GHashTableIter hash_iter2; ++ char *node_name = NULL; ++ GHashTable *node_table = NULL; ++ int active_counter_all = 0; ++ ++ g_hash_table_iter_init(&hash_iter2, active_table); ++ while (g_hash_table_iter_next(&hash_iter2, (gpointer *)&node_name, (gpointer *)&node_table)) { ++ int *active_counter = g_hash_table_lookup(node_table, type); ++ ++ if (active_counter == NULL || *active_counter == 0) { ++ continue; ++ ++ } else { ++ active_counter_all += *active_counter; ++ } ++ ++ if (options & pe_print_rsconly) { ++ node_name = NULL; ++ } ++ ++ if (options & pe_print_html) { ++ status_print("
  • \n"); ++ } ++ ++ if (print_all) { ++ status_print("%s%d/%d\t(%s):\tActive %s\n", pre_text ? pre_text : "", ++ active_counter ? *active_counter : 0, ++ rsc_counter ? *rsc_counter : 0, type, ++ active_counter && (*active_counter > 0) && node_name ? node_name : ""); ++ } else { ++ status_print("%s%d\t(%s):\tActive %s\n", pre_text ? pre_text : "", ++ active_counter ? *active_counter : 0, type, ++ active_counter && (*active_counter > 0) && node_name ? node_name : ""); ++ } ++ ++ if (options & pe_print_html) { ++ status_print("
  • \n"); ++ } ++ } ++ ++ if (print_all && active_counter_all == 0) { ++ if (options & pe_print_html) { ++ status_print("
  • \n"); ++ } ++ ++ status_print("%s%d/%d\t(%s):\tActive\n", pre_text ? pre_text : "", ++ active_counter_all, ++ rsc_counter ? *rsc_counter : 0, type); ++ ++ if (options & pe_print_html) { ++ status_print("
  • \n"); ++ } ++ } ++ } ++ ++ if (rsc_table) { ++ g_hash_table_destroy(rsc_table); ++ rsc_table = NULL; ++ } ++ if (active_table) { ++ g_hash_table_destroy(active_table); ++ active_table = NULL; ++ } ++} +diff --git a/tools/crm_mon.c b/tools/crm_mon.c +index 746094f..a69a4fe 100644 +--- a/tools/crm_mon.c ++++ b/tools/crm_mon.c +@@ -97,6 +97,7 @@ gboolean print_tickets = FALSE; + gboolean watch_fencing = FALSE; + gboolean hide_headers = FALSE; + gboolean print_pending = FALSE; ++gboolean print_brief = FALSE; + + /* FIXME allow, detect, and correctly interpret glob pattern or regex? */ + const char *print_neg_location_prefix; +@@ -342,6 +343,7 @@ static struct crm_option long_options[] = { + {"show-node-attributes", 0, 0, 'A', "Display node attributes" }, + {"hide-headers", 0, 0, 'D', "\tHide all headers" }, + {"pending", 0, 0, 'j', "\t\tDisplay pending state if 'record-pending' is enabled" }, ++ {"brief", 0, 0, 'b', "\t\tBrief output" }, + + {"-spacer-", 1, 0, '-', "\nAdditional Options:"}, + {"interval", 1, 0, 'i', "\tUpdate frequency in seconds" }, +@@ -454,6 +456,9 @@ detect_user_input(GIOChannel *channel, GIOCondition condition, gpointer unused) + case 'j': + print_pending = ! print_pending; + break; ++ case 'b': ++ print_brief = ! print_brief; ++ break; + case '?': + config_mode = TRUE; + break; +@@ -478,6 +483,7 @@ detect_user_input(GIOChannel *channel, GIOCondition condition, gpointer unused) + print_as("%c L: \t%s\n", print_neg_location_prefix ? '*': ' ', get_option_desc('L')); + print_as("%c D: \t%s\n", hide_headers ? '*': ' ', get_option_desc('D')); + print_as("%c j: \t%s\n", print_pending ? '*': ' ', get_option_desc('j')); ++ print_as("%c b: \t%s\n", print_brief ? '*': ' ', get_option_desc('b')); + print_as("\n"); + print_as("Toggle fields via field letter, type any other key to return"); + } +@@ -562,6 +568,9 @@ main(int argc, char **argv) + case 'D': + hide_headers = TRUE; + break; ++ case 'b': ++ print_brief = TRUE; ++ break; + case 'c': + print_tickets = TRUE; + break; +@@ -1326,7 +1335,11 @@ print_status(pe_working_set_t * data_set) + print_as("Node %s (%s): %s\n", node_name, node->details->id, node_mode); + } + +- if (group_by_node) { ++ if (print_brief && group_by_node) { ++ print_rscs_brief(node->details->running_rsc, "\t", print_opts | pe_print_rsconly, ++ stdout, FALSE); ++ ++ } else if (group_by_node) { + GListPtr gIter2 = NULL; + + for (gIter2 = node->details->running_rsc; gIter2 != NULL; gIter2 = gIter2->next) { +@@ -1368,12 +1381,24 @@ print_status(pe_working_set_t * data_set) + + if (group_by_node == FALSE || inactive_resources) { + print_as("\n"); ++ ++ if (print_brief && group_by_node == FALSE) { ++ print_opts |= pe_print_brief; ++ print_rscs_brief(data_set->resources, NULL, print_opts, stdout, ++ 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 (print_brief && group_by_node == FALSE ++ && rsc->variant == pe_native) { ++ continue; ++ } ++ + if (is_set(rsc->flags, pe_rsc_orphan) && is_active == FALSE) { + continue; + +@@ -1740,7 +1765,13 @@ print_html_status(pe_working_set_t * data_set, const char *filename, gboolean we + fprintf(stream, "Node: %s (%s): %s", node->details->uname, node->details->id, + "OFFLINE\n"); + } +- if (group_by_node) { ++ if (print_brief && group_by_node) { ++ fprintf(stream, "
      \n"); ++ print_rscs_brief(node->details->running_rsc, NULL, print_opts | pe_print_rsconly, ++ stream, FALSE); ++ fprintf(stream, "
    \n"); ++ ++ } else if (group_by_node) { + GListPtr lpc2 = NULL; + + fprintf(stream, "
      \n"); +@@ -1765,11 +1796,22 @@ print_html_status(pe_working_set_t * data_set, const char *filename, gboolean we + } + + if (group_by_node == FALSE || inactive_resources) { ++ if (print_brief && group_by_node == FALSE) { ++ print_opts |= pe_print_brief; ++ print_rscs_brief(data_set->resources, NULL, print_opts, stream, ++ 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 (print_brief && group_by_node == FALSE ++ && rsc->variant == pe_native) { ++ continue; ++ } ++ + if (is_set(rsc->flags, pe_rsc_orphan) && is_active == FALSE) { + continue; + diff --git a/pacemaker-display-pending-ops.patch b/pacemaker-display-pending-ops.patch new file mode 100644 index 0000000..930fb6c --- /dev/null +++ b/pacemaker-display-pending-ops.patch @@ -0,0 +1,503 @@ +commit a33aadaf14f1e0cc2fb9d025801a2d86e3732275 +Author: Gao,Yan +Date: Mon Jan 13 20:03:28 2014 +0800 + + Feature: tools: Display pending state in crm_mon/crm_resource/crm_simulate if --pending/-j is supplied (cl#5178) + +diff --git a/include/crm/pengine/common.h b/include/crm/pengine/common.h +index 2477e47..c1901ef 100644 +--- a/include/crm/pengine/common.h ++++ b/include/crm/pengine/common.h +@@ -97,6 +97,7 @@ enum pe_print_options { + pe_print_ops = 0x0100, + pe_print_suppres_nl = 0x0200, + pe_print_xml = 0x0400, ++ pe_print_pending = 0x0800, + }; + /* *INDENT-ON* */ + +diff --git a/include/crm/pengine/status.h b/include/crm/pengine/status.h +index 3f3de17..3a380cc 100644 +--- a/include/crm/pengine/status.h ++++ b/include/crm/pengine/status.h +@@ -275,6 +275,8 @@ struct resource_s { + + resource_t *container; + GListPtr fillers; ++ ++ char *pending_task; + }; + + struct pe_action_s { +diff --git a/lib/pengine/complex.c b/lib/pengine/complex.c +index 2ada463..a592fc8 100644 +--- a/lib/pengine/complex.c ++++ b/lib/pengine/complex.c +@@ -743,5 +743,6 @@ common_free(resource_t * rsc) + free(rsc->clone_name); + free(rsc->allocated_to); + free(rsc->variant_opaque); ++ free(rsc->pending_task); + free(rsc); + } +diff --git a/lib/pengine/native.c b/lib/pengine/native.c +index adfd5ba..be95ba1 100644 +--- a/lib/pengine/native.c ++++ b/lib/pengine/native.c +@@ -291,12 +291,60 @@ native_print_attr(gpointer key, gpointer value, gpointer user_data) + status_print("Option: %s = %s\n", (char *)key, (char *)value); + } + ++static const char * ++native_pending_state(resource_t * rsc) ++{ ++ const char *pending_state = NULL; ++ ++ if (safe_str_eq(rsc->pending_task, CRMD_ACTION_START)) { ++ pending_state = "Starting"; ++ ++ } else if (safe_str_eq(rsc->pending_task, CRMD_ACTION_STOP)) { ++ pending_state = "Stopping"; ++ ++ } else if (safe_str_eq(rsc->pending_task, CRMD_ACTION_MIGRATE)) { ++ pending_state = "Migrating"; ++ ++ } else if (safe_str_eq(rsc->pending_task, CRMD_ACTION_MIGRATED)) { ++ /* Work might be done in here. */ ++ pending_state = "Migrating"; ++ ++ } else if (safe_str_eq(rsc->pending_task, CRMD_ACTION_PROMOTE)) { ++ pending_state = "Promoting"; ++ ++ } else if (safe_str_eq(rsc->pending_task, CRMD_ACTION_DEMOTE)) { ++ pending_state = "Demoting"; ++ } ++ ++ return pending_state; ++} ++ ++static const char * ++native_pending_task(resource_t * rsc) ++{ ++ const char *pending_task = NULL; ++ ++ if (safe_str_eq(rsc->pending_task, CRMD_ACTION_NOTIFY)) { ++ /* "Notifying" is not very useful to be shown. */ ++ pending_task = NULL; ++ ++ } else if (safe_str_eq(rsc->pending_task, CRMD_ACTION_STATUS)) { ++ pending_task = "Monitoring"; ++ ++ } else if (safe_str_eq(rsc->pending_task, "probe")) { ++ pending_task = "Checking"; ++ } ++ ++ return pending_task; ++} ++ + static void + native_print_xml(resource_t * rsc, const char *pre_text, long options, void *print_data) + { + enum rsc_role_e role = rsc->role; + const char *class = crm_element_value(rsc->xml, XML_AGENT_ATTR_CLASS); + const char *prov = crm_element_value(rsc->xml, XML_AGENT_ATTR_PROVIDER); ++ const char *rsc_state = NULL; + + if(role == RSC_ROLE_STARTED && uber_parent(rsc)->variant == pe_master) { + role = RSC_ROLE_SLAVE; +@@ -308,7 +356,14 @@ native_print_xml(resource_t * rsc, const char *pre_text, long options, void *pri + status_print("resource_agent=\"%s%s%s:%s\" ", + class, + prov ? "::" : "", prov ? prov : "", crm_element_value(rsc->xml, XML_ATTR_TYPE)); +- status_print("role=\"%s\" ", role2text(role)); ++ ++ if (options & pe_print_pending) { ++ rsc_state = native_pending_state(rsc); ++ } ++ if (rsc_state == NULL) { ++ rsc_state = role2text(role); ++ } ++ status_print("role=\"%s\" ", rsc_state); + status_print("active=\"%s\" ", rsc->fns->active(rsc, TRUE) ? "true" : "false"); + status_print("orphaned=\"%s\" ", is_set(rsc->flags, pe_rsc_orphan) ? "true" : "false"); + status_print("managed=\"%s\" ", is_set(rsc->flags, pe_rsc_managed) ? "true" : "false"); +@@ -317,6 +372,14 @@ native_print_xml(resource_t * rsc, const char *pre_text, long options, void *pri + is_set(rsc->flags, pe_rsc_failure_ignored) ? "true" : "false"); + status_print("nodes_running_on=\"%d\" ", g_list_length(rsc->running_on)); + ++ if (options & pe_print_pending) { ++ const char *pending_task = native_pending_task(rsc); ++ ++ if (pending_task) { ++ status_print("pending=\"%s\" ", pending_task); ++ } ++ } ++ + if (options & pe_print_dev) { + status_print("provisional=\"%s\" ", + is_set(rsc->flags, pe_rsc_provisional) ? "true" : "false"); +@@ -423,12 +486,29 @@ native_print(resource_t * rsc, const char *pre_text, long options, void *print_d + } else if(is_set(rsc->flags, pe_rsc_failed)) { + offset += snprintf(buffer + offset, LINE_MAX - offset, "FAILED "); + } else { +- offset += snprintf(buffer + offset, LINE_MAX - offset, "%s ", role2text(rsc->role)); ++ const char *rsc_state = NULL; ++ ++ if (options & pe_print_pending) { ++ rsc_state = native_pending_state(rsc); ++ } ++ if (rsc_state == NULL) { ++ rsc_state = role2text(rsc->role); ++ } ++ offset += snprintf(buffer + offset, LINE_MAX - offset, "%s ", rsc_state); + } + + if(node) { + offset += snprintf(buffer + offset, LINE_MAX - offset, "%s ", node->details->uname); + } ++ ++ if (options & pe_print_pending) { ++ const char *pending_task = native_pending_task(rsc); ++ ++ if (pending_task) { ++ offset += snprintf(buffer + offset, LINE_MAX - offset, "(%s) ", pending_task); ++ } ++ } ++ + if(is_not_set(rsc->flags, pe_rsc_managed)) { + offset += snprintf(buffer + offset, LINE_MAX - offset, "(unmanaged) "); + } +diff --git a/lib/pengine/unpack.c b/lib/pengine/unpack.c +index aaa9a67..57960cc 100644 +--- a/lib/pengine/unpack.c ++++ b/lib/pengine/unpack.c +@@ -2757,6 +2757,7 @@ unpack_rsc_op(resource_t * rsc, node_t * node, xmlNode * xml_op, + int rc = 0; + int status = PCMK_LRM_OP_PENDING-1; + int target_rc = get_target_rc(xml_op); ++ int interval = 0; + + gboolean expired = FALSE; + resource_t *parent = rsc; +@@ -2774,6 +2775,7 @@ unpack_rsc_op(resource_t * rsc, node_t * node, xmlNode * xml_op, + crm_element_value_int(xml_op, XML_LRM_ATTR_RC, &rc); + crm_element_value_int(xml_op, XML_LRM_ATTR_CALLID, &task_id); + crm_element_value_int(xml_op, XML_LRM_ATTR_OPSTATUS, &status); ++ crm_element_value_int(xml_op, XML_LRM_ATTR_INTERVAL, &interval); + + CRM_CHECK(task != NULL, return FALSE); + CRM_CHECK(status <= PCMK_LRM_OP_NOT_INSTALLED, return FALSE); +@@ -2807,7 +2809,6 @@ unpack_rsc_op(resource_t * rsc, node_t * node, xmlNode * xml_op, + } + + if (expired && target_rc != rc) { +- int interval = 0; + const char *magic = crm_element_value(xml_op, XML_ATTR_TRANSITION_MAGIC); + + pe_rsc_debug(rsc, "Expired operation '%s' on %s returned '%s' (%d) instead of the expected value: '%s' (%d)", +@@ -2815,7 +2816,6 @@ unpack_rsc_op(resource_t * rsc, node_t * node, xmlNode * xml_op, + services_ocf_exitcode_str(rc), rc, + services_ocf_exitcode_str(target_rc), target_rc); + +- crm_element_value_int(xml_op, XML_LRM_ATTR_INTERVAL, &interval); + if(interval == 0) { + crm_notice("Ignoring expired calculated failure %s (rc=%d, magic=%s) on %s", + task_key, rc, magic, node->details->uname); +@@ -2858,6 +2858,14 @@ unpack_rsc_op(resource_t * rsc, node_t * node, xmlNode * xml_op, + stop_action(rsc, target, FALSE); + } + } ++ ++ if (safe_str_eq(task, CRMD_ACTION_STATUS) && interval == 0) { ++ /* Temporarily comment this out until cl#5184 is fixed */ ++ /*rsc->pending_task = strdup("probe");*/ ++ ++ } else { ++ rsc->pending_task = strdup(task); ++ } + break; + + case PCMK_LRM_OP_DONE: +diff --git a/tools/crm_mon.c b/tools/crm_mon.c +index a9dd1b7..746094f 100644 +--- a/tools/crm_mon.c ++++ b/tools/crm_mon.c +@@ -96,6 +96,7 @@ gboolean print_last_change = TRUE; + gboolean print_tickets = FALSE; + gboolean watch_fencing = FALSE; + gboolean hide_headers = FALSE; ++gboolean print_pending = FALSE; + + /* FIXME allow, detect, and correctly interpret glob pattern or regex? */ + const char *print_neg_location_prefix; +@@ -340,6 +341,7 @@ static struct crm_option long_options[] = { + {"neg-locations", 2, 0, 'L', "Display negative location constraints [optionally filtered by id prefix]"}, + {"show-node-attributes", 0, 0, 'A', "Display node attributes" }, + {"hide-headers", 0, 0, 'D', "\tHide all headers" }, ++ {"pending", 0, 0, 'j', "\t\tDisplay pending state if 'record-pending' is enabled" }, + + {"-spacer-", 1, 0, '-', "\nAdditional Options:"}, + {"interval", 1, 0, 'i', "\tUpdate frequency in seconds" }, +@@ -449,6 +451,9 @@ detect_user_input(GIOChannel *channel, GIOCondition condition, gpointer unused) + case 'D': + hide_headers = ! hide_headers; + break; ++ case 'j': ++ print_pending = ! print_pending; ++ break; + case '?': + config_mode = TRUE; + break; +@@ -472,6 +477,7 @@ detect_user_input(GIOChannel *channel, GIOCondition condition, gpointer unused) + print_as("%c A: \t%s\n", print_nodes_attr ? '*': ' ', get_option_desc('A')); + print_as("%c L: \t%s\n", print_neg_location_prefix ? '*': ' ', get_option_desc('L')); + print_as("%c D: \t%s\n", hide_headers ? '*': ' ', get_option_desc('D')); ++ print_as("%c j: \t%s\n", print_pending ? '*': ' ', get_option_desc('j')); + print_as("\n"); + print_as("Toggle fields via field letter, type any other key to return"); + } +@@ -550,6 +556,9 @@ main(int argc, char **argv) + case 'L': + print_neg_location_prefix = optarg ?: ""; + break; ++ case 'j': ++ print_pending = TRUE; ++ break; + case 'D': + hide_headers = TRUE; + break; +@@ -1159,6 +1168,10 @@ print_status(pe_working_set_t * data_set) + print_opts = pe_print_printf; + } + ++ if (print_pending) { ++ print_opts |= pe_print_pending; ++ } ++ + updates++; + dc = data_set->dc_node; + +@@ -1463,9 +1476,14 @@ print_xml_status(pe_working_set_t * data_set) + xmlNode *stack = NULL; + xmlNode *quorum_node = NULL; + const char *quorum_votes = "unknown"; ++ int print_opts = pe_print_xml; + + dc = data_set->dc_node; + ++ if (print_pending) { ++ print_opts |= pe_print_pending; ++ } ++ + fprintf(stream, "\n"); + fprintf(stream, "\n", VERSION); + +@@ -1567,7 +1585,7 @@ print_xml_status(pe_working_set_t * data_set) + for (lpc2 = node->details->running_rsc; lpc2 != NULL; lpc2 = lpc2->next) { + resource_t *rsc = (resource_t *) lpc2->data; + +- rsc->fns->print(rsc, " ", pe_print_xml | pe_print_rsconly, stream); ++ rsc->fns->print(rsc, " ", print_opts | pe_print_rsconly, stream); + } + fprintf(stream, " \n"); + } else { +@@ -1589,11 +1607,11 @@ print_xml_status(pe_working_set_t * data_set) + + } else if (group_by_node == FALSE) { + if (partially_active || inactive_resources) { +- rsc->fns->print(rsc, " ", pe_print_xml, stream); ++ rsc->fns->print(rsc, " ", print_opts, stream); + } + + } else if (is_active == FALSE && inactive_resources) { +- rsc->fns->print(rsc, " ", pe_print_xml, stream); ++ rsc->fns->print(rsc, " ", print_opts, stream); + } + } + fprintf(stream, " \n"); +@@ -1614,6 +1632,11 @@ print_html_status(pe_working_set_t * data_set, const char *filename, gboolean we + node_t *dc = NULL; + static int updates = 0; + char *filename_tmp = NULL; ++ int print_opts = pe_print_html; ++ ++ if (print_pending) { ++ print_opts |= pe_print_pending; ++ } + + if (web_cgi) { + stream = stdout; +@@ -1725,7 +1748,7 @@ print_html_status(pe_working_set_t * data_set, const char *filename, gboolean we + resource_t *rsc = (resource_t *) lpc2->data; + + fprintf(stream, "
    • "); +- rsc->fns->print(rsc, NULL, pe_print_html | pe_print_rsconly, stream); ++ rsc->fns->print(rsc, NULL, print_opts | pe_print_rsconly, stream); + fprintf(stream, "
    • \n"); + } + fprintf(stream, "
    \n"); +@@ -1752,11 +1775,11 @@ print_html_status(pe_working_set_t * data_set, const char *filename, gboolean we + + } else if (group_by_node == FALSE) { + if (partially_active || inactive_resources) { +- rsc->fns->print(rsc, NULL, pe_print_html, stream); ++ rsc->fns->print(rsc, NULL, print_opts, stream); + } + + } else if (is_active == FALSE && inactive_resources) { +- rsc->fns->print(rsc, NULL, pe_print_html, stream); ++ rsc->fns->print(rsc, NULL, print_opts, stream); + } + } + } +diff --git a/tools/crm_resource.c b/tools/crm_resource.c +index bd576cc..b2cab67 100644 +--- a/tools/crm_resource.c ++++ b/tools/crm_resource.c +@@ -64,6 +64,7 @@ char *xml_file = NULL; + int cib_options = cib_sync_call; + int crmd_replies_needed = 1; /* The welcome message */ + GMainLoop *mainloop = NULL; ++gboolean print_pending = FALSE; + + extern void cleanup_alloc_calculations(pe_working_set_t * data_set); + +@@ -284,6 +285,11 @@ do_find_resource_list(pe_working_set_t * data_set, gboolean raw) + int found = 0; + + GListPtr lpc = NULL; ++ int opts = pe_print_printf | pe_print_rsconly; ++ ++ if (print_pending) { ++ opts |= pe_print_pending; ++ } + + for (lpc = data_set->resources; lpc != NULL; lpc = lpc->next) { + resource_t *rsc = (resource_t *) lpc->data; +@@ -292,7 +298,7 @@ do_find_resource_list(pe_working_set_t * data_set, gboolean raw) + && rsc->fns->active(rsc, TRUE) == FALSE) { + continue; + } +- rsc->fns->print(rsc, NULL, pe_print_printf | pe_print_rsconly, stdout); ++ rsc->fns->print(rsc, NULL, opts, stdout); + found++; + } + +@@ -323,11 +329,16 @@ 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); ++ int opts = pe_print_printf; + + if (the_rsc == NULL) { + return -ENXIO; + } +- the_rsc->fns->print(the_rsc, NULL, pe_print_printf, stdout); ++ ++ if (print_pending) { ++ opts |= pe_print_pending; ++ } ++ the_rsc->fns->print(the_rsc, NULL, opts, stdout); + + if (expanded) { + rsc_xml = dump_xml_formatted(the_rsc->xml); +@@ -1088,6 +1099,10 @@ list_resource_operations(const char *rsc_id, const char *host_uname, gboolean ac + GListPtr ops = find_operations(rsc_id, host_uname, active, data_set); + GListPtr lpc = NULL; + ++ if (print_pending) { ++ opts |= pe_print_pending; ++ } ++ + for (lpc = ops; lpc != NULL; lpc = lpc->next) { + xmlNode *xml_op = (xmlNode *) lpc->data; + +@@ -1275,7 +1290,8 @@ static struct crm_option long_options[] = { + {"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"}, ++ {"list-all-operations", 0, 0, 'o', "List all resource operations. Optionally filtered by resource (-r) and/or node (-N)"}, ++ {"pending", 0, 0, 'j', "\t\tDisplay pending state if 'record-pending' is enabled\n"}, + + {"list-standards", 0, 0, 0, "\tList supported standards"}, + {"list-ocf-providers", 0, 0, 0, "List all available OCF providers"}, +@@ -1598,6 +1614,9 @@ main(int argc, char **argv) + case 'a': + rsc_cmd = flag; + break; ++ case 'j': ++ print_pending = TRUE; ++ break; + case 'p': + case 'g': + case 'd': +diff --git a/tools/crm_simulate.c b/tools/crm_simulate.c +index 61065c4..0956141 100644 +--- a/tools/crm_simulate.c ++++ b/tools/crm_simulate.c +@@ -39,6 +39,7 @@ cib_t *global_cib = NULL; + GListPtr op_fail = NULL; + gboolean quiet = FALSE; + gboolean bringing_nodes_online = FALSE; ++gboolean print_pending = FALSE; + + #define new_node_template "//"XML_CIB_TAG_NODE"[@uname='%s']" + #define node_template "//"XML_CIB_TAG_STATE"[@uname='%s']" +@@ -528,7 +529,7 @@ exec_stonith_action(crm_graph_t * graph, crm_action_t * action) + } + + static void +-print_cluster_status(pe_working_set_t * data_set) ++print_cluster_status(pe_working_set_t * data_set, long options) + { + char *online_nodes = NULL; + char *online_remote_nodes = NULL; +@@ -649,7 +650,7 @@ print_cluster_status(pe_working_set_t * data_set) + && rsc->role == RSC_ROLE_STOPPED) { + continue; + } +- rsc->fns->print(rsc, NULL, pe_print_printf, stdout); ++ rsc->fns->print(rsc, NULL, pe_print_printf | options, stdout); + } + fprintf(stdout, "\n"); + } +@@ -701,7 +702,7 @@ run_simulation(pe_working_set_t * data_set) + data_set->now = get_date(); + + cluster_status(data_set); +- print_cluster_status(data_set); ++ print_cluster_status(data_set, 0); + } + + if (graph_rc != transition_complete) { +@@ -1201,6 +1202,7 @@ static struct crm_option long_options[] = { + {"show-scores", 0, 0, 's', "Show allocation scores"}, + {"show-utilization", 0, 0, 'U', "Show utilization information"}, + {"profile", 1, 0, 'P', "Run all tests in the named directory to create profiling data"}, ++ {"pending", 0, 0, 'j', "\tDisplay pending state if 'record-pending' is enabled"}, + + {"-spacer-", 0, 0, '-', "\nSynthetic Cluster Events:"}, + {"node-up", 1, 0, 'u', "\tBring a node online"}, +@@ -1447,6 +1449,9 @@ main(int argc, char **argv) + process = TRUE; + show_utilization = TRUE; + break; ++ case 'j': ++ print_pending = TRUE; ++ break; + case 'S': + process = TRUE; + simulate = TRUE; +@@ -1515,8 +1520,10 @@ main(int argc, char **argv) + cluster_status(&data_set); + + if (quiet == FALSE) { ++ int options = print_pending ? pe_print_pending : 0; ++ + quiet_log("\nCurrent cluster status:\n"); +- print_cluster_status(&data_set); ++ print_cluster_status(&data_set, options); + } + + if (modified) { diff --git a/pacemaker.changes b/pacemaker.changes index 90b797c..63c5e90 100644 --- a/pacemaker.changes +++ b/pacemaker.changes @@ -1,3 +1,49 @@ +------------------------------------------------------------------- +Sat Jan 25 06:22:21 UTC 2014 - ygao@suse.com + +- Build: Suppress -Wcast-align warnings/errors on arm and ppc64le (bnc#845525) + * Update pacemaker-Wno-cast-align.patch + +------------------------------------------------------------------- +Sat Jan 25 01:22:06 UTC 2014 - ygao@suse.com + +- services: Do not block synced service executions +- Upstream version cs: 96cd1941308be48fdf1e827b88ebd9410cf2010a + +------------------------------------------------------------------- +Fri Jan 24 08:51:31 UTC 2014 - ygao@suse.com + +- crm_mon: Display brief output if "-b/--brief" is supplied or 'b' is toggled (FATE#314757) + * Add pacemaker-crm_mon-brief.patch +- tools: Display pending state in crm_mon/crm_resource/crm_simulate if --pending/-j is supplied (cl#5178) (FATE#315159) + * Add pacemaker-display-pending-ops.patch + +------------------------------------------------------------------- +Mon Jan 20 09:55:26 UTC 2014 - ygao@suse.com + +- Drop the obsolete patch (bnc#857779): + * bug-812269_pacemaker-fencing-update-cib.patch + +------------------------------------------------------------------- +Mon Jan 20 09:47:13 UTC 2014 - ygao@suse.com + +- crm_report: Force grep to interpret logs as text +- pengine: Force record pending for migrate_to actions +- pengine: cl#5186 - Avoid running rsc on two nodes when node is fenced during migration +- cluster: Fix segfault on removing a node (bnc#858745) +- services: Reset the scheduling policy and priority for lrmd's children without replying on SCHED_RESET_ON_FORK (bnc#858857) +- fencing: Update stonith device list only if stonith is enabled (bnc#857779) +- services: Correctly reset the nice value for lrmd's children (bnc#858857) +- pengine: Correctly perform partial migrations when node's uname is not equal to the id. +- fencing: Immediately fail remote fencing operation on peer timeout +- cl#5055: Improved migration support. +- stonith_admin: Ensure pointers passed to sscanf() are properly initialized +- Fix: Prevent potential use-of-NULL +- crmd: Prevent memory leak in error paths +- services: Fixes segfault associated with cancelling in-flight recurring operations. (bnc#859923) +- pengine: cl#5174 - Allow resource sets and templates for location constraints (FATE#315158) +- Upstream version cs: a3cda7619e71399d54f209296aebf3ba713a0bf4 + ------------------------------------------------------------------- Sat Jan 11 11:35:16 UTC 2014 - ygao@suse.com diff --git a/pacemaker.spec b/pacemaker.spec index 0e8debd..304df52 100644 --- a/pacemaker.spec +++ b/pacemaker.spec @@ -95,7 +95,7 @@ Name: pacemaker Summary: Scalable High-Availability cluster resource manager License: GPL-2.0+ and LGPL-2.1+ Group: Productivity/Clustering/HA -Version: 1.1.10+git20140110.3e89301 +Version: 1.1.10+git20140124.96cd194 Release: 0 #Release: %{pcmk_release}%{?dist} Url: http://www.clusterlabs.org @@ -111,9 +111,10 @@ Patch4: pacemaker-NodeUtilization-RA.patch Patch5: pacemaker-colocated-utilization.patch Patch6: pacemaker-cibsecret-tool-temp-disabled.patch Patch7: pacemaker-nagios-plugin-dir.patch -Patch8: bug-812269_pacemaker-fencing-update-cib.patch -Patch9: bug-812269_pacemaker-fencing-device-register-messages.patch -Patch10: pacemaker-Wno-cast-align.patch +Patch8: bug-812269_pacemaker-fencing-device-register-messages.patch +Patch9: pacemaker-Wno-cast-align.patch +Patch10: pacemaker-display-pending-ops.patch +Patch11: pacemaker-crm_mon-brief.patch BuildRoot: %{_tmppath}/%{name}-%{version}-build Provides: pacemaker-ticket-support = 2.0 Conflicts: heartbeat < 3.0 @@ -400,6 +401,7 @@ manager for Corosync, CMAN and/or Linux-HA. %patch8 -p1 %patch9 -p1 %patch10 -p1 +%patch11 -p1 # Force the local time #