"Fossies" - the Fresh Open Source Software Archive

Member "opensaf-5.21.09/src/amf/tools/amf_cluster_status.cc" (31 May 2021, 18087 Bytes) of package /linux/misc/opensaf-5.21.09.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "amf_cluster_status.cc" see the Fossies "Dox" file reference documentation.

    1 /*      -*- OpenSAF  -*-
    2  *
    3  * Copyright (C) 2017, Oracle and/or its affiliates. All rights reserved.
    4  *
    5  * This program is distributed in the hope that it will be useful, but
    6  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
    7  * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
    8  * under the GNU Lesser General Public License Version 2.1, February 1999.
    9  * The complete license can be accessed from the following location:
   10  * http://opensource.org/licenses/lgpl-license.php
   11  * See the Copying file included with the OpenSAF distribution for full
   12  * licensing terms.
   13  *
   14  */
   15 
   16 #include <string>
   17 #include <vector>
   18 #include <map>
   19 #include <algorithm>
   20 #include <iostream>
   21 #include <iomanip>
   22 #include <getopt.h>
   23 
   24 #include "mds/mds_papi.h"
   25 #include "base/osaf_time.h"
   26 #include "base/saf_error.h"
   27 #include "base/osaf_extended_name.h"
   28 #include "base/ncs_main_papi.h"
   29 #include <saImmOm.h>
   30 #include "osaf/immutil/immutil.h"
   31 
   32 enum { AMF_CLUSTER_MDS_VERSION = 1, AMF_CLUSTER_MDS_SVC_ID = 501 };
   33 class CLM_NODE {
   34  public:
   35   std::string clm_rdn;
   36   uint32_t saClmNodeIsMember;
   37   uint32_t saClmNodeID;
   38   CLM_NODE() : clm_rdn(""), saClmNodeIsMember(0), saClmNodeID(0) {}
   39 };
   40 
   41 class AMF_NODE {
   42  public:
   43   std::string amf_rdn;
   44   std::string clm_rdn;
   45   AMF_NODE() : amf_rdn(""), clm_rdn("") {}
   46 };
   47 static const SaVersionT immVersion = {'A', 2, 1};
   48 static MDS_HDL mds_hdl;
   49 static bool is_avd_up = false;
   50 static std::vector<NODE_ID> avnd_up_db;
   51 static std::map<std::string, CLM_NODE> clm_db;
   52 static std::map<std::string, AMF_NODE> amf_db;
   53 static uint32_t width = strlen("NODE(AMF)");
   54 static NODE_ID scs_node_id[2];
   55 static uint32_t scs_count;
   56 static bool print_also = true;
   57 
   58 uint32_t mds_callback(struct ncsmds_callback_info *info) {
   59   uint32_t rc = NCSCC_RC_SUCCESS;
   60   if (info->i_op != MDS_CALLBACK_SVC_EVENT) {
   61     rc = NCSCC_RC_FAILURE;
   62     goto done;
   63   }
   64   if (info->info.svc_evt.i_your_id != AMF_CLUSTER_MDS_SVC_ID) {
   65     std::cerr << "Not my service id :" << info->info.svc_evt.i_your_id
   66               << std::endl;
   67     rc = NCSCC_RC_FAILURE;
   68     goto done;
   69   }
   70 
   71   if (info->info.svc_evt.i_change == NCSMDS_UP) {
   72     if (info->info.svc_evt.i_svc_id == NCSMDS_SVC_ID_AVD) {
   73       if (m_MDS_DEST_IS_AN_ADEST(info->info.svc_evt.i_dest)) {
   74         is_avd_up = true;
   75         if (scs_count < 2)
   76           scs_node_id[scs_count++] = info->info.svc_evt.i_node_id;
   77       }
   78     } else if (info->info.svc_evt.i_svc_id == NCSMDS_SVC_ID_AVND) {
   79       avnd_up_db.push_back(info->info.svc_evt.i_node_id);
   80     }
   81   }
   82 done:
   83   return rc;
   84 }
   85 
   86 static uint32_t mds_get_handle() {
   87   NCSADA_INFO arg;
   88 
   89   memset(&arg, 0, sizeof(NCSADA_INFO));
   90   arg.req = NCSADA_GET_HDLS;
   91   uint32_t rc = ncsada_api(&arg);
   92 
   93   if (rc != NCSCC_RC_SUCCESS) {
   94     std::cerr << "MDS registration failed with :" << rc << std::endl;
   95     return rc;
   96   }
   97   mds_hdl = arg.info.adest_get_hdls.o_mds_pwe1_hdl;
   98   return rc;
   99 }
  100 
  101 static uint32_t mds_init() {
  102   NCSMDS_INFO mds_info;
  103   uint32_t rc;
  104   MDS_SVC_ID svc_id[2] = {NCSMDS_SVC_ID_AVD, NCSMDS_SVC_ID_AVND};
  105 
  106   memset(&mds_info, 0, sizeof(NCSMDS_INFO));
  107   mds_info.i_mds_hdl = mds_hdl;
  108   mds_info.i_svc_id = AMF_CLUSTER_MDS_SVC_ID;
  109   mds_info.i_op = MDS_INSTALL;
  110   mds_info.info.svc_install.i_yr_svc_hdl = 0;
  111   mds_info.info.svc_install.i_install_scope = NCSMDS_SCOPE_NONE;
  112   mds_info.info.svc_install.i_svc_cb = mds_callback;
  113   mds_info.info.svc_install.i_mds_q_ownership = false;
  114   mds_info.info.svc_install.i_mds_svc_pvt_ver = AMF_CLUSTER_MDS_VERSION;
  115   if (NCSCC_RC_SUCCESS != (rc = ncsmds_api(&mds_info))) {
  116     std::cerr << "MDS Install failed:" << rc << std::endl;
  117     goto done;
  118   }
  119 
  120   memset(&mds_info, 0, sizeof(NCSMDS_INFO));
  121   mds_info.i_mds_hdl = mds_hdl;
  122   mds_info.i_svc_id = AMF_CLUSTER_MDS_SVC_ID;
  123   mds_info.i_op = MDS_SUBSCRIBE;
  124   mds_info.info.svc_subscribe.i_num_svcs = 2;
  125   mds_info.info.svc_subscribe.i_scope = NCSMDS_SCOPE_NONE;
  126   mds_info.info.svc_subscribe.i_svc_ids = svc_id;
  127   if (NCSCC_RC_SUCCESS != (rc = ncsmds_api(&mds_info))) {
  128     std::cerr << "MDS Subscription failed" << rc << std::endl;
  129   }
  130 done:
  131   return rc;
  132 }
  133 
  134 static uint32_t mds_finalize() {
  135   NCSMDS_INFO mds_info;
  136 
  137   memset(&mds_info, 0, sizeof(NCSMDS_INFO));
  138   mds_info.i_mds_hdl = mds_hdl;
  139   mds_info.i_svc_id = AMF_CLUSTER_MDS_SVC_ID;
  140   mds_info.i_op = MDS_UNINSTALL;
  141   uint32_t rc = ncsmds_api(&mds_info);
  142   if (rc != NCSCC_RC_SUCCESS) {
  143     std::cerr << "MDS uninstall failed:" << rc << std::endl;
  144   }
  145   return rc;
  146 }
  147 
  148 static SaAisErrorT get_amf_nodes(void) {
  149   SaImmSearchHandleT searchHandle;
  150   SaImmSearchParametersT_2 searchParam;
  151   const SaImmAttrValuesT_2 **attributes;
  152   const char *className = "SaAmfNode";
  153   SaImmHandleT immOmHandle;
  154   const char *rdn;
  155   SaNameT node_name;
  156 
  157   searchParam.searchOneAttr.attrName =
  158       const_cast<SaImmAttrNameT>("SaImmAttrClassName");
  159   searchParam.searchOneAttr.attrValueType = SA_IMM_ATTR_SASTRINGT;
  160   searchParam.searchOneAttr.attrValue = &className;
  161 
  162   SaVersionT local_version = immVersion;
  163   SaAisErrorT rc =
  164       immutil_saImmOmInitialize(&immOmHandle, nullptr, &local_version);
  165   if (rc != SA_AIS_OK) {
  166     std::cerr << "saImmOmInitialize() failed with:" << saf_error(rc) << (rc)
  167               << std::endl;
  168     goto done;
  169   }
  170   rc = immutil_saImmOmSearchInitialize_2(
  171       immOmHandle, nullptr, SA_IMM_SUBTREE,
  172       SA_IMM_SEARCH_ONE_ATTR | SA_IMM_SEARCH_GET_ALL_ATTR, &searchParam,
  173       nullptr, &searchHandle);
  174   if (rc != SA_AIS_OK) {
  175     std::cerr << "saImmOmSearchInitialize_2() failed with:" << saf_error(rc)
  176               << (rc) << std::endl;
  177     goto done;
  178   }
  179 
  180   while ((rc = immutil_saImmOmSearchNext_2(
  181               searchHandle, &node_name, (SaImmAttrValuesT_2 ***)&attributes)) ==
  182          SA_AIS_OK) {
  183     std::string::size_type pos;
  184     std::string::size_type pos1;
  185     AMF_NODE node;
  186     SaNameT saAmfNodeClmNode;
  187     std::string safAmfNode;
  188     // std::cout<<"AMF Node:"<<osaf_extended_name_borrow(&node_name)<<std::endl;
  189     if (immutil_getAttr("saAmfNodeClmNode", attributes, 0, &saAmfNodeClmNode) ==
  190         SA_AIS_OK) {
  191       std::string tmp_string(osaf_extended_name_borrow(&saAmfNodeClmNode));
  192       // std::cout<<"    CLM node:"<<tmp_string.c_str()<<std::endl;
  193       pos = tmp_string.find("=");
  194       pos1 = tmp_string.find(",");
  195       node.clm_rdn = tmp_string.substr(pos + 1, pos1 - pos - 1);
  196       // std::cout<<"    CLM Rdn:"<<node.clm_rdn.c_str()<<std::endl;
  197     }
  198     if ((rdn = immutil_getStringAttr(attributes, "safAmfNode", 0)) != nullptr) {
  199       safAmfNode = std::string(rdn);
  200       pos = safAmfNode.find("=");
  201       node.amf_rdn = safAmfNode.substr(pos + 1);
  202       // std::cout<<"    AMF Rdn:"<<node.amf_rdn.c_str()<<std::endl;
  203       if (width < node.amf_rdn.length()) width = node.amf_rdn.length();
  204     }
  205     amf_db[node.clm_rdn] = node;
  206   }
  207   // std::cout<<"num of amf nodes :"<<clm_db.size()<<std::endl;
  208   if (rc != SA_AIS_ERR_NOT_EXIST)
  209     std::cerr << "saImmOmSearchNext_2() failed with:" << rc << std::endl;
  210   else
  211     rc = SA_AIS_OK;
  212   (void)immutil_saImmOmSearchFinalize(searchHandle);
  213   (void)immutil_saImmOmFinalize(immOmHandle);
  214 done:
  215   return rc;
  216 }
  217 static uint32_t get_clm_nodes() {
  218   SaImmSearchParametersT_2 searchParam;
  219   SaNameT dn;
  220   const SaImmAttrValuesT_2 **attributes;
  221   const char *className = "SaClmNode";
  222   SaImmHandleT imm_om_hdl;
  223   SaImmSearchHandleT search_hdl;
  224   const char *rdn;
  225 
  226   searchParam.searchOneAttr.attrName =
  227       const_cast<SaImmAttrNameT>("SaImmAttrClassName");
  228   searchParam.searchOneAttr.attrValueType = SA_IMM_ATTR_SASTRINGT;
  229   searchParam.searchOneAttr.attrValue = &className;
  230 
  231   SaVersionT local_version = immVersion;
  232   SaAisErrorT rc = immutil_saImmOmInitialize(&imm_om_hdl, nullptr,
  233                                              &local_version);
  234   if (rc != SA_AIS_OK) {
  235     std::cerr << "saImmOmInitialize() failed with:" << saf_error(rc) << (rc)
  236               << std::endl;
  237     goto done;
  238   }
  239 
  240   rc = immutil_saImmOmSearchInitialize_2(
  241       imm_om_hdl, nullptr, SA_IMM_SUBTREE,
  242       SA_IMM_SEARCH_ONE_ATTR | SA_IMM_SEARCH_GET_ALL_ATTR, &searchParam,
  243       nullptr, &search_hdl);
  244   if (rc != SA_AIS_OK) {
  245     std::cerr << "saImmOmSearchInitialize_2() failed with:" << saf_error(rc)
  246               << (rc) << std::endl;
  247     goto done;
  248   }
  249   while ((rc = immutil_saImmOmSearchNext_2(
  250               search_hdl, &dn, (SaImmAttrValuesT_2 ***)&attributes)) ==
  251          SA_AIS_OK) {
  252     std::string::size_type pos;
  253     std::string safNode;
  254     CLM_NODE node;
  255     // std::cout<<"CLM node:"<<osaf_extended_name_borrow(&dn)<<std::endl;
  256     if ((rdn = immutil_getStringAttr(attributes, "safNode", 0)) != nullptr) {
  257       safNode = std::string(rdn);
  258       pos = safNode.find("=");
  259       node.clm_rdn = safNode.substr(pos + 1);
  260       // std::cout<<"    Rdn:"<<node.clm_rdn.c_str()<<std::endl;
  261     }
  262     immutil_getAttr("saClmNodeID", attributes, 0, &node.saClmNodeID);
  263     // std::cout<<"      nodeId:"<<node.saClmNodeID<<std::endl;
  264 
  265     immutil_getAttr("saClmNodeIsMember", attributes, 0,
  266                     &node.saClmNodeIsMember);
  267     // std::cout<<"      saClmNodeIsMember:"<<node.saClmNodeIsMember<<std::endl;
  268     clm_db[node.clm_rdn] = node;
  269   }
  270   if (rc != SA_AIS_ERR_NOT_EXIST)
  271     std::cerr << "saImmOmSearchNext_2() failed with:" << rc << std::endl;
  272   else
  273     rc = SA_AIS_OK;
  274   // std::cout<<"num of clm nodes :"<<clm_db.size()<<std::endl;
  275   (void)immutil_saImmOmSearchFinalize(search_hdl);
  276   (void)immutil_saImmOmFinalize(imm_om_hdl);
  277 done:
  278   return rc;
  279 }
  280 static void print_cluster_info() {
  281   std::cout << std::setw(width) << std::left << "NODE(AMF)"
  282             << "     "
  283             << "STATUS" << std::endl;
  284   std::string filler(width + strlen("     STATUS"), '=');
  285   std::cout << std::setw(width) << filler.c_str() << std::endl;
  286   for (const auto &tmp_amf : amf_db) {
  287     const auto &amf_node = tmp_amf.second;
  288     auto it = clm_db.find(amf_node.clm_rdn);
  289     const auto &clm_node = it->second;
  290     if (std::find(avnd_up_db.begin(), avnd_up_db.end(), clm_node.saClmNodeID) !=
  291         avnd_up_db.end())
  292       std::cout << std::setw(width) << std::left << amf_node.amf_rdn.c_str()
  293                 << "     " << (is_avd_up ? "UP" : "SAM") << std::endl;
  294     else
  295       std::cout << std::setw(width) << std::left << amf_node.amf_rdn.c_str()
  296                 << "     "
  297                 << "DOWN" << std::endl;
  298   }
  299 }
  300 
  301 static void usage(const char *prog_name) {
  302   std::cout << std::endl << "NAME" << std::endl;
  303   std::cout << "\t" << prog_name << std::endl;
  304   std::cout << std::endl << "SYNOPSIS" << std::endl;
  305   std::cout << "\t" << prog_name << " [option]" << std::endl;
  306 
  307   std::cout << std::endl << "DESCRIPTION" << std::endl;
  308   std::cout << "\t"
  309             << "Use this command:"<<std::endl;
  310   std::cout << "\t"
  311             << "- to check if any System Controller(SC) is up."<<std::endl;
  312   std::cout << "\t"
  313             << "- to check if a node is System Controller(SC)."<<std::endl;
  314   std::cout << "\t"
  315             << "- to lists RDNs of AMF nodes with their status: " << std::endl;
  316   std::cout << "\t  "
  317             << "   UP:   Node is up (OpenSAF running)." << std::endl;
  318   std::cout << "\t  "
  319             << "   DOWN: Node is down (OpenSAF not running)." << std::endl;
  320   std::cout << "\t  "
  321             << "   SAM:  Stands for SCs Absence Mode. Node is up without any SCs up in cluster."
  322             << std::endl;
  323   std::cout << "\t"
  324             << "Note: a CLM locked node is shown up if OpenSAF is running on that node."
  325             << std::endl;
  326 
  327   std::cout << std::endl << "OPTIONS" << std::endl;
  328   std::cout << "\t"
  329             << "-s or --controller-status      returns 0 if at least one SC is up"<<std::endl
  330             << "\t"
  331             << "                               returns 1 if SCs are absent"<<std::endl<<std::endl;
  332   std::cout << "\t"
  333             << "-c or --is-controller          returns 0 if this is a SC node"<<std::endl
  334             << "\t"
  335             << "                               returns 1 if this is not a SC node"<<std::endl
  336             << "\t"
  337             << "                               If nodeid is passed as optional argument"<<std::endl
  338             << "\t"
  339             << "                               then nodeid is checked for SC."<<std::endl;
  340   std::cout << "\t"
  341             << "                               Here SC node means active or standby SC"<<std::endl
  342             <<std::endl;
  343   std::cout << "\t"
  344             << "-u or --node-up                returns 0 if this node is up"<<std::endl
  345             << "\t"
  346             << "                               returns 1 if this node is not up"<<std::endl
  347             << "\t"
  348             << "                               If nodeid is passed as optional argument"<<std::endl
  349             << "\t"
  350             << "                               then nodeid is checked for up status."<<std::endl<<std::endl;
  351 
  352   std::cout << "\t"
  353             << "-q or --quiet                  suppresses prints." <<std::endl <<std::endl;
  354   std::cout << "\t"
  355             << "-h or --help                   display this help and exit" <<std::endl<<std::endl;
  356   std::cout << "\t"
  357             << "Note: Without any option, prints AMF nodes and their status" <<std::endl;
  358 
  359   std::cout << std::endl << "EXAMPLE" << std::endl;
  360   std::cout << "\t"
  361             << "amfclusterstatus " << std::endl;
  362   std::cout << "\t"
  363             << "amfclusterstatus -h " << std::endl;
  364   std::cout << "\t"
  365             << "amfclusterstatus -c -q" << std::endl;
  366   std::cout << "\t"
  367             << "amfclusterstatus -c 0x2030f -q" << std::endl;
  368   std::cout << "\t"
  369             << "amfclusterstatus -u -q" << std::endl;
  370   std::cout << "\t"
  371             << "amfclusterstatus -u 0x2030f -q" << std::endl;
  372   std::cout << "\t"
  373             << "amfclusterstatus -s -q" << std::endl;
  374 }
  375 
  376 int main(int argc, char *argv[]) {
  377   char opt_char = 'z';
  378   char *ptr = NULL;
  379   NODE_ID node_id = 0;
  380   bool user_node = false;
  381   unsigned int options_found = 0;
  382 
  383   struct option long_options[] = {
  384     {"help",                no_argument,       0, 'h'},
  385     {"controller-status",   no_argument,       0, 's'},
  386     {"is-controller",       optional_argument, 0, 'c'},
  387     {"node-up",             optional_argument, 0, 'u'},
  388     {"quiet",               no_argument,       0, 'q'},
  389     {0, 0, 0, 0}
  390   };
  391   while (1) {
  392      int option = getopt_long(argc, argv, "sc::u::qh", long_options,NULL);
  393      if (option == -1)
  394        break;
  395 
  396      switch (option) {
  397      case 's':
  398              ++options_found;
  399              opt_char = option;
  400              break;
  401      case 'c':
  402      case 'u':
  403              ++options_found;
  404              opt_char = option;
  405              if (optarg == NULL) {
  406                if ((argv[optind] != NULL) &&
  407                  (argv[optind][0] != '-')) {
  408                    node_id = strtoul(argv[optind], &ptr, 0);
  409                    ++optind;
  410                    user_node = true;
  411                }
  412              } else {
  413                node_id = strtoul(optarg, &ptr, 0);
  414                user_node = true;
  415              }
  416              break;
  417      case 'q':
  418              print_also = false;
  419              break;
  420      case 'h':
  421              usage(basename(argv[0]));
  422              exit(EXIT_SUCCESS);
  423      case '?':
  424              std::cout << "Try "<< basename(argv[0]) << "-h or --help for more information" << std::endl;
  425              exit(EXIT_FAILURE);
  426              break;
  427      }
  428   }
  429 
  430   setenv("SA_ENABLE_EXTENDED_NAMES", "1", 1);
  431   if (ncs_agents_startup() != NCSCC_RC_SUCCESS) {
  432     std::cerr << "ncs_core_agents_startup FAILED" << std::endl;
  433     exit(EXIT_FAILURE);
  434   }
  435 
  436   if (user_node == false) {
  437     node_id = m_NCS_GET_NODE_ID; //Get local node_id
  438   } else if (node_id == 0) {
  439     std::cerr << "Invalid node" << std::endl;
  440     exit(EXIT_FAILURE);
  441   }
  442   if (options_found > 1) {
  443     std::cerr << "Too many options specified" << std::endl;
  444     exit(EXIT_FAILURE);
  445   }
  446   if (mds_get_handle() != NCSCC_RC_SUCCESS) exit(EXIT_FAILURE);
  447   if (mds_init() != NCSCC_RC_SUCCESS) exit(EXIT_FAILURE);
  448   if (get_clm_nodes() != SA_AIS_OK) exit(EXIT_FAILURE);
  449   if (get_amf_nodes() != SA_AIS_OK) exit(EXIT_FAILURE);
  450   if (mds_finalize() != NCSCC_RC_SUCCESS) exit(EXIT_FAILURE);
  451 
  452   switch (opt_char) {
  453   case 's':
  454           if (is_avd_up == true) {
  455             if (print_also == true)
  456                std::cout << "At least one controller is up"<<std::endl;
  457             exit(EXIT_SUCCESS);
  458           } else {
  459             if (print_also == true)
  460               std::cout << "No controller is up"<<std::endl;
  461             exit(EXIT_FAILURE);
  462           }
  463           break;
  464   case 'c':
  465           if ((node_id == scs_node_id[0]) || (node_id == scs_node_id[1])) {
  466             if (print_also == true) {
  467               if (user_node == false)
  468                 std::cout << "This is a Controller node"<<std::endl;
  469               else
  470                 std::cout << "0x" << std::hex
  471                   << node_id << " is a Controller node" << std::endl;
  472             }
  473             exit(EXIT_SUCCESS);
  474           } else {
  475             if (print_also == true) {
  476               if (user_node == false)
  477                 std::cout << "This is not a Controller node"<<std::endl;
  478               else
  479                 std::cout << "0x" << std::hex
  480                   << node_id << " is not a Controller node" << std::endl;
  481             }
  482             exit(EXIT_FAILURE);
  483           }
  484           break;
  485   case 'u':
  486           if (std::find(avnd_up_db.begin(), avnd_up_db.end(), node_id) !=
  487               avnd_up_db.end()) {
  488             if (print_also == true) {
  489               if (user_node == false)
  490                 std::cout << "This node is up"<<std::endl;
  491               else
  492                 std::cout << "0x" << std::hex
  493                   << node_id << " is up" << std::endl;
  494             }
  495             exit(EXIT_SUCCESS);
  496           } else {
  497             if (print_also == true) {
  498               std::cout << "0x" << std::hex
  499                 << node_id << " is not up" <<std::endl;
  500             }
  501             exit(EXIT_FAILURE);
  502           }
  503           break;
  504   default:
  505           if (print_also == true)
  506           print_cluster_info();
  507           break;
  508   }
  509   std::cout << std::endl;
  510   ncs_agents_shutdown();
  511   return EXIT_SUCCESS;
  512 }