"Fossies" - the Fresh Open Source Software Archive

Member "opensaf-5.21.09/src/amf/amfd/csi.cc" (14 Sep 2021, 55577 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 "csi.cc" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 5.21.06_vs_5.21.09.

    1 /*      -*- OpenSAF  -*-
    2  *
    3  * (C) Copyright 2008 The OpenSAF Foundation
    4  * Copyright (C) 2017, Oracle and/or its affiliates. All rights reserved.
    5  *
    6  * This program is distributed in the hope that it will be useful, but
    7  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
    8  * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
    9  * under the GNU Lesser General Public License Version 2.1, February 1999.
   10  * The complete license can be accessed from the following location:
   11  * http://opensource.org/licenses/lgpl-license.php
   12  * See the Copying file included with the OpenSAF distribution for full
   13  * licensing terms.
   14  *
   15  * Author(s): Emerson Network Power
   16  *            Ericsson
   17  *
   18  */
   19 
   20 #include "base/logtrace.h"
   21 
   22 #include "amf/amfd/util.h"
   23 #include "amf/common/amf_util.h"
   24 #include "amf/amfd/csi.h"
   25 #include "amf/amfd/imm.h"
   26 #include "amf/amfd/proc.h"
   27 
   28 AmfDb<std::string, AVD_CSI> *csi_db = nullptr;
   29 std::set<std::string> container_csis;
   30 
   31 //
   32 AVD_COMP *AVD_CSI::find_assigned_comp(
   33     const std::string &cstype, const AVD_SU_SI_REL *sisu,
   34     const std::vector<AVD_COMP *> &list_of_comp) {
   35   auto iter = list_of_comp.begin();
   36   AVD_COMP *comp = nullptr;
   37   for (; iter != list_of_comp.end(); ++iter) {
   38     comp = *iter;
   39     AVD_COMPCS_TYPE *cst;
   40     if (nullptr != (cst = avd_compcstype_find_match(cstype, comp))) {
   41       if (SA_AMF_HA_ACTIVE == sisu->state) {
   42         if (cst->saAmfCompNumCurrActiveCSIs < cst->saAmfCompNumMaxActiveCSIs) {
   43           break;
   44         } else { /* We can't assign this csi to this comp, so check for another
   45                     comp */
   46           continue;
   47         }
   48       } else {
   49         if (cst->saAmfCompNumCurrStandbyCSIs <
   50             cst->saAmfCompNumMaxStandbyCSIs) {
   51           break;
   52         } else { /* We can't assign this csi to this comp, so check for another
   53                     comp */
   54           continue;
   55         }
   56       }
   57     }
   58   }
   59   if (iter == list_of_comp.end()) {
   60     return nullptr;
   61   } else {
   62     return comp;
   63   }
   64 }
   65 
   66 void avd_csi_delete(AVD_CSI *csi) {
   67   AVD_CSI_ATTR *temp;
   68   TRACE_ENTER2("%s", csi->name.c_str());
   69 
   70   /* Delete CSI attributes */
   71   temp = csi->list_attributes;
   72   while (temp != nullptr) {
   73     avd_csi_remove_csiattr(csi, temp);
   74     temp = csi->list_attributes;
   75   }
   76 
   77   avd_cstype_remove_csi(csi);
   78   csi->si->remove_csi(csi);
   79 
   80   csi_db->erase(csi->name);
   81 
   82   if (csi->saAmfCSIDependencies != nullptr) {
   83     AVD_CSI_DEPS *csi_dep;
   84     AVD_CSI_DEPS *next_csi_dep;
   85 
   86     csi_dep = csi->saAmfCSIDependencies;
   87     while (csi_dep != nullptr) {
   88       next_csi_dep = csi_dep->csi_dep_next;
   89       delete csi_dep;
   90       csi_dep = next_csi_dep;
   91     }
   92   }
   93 
   94   delete csi;
   95   TRACE_LEAVE2();
   96 }
   97 
   98 void csi_cmplt_delete(AVD_CSI *csi, bool ckpt) {
   99   AVD_PG_CSI_NODE *curr;
  100   TRACE_ENTER2("%s", csi->name.c_str());
  101   if (!ckpt) {
  102     /* inform the avnds that track this csi */
  103     for (curr = (AVD_PG_CSI_NODE *)m_NCS_DBLIST_FIND_FIRST(&csi->pg_node_list);
  104          curr != nullptr; curr = (AVD_PG_CSI_NODE *)m_NCS_DBLIST_FIND_NEXT(
  105                               &curr->csi_dll_node)) {
  106       avd_snd_pg_upd_msg(avd_cb, curr->node, 0,
  107                          static_cast<SaAmfProtectionGroupChangesT>(0),
  108                          csi->name);
  109     }
  110   }
  111 
  112   /* delete the pg-node list */
  113   avd_pg_csi_node_del_all(avd_cb, csi);
  114 
  115   /* free memory and remove from DB */
  116   avd_csi_delete(csi);
  117   TRACE_LEAVE2();
  118 }
  119 
  120 /**
  121  * Validate configuration attributes for an AMF CSI object
  122  * @param csi
  123  *
  124  * @return int
  125  */
  126 static int is_config_valid(const std::string &dn,
  127                            const SaImmAttrValuesT_2 **attributes,
  128                            CcbUtilOperationData_t *opdata) {
  129   SaAisErrorT rc;
  130   SaNameT aname;
  131   std::string parent;
  132   unsigned int values_number;
  133 
  134   TRACE_ENTER2("%s", dn.c_str());
  135 
  136   parent = avd_getparent(dn);
  137   if (parent.empty() == true) {
  138     report_ccb_validation_error(opdata, "No parent to '%s' ", dn.c_str());
  139     TRACE_LEAVE();
  140     return 0;
  141   }
  142 
  143   if (parent.compare(0, 6, "safSi=") != 0) {
  144     LOG_ER("Wrong parent '%s' to '%s' ", parent.c_str(), dn.c_str());
  145     TRACE_LEAVE();
  146     return 0;
  147   }
  148 
  149   rc = immutil_getAttr(const_cast<SaImmAttrNameT>("saAmfCSType"), attributes, 0,
  150                        &aname);
  151   osafassert(rc == SA_AIS_OK);
  152 
  153   if (cstype_db->find(Amf::to_string(&aname)) == nullptr) {
  154     /* CS type does not exist in current model, check CCB if passed as param */
  155     if (opdata == nullptr) {
  156       report_ccb_validation_error(opdata, "'%s' does not exist in model",
  157                                   osaf_extended_name_borrow(&aname));
  158       TRACE_LEAVE();
  159       return 0;
  160     }
  161 
  162     if (ccbutil_getCcbOpDataByDN(opdata->ccbId, &aname) == nullptr) {
  163       report_ccb_validation_error(
  164           opdata, "'%s' does not exist in existing model or in CCB",
  165           osaf_extended_name_borrow(&aname));
  166       TRACE_LEAVE();
  167       return 0;
  168     }
  169   }
  170 
  171   /* Verify that all (if any) CSI dependencies are valid */
  172   if ((immutil_getAttrValuesNumber(
  173            const_cast<SaImmAttrNameT>("saAmfCSIDependencies"), attributes,
  174            &values_number) == SA_AIS_OK) &&
  175       (values_number > 0)) {
  176     unsigned int i;
  177     std::string csi_dependency;
  178     std::string dep_parent;
  179 
  180     for (i = 0; i < values_number; i++) {
  181       SaNameT tmp_dependency;
  182       rc = immutil_getAttr(const_cast<SaImmAttrNameT>("saAmfCSIDependencies"),
  183                            attributes, i, &tmp_dependency);
  184       osafassert(rc == SA_AIS_OK);
  185       csi_dependency = Amf::to_string(&tmp_dependency);
  186 
  187       if (dn.compare(csi_dependency) == 0) {
  188         report_ccb_validation_error(
  189             opdata,
  190             "'%s' validation failed - dependency configured to"
  191             " itself!",
  192             dn.c_str());
  193         TRACE_LEAVE();
  194         return 0;
  195       }
  196 
  197       if (csi_db->find(csi_dependency) == nullptr) {
  198         /* CSI does not exist in current model, check CCB if passed as param */
  199         if (opdata == nullptr) {
  200           /* initial loading, check IMM */
  201           if (object_exist_in_imm(csi_dependency) == false) {
  202             report_ccb_validation_error(opdata,
  203                                         "'%s' validation failed - '%s' does not"
  204                                         " exist",
  205                                         dn.c_str(), csi_dependency.c_str());
  206             TRACE_LEAVE();
  207             return 0;
  208           }
  209         } else if (ccbutil_getCcbOpDataByDN(opdata->ccbId, &tmp_dependency) ==
  210                    nullptr) {
  211           report_ccb_validation_error(
  212               opdata,
  213               "'%s' validation failed - '%s' does not exist"
  214               " in existing model or in CCB",
  215               dn.c_str(), csi_dependency.c_str());
  216           TRACE_LEAVE();
  217           return 0;
  218         }
  219       }
  220 
  221       dep_parent = avd_getparent(csi_dependency);
  222       if (dep_parent.empty() == true) {
  223         report_ccb_validation_error(opdata,
  224                                     "'%s' validation failed - invalid "
  225                                     "saAmfCSIDependency '%s'",
  226                                     dn.c_str(), csi_dependency.c_str());
  227         TRACE_LEAVE();
  228         return 0;
  229       }
  230 
  231       if (parent.compare(dep_parent) != 0) {
  232         report_ccb_validation_error(
  233             opdata,
  234             "'%s' validation failed - dependency to CSI in other"
  235             " SI is not allowed",
  236             dn.c_str());
  237         TRACE_LEAVE();
  238         return 0;
  239       }
  240     }
  241   }
  242 
  243   /* Verify that the SI can contain this CSI */
  244   {
  245     AVD_SI *avd_si;
  246     std::string si_name;
  247 
  248     avsv_sanamet_init(dn, si_name, "safSi");
  249 
  250     if (nullptr != (avd_si = avd_si_get(si_name))) {
  251       /* Check for any admin operations undergoing. This is valid during dyn
  252        * add*/
  253       if ((opdata != nullptr) &&
  254           (AVD_SG_FSM_STABLE != avd_si->sg_of_si->sg_fsm_state)) {
  255         report_ccb_validation_error(opdata,
  256                                     "SG('%s') fsm state('%u') is not in "
  257                                     "AVD_SG_FSM_STABLE(0)",
  258                                     avd_si->sg_of_si->name.c_str(),
  259                                     avd_si->sg_of_si->sg_fsm_state);
  260         TRACE_LEAVE();
  261         return 0;
  262       }
  263     } else {
  264       if (opdata == nullptr) {
  265         report_ccb_validation_error(opdata, "'%s' does not exist in model",
  266                                     si_name.c_str());
  267         TRACE_LEAVE();
  268         return 0;
  269       }
  270 
  271       const SaNameTWrapper si(si_name);
  272       if (ccbutil_getCcbOpDataByDN(opdata->ccbId, si) == nullptr) {
  273         report_ccb_validation_error(
  274             opdata, "'%s' does not exist in existing model or in CCB",
  275             si_name.c_str());
  276         TRACE_LEAVE();
  277         return 0;
  278       }
  279     }
  280 #if 0
  281                 svctypecstype = avd_svctypecstypes_get(&svctypecstype_name);
  282                 if (svctypecstype == nullptr) {
  283                         LOG_ER("Not found '%s'", svctypecstype_name.value);
  284                         return -1;
  285                 }
  286 
  287                 if (svctypecstype->curr_num_csis == svctypecstype->saAmfSvctMaxNumCSIs) {
  288                         LOG_ER("SI '%s' cannot contain more CSIs of this type '%s*",
  289                                 csi->si->name.value, csi->saAmfCSType.value);
  290                         return -1;
  291                 }
  292 #endif
  293   }
  294   TRACE_LEAVE();
  295   return 1;
  296 }
  297 /**
  298  * @brief       Check whether the CSI dependency is already existing in the
  299  * existing list if not adds to the dependencies list
  300  *
  301  * @param[in]   csi - csi to which the dependency is added
  302  * @param[in]   new_csi_dep - csi dependency to be added
  303  *
  304  * @return      true/false
  305  */
  306 static bool csi_add_csidep(AVD_CSI *csi, AVD_CSI_DEPS *new_csi_dep) {
  307   AVD_CSI_DEPS *temp_csi_dep;
  308   bool csi_added = false;
  309 
  310   /* Check whether the CSI dependency is already existing in the existing list.
  311    * If yes, it should not get added again
  312    */
  313   for (temp_csi_dep = csi->saAmfCSIDependencies; temp_csi_dep != nullptr;
  314        temp_csi_dep = temp_csi_dep->csi_dep_next) {
  315     if (new_csi_dep->csi_dep_name_value.compare(
  316             temp_csi_dep->csi_dep_name_value) == 0) {
  317       csi_added = true;
  318     }
  319   }
  320   if (!csi_added) {
  321     /* Add into the CSI dependency list */
  322     new_csi_dep->csi_dep_next = csi->saAmfCSIDependencies;
  323     csi->saAmfCSIDependencies = new_csi_dep;
  324   }
  325 
  326   return csi_added;
  327 }
  328 
  329 /**
  330  * Removes a CSI dep from the saAmfCSIDependencies list and free the memory
  331  */
  332 static void csi_remove_csidep(AVD_CSI *csi, const std::string &required_dn) {
  333   AVD_CSI_DEPS *prev = nullptr;
  334   AVD_CSI_DEPS *curr;
  335 
  336   for (curr = csi->saAmfCSIDependencies; curr != nullptr;
  337        curr = curr->csi_dep_next) {
  338     if (required_dn.compare(curr->csi_dep_name_value) == 0) {
  339       break;
  340     }
  341     prev = curr;
  342   }
  343 
  344   if (curr != nullptr) {
  345     if (prev == nullptr) {
  346       csi->saAmfCSIDependencies = curr->csi_dep_next;
  347     } else {
  348       prev->csi_dep_next = curr->csi_dep_next;
  349     }
  350   }
  351 
  352   delete curr;
  353 }
  354 
  355 //
  356 AVD_CSI::AVD_CSI(const std::string &csi_name) : name(csi_name) {}
  357 /**
  358  * @brief       creates new csi and adds csi node to the csi_db
  359  *
  360  * @param[in]   csi_name
  361  *
  362  * @return      pointer to AVD_CSI
  363  */
  364 AVD_CSI *csi_create(const std::string &csi_name) {
  365   AVD_CSI *csi;
  366 
  367   TRACE_ENTER2("'%s'", csi_name.c_str());
  368 
  369   csi = new AVD_CSI(csi_name);
  370 
  371   if (csi_db->insert(csi->name, csi) != NCSCC_RC_SUCCESS) osafassert(0);
  372 
  373   TRACE_LEAVE();
  374   return csi;
  375 }
  376 /**
  377  * @brief       Reads csi attributes  from imm and csi to the model
  378  *
  379  * @param[in]   csi_name
  380  *
  381  * @return      pointer to AVD_CSI
  382  */
  383 static void csi_get_attr_and_add_to_model(AVD_CSI *csi,
  384                                           const SaImmAttrValuesT_2 **attributes,
  385                                           const std::string &si_name) {
  386   int rc = -1;
  387   unsigned int values_number = 0;
  388   SaAisErrorT error;
  389   SaNameT cs_type;
  390 
  391   TRACE_ENTER2("'%s'", csi->name.c_str());
  392 
  393   /* initialize the pg node-list */
  394   csi->pg_node_list.order = NCS_DBLIST_ANY_ORDER;
  395   csi->pg_node_list.cmp_cookie = avsv_dblist_uns32_cmp;
  396   csi->pg_node_list.free_cookie = 0;
  397 
  398   error = immutil_getAttr(const_cast<SaImmAttrNameT>("saAmfCSType"), attributes,
  399                           0, &cs_type);
  400   osafassert(error == SA_AIS_OK);
  401   csi->saAmfCSType = Amf::to_string(&cs_type);
  402 
  403   if ((immutil_getAttrValuesNumber(
  404            const_cast<SaImmAttrNameT>("saAmfCSIDependencies"), attributes,
  405            &values_number) == SA_AIS_OK)) {
  406     if (values_number == 0) {
  407       /* No Dependency Configured. Mark rank as 1.*/
  408       csi->rank = 1;
  409     } else {
  410       /* Dependency Configured. Decide rank when adding it in si list.*/
  411       unsigned int i;
  412       bool found;
  413       AVD_CSI_DEPS *new_csi_dep = nullptr;
  414 
  415       TRACE("checking dependencies");
  416 
  417       for (i = 0; i < values_number; i++) {
  418         TRACE("i %u", i);
  419         new_csi_dep = new AVD_CSI_DEPS();
  420         SaNameT temp_name;
  421         if (immutil_getAttr(const_cast<SaImmAttrNameT>("saAmfCSIDependencies"),
  422                             attributes, i, &temp_name) != SA_AIS_OK) {
  423           LOG_ER("Get saAmfCSIDependencies FAILED for '%s'", csi->name.c_str());
  424           // make sure we don't leak any memory if
  425           // saAmfCSIDependencies can't be read
  426           delete new_csi_dep;
  427           goto done;
  428         }
  429         new_csi_dep->csi_dep_name_value = Amf::to_string(&temp_name);
  430         found = csi_add_csidep(csi, new_csi_dep);
  431         if (found == true) delete new_csi_dep;
  432       }
  433     }
  434   } else {
  435     csi->rank = 1;
  436     TRACE_ENTER2("DEP not configured, marking rank 1. Csi'%s', Rank'%u'",
  437                  csi->name.c_str(), csi->rank);
  438   }
  439 
  440   if ((immutil_getAttrValuesNumber(
  441            const_cast<SaImmAttrNameT>(
  442                "osafAmfCSICommunicateCsiAttributeChange"),
  443            attributes, &values_number) != SA_AIS_OK)) {
  444     TRACE("Default for osafAmfCSICommunicateCsiAttributeChange set to false");
  445     csi->osafAmfCSICommunicateCsiAttributeChange =
  446         false;  // Default value is always 0.
  447   }
  448 
  449   TRACE("find %s", csi->saAmfCSType.c_str());
  450   csi->cstype = cstype_db->find(csi->saAmfCSType);
  451   csi->si = avd_si_get(si_name);
  452 
  453   avd_cstype_add_csi(csi);
  454   csi->si->add_csi(csi);
  455 
  456   rc = 0;
  457 
  458 done:
  459   if (rc != 0) {
  460     delete csi;
  461     osafassert(0);
  462   }
  463   TRACE_LEAVE();
  464 }
  465 
  466 /**
  467  * Get configuration for all AMF CSI objects from IMM and create
  468  * AVD internal objects.
  469  *
  470  * @param si_name
  471  * @param si
  472  *
  473  * @return int
  474  */
  475 SaAisErrorT avd_csi_config_get(const std::string &si_name, AVD_SI *si) {
  476   SaAisErrorT error = SA_AIS_ERR_FAILED_OPERATION, rc;
  477   SaImmSearchHandleT searchHandle;
  478   SaImmSearchParametersT_2 searchParam;
  479   SaNameT temp_csi_name;
  480 
  481   const SaImmAttrValuesT_2 **attributes;
  482   const char *className = "SaAmfCSI";
  483   AVD_CSI *csi;
  484 
  485   searchParam.searchOneAttr.attrName =
  486       const_cast<SaImmAttrNameT>("SaImmAttrClassName");
  487   searchParam.searchOneAttr.attrValueType = SA_IMM_ATTR_SASTRINGT;
  488   searchParam.searchOneAttr.attrValue = &className;
  489 
  490   if ((rc = immutil_saImmOmSearchInitialize_o2(
  491           avd_cb->immOmHandle, si_name.c_str(), SA_IMM_SUBTREE,
  492           SA_IMM_SEARCH_ONE_ATTR | SA_IMM_SEARCH_GET_ALL_ATTR, &searchParam,
  493           nullptr, &searchHandle)) != SA_AIS_OK) {
  494     LOG_ER("saImmOmSearchInitialize_2 failed");
  495     error = rc;
  496     goto done1;
  497   }
  498 
  499   while (immutil_saImmOmSearchNext_2(searchHandle, &temp_csi_name,
  500                                      (SaImmAttrValuesT_2 ***)&attributes) ==
  501          SA_AIS_OK) {
  502     const std::string csi_name(Amf::to_string(&temp_csi_name));
  503     if (!is_config_valid(csi_name, attributes, nullptr)) goto done2;
  504 
  505     if ((csi = csi_db->find(csi_name)) == nullptr) {
  506       csi = csi_create(csi_name);
  507 
  508       csi_get_attr_and_add_to_model(csi, attributes, si_name);
  509     }
  510 
  511     if ((rc = avd_csiattr_config_get(csi_name, csi)) != SA_AIS_OK) {
  512       if ((rc == SA_AIS_ERR_NOT_EXIST) && (avd_cb->is_active() == false)) {
  513         avd_csi_delete(csi);
  514       } else {
  515         goto done2;
  516       }
  517     }
  518   }
  519 
  520   error = SA_AIS_OK;
  521 
  522 done2:
  523   (void)immutil_saImmOmSearchFinalize(searchHandle);
  524 done1:
  525 
  526   return error;
  527 }
  528 
  529 /*****************************************************************************
  530  * Function: csi_ccb_completed_create_hdlr
  531  *
  532  * Purpose: This routine validates create CCB operations on SaAmfCSI objects.
  533  *
  534  *
  535  * Input  : Ccb Util Oper Data
  536  *
  537  * Returns: None.
  538  *
  539  * NOTES  : None.
  540  *
  541  *
  542  **************************************************************************/
  543 static SaAisErrorT csi_ccb_completed_create_hdlr(
  544     CcbUtilOperationData_t *opdata) {
  545   SaAisErrorT rc = SA_AIS_ERR_BAD_OPERATION;
  546   std::string si_name;
  547   AVD_SI *avd_si;
  548   AVD_COMP *t_comp;
  549   AVD_SU_SI_REL *t_sisu;
  550   AVD_COMP_CSI_REL *compcsi;
  551   SaNameT cstype_name;
  552   const std::string object_name(Amf::to_string(&opdata->objectName));
  553 
  554   TRACE_ENTER2("CCB ID %llu, '%s'", opdata->ccbId, object_name.c_str());
  555 
  556   if (!is_config_valid(object_name, opdata->param.create.attrValues, opdata))
  557     goto done;
  558 
  559   rc = immutil_getAttr(const_cast<SaImmAttrNameT>("saAmfCSType"),
  560                        opdata->param.create.attrValues, 0, &cstype_name);
  561   osafassert(rc == SA_AIS_OK);
  562 
  563   avsv_sanamet_init(object_name, si_name, "safSi");
  564   avd_si = avd_si_get(si_name);
  565 
  566   if (nullptr != avd_si) {
  567     /* Check whether si has been assigned to any SU. */
  568     if (nullptr != avd_si->list_of_sisu) {
  569       t_sisu = avd_si->list_of_sisu;
  570       while (t_sisu) {
  571         if (t_sisu->csi_add_rem == true) {
  572           LOG_NO(
  573               "CSI create of '%s' in queue: pending assignment"
  574               " for '%s'",
  575               object_name.c_str(), t_sisu->su->name.c_str());
  576         }
  577         t_sisu = t_sisu->si_next;
  578       } /*  while(t_sisu) */
  579 
  580       t_sisu = avd_si->list_of_sisu;
  581       while (t_sisu) {
  582         AVD_SU *su = t_sisu->su;
  583         /* We need to assign this csi if an extra component exists, which is
  584          * unassigned.*/
  585 
  586         su->reset_all_comps_assign_flag();
  587 
  588         compcsi = t_sisu->list_of_csicomp;
  589         while (compcsi != nullptr) {
  590           compcsi->comp->set_assigned(true);
  591           compcsi = compcsi->susi_csicomp_next;
  592         }
  593 
  594         t_comp = su->find_unassigned_comp_that_provides_cstype(
  595             Amf::to_string(&cstype_name));
  596 
  597         /* Component not found.*/
  598         if (nullptr == t_comp) {
  599           /* This means that all the components are assigned, let us assigned it
  600              to assigned component.*/
  601           t_comp = AVD_CSI::find_assigned_comp(Amf::to_string(&cstype_name),
  602                                                t_sisu, su->list_of_comp);
  603         }
  604         if (nullptr == t_comp) {
  605           report_ccb_validation_error(
  606               opdata,
  607               "Compcsi doesn't exist or "
  608               "MaxActiveCSI/MaxStandbyCSI have reached for csi '%s'",
  609               object_name.c_str());
  610           rc = SA_AIS_ERR_BAD_OPERATION;
  611           goto done;
  612         }
  613 
  614         t_sisu = t_sisu->si_next;
  615       } /*  while(t_sisu) */
  616     }   /* if (nullptr != si->list_of_sisu) */
  617   }
  618 
  619   rc = SA_AIS_OK;
  620 done:
  621   TRACE_LEAVE();
  622   return rc;
  623 }
  624 
  625 /*****************************************************************************
  626  * Function: csi_ccb_completed_modify_hdlr
  627  *
  628  * Purpose: This routine validates modify CCB operations on SaAmfCSI objects.
  629  *
  630  *
  631  * Input  : Ccb Util Oper Data
  632  *
  633  * Returns: None.
  634  *
  635  * NOTES  : None.
  636  *
  637  *
  638  **************************************************************************/
  639 static SaAisErrorT csi_ccb_completed_modify_hdlr(
  640     CcbUtilOperationData_t *opdata) {
  641   SaAisErrorT rc = SA_AIS_ERR_BAD_OPERATION;
  642   const SaImmAttrModificationT_2 *attr_mod;
  643   int i = 0;
  644   AVD_CSI *csi = csi_db->find(Amf::to_string(&opdata->objectName));
  645   if (csi == nullptr && avd_cb->is_active() == false) {
  646     LOG_WA("Csi modify completed (STDBY): csi does not exist");
  647     return SA_AIS_OK;
  648   }
  649   const std::string object_name(Amf::to_string(&opdata->objectName));
  650 
  651   assert(csi);
  652   TRACE_ENTER2("CCB ID %llu, '%s'", opdata->ccbId, object_name.c_str());
  653 
  654   while ((attr_mod = opdata->param.modify.attrMods[i++]) != nullptr) {
  655     if (!strcmp(attr_mod->modAttr.attrName, "saAmfCSType")) {
  656       SaNameT cstype_name = *(SaNameT *)attr_mod->modAttr.attrValues[0];
  657       if (SA_AMF_ADMIN_LOCKED != csi->si->saAmfSIAdminState) {
  658         report_ccb_validation_error(
  659             opdata, "Parent SI is not in locked state, SI state '%d'",
  660             csi->si->saAmfSIAdminState);
  661         goto done;
  662       }
  663       if (cstype_db->find(Amf::to_string(&cstype_name)) == nullptr) {
  664         report_ccb_validation_error(opdata, "CS Type not found '%s'",
  665                                     osaf_extended_name_borrow(&cstype_name));
  666         goto done;
  667       }
  668     } else if (!strcmp(attr_mod->modAttr.attrName,
  669                        "osafAmfCSICommunicateCsiAttributeChange")) {
  670       if ((attr_mod->modType == SA_IMM_ATTR_VALUES_DELETE) ||
  671           (attr_mod->modAttr.attrValues == nullptr)) {
  672         report_ccb_validation_error(
  673             opdata,
  674             "Invalid modification of osafAmfCSICommunicateCsiAttributeChange, valid (0 or 1)");
  675         goto done;
  676       }
  677       uint32_t val =
  678           static_cast<uint32_t>(*(uint32_t *)attr_mod->modAttr.attrValues[0]);
  679       if (val > 1) {
  680         report_ccb_validation_error(
  681             opdata,
  682             "Modification of osafAmfCSICommunicateCsiAttributeChange fails,"
  683             " Invalid Input %d",
  684             val);
  685         goto done;
  686       }
  687     } else if (!strcmp(attr_mod->modAttr.attrName, "saAmfCSIDependencies")) {
  688       // Reject replacement of CSI deps, only deletion and addition are
  689       // supported.
  690       if (attr_mod->modType == SA_IMM_ATTR_VALUES_REPLACE) {
  691         report_ccb_validation_error(
  692             opdata, "'%s' - replacement of CSI dependency is not supported",
  693             object_name.c_str());
  694         goto done;
  695       }
  696       const std::string required_dn(Amf::to_string(
  697           static_cast<SaNameT *>(attr_mod->modAttr.attrValues[0])));
  698       const AVD_CSI *required_csi = csi_db->find(required_dn);
  699 
  700       // Required CSI must exist in current model
  701       if (required_csi == nullptr) {
  702         report_ccb_validation_error(opdata, "CSI '%s' does not exist",
  703                                     required_dn.c_str());
  704         goto done;
  705       }
  706 
  707       // Required CSI must be contained in the same SI
  708       std::string si_name;
  709       avsv_sanamet_init(required_dn, si_name, "safSi");
  710       if (object_name.find(si_name) == std::string::npos) {
  711         report_ccb_validation_error(opdata,
  712                                     "'%s' is not in the same SI as '%s'",
  713                                     object_name.c_str(), required_dn.c_str());
  714         goto done;
  715       }
  716 
  717       if (attr_mod->modType == SA_IMM_ATTR_VALUES_ADD) {
  718         AVD_CSI_DEPS *csi_dep;
  719 
  720         if (attr_mod->modAttr.attrValuesNumber > 1) {
  721           report_ccb_validation_error(opdata,
  722                                       "only one dep can be added at a time");
  723           goto done;
  724         }
  725 
  726         // check cyclic dependencies by scanning the deps of the required CSI
  727         for (csi_dep = required_csi->saAmfCSIDependencies; csi_dep;
  728              csi_dep = csi_dep->csi_dep_next) {
  729           if (csi_dep->csi_dep_name_value.compare(object_name) == 0) {
  730             // the required CSI requires this CSI
  731             report_ccb_validation_error(
  732                 opdata, "cyclic dependency between '%s' and '%s'",
  733                 object_name.c_str(), required_dn.c_str());
  734             goto done;
  735           }
  736         }
  737 
  738         // don't allow adding the same dep again
  739         for (csi_dep = csi->saAmfCSIDependencies; csi_dep;
  740              csi_dep = csi_dep->csi_dep_next) {
  741           if (csi_dep->csi_dep_name_value.compare(required_dn.c_str()) == 0) {
  742             // dep already exist, should we return OK instead?
  743             report_ccb_validation_error(
  744                 opdata, "dependency between '%s' and '%s' already exist",
  745                 object_name.c_str(), required_dn.c_str());
  746             goto done;
  747           }
  748         }
  749 
  750         // disallow dep between same CSIs
  751         if (csi->name.compare(required_dn.c_str()) == 0) {
  752           report_ccb_validation_error(opdata, "dependency for '%s' to itself",
  753                                       csi->name.c_str());
  754           goto done;
  755         }
  756       } else if (attr_mod->modType == SA_IMM_ATTR_VALUES_DELETE) {
  757         if (attr_mod->modAttr.attrValuesNumber > 1) {
  758           report_ccb_validation_error(opdata,
  759                                       "only one dep can be removed at a time");
  760           goto done;
  761         }
  762       }
  763     } else {
  764       report_ccb_validation_error(
  765           opdata, "Modification of attribute '%s' not supported",
  766           attr_mod->modAttr.attrName);
  767       goto done;
  768     }
  769   }
  770 
  771   rc = SA_AIS_OK;
  772 done:
  773   TRACE_LEAVE2("%u", rc);
  774   return rc;
  775 }
  776 
  777 /*****************************************************************************
  778  * Function: csi_ccb_completed_delete_hdlr
  779  *
  780  * Purpose: This routine validates delete CCB operations on SaAmfCSI objects.
  781  *
  782  *
  783  * Input  : Ccb Util Oper Data
  784  *
  785  * Returns: None.
  786  *
  787  * NOTES  : None.
  788  *
  789  *
  790  **************************************************************************/
  791 static SaAisErrorT csi_ccb_completed_delete_hdlr(
  792     CcbUtilOperationData_t *opdata) {
  793   SaAisErrorT rc = SA_AIS_ERR_BAD_OPERATION;
  794   AVD_CSI *csi;
  795   AVD_SU_SI_REL *t_sisu;
  796   const std::string object_name(Amf::to_string(&opdata->objectName));
  797 
  798   TRACE_ENTER2("CCB ID %llu, '%s'", opdata->ccbId, object_name.c_str());
  799 
  800   csi = csi_db->find(object_name);
  801 
  802   if (avd_cb->avail_state_avd != SA_AMF_HA_ACTIVE) {
  803     if (csi == nullptr) {
  804       /* This means that csi has been deleted during checkpointing at STDBY and
  805          completed callback has arrived delayed.*/
  806       TRACE("CSI delete completed (STDBY): '%s' does not exist",
  807             osaf_extended_name_borrow(&opdata->objectName));
  808     }
  809     // IMM honors response of completed callback only from active amfd, so reply
  810     // ok from standby amfd.
  811     rc = SA_AIS_OK;
  812     opdata->userData = csi; /* Save for later use in apply */
  813     goto done;
  814   }
  815 
  816   if (AVD_SG_FSM_STABLE != csi->si->sg_of_si->sg_fsm_state) {
  817     report_ccb_validation_error(
  818         opdata, "SG('%s') fsm state('%u') is not in AVD_SG_FSM_STABLE(0)",
  819         csi->si->sg_of_si->name.c_str(), csi->si->sg_of_si->sg_fsm_state);
  820     rc = SA_AIS_ERR_BAD_OPERATION;
  821     goto done;
  822   }
  823 
  824   if (csi->si->saAmfSIAdminState != SA_AMF_ADMIN_LOCKED) {
  825     if (nullptr == csi->si->list_of_sisu) {
  826       /* UnLocked but not assigned. Safe to delete.*/
  827     } else { /* Assigned to some SU, check whether the last csi. */
  828       /* SI is unlocked and this is the last csi to be deleted, then donot allow
  829        * it. */
  830       if (csi->si->list_of_csi->si_list_of_csi_next == nullptr) {
  831         report_ccb_validation_error(
  832             opdata,
  833             " csi('%s') is the last csi in si('%s'). Lock SI and"
  834             " then delete csi.",
  835             csi->name.c_str(), csi->si->name.c_str());
  836         rc = SA_AIS_ERR_BAD_OPERATION;
  837         goto done;
  838       }
  839       t_sisu = csi->si->list_of_sisu;
  840       while (t_sisu) {
  841         if (t_sisu->csi_add_rem == true) {
  842           LOG_NO(
  843               "CSI remove of '%s' rejected: pending "
  844               "assignment for '%s'",
  845               csi->name.c_str(), t_sisu->su->name.c_str());
  846           if (avd_cb->avail_state_avd == SA_AMF_HA_ACTIVE) {
  847             rc = SA_AIS_ERR_BAD_OPERATION;
  848             goto done;
  849           }
  850         }
  851         t_sisu = t_sisu->si_next;
  852       } /*  while(t_sisu) */
  853     }
  854   } else {
  855     if (csi->list_compcsi != nullptr) {
  856       report_ccb_validation_error(opdata, "SaAmfCSI '%s' is in use",
  857                                   csi->name.c_str());
  858       rc = SA_AIS_ERR_BAD_OPERATION;
  859       goto done;
  860     }
  861   }
  862 
  863   rc = SA_AIS_OK;
  864   opdata->userData = csi; /* Save for later use in apply */
  865 done:
  866   TRACE_LEAVE2("%u", rc);
  867   return rc;
  868 }
  869 
  870 static SaAisErrorT csi_ccb_completed_cb(CcbUtilOperationData_t *opdata) {
  871   SaAisErrorT rc = SA_AIS_ERR_BAD_OPERATION;
  872 
  873   TRACE_ENTER2("CCB ID %llu, '%s'", opdata->ccbId,
  874                osaf_extended_name_borrow(&opdata->objectName));
  875 
  876   switch (opdata->operationType) {
  877     case CCBUTIL_CREATE:
  878       rc = csi_ccb_completed_create_hdlr(opdata);
  879       break;
  880     case CCBUTIL_MODIFY:
  881       rc = csi_ccb_completed_modify_hdlr(opdata);
  882       break;
  883     case CCBUTIL_DELETE:
  884       rc = csi_ccb_completed_delete_hdlr(opdata);
  885       break;
  886     default:
  887       osafassert(0);
  888       break;
  889   }
  890 
  891   TRACE_LEAVE();
  892   return rc;
  893 }
  894 
  895 static void ccb_apply_delete_hdlr(CcbUtilOperationData_t *opdata) {
  896   AVD_SU_SI_REL *t_sisu;
  897   AVD_COMP_CSI_REL *t_csicomp;
  898   AVD_CSI *csi = static_cast<AVD_CSI *>(opdata->userData);
  899   AVD_CSI *csi_in_db;
  900 
  901   bool first_sisu = true;
  902 
  903   TRACE_ENTER();
  904   if (avd_cb->avail_state_avd != SA_AMF_HA_ACTIVE) {
  905     /* A double check whether csi has been deleted from DB or not and whether
  906        pointer stored userData is still valid. */
  907     csi_in_db = csi_db->find(Amf::to_string(&opdata->objectName));
  908     if ((csi == nullptr) || (csi_in_db == nullptr)) {
  909       /* This means that csi has been deleted during checkpointing at STDBY and
  910          delete callback has arrived delayed.*/
  911       LOG_WA("CSI delete apply (STDBY): csi does not exist");
  912       goto done;
  913     }
  914     if (csi->list_compcsi == nullptr) {
  915       /* delete the pg-node list */
  916       avd_pg_csi_node_del_all(avd_cb, csi);
  917 
  918       /* free memory and remove from DB */
  919       avd_csi_delete(csi);
  920     }
  921     goto done;
  922   }
  923 
  924   osafassert(csi != nullptr);
  925   TRACE("'%s'", csi->name.c_str());
  926 
  927   /* Check whether si has been assigned to any SU. */
  928   if ((nullptr != csi->si->list_of_sisu) && (csi->compcsi_cnt != 0)) {
  929     TRACE("compcsi_cnt'%u'", csi->compcsi_cnt);
  930     /* csi->compcsi_cnt == 0 ==> This means that there is no comp_csi related to
  931        this csi in the SI. It may happen this csi is not assigned to any CSI
  932        because of no compcstype match, but its si may have SUSI. This will
  933        happen in case of deleting one comp from SU in upgrade case Scenario :
  934        Add one comp1-csi1, comp2-csi2 in upgrade procedure, then delete
  935        comp1-csi1 i.e. in the end call immcfg -d csi1. Since csi1 will not be
  936        assigned to anybody because of unique comp-cstype configured and since
  937        comp1 is deleted so, there wouldn't be any assignment. So, Just delete
  938        csi.*/
  939     t_sisu = csi->si->list_of_sisu;
  940     while (t_sisu) {
  941       /* Find the relevant comp-csi to send susi delete. */
  942       for (t_csicomp = t_sisu->list_of_csicomp; t_csicomp;
  943            t_csicomp = t_csicomp->susi_csicomp_next)
  944         if (t_csicomp->csi == csi) break;
  945       osafassert(t_csicomp);
  946       /* Mark comp-csi and sisu to be under csi add/rem.*/
  947       /* Send csi assignment for act susi first to the corresponding amfnd. */
  948       if ((SA_AMF_HA_ACTIVE == t_sisu->state) && (true == first_sisu)) {
  949         first_sisu = false;
  950         if (avd_snd_susi_msg(avd_cb, t_sisu->su, t_sisu, AVSV_SUSI_ACT_DEL,
  951                              true, t_csicomp) != NCSCC_RC_SUCCESS) {
  952           LOG_ER("susi send failure for su'%s' and si'%s'",
  953                  t_sisu->su->name.c_str(), t_sisu->si->name.c_str());
  954           goto done;
  955         }
  956       }
  957       t_sisu->csi_add_rem = static_cast<SaBoolT>(true);
  958       t_sisu->comp_name = Amf::to_string(&t_csicomp->comp->comp_info.name);
  959       t_sisu->csi_name = t_csicomp->csi->name;
  960       m_AVSV_SEND_CKPT_UPDT_ASYNC_UPDT(avd_cb, t_sisu, AVSV_CKPT_AVD_SI_ASS);
  961       t_sisu = t_sisu->si_next;
  962     } /* while(t_sisu) */
  963 
  964   } else { /* if (nullptr != csi->si->list_of_sisu) */
  965     csi_cmplt_delete(csi, false);
  966   }
  967 
  968 /* Send pg update and delete csi after all csi gets removed. */
  969 done:
  970   TRACE_LEAVE();
  971 }
  972 
  973 /*****************************************************************************
  974  * Function: csi_ccb_apply_modify_hdlr
  975  *
  976  * Purpose: This routine handles modify operations on SaAmfCSI objects.
  977  *
  978  *
  979  * Input  : Ccb Util Oper Data.
  980  *
  981  * Returns: None.
  982  *
  983  * NOTES  : None.
  984  *
  985  *
  986  **************************************************************************/
  987 static void csi_ccb_apply_modify_hdlr(struct CcbUtilOperationData *opdata) {
  988   const SaImmAttrModificationT_2 *attr_mod;
  989   int i = 0;
  990 
  991   TRACE_ENTER2("CCB ID %llu, '%s'", opdata->ccbId,
  992                osaf_extended_name_borrow(&opdata->objectName));
  993 
  994   AVD_CSI *csi = csi_db->find(Amf::to_string(&opdata->objectName));
  995   if (csi == nullptr && avd_cb->is_active() == false) {
  996     LOG_WA("Csi modify apply (STDBY): csi does not exist");
  997     return;
  998   }
  999   assert(csi != nullptr);
 1000   AVD_SI *si = csi->si;
 1001   assert(si != nullptr);
 1002 
 1003   while ((attr_mod = opdata->param.modify.attrMods[i++]) != nullptr) {
 1004     if (!strcmp(attr_mod->modAttr.attrName, "saAmfCSType")) {
 1005       AVD_CS_TYPE *csi_type;
 1006       SaNameT cstype_name = *(SaNameT *)attr_mod->modAttr.attrValues[0];
 1007       TRACE("saAmfCSType modified from '%s' to '%s' for Csi'%s'",
 1008             csi->saAmfCSType.c_str(), osaf_extended_name_borrow(&cstype_name),
 1009             csi->name.c_str());
 1010       csi_type = cstype_db->find(Amf::to_string(&cstype_name));
 1011       avd_cstype_remove_csi(csi);
 1012       csi->saAmfCSType = Amf::to_string(&cstype_name);
 1013       csi->cstype = csi_type;
 1014       avd_cstype_add_csi(csi);
 1015     } else if (!strcmp(attr_mod->modAttr.attrName,
 1016                        "osafAmfCSICommunicateCsiAttributeChange")) {
 1017       csi->osafAmfCSICommunicateCsiAttributeChange =
 1018           static_cast<bool>(*((bool *)attr_mod->modAttr.attrValues[0]));
 1019       LOG_NO(
 1020           "Modified osafAmfCSICommunicateCsiAttributeChange for '%s' to '%u'",
 1021           csi->name.c_str(), csi->osafAmfCSICommunicateCsiAttributeChange);
 1022     } else if (!strcmp(attr_mod->modAttr.attrName, "saAmfCSIDependencies")) {
 1023       if (attr_mod->modType == SA_IMM_ATTR_VALUES_ADD) {
 1024         assert(attr_mod->modAttr.attrValuesNumber == 1);
 1025         si->remove_csi(csi);
 1026         AVD_CSI_DEPS *new_csi_dep = new AVD_CSI_DEPS();
 1027         new_csi_dep->csi_dep_name_value = Amf::to_string(
 1028             static_cast<SaNameT *>(attr_mod->modAttr.attrValues[0]));
 1029         bool already_exist = csi_add_csidep(csi, new_csi_dep);
 1030         if (already_exist) delete new_csi_dep;
 1031         csi->rank = 0;  // indicate that there is a dep to another CSI
 1032         si->add_csi(csi);
 1033       } else if (attr_mod->modType == SA_IMM_ATTR_VALUES_DELETE) {
 1034         assert(attr_mod->modAttr.attrValuesNumber == 1);
 1035         const SaNameT *required_dn = (SaNameT *)attr_mod->modAttr.attrValues[0];
 1036         csi_remove_csidep(csi, Amf::to_string(required_dn));
 1037 
 1038         // Mark rank of all the CSIs to 0.
 1039         for (AVD_CSI *tmp_csi = csi->si->list_of_csi; tmp_csi;
 1040              tmp_csi = tmp_csi->si_list_of_csi_next) {
 1041           tmp_csi->rank = 0;  // indicate that there is a dep to another CSI
 1042         }
 1043         // Rearrange Rank of all the CSIs now.
 1044         for (AVD_CSI *tmp_csi = csi->si->list_of_csi; tmp_csi;
 1045              tmp_csi = tmp_csi->si_list_of_csi_next) {
 1046           tmp_csi->si->arrange_dep_csi(tmp_csi);
 1047         }
 1048       } else
 1049         assert(0);
 1050     } else {
 1051       osafassert(0);
 1052     }
 1053   }
 1054   TRACE_LEAVE();
 1055 }
 1056 
 1057 /*****************************************************************************
 1058  * Function: csi_ccb_apply_create_hdlr
 1059  *
 1060  * Purpose: This routine handles create operations on SaAmfCSI objects.
 1061  *
 1062  *
 1063  * Input  : Ccb Util Oper Data.
 1064  *
 1065  * Returns: None.
 1066  *
 1067  * NOTES  : None.
 1068  *
 1069  *
 1070  **************************************************************************/
 1071 static void csi_ccb_apply_create_hdlr(struct CcbUtilOperationData *opdata) {
 1072   TRACE_ENTER();
 1073 
 1074   AVD_CSI *csi = nullptr;
 1075   if ((csi = csi_db->find(Amf::to_string(&opdata->objectName))) == nullptr) {
 1076     /* this check is added because, some times there is
 1077        possibility that before getting ccb apply callback
 1078        we might get compcsi create checkpoint and csi will
 1079        be created as part of checkpoint processing */
 1080     csi = csi_create(Amf::to_string(&opdata->objectName));
 1081   }
 1082   csi_get_attr_and_add_to_model(
 1083       csi, opdata->param.create.attrValues,
 1084       Amf::to_string(opdata->param.create.parentName));
 1085 
 1086   if (avd_cb->avail_state_avd != SA_AMF_HA_ACTIVE) goto done;
 1087 
 1088   csi_assign_hdlr(csi);
 1089 
 1090 done:
 1091   TRACE_LEAVE();
 1092 }
 1093 
 1094 /**
 1095  * @brief       Assign csi to component as per compcsi configurations.
 1096  *
 1097  * @param[in]   csi pointer.
 1098  *
 1099  * @return      OK if csi is assigned else NO_OP.
 1100  */
 1101 SaAisErrorT csi_assign_hdlr(AVD_CSI *csi) {
 1102   AVD_COMP *t_comp;
 1103   AVD_SU_SI_REL *t_sisu;
 1104   bool first_sisu = true;
 1105   AVD_COMP_CSI_REL *compcsi;
 1106   SaAisErrorT rc = SA_AIS_ERR_NO_OP;
 1107 
 1108   TRACE_ENTER();
 1109 
 1110   /* Check whether csi assignment is already in progress and if yes, then
 1111      return. This csi will be assigned after the undergoing csi assignment gets
 1112      over.*/
 1113   if (csi->si->list_of_sisu != nullptr) {
 1114     for (t_sisu = csi->si->list_of_sisu; t_sisu != nullptr;
 1115          t_sisu = t_sisu->si_next) {
 1116       if (t_sisu->csi_add_rem == true) {
 1117         LOG_NO("CSI create '%s' delayed: pending assignment for '%s'",
 1118                csi->name.c_str(), t_sisu->su->name.c_str());
 1119         goto done;
 1120       }
 1121     }
 1122   }
 1123 
 1124   /* Check whether si has been assigned to any SU. */
 1125   if (nullptr != csi->si->list_of_sisu) {
 1126     t_sisu = csi->si->list_of_sisu;
 1127     while (t_sisu) {
 1128       /* We need to assign this csi if an extra component exists, which is
 1129        * unassigned.*/
 1130 
 1131       t_sisu->su->reset_all_comps_assign_flag();
 1132 
 1133       compcsi = t_sisu->list_of_csicomp;
 1134       while (compcsi != nullptr) {
 1135         compcsi->comp->set_assigned(true);
 1136         compcsi = compcsi->susi_csicomp_next;
 1137       }
 1138 
 1139       t_comp = t_sisu->su->find_unassigned_comp_that_provides_cstype(
 1140           csi->saAmfCSType);
 1141 
 1142       /* Component not found.*/
 1143       if (nullptr == t_comp) {
 1144         /* This means that all the components are assigned, let us assigned it
 1145            to assigned component.*/
 1146         t_comp = AVD_CSI::find_assigned_comp(csi->saAmfCSType, t_sisu,
 1147                                              t_sisu->su->list_of_comp);
 1148       }
 1149       if (nullptr == t_comp) {
 1150         LOG_ER(
 1151             "Compcsi doesn't exist or MaxActiveCSI/MaxStandbyCSI have reached for csi '%s'",
 1152             csi->name.c_str());
 1153         goto done;
 1154       }
 1155 
 1156       if ((compcsi = avd_compcsi_create(t_sisu, csi, t_comp, true)) ==
 1157           nullptr) {
 1158         /* free all the CSI assignments and end this loop */
 1159         avd_compcsi_delete(avd_cb, t_sisu, true);
 1160         break;
 1161       }
 1162       /* Mark comp-csi and sisu to be under csi add/rem.*/
 1163       /* Send csi assignment for act susi first to the corresponding amfnd. */
 1164       if ((SA_AMF_HA_ACTIVE == t_sisu->state) && (true == first_sisu)) {
 1165         first_sisu = false;
 1166         if (avd_snd_susi_msg(avd_cb, t_sisu->su, t_sisu, AVSV_SUSI_ACT_ASGN,
 1167                              true, compcsi) != NCSCC_RC_SUCCESS) {
 1168           /* free all the CSI assignments and end this loop */
 1169           avd_compcsi_delete(avd_cb, t_sisu, true);
 1170           /* Unassign the SUSI */
 1171           avd_susi_update_assignment_counters(t_sisu, AVSV_SUSI_ACT_DEL,
 1172                                               static_cast<SaAmfHAStateT>(0),
 1173                                               static_cast<SaAmfHAStateT>(0));
 1174           avd_susi_delete(avd_cb, t_sisu, true);
 1175           goto done;
 1176         }
 1177         rc = SA_AIS_OK;
 1178       }
 1179       t_sisu->csi_add_rem = static_cast<SaBoolT>(true);
 1180       t_sisu->comp_name = Amf::to_string(&compcsi->comp->comp_info.name);
 1181       t_sisu->csi_name = compcsi->csi->name;
 1182       m_AVSV_SEND_CKPT_UPDT_ASYNC_UPDT(avd_cb, t_sisu, AVSV_CKPT_AVD_SI_ASS);
 1183       t_sisu = t_sisu->si_next;
 1184     } /* while(t_sisu) */
 1185 
 1186   } /* if (nullptr != csi->si->list_of_sisu) */
 1187   else if (csi->si->saAmfSIAdminState == SA_AMF_ADMIN_UNLOCKED) {
 1188     /* CSI has been added into an SI, now SI can be assigned */
 1189     csi->si->sg_of_si->si_assign(avd_cb, csi->si);
 1190   }
 1191 done:
 1192   TRACE_LEAVE();
 1193   return rc;
 1194 }
 1195 
 1196 static void csi_ccb_apply_cb(CcbUtilOperationData_t *opdata) {
 1197   TRACE_ENTER2("CCB ID %llu, '%s'", opdata->ccbId,
 1198                osaf_extended_name_borrow(&opdata->objectName));
 1199 
 1200   switch (opdata->operationType) {
 1201     case CCBUTIL_CREATE:
 1202       csi_ccb_apply_create_hdlr(opdata);
 1203       break;
 1204     case CCBUTIL_MODIFY:
 1205       csi_ccb_apply_modify_hdlr(opdata);
 1206       break;
 1207     case CCBUTIL_DELETE:
 1208       ccb_apply_delete_hdlr(opdata);
 1209       break;
 1210     default:
 1211       osafassert(0);
 1212       break;
 1213   }
 1214 
 1215   TRACE_LEAVE();
 1216 }
 1217 
 1218 /**
 1219  * Create an SaAmfCSIAssignment runtime object in IMM.
 1220  * @param ha_state
 1221  * @param csi_dn
 1222  * @param comp_dn
 1223  */
 1224 static void avd_create_csiassignment_in_imm(SaAmfHAStateT ha_state,
 1225                                             const std::string &csi_dn,
 1226                                             const std::string &_comp_dn) {
 1227   SaNameT dn;
 1228   SaAmfHAReadinessStateT saAmfCSICompHAReadinessState =
 1229       SA_AMF_HARS_READY_FOR_ASSIGNMENT;
 1230   void *arr1[] = {&dn};
 1231   void *arr2[] = {&ha_state};
 1232   void *arr3[] = {&saAmfCSICompHAReadinessState};
 1233   const SaImmAttrValuesT_2 attr_safCSIComp = {
 1234       const_cast<SaImmAttrNameT>("safCSIComp"), SA_IMM_ATTR_SANAMET, 1, arr1};
 1235   const SaImmAttrValuesT_2 attr_saAmfCSICompHAState = {
 1236       const_cast<SaImmAttrNameT>("saAmfCSICompHAState"), SA_IMM_ATTR_SAUINT32T,
 1237       1, arr2};
 1238   const SaImmAttrValuesT_2 attr_saAmfCSICompHAReadinessState = {
 1239       const_cast<SaImmAttrNameT>("saAmfCSICompHAReadinessState"),
 1240       SA_IMM_ATTR_SAUINT32T, 1, arr3};
 1241   const SaImmAttrValuesT_2 *attrValues[] = {
 1242       &attr_safCSIComp, &attr_saAmfCSICompHAState,
 1243       &attr_saAmfCSICompHAReadinessState, nullptr};
 1244 
 1245   const SaNameTWrapper comp_dn(_comp_dn);
 1246   avsv_create_association_class_dn(comp_dn, nullptr, "safCSIComp", &dn);
 1247 
 1248   TRACE("Adding %s", osaf_extended_name_borrow(&dn));
 1249   avd_saImmOiRtObjectCreate("SaAmfCSIAssignment", csi_dn, attrValues);
 1250   osaf_extended_name_free(&dn);
 1251 }
 1252 
 1253 AVD_COMP_CSI_REL *avd_compcsi_create(AVD_SU_SI_REL *susi, AVD_CSI *csi,
 1254                                      AVD_COMP *comp, bool create_in_imm) {
 1255   AVD_COMP_CSI_REL *compcsi = nullptr;
 1256 
 1257   if ((csi == nullptr) && (comp == nullptr)) {
 1258     LOG_ER("Either csi or comp is nullptr");
 1259     return nullptr;
 1260   }
 1261   TRACE_ENTER2("Comp'%s' and Csi'%s'",
 1262                osaf_extended_name_borrow(&comp->comp_info.name),
 1263                csi->name.c_str());
 1264 
 1265   /* do not add if already in there */
 1266   for (compcsi = susi->list_of_csicomp; compcsi;
 1267        compcsi = compcsi->susi_csicomp_next) {
 1268     if ((compcsi->comp == comp) && (compcsi->csi == csi)) goto done;
 1269   }
 1270 
 1271   compcsi = new AVD_COMP_CSI_REL();
 1272 
 1273   compcsi->comp = comp;
 1274   compcsi->csi = csi;
 1275   compcsi->susi = susi;
 1276 
 1277   /* Add to the CSI owned list */
 1278   if (csi->list_compcsi == nullptr) {
 1279     csi->list_compcsi = compcsi;
 1280   } else {
 1281     compcsi->csi_csicomp_next = csi->list_compcsi;
 1282     csi->list_compcsi = compcsi;
 1283   }
 1284   csi->compcsi_cnt++;
 1285 
 1286   /* Add to the SUSI owned list */
 1287   if (susi->list_of_csicomp == nullptr) {
 1288     susi->list_of_csicomp = compcsi;
 1289   } else {
 1290     compcsi->susi_csicomp_next = susi->list_of_csicomp;
 1291     susi->list_of_csicomp = compcsi;
 1292   }
 1293   if (create_in_imm)
 1294     avd_create_csiassignment_in_imm(susi->state, csi->name,
 1295                                     Amf::to_string(&comp->comp_info.name));
 1296 done:
 1297   TRACE_LEAVE();
 1298   return compcsi;
 1299 }
 1300 
 1301 /** Delete an SaAmfCSIAssignment from IMM
 1302  *
 1303  * @param comp_dn
 1304  * @param csi_dn
 1305  */
 1306 static void avd_delete_csiassignment_from_imm(const std::string &comp_dn,
 1307                                               const std::string &csi_dn) {
 1308   SaNameT dn;
 1309   const SaNameTWrapper comp(comp_dn);
 1310   const SaNameTWrapper csi(csi_dn);
 1311 
 1312   avsv_create_association_class_dn(comp, csi, "safCSIComp", &dn);
 1313   TRACE("Deleting %s", osaf_extended_name_borrow(&dn));
 1314 
 1315   avd_saImmOiRtObjectDelete(Amf::to_string(&dn));
 1316   osaf_extended_name_free(&dn);
 1317 }
 1318 
 1319 /*****************************************************************************
 1320  * Function: avd_compcsi_delete
 1321  *
 1322  * Purpose:  This function will delete and free all the AVD_COMP_CSI_REL
 1323  * structure from the list_of_csicomp in the SUSI relationship
 1324  *
 1325  * Input: cb - the AVD control block
 1326  *        susi - The SU SI relationship structure that encompasses this
 1327  *               component CSI relationship.
 1328  *
 1329  * Returns: NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE .
 1330  *
 1331  * NOTES:
 1332  *
 1333  *
 1334  **************************************************************************/
 1335 
 1336 uint32_t avd_compcsi_delete(AVD_CL_CB *cb, AVD_SU_SI_REL *susi, bool ckpt) {
 1337   AVD_COMP_CSI_REL *lcomp_csi;
 1338   AVD_COMP_CSI_REL *i_compcsi, *prev_compcsi = nullptr;
 1339 
 1340   TRACE_ENTER();
 1341   while (susi->list_of_csicomp != nullptr) {
 1342     lcomp_csi = susi->list_of_csicomp;
 1343 
 1344     i_compcsi = lcomp_csi->csi->list_compcsi;
 1345     while ((i_compcsi != nullptr) && (i_compcsi != lcomp_csi)) {
 1346       prev_compcsi = i_compcsi;
 1347       i_compcsi = i_compcsi->csi_csicomp_next;
 1348     }
 1349     if (i_compcsi != lcomp_csi) {
 1350       /* not found */
 1351     } else {
 1352       if (prev_compcsi == nullptr) {
 1353         lcomp_csi->csi->list_compcsi = i_compcsi->csi_csicomp_next;
 1354       } else {
 1355         prev_compcsi->csi_csicomp_next = i_compcsi->csi_csicomp_next;
 1356       }
 1357       lcomp_csi->csi->compcsi_cnt--;
 1358 
 1359       /* trigger pg upd */
 1360       if (!ckpt) {
 1361         avd_pg_compcsi_chg_prc(cb, lcomp_csi, true);
 1362       }
 1363 
 1364       i_compcsi->csi_csicomp_next = nullptr;
 1365     }
 1366 
 1367     susi->list_of_csicomp = lcomp_csi->susi_csicomp_next;
 1368     lcomp_csi->susi_csicomp_next = nullptr;
 1369     prev_compcsi = nullptr;
 1370     avd_delete_csiassignment_from_imm(
 1371         Amf::to_string(&lcomp_csi->comp->comp_info.name), lcomp_csi->csi->name);
 1372     delete lcomp_csi;
 1373   }
 1374 
 1375   TRACE_LEAVE();
 1376   return NCSCC_RC_SUCCESS;
 1377 }
 1378 
 1379 /*****************************************************************************
 1380  * Function: avd_compcsi_from_csi_and_susi_delete
 1381  *
 1382  * Purpose:  This function will delete and free AVD_COMP_CSI_REL
 1383  * structure from the list_of_csicomp and SUSI.
 1384  *
 1385  * Input: susi - SUSI from where comp-csi need to be deleted.
 1386  *        compcsi - To be deleted.
 1387  *        ckpt - whether this function has been called form checkpoint context.
 1388  * Returns: None.
 1389  *
 1390  * NOTES:
 1391  *
 1392  *
 1393  **************************************************************************/
 1394 void avd_compcsi_from_csi_and_susi_delete(AVD_SU_SI_REL *susi,
 1395                                           AVD_COMP_CSI_REL *comp_csi,
 1396                                           bool ckpt) {
 1397   AVD_COMP_CSI_REL *t_compcsi, *t_compcsi_susi, *prev_compcsi = nullptr;
 1398 
 1399   TRACE_ENTER2("Csi'%s', compcsi_cnt'%u'", comp_csi->csi->name.c_str(),
 1400                comp_csi->csi->compcsi_cnt);
 1401 
 1402   /* Find the comp-csi in susi. */
 1403   t_compcsi_susi = susi->list_of_csicomp;
 1404   while (t_compcsi_susi) {
 1405     if (t_compcsi_susi == comp_csi) break;
 1406     prev_compcsi = t_compcsi_susi;
 1407     t_compcsi_susi = t_compcsi_susi->susi_csicomp_next;
 1408   }
 1409   osafassert(t_compcsi_susi);
 1410   /* Delink the csi from this susi. */
 1411   if (nullptr == prev_compcsi)
 1412     susi->list_of_csicomp = t_compcsi_susi->susi_csicomp_next;
 1413   else {
 1414     prev_compcsi->susi_csicomp_next = t_compcsi_susi->susi_csicomp_next;
 1415     t_compcsi_susi->susi_csicomp_next = nullptr;
 1416   }
 1417 
 1418   prev_compcsi = nullptr;
 1419   /* Find the comp-csi in csi->list_compcsi. */
 1420   t_compcsi = comp_csi->csi->list_compcsi;
 1421   while (t_compcsi) {
 1422     if (t_compcsi == comp_csi) break;
 1423     prev_compcsi = t_compcsi;
 1424     t_compcsi = t_compcsi->csi_csicomp_next;
 1425   }
 1426   osafassert(t_compcsi);
 1427   /* Delink the csi from csi->list_compcsi. */
 1428   if (nullptr == prev_compcsi)
 1429     comp_csi->csi->list_compcsi = t_compcsi->csi_csicomp_next;
 1430   else {
 1431     prev_compcsi->csi_csicomp_next = t_compcsi->csi_csicomp_next;
 1432     t_compcsi->csi_csicomp_next = nullptr;
 1433   }
 1434 
 1435   osafassert(t_compcsi == t_compcsi_susi);
 1436   comp_csi->csi->compcsi_cnt--;
 1437 
 1438   if (!ckpt)
 1439     avd_snd_pg_upd_msg(avd_cb, comp_csi->comp->su->su_on_node, comp_csi,
 1440                        SA_AMF_PROTECTION_GROUP_REMOVED, std::string(""));
 1441   avd_delete_csiassignment_from_imm(
 1442       Amf::to_string(&comp_csi->comp->comp_info.name), comp_csi->csi->name);
 1443   delete comp_csi;
 1444 
 1445   TRACE_LEAVE();
 1446 }
 1447 
 1448 void avd_csi_remove_csiattr(AVD_CSI *csi, AVD_CSI_ATTR *attr) {
 1449   AVD_CSI_ATTR *p_attr = nullptr;
 1450 
 1451   TRACE_ENTER();
 1452   /* remove ATTR from CSI list */
 1453   AVD_CSI_ATTR *i_attr = csi->list_attributes;
 1454 
 1455   while ((i_attr != nullptr) && (i_attr != attr)) {
 1456     p_attr = i_attr;
 1457     i_attr = i_attr->attr_next;
 1458   }
 1459 
 1460   if (i_attr != attr) {
 1461     /* Log a fatal error */
 1462     osafassert(0);
 1463   } else {
 1464     if (p_attr == nullptr) {
 1465       csi->list_attributes = i_attr->attr_next;
 1466     } else {
 1467       p_attr->attr_next = i_attr->attr_next;
 1468       osaf_extended_name_free(&attr->name_value.name);
 1469       osaf_extended_name_free(&attr->name_value.value);
 1470       delete[] attr->name_value.string_ptr;
 1471       delete attr;
 1472     }
 1473   }
 1474 
 1475   osafassert(csi->num_attributes > 0);
 1476   csi->num_attributes--;
 1477   TRACE_LEAVE();
 1478 }
 1479 
 1480 void avd_csi_add_csiattr(AVD_CSI *csi, AVD_CSI_ATTR *csiattr) {
 1481   int cnt = 1;
 1482   AVD_CSI_ATTR *ptr;
 1483 
 1484   TRACE_ENTER();
 1485   /* Count number of attributes (multivalue) */
 1486   ptr = csiattr;
 1487   osafassert(ptr != nullptr);
 1488   while (ptr->attr_next != nullptr) {
 1489     cnt++;
 1490     ptr = ptr->attr_next;
 1491   }
 1492 
 1493   ptr->attr_next = csi->list_attributes;
 1494   csi->list_attributes = csiattr;
 1495   csi->num_attributes += cnt;
 1496   TRACE_LEAVE();
 1497 }
 1498 
 1499 void avd_csi_constructor(void) {
 1500   csi_db = new AmfDb<std::string, AVD_CSI>;
 1501   avd_class_impl_set("SaAmfCSI", nullptr, nullptr, csi_ccb_completed_cb,
 1502                      csi_ccb_apply_cb);
 1503 }
 1504 
 1505 /**
 1506  * @brief       Check whether the Single csi assignment is undergoing on the SG.
 1507  *
 1508  * @param[in]   sg - Pointer to the Service Group.
 1509  *
 1510  * @return      true if operation is undergoing else false.
 1511  */
 1512 bool csi_assignment_validate(AVD_SG *sg) {
 1513   AVD_SU_SI_REL *temp_sisu;
 1514 
 1515   for (const auto &temp_si : sg->list_of_si)
 1516     for (temp_sisu = temp_si->list_of_sisu; temp_sisu;
 1517          temp_sisu = temp_sisu->si_next)
 1518       if (temp_sisu->csi_add_rem == true) return true;
 1519   return false;
 1520 }
 1521 
 1522 /**
 1523  * @brief       Checks if sponsor CSIs of any CSI are assigned to any comp in
 1524  * this SU.
 1525  *
 1526  * @param[in]   ptr to CSI.
 1527  * @param[in]   ptr to SU.
 1528  *
 1529  * @return      true/false.
 1530  */
 1531 bool are_sponsor_csis_assigned_in_su(AVD_CSI *csi, AVD_SU *su) {
 1532   for (AVD_CSI_DEPS *spons_csi = csi->saAmfCSIDependencies;
 1533        spons_csi != nullptr; spons_csi = spons_csi->csi_dep_next) {
 1534     bool is_sponsor_assigned = false;
 1535 
 1536     AVD_CSI *tmp_csi = csi_db->find(spons_csi->csi_dep_name_value);
 1537 
 1538     // Check if this sponsor csi is assigned to any comp in this su.
 1539     for (AVD_COMP_CSI_REL *compcsi = tmp_csi->list_compcsi; compcsi;
 1540          compcsi = compcsi->csi_csicomp_next) {
 1541       if (compcsi->comp->su == su) is_sponsor_assigned = true;
 1542     }
 1543     // Return false if this sponsor is not assigned to this SU.
 1544     if (is_sponsor_assigned == false) return false;
 1545   }
 1546   return true;
 1547 }
 1548 
 1549 /**
 1550  * Clean up COMPCSI objects by searching for SaAmfCSIAssignment instances in IMM
 1551  * @return SA_AIS_OK when OK
 1552  */
 1553 /**
 1554  * Re-create csi assignment and update comp related states, which are
 1555  * collected after headless
 1556  * Update relevant runtime attributes
 1557  * @return SA_AIS_OK when OK
 1558  */
 1559 SaAisErrorT avd_compcsi_recreate(AVSV_N2D_ND_CSICOMP_STATE_MSG_INFO *info) {
 1560   AVD_COMP *comp;
 1561   AVD_CSI *csi;
 1562   const AVSV_CSICOMP_STATE_MSG *csicomp;
 1563   const AVSV_COMP_STATE_MSG *comp_state;
 1564 
 1565   TRACE_ENTER();
 1566 
 1567   AVD_AVND *node = avd_node_find_nodeid(info->node_id);
 1568   if (node == 0) {
 1569     LOG_ER("Node %" PRIx32 " has left the cluster", info->node_id);
 1570     return SA_AIS_ERR_NOT_EXIST;
 1571   }
 1572 
 1573   for (csicomp = info->csicomp_list; csicomp != nullptr;
 1574        csicomp = csicomp->next) {
 1575     csi = csi_db->find(Amf::to_string(&csicomp->safCSI));
 1576     osafassert(csi);
 1577 
 1578     comp = comp_db->find(Amf::to_string(&csicomp->safComp));
 1579     osafassert(comp);
 1580 
 1581     TRACE("Received CSICOMP state msg: csi %s, comp %s",
 1582           osaf_extended_name_borrow(&csicomp->safCSI),
 1583           osaf_extended_name_borrow(&csicomp->safComp));
 1584 
 1585     const AVD_SI *si = csi->si;
 1586     osafassert(si);
 1587 
 1588     AVD_SU_SI_REL *susi = avd_susi_find(avd_cb, comp->su->name, si->name);
 1589     if (susi == 0) {
 1590       LOG_ER("SU_SI_REL record for SU '%s' and SI '%s' was not found",
 1591              comp->su->name.c_str(), si->name.c_str());
 1592       return SA_AIS_ERR_NOT_EXIST;
 1593     }
 1594 
 1595     AVD_COMP_CSI_REL *compcsi = avd_compcsi_create(susi, csi, comp, true);
 1596     osafassert(compcsi);
 1597   }
 1598 
 1599   for (comp_state = info->comp_list; comp_state != nullptr;
 1600        comp_state = comp_state->next) {
 1601     comp = comp_db->find(Amf::to_string(&comp_state->safComp));
 1602     osafassert(comp);
 1603 
 1604     // operation state
 1605     comp->avd_comp_oper_state_set(
 1606         static_cast<SaAmfOperationalStateT>(comp_state->comp_oper_state));
 1607 
 1608     // . update saAmfCompReadinessState after SU:saAmfSuReadinessState
 1609     // . saAmfCompCurrProxyName and saAmfCompCurrProxiedNames wouldn't change
 1610     // during headless
 1611     //   so they need not to update
 1612 
 1613     // presense state
 1614     comp->avd_comp_pres_state_set(
 1615         static_cast<SaAmfPresenceStateT>(comp_state->comp_pres_state));
 1616 
 1617     // restart count
 1618     comp->saAmfCompRestartCount = comp_state->comp_restart_cnt;
 1619     m_AVSV_SEND_CKPT_UPDT_ASYNC_UPDT(avd_cb, comp,
 1620                                      AVSV_CKPT_COMP_RESTART_COUNT);
 1621     avd_saImmOiRtObjectUpdate(
 1622         Amf::to_string(&comp->comp_info.name),
 1623         const_cast<SaImmAttrNameT>("saAmfCompRestartCount"),
 1624         SA_IMM_ATTR_SAUINT32T, &comp->saAmfCompRestartCount);
 1625   }
 1626 
 1627   TRACE_LEAVE();
 1628   return SA_AIS_OK;
 1629 }
 1630 
 1631 void avd_compcsi_cleanup_imm_object(AVD_CL_CB *cb) {
 1632   SaAisErrorT rc;
 1633   SaImmSearchHandleT searchHandle;
 1634   SaImmSearchParametersT_2 searchParam;
 1635 
 1636   SaNameT dn;
 1637   const SaImmAttrValuesT_2 **attributes;
 1638   AVD_SU_SI_REL *susi;
 1639 
 1640   const char *className = "SaAmfCSIAssignment";
 1641   const SaImmAttrNameT siass_attributes[] = {
 1642       const_cast<SaImmAttrNameT>("safCSIComp"), NULL};
 1643 
 1644   TRACE_ENTER();
 1645 
 1646   osafassert(cb->scs_absence_max_duration > 0);
 1647 
 1648   searchParam.searchOneAttr.attrName =
 1649       const_cast<SaImmAttrNameT>("SaImmAttrClassName");
 1650   searchParam.searchOneAttr.attrValueType = SA_IMM_ATTR_SASTRINGT;
 1651   searchParam.searchOneAttr.attrValue = &className;
 1652 
 1653   if ((rc = immutil_saImmOmSearchInitialize_2(
 1654            cb->immOmHandle, NULL, SA_IMM_SUBTREE,
 1655            SA_IMM_SEARCH_ONE_ATTR | SA_IMM_SEARCH_GET_SOME_ATTR, &searchParam,
 1656            siass_attributes, &searchHandle)) != SA_AIS_OK) {
 1657     LOG_ER("%s: saImmOmSearchInitialize_2 failed: %u", __FUNCTION__, rc);
 1658     goto done;
 1659   }
 1660 
 1661   while ((rc = immutil_saImmOmSearchNext_2(
 1662               searchHandle, &dn, (SaImmAttrValuesT_2 ***)&attributes)) ==
 1663          SA_AIS_OK) {
 1664     AVD_SI *si = si_db->find(strstr(osaf_extended_name_borrow(&dn), "safSi"));
 1665     osafassert(si);
 1666 
 1667     AVD_CSI *csi =
 1668         csi_db->find(strstr(osaf_extended_name_borrow(&dn), "safCsi"));
 1669     osafassert(csi);
 1670     SaNameT comp_name;
 1671     avsv_sanamet_init_from_association_dn(&dn, &comp_name, "safComp",
 1672                                           csi->name.c_str());
 1673     AVD_COMP *comp = comp_db->find(Amf::to_string(&comp_name));
 1674     if (comp == nullptr) {
 1675       LOG_WA("Component %s not found in comp_db",
 1676              osaf_extended_name_borrow(&comp_name));
 1677       osaf_extended_name_free(&comp_name);
 1678       continue;
 1679     }
 1680     osaf_extended_name_free(&comp_name);
 1681 
 1682     susi = avd_susi_find(avd_cb, comp->su->name, si->name);
 1683     if (susi == nullptr || (susi->fsm == AVD_SU_SI_STATE_ABSENT)) {
 1684       avd_saImmOiRtObjectDelete(Amf::to_string(&dn));
 1685     }
 1686   }
 1687 
 1688   (void)immutil_saImmOmSearchFinalize(searchHandle);
 1689 
 1690 done:
 1691   TRACE_LEAVE();
 1692 }
 1693 
 1694 bool AVD_CSI::is_container_csi(void) const {
 1695   auto iter(container_csis.find(name));
 1696   return (iter != container_csis.end()) ? true : false;
 1697 }