Fix the problems: 1) clmprint returns 0 for the error case. 2) clmprint does not handle invalid inputs. 3) clmprint does not deal with non-member node. --- src/clm/tools/Makefile | 18 +++++ src/clm/tools/clm_print.c | 191 +++++++++++++++++++++++++++++++++++++++------- 2 files changed, 182 insertions(+), 27 deletions(-) create mode 100644 src/clm/tools/Makefile
diff --git a/src/clm/tools/Makefile b/src/clm/tools/Makefile new file mode 100644 index 0000000..1e39957 --- /dev/null +++ b/src/clm/tools/Makefile @@ -0,0 +1,18 @@ +# -*- OpenSAF -*- +# +# Copyright Ericsson AB 2017 - All Rights Reserved. +# +# This program 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. This file and program are licensed +# under the GNU Lesser General Public License Version 2.1, February 1999. +# The complete license can be accessed from the following location: +# http://opensource.org/licenses/lgpl-license.php +# See the Copying file included with the OpenSAF distribution for full +# licensing terms. +# +# Author(s): Ericsson AB +# + +all: + $(MAKE) -C ../../.. bin/clmprint diff --git a/src/clm/tools/clm_print.c b/src/clm/tools/clm_print.c index eb01d3e..f44aee2 100644 --- a/src/clm/tools/clm_print.c +++ b/src/clm/tools/clm_print.c @@ -1,6 +1,7 @@ /* -*- OpenSAF -*- * * Copyright (C) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright Ericsson AB 2017 - All Rights Reserved. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY @@ -59,9 +60,9 @@ static char *clm_step[] = { static void print_node(const SaClmClusterNodeT_4 *clusterNode) { - printf("====Node Info for nodeId: %u========================>\n", + printf("\n====Node Info for nodeId: %u========================>\n", clusterNode->nodeId); - printf(" Node Id : %u(%x)\n", + printf(" Node Id : %u(0x%x)\n", clusterNode->nodeId, clusterNode->nodeId); printf(" Address Family : %s\n", clusterNode->nodeAddress.family == 1 @@ -84,6 +85,7 @@ static void print_node(const SaClmClusterNodeT_4 *clusterNode) clusterNode->bootTimestamp); printf(" Initial View Number : %llu\n", clusterNode->initialViewNumber); + printf("<=======================================================\n\n"); } static void clm_node_get_callback(SaInvocationT invocation, @@ -133,7 +135,6 @@ static void clm_track_callback(const SaClmClusterNotificationBufferT_4 print_node(¬ificationBuffer->notification[i].clusterNode); printf(" Change : %s\n", clm_change[notificationBuffer->notification[i].clusterChange]); - printf("<================================================\n\n"); } if ((step == SA_CLM_CHANGE_VALIDATE) || (step == SA_CLM_CHANGE_START)) { @@ -217,6 +218,93 @@ static void clm_dispatch(void) exit(EXIT_SUCCESS); } } + +/* + * Exit the program with EXIT_FAILURE if passing invalid options, + * update the output `bit_mask` otherwise. + */ +static void validate_option(const char opt, uint32_t *bit_mask) +{ + enum mask_position { + OPT_HELP, + OPT_NODEGET, + OPT_ASYNCGET, + OPT_TRACK, + OPT_BTRACK, + OPT_TIMEOUT + }; + + switch (opt) { + case 'n': + if ((*bit_mask >> OPT_NODEGET) & 1) { + fprintf(stderr, "error - duplicated options!\n"); + exit(EXIT_FAILURE); + } + + if ((*bit_mask) && (*bit_mask ^ (1 << OPT_TIMEOUT))) { + fprintf(stderr, "error - multiple options!\n"); + exit(EXIT_FAILURE); + } + + *bit_mask |= (1 << OPT_NODEGET); + break; + + case 'a': + if ((*bit_mask >> OPT_ASYNCGET) & 1) { + fprintf(stderr, "error - duplicated options!\n"); + exit(EXIT_FAILURE); + } + + if ((*bit_mask) && (*bit_mask ^ (1 << OPT_TIMEOUT))) { + fprintf(stderr, "error - multiple options!\n"); + exit(EXIT_FAILURE); + } + + *bit_mask |= (1 << OPT_ASYNCGET); + break; + + case 'b': + if ((*bit_mask >> OPT_BTRACK) & 1) { + fprintf(stderr, "error - duplicated options!\n"); + exit(EXIT_FAILURE); + } + + if ((*bit_mask) && (*bit_mask ^ (1 << OPT_TIMEOUT))) { + fprintf(stderr, "error - multiple options!\n"); + exit(EXIT_FAILURE); + } + + *bit_mask |= (1 << OPT_BTRACK); + break; + + case 'm': + if ((*bit_mask >> OPT_TRACK) & 1) { + fprintf(stderr, "error - duplicated options!\n"); + exit(EXIT_FAILURE); + } + + if ((*bit_mask) && (*bit_mask ^ (1 << OPT_TIMEOUT))) { + fprintf(stderr, "error - multiple options!\n"); + exit(EXIT_FAILURE); + } + + *bit_mask |= (1 << OPT_TRACK); + break; + + case 't': + if ((*bit_mask >> OPT_TIMEOUT) & 1) { + fprintf(stderr, "error - duplicated options!\n"); + exit(EXIT_FAILURE); + } + + *bit_mask |= (1 << OPT_TIMEOUT); + break; + + default: + break; + } +} + int main(int argc, char *argv[]) { SaClmClusterNotificationT_4 clusterNotification[SIZE_NOTIFICATIONS]; @@ -228,6 +316,7 @@ int main(int argc, char *argv[]) int c; char *ptr = NULL, *tmp_optarg = NULL; SaClmNodeIdT node_id = SA_CLM_LOCAL_NODE_ID; + uint32_t bit_mask = 0; is_cbk_received = false; @@ -251,6 +340,9 @@ int main(int argc, char *argv[]) if (c == -1) break; + /* Terminate the program if passing invalid options */ + validate_option(c, &bit_mask); + switch (c) { case 'n': case 'a': @@ -259,15 +351,25 @@ int main(int argc, char *argv[]) if ((argv[optind] != NULL) && (argv[optind][0] != '-')) { node_id = strtoul(argv[optind], &ptr, 0); + if (argv[optind][0] == '\0' || *ptr != '\0') { + fprintf(stderr, "error - input wrong data format!\n"); + exit(EXIT_FAILURE); + } ++optind; } - } else + } else { node_id = strtoul(optarg, &ptr, 0); - printf("node_id:%u(%x)\n", node_id, node_id); + if (*optarg == '\0' || *ptr != '\0') { + fprintf(stderr, "error - input wrong data format!\n"); + exit(EXIT_FAILURE); + } + } break; + case 'b': mychar = c; break; + case 'm': mychar = c; if (optarg == NULL) { @@ -311,19 +413,28 @@ int main(int argc, char *argv[]) exit(EXIT_FAILURE); } break; + case 't': - timeout = atoi(optarg) * 1000; + timeout = strtoul(optarg, &ptr, 0); + if (*optarg == '\0' || *ptr != '\0') { + fprintf(stderr, "error: input wrong data format!\n"); + exit(EXIT_FAILURE); + } + timeout = timeout * 1000; break; + case 'h': usage(basename(argv[0])); exit(EXIT_SUCCESS); break; + default: printf("Try '%s --help' for more information\n", argv[0]); exit(EXIT_FAILURE); break; } } + rc = saClmInitialize_4(&clm_handle, &clm_callbacks, &clm_version); if (rc != SA_AIS_OK) { fprintf(stderr, "error - clmprint:: saClmInitialize_4 failed, rc = %d\n", rc); @@ -335,53 +446,80 @@ int main(int argc, char *argv[]) fprintf(stderr, "error - clmprint:: saClmSelectionObjectGet failed, rc = %d\n", rc); exit(EXIT_FAILURE); } + clm_fds[0].fd = clm_selobject; clm_fds[0].events = POLLIN; switch (mychar) { case 'n': rc = saClmClusterNodeGet_4(clm_handle, node_id, ((timeout == -1) ? (TIME_OUT) : timeout), &clusterNode); - if (rc != SA_AIS_OK) { + if (rc == SA_AIS_ERR_NOT_EXIST) { + fprintf(stdout, "Node id 0x%x is not in cluster membership\n", node_id); + exit(EXIT_SUCCESS); + } else if (rc == SA_AIS_ERR_UNAVAILABLE) { + fprintf(stdout, "error - invoking clmprint from non-member node\n"); + exit(EXIT_FAILURE); + } else if (rc != SA_AIS_OK) { fprintf(stderr, "error - clmprint:: saClmClusterNodeGet_4 failed, rc = %d\n", rc); - } else { - printf("\n"); - print_node(&clusterNode); - printf("<=======================================================\n\n"); + exit(EXIT_FAILURE); } + + print_node(&clusterNode); break; + case 'a': rc = saClmClusterNodeGetAsync(clm_handle, INVOCATION_ID, node_id); - if (rc != SA_AIS_OK) + if (rc == SA_AIS_ERR_NOT_EXIST) { + fprintf(stdout, "Node id 0x%x is not in cluster membership\n", node_id); + exit(EXIT_SUCCESS); + } else if (rc == SA_AIS_ERR_UNAVAILABLE) { + fprintf(stdout, "error - invoking clmprint from non-member node\n"); + exit(EXIT_FAILURE); + } else if (rc != SA_AIS_OK) { fprintf(stderr, "error - clmprint :: saClmClusterNodeGetAsync failed, rc = %d\n", rc); - else - clm_dispatch(); + exit(EXIT_FAILURE); + } + + clm_dispatch(); break; + case 'b': clusterNotificationBuffer.numberOfItems = SIZE_NOTIFICATIONS; rc = saClmClusterTrack_4(clm_handle, SA_TRACK_CURRENT, &clusterNotificationBuffer); - if (rc != SA_AIS_OK) { + if (rc == SA_AIS_ERR_UNAVAILABLE) { + fprintf(stdout, "error - invoking clmprint from non-member node\n"); + exit(EXIT_FAILURE); + } else if (rc != SA_AIS_OK) { fprintf(stderr, "error - clmprint:: saClmClusterTrack_4 failed, rc = %d\n", rc); - } else { - printf("\nnumberOfItems = %d\n\n", clusterNotificationBuffer.numberOfItems); - for (uint32_t i = 0; i < clusterNotificationBuffer.numberOfItems; i++) { - print_node(&clusterNotificationBuffer.notification[i].clusterNode); - printf(" Change : %s\n", - clm_change[clusterNotificationBuffer.notification[i].clusterChange]); - printf("<===================================================\n\n"); - } + exit(EXIT_FAILURE); + } + + printf("\nnumberOfItems = %d\n\n", clusterNotificationBuffer.numberOfItems); + for (uint32_t i = 0; i < clusterNotificationBuffer.numberOfItems; i++) { + print_node(&clusterNotificationBuffer.notification[i].clusterNode); + printf(" Change : %s\n", + clm_change[clusterNotificationBuffer.notification[i].clusterChange]); } break; + case 'm': rc = saClmClusterTrack_4(clm_handle, trackFlags, NULL); - if (rc != SA_AIS_OK) + if (rc == SA_AIS_ERR_UNAVAILABLE) { + fprintf(stdout, "error - invoking clmprint from non-member node\n"); + exit(EXIT_FAILURE); + } else if (rc != SA_AIS_OK) { fprintf(stderr, "error - clmprint:: saClmClusterTrack_4 failed, rc = %d\n", rc); - else - clm_dispatch(); + exit(EXIT_FAILURE); + } + + clm_dispatch(); break; + default: usage(basename(argv[0])); break; } + rc = saClmFinalize(clm_handle); if (rc != SA_AIS_OK) { fprintf(stderr, "error - clmprint:: saClmFinalize failed, rc = %d\n", rc); @@ -389,4 +527,3 @@ int main(int argc, char *argv[]) } return 0; } - -- 1.9.1 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ Opensaf-devel mailing list Opensaf-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/opensaf-devel