This ticket adds support for container/contained.
---
 src/amf/amfnd/amfnd.cc    |   5 ++-
 src/amf/amfnd/avnd_cb.h   |   2 +
 src/amf/amfnd/avnd_comp.h |  64 +++++++++++++++++++++--------
 src/amf/amfnd/avnd_evt.h  |   1 +
 src/amf/amfnd/avnd_mds.h  |   4 +-
 src/amf/amfnd/avnd_proc.h |   2 +
 src/amf/amfnd/avnd_su.h   |   4 ++
 src/amf/amfnd/cbq.cc      | 102 ++++++++++++++++++++++++++++++----------------
 src/amf/amfnd/chc.cc      |   2 +-
 src/amf/amfnd/clc.cc      |  95 ++++++++++++++++++++++++++++++++++++++++--
 src/amf/amfnd/comp.cc     |  90 ++++++++++++++++++++++++++++++++++++----
 src/amf/amfnd/compdb.cc   |  22 +++++++++-
 src/amf/amfnd/err.cc      |   2 +-
 src/amf/amfnd/evt.cc      |   2 +
 src/amf/amfnd/main.cc     |   1 +
 src/amf/amfnd/mds.cc      |  23 ++++++++++-
 src/amf/amfnd/proxy.cc    |   2 +-
 src/amf/amfnd/su.cc       |   8 ++++
 src/amf/amfnd/susm.cc     |  88 ++++++++++++++++++++++++++++++++++++---
 19 files changed, 440 insertions(+), 79 deletions(-)

diff --git a/src/amf/amfnd/amfnd.cc b/src/amf/amfnd/amfnd.cc
index 3ac3f8fb0..9e8739bee 100644
--- a/src/amf/amfnd/amfnd.cc
+++ b/src/amf/amfnd/amfnd.cc
@@ -30,6 +30,7 @@
 // Remember MDS install version of Agents. It can be used to send msg to Agent
 // based on their versions.
 std::map<MDS_DEST, MDS_SVC_PVT_SUB_PART_VER> agent_mds_ver_db;
+std::set<std::string> container_csis;
 extern const AVND_EVT_HDLR g_avnd_func_list[AVND_EVT_MAX];
 
 static uint32_t avnd_evt_avnd_avnd_api_msg_hdl(AVND_CB *cb, AVND_EVT *evt);
@@ -78,7 +79,7 @@ uint32_t avnd_evt_avnd_avnd_evh(AVND_CB *cb, AVND_EVT *evt) {
       goto done;
     }
 
-    avnd_comp_cbq_rec_pop_and_del(cb, o_comp, cbk_rec, false);
+    avnd_comp_cbq_rec_pop_and_del(cb, o_comp, cbk_rec->opq_hdl, false);
     goto done;
   }
 
@@ -373,7 +374,7 @@ uint32_t avnd_evt_avnd_avnd_cbk_msg_hdl(AVND_CB *cb, 
AVND_EVT *evt) {
     /* pop & delete */
     uint32_t found;
 
-    m_AVND_COMP_CBQ_REC_POP(comp, rec, found);
+    rec = avnd_comp_cbq_rec_pop(comp, rec->opq_hdl, found);
     rec->cbk_info = 0;
     if (found) avnd_comp_cbq_rec_del(cb, comp, rec);
   }
diff --git a/src/amf/amfnd/avnd_cb.h b/src/amf/amfnd/avnd_cb.h
index ff21e3108..8b0cc2304 100644
--- a/src/amf/amfnd/avnd_cb.h
+++ b/src/amf/amfnd/avnd_cb.h
@@ -33,6 +33,7 @@
 #ifndef AMF_AMFND_AVND_CB_H_
 #define AMF_AMFND_AVND_CB_H_
 #include <map>
+#include <set>
 #include <vector>
 
 typedef struct avnd_cb_tag {
@@ -151,5 +152,6 @@ void cb_increment_su_failover_count(AVND_CB &cb, const 
AVND_SU &su);
 
 extern AVND_CB *avnd_cb;
 extern std::map<MDS_DEST, MDS_SVC_PVT_SUB_PART_VER> agent_mds_ver_db;
+extern std::set<std::string> container_csis;
 
 #endif  // AMF_AMFND_AVND_CB_H_
diff --git a/src/amf/amfnd/avnd_comp.h b/src/amf/amfnd/avnd_comp.h
index 611e90e11..b02e704a4 100644
--- a/src/amf/amfnd/avnd_comp.h
+++ b/src/amf/amfnd/avnd_comp.h
@@ -31,6 +31,7 @@
 #define AMF_AMFND_AVND_COMP_H_
 
 #include <bitset>
+#include <vector>
 
 struct avnd_cb_tag;
 struct avnd_su_si_rec;
@@ -72,6 +73,7 @@ typedef enum avnd_comp_clc_pres_fsm_ev {
   AVND_COMP_CLC_PRES_FSM_EV_CLEANUP_FAIL,
   AVND_COMP_CLC_PRES_FSM_EV_RESTART,
   AVND_COMP_CLC_PRES_FSM_EV_ORPH,
+  AVND_COMP_CLC_PRES_FSM_EV_INST_TRY_AGAIN,
   AVND_COMP_CLC_PRES_FSM_EV_MAX
 } AVND_COMP_CLC_PRES_FSM_EV;
 
@@ -324,6 +326,7 @@ typedef struct avnd_comp_tag {
 
   std::string name; /* comp name */
   std::string saAmfCompType;
+  std::string saAmfCompContainerCsi;
   uint32_t numOfCompCmdEnv;   /* number of comp command environment variables 
*/
   SaStringT *saAmfCompCmdEnv; /* comp command environment variables */
   uint32_t inst_level;        /* comp instantiation level */
@@ -384,6 +387,9 @@ typedef struct avnd_comp_tag {
 
   struct avnd_comp_tag *pxy_comp; /* ptr to the proxy comp (if any) */
 
+  // list of associated contained sus.
+  std::vector<avnd_su_tag *> list_of_contained_sus;
+
   AVND_COMP_CLC_PRES_FSM_EV
       pend_evt; /* stores last fsm event got in orph state */
 
@@ -412,6 +418,9 @@ typedef struct avnd_comp_tag {
   SaInvocationT
       term_cbq_inv_value; /* invocation value for termination callback. */
   SaVersionT version;     // SAF version of comp.
+
+  bool container(void) const;
+  bool contained(void) const;
 } AVND_COMP;
 
 #define AVND_COMP_NULL ((AVND_COMP *)0)
@@ -457,6 +466,8 @@ typedef struct avnd_comp_tag {
 #define AVND_COMP_TYPE_PROXIED 0x00000004
 #define AVND_COMP_TYPE_PREINSTANTIABLE 0x00000008
 #define AVND_COMP_TYPE_SAAWARE 0x00000010
+#define AVND_COMP_TYPE_CONTAINER 0x00000020
+#define AVND_COMP_TYPE_CONTAINED 0x00000040
 
 /* component state (comp-reg, failed etc.) values */
 #define AVND_COMP_FLAG_REG 0x00000100
@@ -492,6 +503,8 @@ typedef struct avnd_comp_tag {
 #define m_AVND_COMP_TYPE_IS_PREINSTANTIABLE(x) \
   (((x)->flag) & AVND_COMP_TYPE_PREINSTANTIABLE)
 #define m_AVND_COMP_TYPE_IS_SAAWARE(x) (((x)->flag) & AVND_COMP_TYPE_SAAWARE)
+#define m_AVND_COMP_TYPE_IS_CONTAINER(x) (((x)->flag) & 
AVND_COMP_TYPE_CONTAINER)
+#define m_AVND_COMP_TYPE_IS_CONTAINED(x) (((x)->flag) & 
AVND_COMP_TYPE_CONTAINED)
 
 /* macros for setting the comp types */
 #define m_AVND_COMP_TYPE_SET(x, bitmap) (((x)->flag) |= (bitmap))
@@ -800,25 +813,29 @@ void m_AVND_COMP_OPER_STATE_AVD_SYNC(struct avnd_cb_tag 
*cb,
       (o_rec) = 0;                             \
   }
 
-/* macro to pop a given callback record from the list */
-#define m_AVND_COMP_CBQ_REC_POP(comp, rec, o_found)         \
-  {                                                         \
-    AVND_COMP_CBK *prv = (comp)->cbk_list, *curr;           \
-    o_found = false;                                        \
-    for (curr = (comp)->cbk_list; curr && !(curr == (rec)); \
-         prv = curr, curr = curr->next)                     \
-      ;                                                     \
-    if (curr) {                                             \
-      /* found the record... pop it */                      \
-      o_found = true;                                       \
-      if (curr == (comp)->cbk_list)                         \
-        (comp)->cbk_list = curr->next;                      \
-      else                                                  \
-        prv->next = curr->next;                             \
-      curr->next = 0;                                       \
-    }                                                       \
+/* inline function to pop a given callback record from the list */
+inline AVND_COMP_CBK * avnd_comp_cbq_rec_pop(AVND_COMP *comp,
+                                             uint32_t opq_hdl,
+                                             uint32_t& o_found) {
+  AVND_COMP_CBK *prv = comp->cbk_list, *curr, *rec(0);
+  o_found = false;
+  for (curr = comp->cbk_list; curr && (curr->opq_hdl != opq_hdl);
+       prv = curr, curr = curr->next)
+    ;
+  if (curr) {
+    /* found the record... pop it */
+    o_found = true;
+    rec = curr;
+    if (curr == comp->cbk_list)
+      comp->cbk_list = curr->next;
+    else
+      prv->next = curr->next;
+    curr->next = 0;
   }
 
+  return rec;
+}
+
 /* macro to get the callback record with the same inv value */
 /* note that inv value is derived from the hdl mngr */
 #define m_AVND_COMP_CBQ_INV_GET(comp, invc, o_rec)         \
@@ -860,7 +877,7 @@ extern void avnd_comp_hc_rec_del_all(struct avnd_cb_tag *, 
AVND_COMP *);
 
 extern void avnd_comp_cbq_del(struct avnd_cb_tag *, AVND_COMP *, bool);
 extern void avnd_comp_cbq_rec_pop_and_del(struct avnd_cb_tag *, AVND_COMP *,
-                                          AVND_COMP_CBK *, bool);
+                                          uint32_t opq_hdl, bool);
 extern AVND_COMP_CBK *avnd_comp_cbq_rec_add(struct avnd_cb_tag *, AVND_COMP *,
                                             AVSV_AMF_CBK_INFO *, MDS_DEST *,
                                             SaTimeT);
@@ -1012,5 +1029,16 @@ void avnd_amf_pxied_comp_inst_cbk_fill(AVSV_AMF_CBK_INFO 
*cbk,
                                        const std::string &cn);
 void avnd_amf_pxied_comp_clean_cbk_fill(AVSV_AMF_CBK_INFO *cbk,
                                         const std::string &cn);
+void avnd_amf_contained_comp_inst_cbk_fill(AVSV_AMF_CBK_INFO *cbk,
+                                       const std::string &cn);
+void avnd_amf_contained_comp_clean_cbk_fill(AVSV_AMF_CBK_INFO *cbk,
+                                       const std::string &cn);
+
+AVND_COMP * avnd_get_comp_from_csi(avnd_cb_tag *, const std::string& csi);
+
+inline AVND_COMP * get_associated_container_comp(avnd_cb_tag *cb,
+                                                 const AVND_COMP *comp) {
+  return avnd_get_comp_from_csi(cb, comp->saAmfCompContainerCsi);
+}
 
 #endif  // AMF_AMFND_AVND_COMP_H_
diff --git a/src/amf/amfnd/avnd_evt.h b/src/amf/amfnd/avnd_evt.h
index be3fd4833..7b79629dc 100644
--- a/src/amf/amfnd/avnd_evt.h
+++ b/src/amf/amfnd/avnd_evt.h
@@ -53,6 +53,7 @@ typedef enum avnd_evt_type {
   AVND_EVT_AVD_HEARTBEAT_MSG,
   AVND_EVT_AVD_REBOOT_MSG,
   AVND_EVT_AVD_COMPCSI_ASSIGN_MSG,
+  AVND_EVT_AVD_CONTAINED_SU_MSG,
   AVND_EVT_AVD_MAX,
 
   /* AvA event types */
diff --git a/src/amf/amfnd/avnd_mds.h b/src/amf/amfnd/avnd_mds.h
index 398825c8d..14dbf9e11 100644
--- a/src/amf/amfnd/avnd_mds.h
+++ b/src/amf/amfnd/avnd_mds.h
@@ -33,10 +33,10 @@
 #define AMF_AMFND_AVND_MDS_H_
 
 /* In Service upgrade support */
-#define AVND_MDS_SUB_PART_VERSION 7
+#define AVND_MDS_SUB_PART_VERSION 8
 
 #define AVND_AVD_SUBPART_VER_MIN 1
-#define AVND_AVD_SUBPART_VER_MAX 7
+#define AVND_AVD_SUBPART_VER_MAX 8
 
 #define AVND_AVND_SUBPART_VER_MIN 1
 #define AVND_AVND_SUBPART_VER_MAX 1
diff --git a/src/amf/amfnd/avnd_proc.h b/src/amf/amfnd/avnd_proc.h
index 8d5bea3c4..24dc988be 100644
--- a/src/amf/amfnd/avnd_proc.h
+++ b/src/amf/amfnd/avnd_proc.h
@@ -147,5 +147,7 @@ uint32_t avnd_evt_tmr_sc_absence_evh(struct avnd_cb_tag *,
                                      struct avnd_evt_tag *);
 uint32_t avnd_evt_avd_reboot_evh(struct avnd_cb_tag *, struct avnd_evt_tag *);
 uint32_t avnd_amfa_mds_info_evh(struct avnd_cb_tag *, struct avnd_evt_tag *);
+uint32_t avnd_evt_avd_contained_su_evh(struct avnd_cb_tag *,
+                                       struct avnd_evt_tag *);
 
 #endif  // AMF_AMFND_AVND_PROC_H_
diff --git a/src/amf/amfnd/avnd_su.h b/src/amf/amfnd/avnd_su.h
index c1df8f8fd..45effd6c9 100644
--- a/src/amf/amfnd/avnd_su.h
+++ b/src/amf/amfnd/avnd_su.h
@@ -168,6 +168,10 @@ typedef struct avnd_su_tag {
   bool avnd_su_check_sis_previous_assign_state(
       const AVND_SU_SI_ASSIGN_STATE prev_state) const;
 
+  //Members related to container and containd functionality.
+  std::string container_su_name; /* su name */
+  bool contained(void) const;
+  void update_container_comp(void);
 } AVND_SU;
 
 #define AVND_SU_NULL ((AVND_SU *)0)
diff --git a/src/amf/amfnd/cbq.cc b/src/amf/amfnd/cbq.cc
index 5e087a63b..8d8cc35d6 100644
--- a/src/amf/amfnd/cbq.cc
+++ b/src/amf/amfnd/cbq.cc
@@ -135,7 +135,7 @@ uint32_t avnd_evt_ava_csi_quiescing_compl_evh(AVND_CB *cb, 
AVND_EVT *evt) {
            invocation handle in the response with the original one. Check
            function avnd_evt_avnd_avnd_cbk_msg_hdl()'s comments */
         qsc->inv = cbk_rec->orig_opq_hdl;
-        avnd_comp_cbq_rec_pop_and_del(cb, comp, cbk_rec, false);
+        avnd_comp_cbq_rec_pop_and_del(cb, comp, cbk_rec->opq_hdl, false);
 
         /* We need to forward this req to other AvND */
         /* Before sending api_info, we need to overwrite the component name as
@@ -326,7 +326,7 @@ uint32_t avnd_evt_ava_resp_evh(AVND_CB *cb, AVND_EVT *evt) {
             (SA_AMF_HA_QUIESCING == cbk_rec->cbk_info->param.csi_set.ha)) {
           /* Don't delete the callback. */
         } else {
-          avnd_comp_cbq_rec_pop_and_del(cb, comp, cbk_rec, false);
+          avnd_comp_cbq_rec_pop_and_del(cb, comp, cbk_rec->opq_hdl, false);
         }
 
         /* We need to forward this req to other AvND */
@@ -370,7 +370,7 @@ uint32_t avnd_evt_ava_resp_evh(AVND_CB *cb, AVND_EVT *evt) {
         }
       } else {
         /* comp is healthy.. remove the cbk record */
-        avnd_comp_cbq_rec_pop_and_del(cb, comp, cbk_rec, false);
+        avnd_comp_cbq_rec_pop_and_del(cb, comp, cbk_rec->opq_hdl, false);
 
         if (hc_rec) {
           if (hc_rec->status == AVND_COMP_HC_STATUS_SND_TMR_EXPD) {
@@ -399,16 +399,20 @@ uint32_t avnd_evt_ava_resp_evh(AVND_CB *cb, AVND_EVT 
*evt) {
          any body, follow the clc. No need to check for PI along with
          proxied, because in case of PI only, term response will come
          back from component. */
-      if ((SA_AIS_OK == resp->err) && (!m_AVND_COMP_TYPE_IS_PROXIED(comp))) {
+
+      // XXX TODO_70: container and contained can be same process or different 
process.
+      if ((SA_AIS_OK == resp->err) && (!m_AVND_COMP_TYPE_IS_PROXIED(comp) &&
+          (comp->contained() == false))) {
         /* Save invocation value to delete cbq record when
            down event comes. */
         comp->term_cbq_inv_value = resp->inv;
       } else {
+        uint32_t opq_hdl(cbk_rec->opq_hdl);
         rc = avnd_comp_clc_fsm_run(cb, comp,
                                    (SA_AIS_OK == resp->err)
                                        ? AVND_COMP_CLC_PRES_FSM_EV_TERM_SUCC
                                        : AVND_COMP_CLC_PRES_FSM_EV_CLEANUP);
-        avnd_comp_cbq_rec_pop_and_del(cb, comp, cbk_rec, false);
+        avnd_comp_cbq_rec_pop_and_del(cb, comp, opq_hdl, false);
       }
 
       // if all OK send a response to the client
@@ -428,7 +432,7 @@ uint32_t avnd_evt_ava_resp_evh(AVND_CB *cb, AVND_EVT *evt) {
         LOG_ER("'%s', not found",
                osaf_extended_name_borrow(
                    &cbk_rec->cbk_info->param.csi_attr_change.csi_name));
-      avnd_comp_cbq_rec_pop_and_del(cb, comp, cbk_rec, false);
+      avnd_comp_cbq_rec_pop_and_del(cb, comp, cbk_rec->opq_hdl, false);
       if (m_AVND_TMR_IS_ACTIVE(cbk_rec->resp_tmr)) {
         m_AVND_TMR_COMP_CBK_RESP_STOP(cb, *cbk_rec)
       }
@@ -446,11 +450,12 @@ uint32_t avnd_evt_ava_resp_evh(AVND_CB *cb, AVND_EVT 
*evt) {
       if (m_AVND_COMP_TYPE_IS_PROXIED(comp) &&
           !m_AVND_COMP_TYPE_IS_PREINSTANTIABLE(comp)) {
         /* trigger comp-fsm & delete the record */
+        uint32_t opq_hdl(cbk_rec->opq_hdl);
         rc = avnd_comp_clc_fsm_run(cb, comp,
                                    (SA_AIS_OK == resp->err)
                                        ? AVND_COMP_CLC_PRES_FSM_EV_INST_SUCC
                                        : AVND_COMP_CLC_PRES_FSM_EV_INST_FAIL);
-        avnd_comp_cbq_rec_pop_and_del(cb, comp, cbk_rec, false);
+        avnd_comp_cbq_rec_pop_and_del(cb, comp, opq_hdl, false);
         if (NCSCC_RC_SUCCESS != rc) goto done;
         break;
       }
@@ -473,14 +478,14 @@ uint32_t avnd_evt_ava_resp_evh(AVND_CB *cb, AVND_EVT 
*evt) {
         AVND_COMP_CSI_REC *temp_csi = m_AVND_COMPDB_REC_CSI_GET_FIRST(*comp);
 
         if (cbk_rec->cbk_info->param.csi_set.ha != temp_csi->si->curr_state) {
-          avnd_comp_cbq_rec_pop_and_del(cb, comp, cbk_rec, false);
+          avnd_comp_cbq_rec_pop_and_del(cb, comp, cbk_rec->opq_hdl, false);
           break;
         }
       } else if (cbk_rec->cbk_info->param.csi_set.ha != csi->si->curr_state) {
-        avnd_comp_cbq_rec_pop_and_del(cb, comp, cbk_rec, false);
+        avnd_comp_cbq_rec_pop_and_del(cb, comp, cbk_rec->opq_hdl, false);
         break;
       } else if (m_AVND_COMP_IS_ALL_CSI(comp)) {
-        avnd_comp_cbq_rec_pop_and_del(cb, comp, cbk_rec, false);
+        avnd_comp_cbq_rec_pop_and_del(cb, comp, cbk_rec->opq_hdl, false);
         break;
       }
 
@@ -515,11 +520,12 @@ uint32_t avnd_evt_ava_resp_evh(AVND_CB *cb, AVND_EVT 
*evt) {
       if (m_AVND_COMP_TYPE_IS_PROXIED(comp) &&
           !m_AVND_COMP_TYPE_IS_PREINSTANTIABLE(comp)) {
         /* trigger comp-fsm & delete the record */
+        uint32_t opq_hdl(cbk_rec->opq_hdl);
         rc = avnd_comp_clc_fsm_run(cb, comp,
                                    (SA_AIS_OK == resp->err)
                                        ? AVND_COMP_CLC_PRES_FSM_EV_TERM_SUCC
                                        : AVND_COMP_CLC_PRES_FSM_EV_CLEANUP);
-        avnd_comp_cbq_rec_pop_and_del(cb, comp, cbk_rec, false);
+        avnd_comp_cbq_rec_pop_and_del(cb, comp, opq_hdl, false);
         break;
       }
 
@@ -552,24 +558,52 @@ uint32_t avnd_evt_ava_resp_evh(AVND_CB *cb, AVND_EVT 
*evt) {
 
       break;
 
-    case AVSV_AMF_PXIED_COMP_INST:
-      /* trigger comp-fsm & delete the record */
-      rc = avnd_comp_clc_fsm_run(cb, comp,
-                                 (SA_AIS_OK == resp->err)
-                                     ? AVND_COMP_CLC_PRES_FSM_EV_INST_SUCC
-                                     : AVND_COMP_CLC_PRES_FSM_EV_INST_FAIL);
-      avnd_comp_cbq_rec_pop_and_del(cb, comp, cbk_rec, false);
+    case AVSV_AMF_PXIED_COMP_INST: {
+        /* trigger comp-fsm & delete the record */
+        uint32_t opq_hdl(cbk_rec->opq_hdl);
+        rc = avnd_comp_clc_fsm_run(cb, comp,
+                                   (SA_AIS_OK == resp->err)
+                                       ? AVND_COMP_CLC_PRES_FSM_EV_INST_SUCC
+                                       : AVND_COMP_CLC_PRES_FSM_EV_INST_FAIL);
+        avnd_comp_cbq_rec_pop_and_del(cb, comp, opq_hdl, false);
+      }
       break;
 
-    case AVSV_AMF_PXIED_COMP_CLEAN:
-      /* trigger comp-fsm & delete the record */
+    case AVSV_AMF_PXIED_COMP_CLEAN: {
+        /* trigger comp-fsm & delete the record */
+        uint32_t opq_hdl(cbk_rec->opq_hdl);
+        rc = avnd_comp_clc_fsm_run(cb, comp,
+                                   (SA_AIS_OK == resp->err)
+                                       ? AVND_COMP_CLC_PRES_FSM_EV_CLEANUP_SUCC
+                                       : 
AVND_COMP_CLC_PRES_FSM_EV_CLEANUP_FAIL);
+        avnd_comp_cbq_rec_pop_and_del(cb, comp, opq_hdl, false);
+      }
+      break;
+
+    case AVSV_AMF_CONTAINED_COMP_INST: {
+      AVND_COMP_CLC_PRES_FSM_EV event(AVND_COMP_CLC_PRES_FSM_EV_INST_SUCC);
+
+      uint32_t opq_hdl(cbk_rec->opq_hdl);
+      if (resp->err == SA_AIS_ERR_TRY_AGAIN)
+        event = AVND_COMP_CLC_PRES_FSM_EV_INST_TRY_AGAIN;
+      else if (resp->err != SA_AIS_OK)
+        event = AVND_COMP_CLC_PRES_FSM_EV_INST_FAIL;
 
+      rc = avnd_comp_clc_fsm_run(cb, comp, event);
+
+      avnd_comp_cbq_rec_pop_and_del(cb, comp, opq_hdl, false);
+      break;
+    }
+
+    case AVSV_AMF_CONTAINED_COMP_CLEAN: {
+      uint32_t opq_hdl(cbk_rec->opq_hdl);
       rc = avnd_comp_clc_fsm_run(cb, comp,
                                  (SA_AIS_OK == resp->err)
                                      ? AVND_COMP_CLC_PRES_FSM_EV_CLEANUP_SUCC
                                      : AVND_COMP_CLC_PRES_FSM_EV_CLEANUP_FAIL);
-      avnd_comp_cbq_rec_pop_and_del(cb, comp, cbk_rec, false);
+      avnd_comp_cbq_rec_pop_and_del(cb, comp, opq_hdl, false);
       break;
+    }
 
     case AVSV_AMF_PG_TRACK:
     default:
@@ -633,7 +667,7 @@ uint32_t avnd_evt_tmr_cbk_resp_evh(AVND_CB *cb, AVND_EVT 
*evt) {
                               cbk_rec);
       rec->comp->term_cbq_inv_value = 0;
       if (cbk_rec) {
-        avnd_comp_cbq_rec_pop_and_del(cb, rec->comp, cbk_rec, false);
+        avnd_comp_cbq_rec_pop_and_del(cb, rec->comp, cbk_rec->opq_hdl, false);
       }
     }
     rc =
@@ -731,7 +765,7 @@ uint32_t avnd_comp_cbq_send(AVND_CB *cb, AVND_COMP *comp, 
MDS_DEST *dest,
     /* pop & delete */
     uint32_t found;
 
-    m_AVND_COMP_CBQ_REC_POP(comp, rec, found);
+    rec = avnd_comp_cbq_rec_pop(comp, rec->opq_hdl, found);
     rec->cbk_info = 0;
     if (found) avnd_comp_cbq_rec_del(cb, comp, rec);
   }
@@ -905,12 +939,12 @@ void avnd_comp_cbq_del(AVND_CB *cb, AVND_COMP *comp, bool 
send_del_cbk) {
   Notes         : None.
 ******************************************************************************/
 void avnd_comp_cbq_rec_pop_and_del(AVND_CB *cb, AVND_COMP *comp,
-                                   AVND_COMP_CBK *rec, bool send_del_cbk) {
+                                   uint32_t opq_hdl, bool send_del_cbk) {
   uint32_t found;
   NODE_ID dest_node_id = 0;
 
   /* pop the record */
-  m_AVND_COMP_CBQ_REC_POP(comp, rec, found);
+  AVND_COMP_CBK *rec(avnd_comp_cbq_rec_pop(comp, opq_hdl, found));
 
   if (found) {
     /* Check if del cbk is to be sent. */
@@ -1046,7 +1080,7 @@ void avnd_comp_cbq_finalize(AVND_CB *cb, AVND_COMP *comp, 
SaAmfHandleT hdl,
         avnd_comp_clc_fsm_run(cb, comp, AVND_COMP_CLC_PRES_FSM_EV_CLEANUP);
       }
 
-      avnd_comp_cbq_rec_pop_and_del(cb, comp, curr, true);
+      avnd_comp_cbq_rec_pop_and_del(cb, comp, curr->opq_hdl, true);
       curr = (prv) ? prv->next : comp->cbk_list;
     } else {
       prv = curr;
@@ -1103,7 +1137,7 @@ void avnd_comp_cbq_csi_rec_del(AVND_CB *cb, AVND_COMP 
*comp,
     }
 
     if (true == to_del) {
-      avnd_comp_cbq_rec_pop_and_del(cb, comp, curr, true);
+      avnd_comp_cbq_rec_pop_and_del(cb, comp, curr->opq_hdl, true);
       curr = (prv) ? prv->next : comp->cbk_list;
     } else {
       prv = curr;
@@ -1139,9 +1173,9 @@ void avnd_comp_unreg_cbk_process(AVND_CB *cb, AVND_COMP 
*comp) {
     switch (cbk->cbk_info->type) {
       case AVSV_AMF_HC:
       case AVSV_AMF_COMP_TERM: {
-        bool found = false;
+        uint32_t found = false;
 
-        m_AVND_COMP_CBQ_REC_POP(comp, cbk, found);
+        avnd_comp_cbq_rec_pop(comp, cbk->opq_hdl, found);
 
         if (!found)
           LOG_NO("%s - '%s' type:%u", __FUNCTION__, comp->name.c_str(),
@@ -1174,14 +1208,14 @@ void avnd_comp_unreg_cbk_process(AVND_CB *cb, AVND_COMP 
*comp) {
           AVND_COMP_CSI_REC *temp_csi = m_AVND_COMPDB_REC_CSI_GET_FIRST(*comp);
 
           if (cbk->cbk_info->param.csi_set.ha != temp_csi->si->curr_state) {
-            avnd_comp_cbq_rec_pop_and_del(cb, comp, cbk, true);
+            avnd_comp_cbq_rec_pop_and_del(cb, comp, cbk->opq_hdl, true);
             break;
           }
         } else if (cbk->cbk_info->param.csi_set.ha != csi->si->curr_state) {
-          avnd_comp_cbq_rec_pop_and_del(cb, comp, cbk, true);
+          avnd_comp_cbq_rec_pop_and_del(cb, comp, cbk->opq_hdl, true);
           break;
         } else if (m_AVND_COMP_IS_ALL_CSI(comp)) {
-          avnd_comp_cbq_rec_pop_and_del(cb, comp, cbk, true);
+          avnd_comp_cbq_rec_pop_and_del(cb, comp, cbk->opq_hdl, true);
           break;
         }
 
@@ -1195,7 +1229,7 @@ void avnd_comp_unreg_cbk_process(AVND_CB *cb, AVND_COMP 
*comp) {
         if (comp->csi_list.n_nodes) {
           (void)avnd_comp_csi_remove_done(cb, comp, csi);
         } else {
-          avnd_comp_cbq_rec_pop_and_del(cb, comp, cbk, true);
+          avnd_comp_cbq_rec_pop_and_del(cb, comp, cbk->opq_hdl, true);
         }
 
       } break;
@@ -1206,7 +1240,7 @@ void avnd_comp_unreg_cbk_process(AVND_CB *cb, AVND_COMP 
*comp) {
 
       default: {
         /* pop and delete this records */
-        avnd_comp_cbq_rec_pop_and_del(cb, comp, cbk, true);
+        avnd_comp_cbq_rec_pop_and_del(cb, comp, cbk->opq_hdl, true);
       } break;
     }
 
diff --git a/src/amf/amfnd/chc.cc b/src/amf/amfnd/chc.cc
index 3cae877c1..4da10d3c9 100644
--- a/src/amf/amfnd/chc.cc
+++ b/src/amf/amfnd/chc.cc
@@ -892,7 +892,7 @@ uint32_t avnd_comp_hc_rec_stop(AVND_CB *cb, AVND_COMP *comp,
     AVND_COMP_CBK *cbk_rec = 0;
     m_AVND_COMPDB_CBQ_HC_CBK_GET(comp, rec->key, cbk_rec);
     if (cbk_rec) /* pop & delete this record */
-      avnd_comp_cbq_rec_pop_and_del(cb, comp, cbk_rec, true);
+      avnd_comp_cbq_rec_pop_and_del(cb, comp, cbk_rec->opq_hdl, true);
   }
 
   /* delete the record */
diff --git a/src/amf/amfnd/clc.cc b/src/amf/amfnd/clc.cc
index c8e60e61b..8fc1430c5 100644
--- a/src/amf/amfnd/clc.cc
+++ b/src/amf/amfnd/clc.cc
@@ -56,6 +56,7 @@ static uint32_t avnd_comp_clc_inst_term_hdler(AVND_CB *, 
AVND_COMP *);
 static uint32_t avnd_comp_clc_inst_clean_hdler(AVND_CB *, AVND_COMP *);
 static uint32_t avnd_comp_clc_inst_restart_hdler(AVND_CB *, AVND_COMP *);
 static uint32_t avnd_comp_clc_inst_orph_hdler(AVND_CB *, AVND_COMP *);
+static uint32_t avnd_comp_clc_inst_try_again_hdler(AVND_CB *, AVND_COMP *);
 static uint32_t avnd_comp_clc_terming_termsucc_hdler(AVND_CB *, AVND_COMP *);
 static uint32_t avnd_comp_clc_terming_termfail_hdler(AVND_CB *, AVND_COMP *);
 static uint32_t avnd_comp_clc_terming_cleansucc_hdler(AVND_CB *, AVND_COMP *);
@@ -114,6 +115,7 @@ static AVND_COMP_CLC_FSM_FN
             avnd_comp_clc_insting_cleanfail_hdler, /* CLEANUP_FAIL EV */
             avnd_comp_clc_insting_restart_hdler,   /* RESTART EV */
             0,                                     /* ORPH EV */
+           avnd_comp_clc_inst_try_again_hdler,    /* TRY_AGAIN EV */
         },
 
         /* SA_AMF_PRESENCE_INSTANTIATED */
@@ -159,6 +161,7 @@ static AVND_COMP_CLC_FSM_FN
             avnd_comp_clc_restart_cleanfail_hdler, /* CLEANUP_FAIL EV */
             avnd_comp_clc_restart_restart_hdler,   /* RESTART EV */
             0,                                     /* ORPH EV */
+           avnd_comp_clc_inst_try_again_hdler,    /* TRY_AGAIN EV */
         },
 
         /* SA_AMF_PRESENCE_INSTANTIATION_FAILED */
@@ -1383,7 +1386,7 @@ uint32_t avnd_comp_clc_st_chng_prc(AVND_CB *cb, AVND_COMP 
*comp,
       /* flush out the cbk related to health check */
       if (curr_rec->cbk_info->type == AVSV_AMF_HC) {
         /* delete the HC cbk */
-        avnd_comp_cbq_rec_pop_and_del(cb, comp, curr_rec, true);
+        avnd_comp_cbq_rec_pop_and_del(cb, comp, curr_rec->opq_hdl, true);
         continue;
       }
     } /* while */
@@ -1425,7 +1428,7 @@ uint32_t avnd_comp_clc_st_chng_prc(AVND_CB *cb, AVND_COMP 
*comp,
         /* send it */
         rc = avnd_comp_cbq_rec_send(cb, comp, curr_rec, true);
         if (NCSCC_RC_SUCCESS != rc) {
-          avnd_comp_cbq_rec_pop_and_del(cb, comp, curr_rec, true);
+          avnd_comp_cbq_rec_pop_and_del(cb, comp, curr_rec->opq_hdl, true);
         }
       } /* while loop */
     }
@@ -1583,6 +1586,15 @@ uint32_t avnd_comp_clc_uninst_inst_hdler(AVND_CB *cb, 
AVND_COMP *comp) {
   }
 
   /* instantiate the comp */
+  if (comp->contained() == true) {
+    rc = avnd_comp_cbk_send(cb, comp, AVSV_AMF_CONTAINED_COMP_INST, 0, 0);
+    if (NCSCC_RC_SUCCESS == rc) {
+      avnd_comp_pres_state_set(cb, comp, SA_AMF_PRESENCE_INSTANTIATING);
+      m_AVND_TMR_COMP_REG_START(cb, *comp, rc);
+    }
+    goto done;
+  }
+
   rc = avnd_comp_clc_cmd_execute(cb, comp, AVND_COMP_CLC_CMD_TYPE_INSTANTIATE);
 
   if (NCSCC_RC_SUCCESS == rc) {
@@ -1703,11 +1715,15 @@ uint32_t avnd_comp_clc_xxxing_instfail_hdler(AVND_CB 
*cb, AVND_COMP *comp) {
   avnd_comp_pm_finalize(cb, comp, comp->reg_hdl);
   avnd_comp_pm_rec_del_all(cb, comp); /*if at all anythnig is left behind */
 
-  /* no state transition */
+  // B.04.01 contained instantiation failure there are no retries
+  if (m_AVND_COMP_TYPE_IS_CONTAINED(comp))
+    avnd_comp_pres_state_set(cb, comp, SA_AMF_PRESENCE_INSTANTIATION_FAILED);
 
   /* cleanup the comp */
   if (m_AVND_COMP_TYPE_IS_PROXIED(comp) && comp->pxy_comp != 0)
     rc = avnd_comp_cbk_send(cb, comp, AVSV_AMF_PXIED_COMP_CLEAN, 0, 0);
+  else if (m_AVND_COMP_TYPE_IS_CONTAINED(comp))
+    rc = avnd_comp_cbk_send(cb, comp, AVSV_AMF_CONTAINED_COMP_CLEAN, 0, 0);
   else
     rc = avnd_comp_clc_cmd_execute(cb, comp, AVND_COMP_CLC_CMD_TYPE_CLEANUP);
 
@@ -1715,6 +1731,51 @@ uint32_t avnd_comp_clc_xxxing_instfail_hdler(AVND_CB 
*cb, AVND_COMP *comp) {
   return rc;
 }
 
+/****************************************************************************
+  Name          : avnd_comp_clc_inst_try_again_hdler
+
+  Description   : This routine processes the `try again` event in
+                  `instantiating/restarting` state for a proxied/contained 
comp.
+
+  Arguments     : cb   - ptr to the AvND control block
+                  comp - ptr to the comp
+
+  Return Values : NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE
+
+  Notes         : None.
+******************************************************************************/
+uint32_t avnd_comp_clc_inst_try_again_hdler(AVND_CB *cb, AVND_COMP *comp) {
+  uint32_t rc = NCSCC_RC_SUCCESS;
+  TRACE_ENTER2("'%s': Try again event in the Instantiating/Restarting state",
+               comp->name.c_str());
+
+  // only a proxied or contained component can do TRY_AGAIN
+  osafassert(m_AVND_COMP_TYPE_IS_PROXIED(comp) ||
+             m_AVND_COMP_TYPE_IS_CONTAINED(comp));
+
+  /* reset the comp-reg & instantiate params */
+  m_AVND_COMP_CLC_INST_PARAM_RESET(comp);
+
+  /* delete hc-list, cbk-list, pg-list & pm-list */
+  avnd_comp_hc_rec_del_all(cb, comp);
+  avnd_comp_cbq_del(cb, comp, true);
+
+  /* re-using the function to stop all PM started by this comp */
+  avnd_comp_pm_finalize(cb, comp, comp->reg_hdl);
+  avnd_comp_pm_rec_del_all(cb, comp); /* if at all anything is left behind */
+
+  /* no state transition */
+
+  /* cleanup the comp */
+  if (comp->pxy_comp)
+    rc = avnd_comp_cbk_send(cb, comp, AVSV_AMF_PXIED_COMP_CLEAN, 0, 0);
+  else if (m_AVND_COMP_TYPE_IS_CONTAINED(comp))
+    rc = avnd_comp_cbk_send(cb, comp, AVSV_AMF_CONTAINED_COMP_CLEAN, 0, 0);
+
+  TRACE_LEAVE2("%u", rc);
+  return rc;
+}
+
 /****************************************************************************
   Name          : avnd_comp_clc_insting_term_hdler
 
@@ -1916,9 +1977,18 @@ uint32_t avnd_comp_clc_xxxing_cleansucc_hdler(AVND_CB 
*cb, AVND_COMP *comp) {
         /* start a timer for proxied instantiating timeout duration */
         m_AVND_TMR_PXIED_COMP_INST_START(cb, *comp, rc);
       }
-    } else
+    } else if (comp->contained() == true) {
+      rc = avnd_comp_cbk_send(cb, comp, AVSV_AMF_CONTAINED_COMP_INST, 0, 0);
+      if (NCSCC_RC_SUCCESS == rc) {
+        avnd_comp_pres_state_set(cb, comp, SA_AMF_PRESENCE_INSTANTIATING);
+        m_AVND_TMR_COMP_REG_START(cb, *comp, rc);
+      }
+      clc_info->inst_retry_cnt++;
+      goto done;
+    } else {
       rc = avnd_comp_clc_cmd_execute(cb, comp,
                                      AVND_COMP_CLC_CMD_TYPE_INSTANTIATE);
+    }
 
     if (NCSCC_RC_SUCCESS == rc) {
       /* timestamp the start of this instantiation phase */
@@ -2035,6 +2105,7 @@ uint32_t avnd_comp_clc_inst_term_hdler(AVND_CB *cb, 
AVND_COMP *comp) {
     avnd_comp_pm_rec_del_all(cb, comp); /*if at all anythnig is left behind */
 
   } else if (m_AVND_COMP_TYPE_IS_SAAWARE(comp) ||
+             (comp->contained() == true) ||
              (m_AVND_COMP_TYPE_IS_PROXIED(comp) &&
               m_AVND_COMP_TYPE_IS_PREINSTANTIABLE(comp))) {
     /* invoke terminate callback */
@@ -2139,6 +2210,8 @@ uint32_t avnd_comp_clc_inst_clean_hdler(AVND_CB *cb, 
AVND_COMP *comp) {
       /*Send amfd to gracefully remove assignments for thus SU.*/
       su_send_suRestart_recovery_msg(comp->su);
       goto done;
+    } else if (comp->contained() == true) {
+      rc = avnd_comp_cbk_send(cb, comp, AVSV_AMF_CONTAINED_COMP_CLEAN, 0, 0);
     } else
       rc = avnd_comp_clc_cmd_execute(cb, comp, AVND_COMP_CLC_CMD_TYPE_CLEANUP);
   }
@@ -2180,6 +2253,8 @@ uint32_t avnd_comp_clc_inst_restart_hdler(AVND_CB *cb, 
AVND_COMP *comp) {
   /* terminate / cleanup the comp */
   if (m_AVND_COMP_IS_FAILED(comp) && m_AVND_COMP_TYPE_IS_PROXIED(comp))
     rc = avnd_comp_cbk_send(cb, comp, AVSV_AMF_PXIED_COMP_CLEAN, 0, 0);
+  else if (m_AVND_COMP_IS_FAILED(comp) && (comp->contained() == true))
+    rc = avnd_comp_cbk_send(cb, comp, AVSV_AMF_CONTAINED_COMP_CLEAN, 0, 0);
   else if (m_AVND_COMP_IS_FAILED(comp)) {
     rc = avnd_comp_clc_cmd_execute(cb, comp, AVND_COMP_CLC_CMD_TYPE_CLEANUP);
     m_AVND_COMP_REG_PARAM_RESET(cb, comp);
@@ -2331,6 +2406,8 @@ uint32_t avnd_comp_clc_terming_termfail_hdler(AVND_CB 
*cb, AVND_COMP *comp) {
   /* cleanup the comp */
   if (m_AVND_COMP_TYPE_IS_PROXIED(comp) && comp->pxy_comp != 0)
     rc = avnd_comp_cbk_send(cb, comp, AVSV_AMF_PXIED_COMP_CLEAN, 0, 0);
+  else if (m_AVND_COMP_TYPE_IS_CONTAINED(comp))
+    rc = avnd_comp_cbk_send(cb, comp, AVSV_AMF_CONTAINED_COMP_CLEAN, 0, 0);
   else
     rc = avnd_comp_clc_cmd_execute(cb, comp, AVND_COMP_CLC_CMD_TYPE_CLEANUP);
 
@@ -2599,6 +2676,8 @@ uint32_t avnd_comp_clc_restart_term_hdler(AVND_CB *cb, 
AVND_COMP *comp) {
   /* cleanup the comp */
   if (m_AVND_COMP_TYPE_IS_PROXIED(comp) && comp->pxy_comp != 0)
     rc = avnd_comp_cbk_send(cb, comp, AVSV_AMF_PXIED_COMP_CLEAN, 0, 0);
+  else if (m_AVND_COMP_TYPE_IS_CONTAINED(comp))
+    rc = avnd_comp_cbk_send(cb, comp, AVSV_AMF_CONTAINED_COMP_CLEAN, 0, 0);
   else {
     rc = avnd_comp_clc_cmd_execute(cb, comp, AVND_COMP_CLC_CMD_TYPE_CLEANUP);
 
@@ -2677,6 +2756,8 @@ uint32_t avnd_comp_clc_restart_termsucc_hdler(AVND_CB 
*cb, AVND_COMP *comp) {
            !m_AVND_COMP_TYPE_IS_PREINSTANTIABLE(comp))
     /* proxied non-pre-instantiable comp */
     rc = avnd_comp_cbk_send(cb, comp, AVSV_AMF_CSI_SET, 0, 0);
+  else if (comp->contained() == true)
+    rc = avnd_comp_cbk_send(cb, comp, AVSV_AMF_CONTAINED_COMP_INST, 0, 0);
   else if (m_AVND_COMP_TYPE_IS_PROXIED(comp))
     ; /* do nothing */
   else
@@ -2713,6 +2794,8 @@ uint32_t avnd_comp_clc_restart_termfail_hdler(AVND_CB 
*cb, AVND_COMP *comp) {
   /* cleanup the comp */
   if (m_AVND_COMP_TYPE_IS_PROXIED(comp) && comp->pxy_comp != 0)
     rc = avnd_comp_cbk_send(cb, comp, AVSV_AMF_PXIED_COMP_CLEAN, 0, 0);
+  else if (m_AVND_COMP_TYPE_IS_CONTAINED(comp))
+    rc = avnd_comp_cbk_send(cb, comp, AVSV_AMF_CONTAINED_COMP_CLEAN, 0, 0);
   else
     rc = avnd_comp_clc_cmd_execute(cb, comp, AVND_COMP_CLC_CMD_TYPE_CLEANUP);
 
@@ -2748,6 +2831,8 @@ uint32_t avnd_comp_clc_restart_clean_hdler(AVND_CB *cb, 
AVND_COMP *comp) {
   /* cleanup the comp */
   if (m_AVND_COMP_TYPE_IS_PROXIED(comp) && comp->pxy_comp != 0)
     rc = avnd_comp_cbk_send(cb, comp, AVSV_AMF_PXIED_COMP_CLEAN, 0, 0);
+  else if (m_AVND_COMP_TYPE_IS_CONTAINED(comp))
+    rc = avnd_comp_cbk_send(cb, comp, AVSV_AMF_CONTAINED_COMP_CLEAN, 0, 0);
   else
     rc = avnd_comp_clc_cmd_execute(cb, comp, AVND_COMP_CLC_CMD_TYPE_CLEANUP);
   if (NCSCC_RC_SUCCESS == rc) {
@@ -3314,6 +3399,8 @@ static uint32_t 
avnd_comp_clc_restart_restart_hdler(AVND_CB *cb,
 
   if (m_AVND_COMP_TYPE_IS_PROXIED(comp) && comp->pxy_comp != 0)
     rc = avnd_comp_cbk_send(cb, comp, AVSV_AMF_PXIED_COMP_CLEAN, 0, 0);
+  else if (m_AVND_COMP_TYPE_IS_CONTAINED(comp))
+    rc = avnd_comp_cbk_send(cb, comp, AVSV_AMF_CONTAINED_COMP_CLEAN, 0, 0);
   else
     rc = avnd_comp_clc_cmd_execute(cb, comp, AVND_COMP_CLC_CMD_TYPE_CLEANUP);
 
diff --git a/src/amf/amfnd/comp.cc b/src/amf/amfnd/comp.cc
index fdaa342c1..21abb310c 100644
--- a/src/amf/amfnd/comp.cc
+++ b/src/amf/amfnd/comp.cc
@@ -106,7 +106,7 @@ uint32_t avnd_evt_ava_finalize_evh(AVND_CB *cb, AVND_EVT 
*evt) {
     m_AVND_COMP_CBQ_INV_GET(comp, comp->term_cbq_inv_value, cbk_rec);
     comp->term_cbq_inv_value = 0;
     rc = avnd_comp_clc_fsm_run(cb, comp, AVND_COMP_CLC_PRES_FSM_EV_TERM_SUCC);
-    if (cbk_rec) avnd_comp_cbq_rec_pop_and_del(cb, comp, cbk_rec, false);
+    if (cbk_rec) avnd_comp_cbq_rec_pop_and_del(cb, comp, cbk_rec->opq_hdl, 
false);
   }
 
   /* npi comps dont interact with amf */
@@ -429,7 +429,7 @@ uint32_t avnd_evt_mds_ava_dn_evh(AVND_CB *cb, AVND_EVT 
*evt) {
       m_AVND_COMP_CBQ_INV_GET(comp, comp->term_cbq_inv_value, cbk_rec);
       comp->term_cbq_inv_value = 0;
       rc = avnd_comp_clc_fsm_run(cb, comp, 
AVND_COMP_CLC_PRES_FSM_EV_TERM_SUCC);
-      if (cbk_rec) avnd_comp_cbq_rec_pop_and_del(cb, comp, cbk_rec, false);
+      if (cbk_rec) avnd_comp_cbq_rec_pop_and_del(cb, comp, cbk_rec->opq_hdl, 
false);
       goto done;
     }
     /* found the matching comp; trigger error processing */
@@ -632,6 +632,25 @@ proceed_next:
     }
   }
 
+  // check if the correct callbacks have been registered
+  if (m_AVND_COMP_TYPE_IS_CONTAINER(*o_comp)) {
+    if (!(reg->callbacks & AVSV_AMF_CALLBACK_TERMINATE) ||
+        !(reg->callbacks & AVSV_AMF_CALLBACK_CSI_SET) ||
+        !(reg->callbacks & AVSV_AMF_CALLBACK_CSI_REMOVE) ||
+        !(reg->callbacks & AVSV_AMF_CALLBACK_CONTAINED_INST) ||
+        !(reg->callbacks & AVSV_AMF_CALLBACK_CONTAINED_CLEAN)) {
+      *o_amf_rc = SA_AIS_ERR_INIT;
+      return;
+    }
+  } else if (m_AVND_COMP_TYPE_IS_CONTAINED(*o_comp)) {
+    if (!(reg->callbacks & AVSV_AMF_CALLBACK_TERMINATE) ||
+        !(reg->callbacks & AVSV_AMF_CALLBACK_CSI_SET) ||
+        !(reg->callbacks & AVSV_AMF_CALLBACK_CSI_REMOVE)) {
+      *o_amf_rc = SA_AIS_ERR_INIT;
+      return ;
+    }
+  }
+
   return;
 }
 
@@ -2018,7 +2037,7 @@ uint32_t avnd_comp_cbk_send(AVND_CB *cb, AVND_COMP *comp,
    * cbk is an exception)
    */
   if ((AVSV_AMF_HC != type) && !m_AVND_COMP_IS_REG(comp) &&
-      !m_AVND_COMP_PRES_STATE_IS_ORPHANED(comp))
+      !comp->contained() && !m_AVND_COMP_PRES_STATE_IS_ORPHANED(comp))
     goto done;
 
   /* allocate cbk-info memory */
@@ -2142,6 +2161,22 @@ uint32_t avnd_comp_cbk_send(AVND_CB *cb, AVND_COMP *comp,
       set_params_for_csi_attr_change_cbk(cbk_info, comp, csi_rec);
       per = comp->csi_set_cbk_timeout;
       break;
+    case AVSV_AMF_CONTAINED_COMP_INST: {
+        AVND_COMP *container(get_associated_container_comp(cb, comp));
+        avnd_amf_contained_comp_inst_cbk_fill(cbk_info, comp->name);
+        per = comp->pxied_inst_cbk_timeout;
+        dest = &container->reg_dest;
+        hdl = container->reg_hdl;
+      }
+      break;
+    case AVSV_AMF_CONTAINED_COMP_CLEAN: {
+        AVND_COMP *container(get_associated_container_comp(cb, comp));
+        avnd_amf_contained_comp_clean_cbk_fill(cbk_info, comp->name);
+        per = comp->pxied_clean_cbk_timeout;
+        dest = &container->reg_dest;
+        hdl = container->reg_hdl;
+      }
+      break;
     case AVSV_AMF_PG_TRACK:
     default:
       osafassert(0);
@@ -2612,18 +2647,18 @@ void avnd_comp_cmplete_all_assignment(AVND_CB *cb, 
AVND_COMP *comp) {
         temp_csi = m_AVND_COMPDB_REC_CSI_GET_FIRST(*comp);
 
         if (cbk->cbk_info->param.csi_set.ha != temp_csi->si->curr_state) {
-          avnd_comp_cbq_rec_pop_and_del(cb, comp, cbk, true);
+          avnd_comp_cbq_rec_pop_and_del(cb, comp, cbk->opq_hdl, true);
           continue;
         }
       } else if (cbk->cbk_info->param.csi_set.ha != csi->si->curr_state) {
         /* if assignment was overriden by new one */
-        avnd_comp_cbq_rec_pop_and_del(cb, comp, cbk, true);
+        avnd_comp_cbq_rec_pop_and_del(cb, comp, cbk->opq_hdl, true);
         continue;
       } else if (m_AVND_COMP_IS_ALL_CSI(comp)) {
         /* if both target all and target one operation are
          * pending, we need not respond for target one
          */
-        avnd_comp_cbq_rec_pop_and_del(cb, comp, cbk, true);
+        avnd_comp_cbq_rec_pop_and_del(cb, comp, cbk->opq_hdl, true);
         continue;
       }
 
@@ -2639,11 +2674,11 @@ void avnd_comp_cmplete_all_assignment(AVND_CB *cb, 
AVND_COMP *comp) {
         rc = avnd_comp_csi_remove_done(cb, comp, csi);
         if ((!csi) || (NCSCC_RC_SUCCESS != rc)) break;
       } else {
-        avnd_comp_cbq_rec_pop_and_del(cb, comp, cbk, true);
+        avnd_comp_cbq_rec_pop_and_del(cb, comp, cbk->opq_hdl, true);
       }
     } else {
       /* pop this rec */
-      m_AVND_COMP_CBQ_REC_POP(comp, cbk, found);
+      avnd_comp_cbq_rec_pop(comp, cbk->opq_hdl, found);
       if (!found) {
         LOG_ER("Comp callback record not found: '%s'", comp->name.c_str());
         break;
@@ -3058,6 +3093,18 @@ void 
avnd_amf_pxied_comp_clean_cbk_fill(AVSV_AMF_CBK_INFO *cbk,
   osaf_extended_name_alloc(cn.c_str(), &cbk->param.comp_term.comp_name);
 }
 
+void avnd_amf_contained_comp_inst_cbk_fill(AVSV_AMF_CBK_INFO *cbk,
+                                           const std::string &cn) {
+  cbk->type = AVSV_AMF_CONTAINED_COMP_INST;
+  osaf_extended_name_alloc(cn.c_str(), &cbk->param.contained_inst.comp_name);
+}
+
+void avnd_amf_contained_comp_clean_cbk_fill(AVSV_AMF_CBK_INFO *cbk,
+                                            const std::string &cn) {
+  cbk->type = AVSV_AMF_CONTAINED_COMP_CLEAN;
+  osaf_extended_name_alloc(cn.c_str(), &cbk->param.contained_clean.comp_name);
+}
+
 /**
  * @brief  This event is for remembering MDS dest and version of agent.
  * @param  ptr to AVND_CB
@@ -3073,3 +3120,30 @@ uint32_t avnd_amfa_mds_info_evh(AVND_CB *cb, AVND_EVT 
*evt) {
   TRACE_LEAVE();
   return NCSCC_RC_SUCCESS;
 }
+
+bool AVND_COMP::container (void) const {
+  return (flag & AVND_COMP_TYPE_CONTAINER);
+}
+
+bool AVND_COMP::contained (void) const {
+  return (flag & AVND_COMP_TYPE_CONTAINED);
+}
+
+AVND_COMP * avnd_get_comp_from_csi(AVND_CB *cb, const std::string& csi) {
+  AVND_COMP *acomp(0);
+
+  for (AVND_COMP *comp(avnd_compdb_rec_get_next(cb->compdb, ""));
+       comp != nullptr;
+       comp = avnd_compdb_rec_get_next(cb->compdb, comp->name)) {
+    const AVND_COMP_CSI_REC *csi_rec(avnd_compdb_csi_rec_get(cb, comp->name,
+                                                             csi));
+
+    if (csi_rec) {
+      acomp = comp;
+      TRACE("found associated comp: %s", acomp->name.c_str());
+      break;
+    }
+  }
+
+  return acomp;
+}
diff --git a/src/amf/amfnd/compdb.cc b/src/amf/amfnd/compdb.cc
index 7f78194f8..55705b837 100644
--- a/src/amf/amfnd/compdb.cc
+++ b/src/amf/amfnd/compdb.cc
@@ -1032,6 +1032,20 @@ static void init_comp_category(AVND_COMP *comp, 
SaAmfCompCategoryT category) {
   osafassert(comptype != AVSV_COMP_TYPE_INVALID);
 
   switch (comptype) {
+    case AVSV_COMP_TYPE_CONTAINER:
+      m_AVND_COMP_TYPE_SET(comp, AVND_COMP_TYPE_CONTAINER);
+      m_AVND_COMP_TYPE_SET(comp, AVND_COMP_TYPE_LOCAL);
+      m_AVND_COMP_TYPE_SET(comp, AVND_COMP_TYPE_SAAWARE);
+      m_AVND_COMP_TYPE_SET(comp, AVND_COMP_TYPE_PREINSTANTIABLE);
+      break;
+
+    case AVSV_COMP_TYPE_CONTAINED:
+      m_AVND_COMP_TYPE_SET(comp, AVND_COMP_TYPE_CONTAINED);
+      m_AVND_COMP_TYPE_SET(comp, AVND_COMP_TYPE_LOCAL);
+      m_AVND_COMP_TYPE_SET(comp, AVND_COMP_TYPE_SAAWARE);
+      m_AVND_COMP_TYPE_SET(comp, AVND_COMP_TYPE_PREINSTANTIABLE);
+      break;
+
     case AVSV_COMP_TYPE_SA_AWARE:
       m_AVND_COMP_TYPE_SET(comp, AVND_COMP_TYPE_LOCAL);
       m_AVND_COMP_TYPE_SET(comp, AVND_COMP_TYPE_SAAWARE);
@@ -1280,7 +1294,7 @@ static int comp_init(AVND_COMP *comp, const 
SaImmAttrValuesT_2 **attributes) {
   SaImmHandleT immOmHandle;
   SaVersionT immVersion = {'A', 2, 15};
   SaNameT node_name;
-  SaNameT saAmfCtSwBundle;
+  SaNameT saAmfCtSwBundle, container_csi;
   SaAisErrorT error;
 
   TRACE_ENTER2("%s", comp->name.c_str());
@@ -1307,6 +1321,12 @@ static int comp_init(AVND_COMP *comp, const 
SaImmAttrValuesT_2 **attributes) {
       immOmHandle, const_cast<SaImmAttrNameT>("saAmfNodeSwBundlePathPrefix"),
       Amf::to_string(&nodeswbundle_name), &path_prefix);
 
+  if (immutil_getAttr(const_cast<SaImmAttrNameT>("saAmfCompContainerCsi"),
+                      attributes, 0, &container_csi) == SA_AIS_OK) {
+    comp->saAmfCompContainerCsi = Amf::to_string(&container_csi);
+    container_csis.insert(comp->saAmfCompContainerCsi);
+  }
+
   if 
(immutil_getAttr(const_cast<SaImmAttrNameT>("saAmfCompInstantiationLevel"),
                       attributes, 0, &comp->inst_level) != SA_AIS_OK) {
     comp->inst_level = comptype->saAmfCtDefInstantiationLevel;
diff --git a/src/amf/amfnd/err.cc b/src/amf/amfnd/err.cc
index 1d6eb3757..77e4bcc9a 100644
--- a/src/amf/amfnd/err.cc
+++ b/src/amf/amfnd/err.cc
@@ -379,7 +379,7 @@ uint32_t avnd_err_process(AVND_CB *cb, AVND_COMP *comp,
     /* get the matching entry from the cbk list */
     m_AVND_COMP_CBQ_INV_GET(comp, comp->term_cbq_inv_value, cbk_rec);
     comp->term_cbq_inv_value = 0;
-    if (cbk_rec) avnd_comp_cbq_rec_pop_and_del(cb, comp, cbk_rec, false);
+    if (cbk_rec) avnd_comp_cbq_rec_pop_and_del(cb, comp, cbk_rec->opq_hdl, 
false);
   }
 
   // Handle errors differently when shutdown has started
diff --git a/src/amf/amfnd/evt.cc b/src/amf/amfnd/evt.cc
index b2ae29bec..09918f59b 100644
--- a/src/amf/amfnd/evt.cc
+++ b/src/amf/amfnd/evt.cc
@@ -87,6 +87,7 @@ AVND_EVT *avnd_evt_create(AVND_CB *cb, AVND_EVT_TYPE type,
     case AVND_EVT_AVD_ADMIN_OP_REQ_MSG:
     case AVND_EVT_AVD_REBOOT_MSG:
     case AVND_EVT_AVD_COMPCSI_ASSIGN_MSG:
+    case AVND_EVT_AVD_CONTAINED_SU_MSG:
       evt->info.avd = (AVSV_DND_MSG *)info;
       break;
 
@@ -238,6 +239,7 @@ void avnd_evt_destroy(AVND_EVT *evt) {
     case AVND_EVT_AVD_HEARTBEAT_MSG:
     case AVND_EVT_AVD_REBOOT_MSG:
     case AVND_EVT_AVD_COMPCSI_ASSIGN_MSG:
+    case AVND_EVT_AVD_CONTAINED_SU_MSG:
       if (evt->info.avd) avsv_dnd_msg_free(evt->info.avd);
       break;
 
diff --git a/src/amf/amfnd/main.cc b/src/amf/amfnd/main.cc
index 07915ca27..af92808a5 100644
--- a/src/amf/amfnd/main.cc
+++ b/src/amf/amfnd/main.cc
@@ -72,6 +72,7 @@ extern const AVND_EVT_HDLR g_avnd_func_list[AVND_EVT_MAX] = {
     avnd_evt_avd_hb_evh,                   /* AVND_EVT_AVD_HEARTBEAT_MSG */
     avnd_evt_avd_reboot_evh,               /* /AVND_EVT_AVD_REBOOT_MSG */
     avnd_evt_avd_compcsi_evh,              // AVND_EVT_AVD_COMPCSI_ASSIGN_MSG
+    avnd_evt_avd_contained_su_evh,         // AVND_EVT_AVD_CONTAINED_SU_MSG
 
     /* AvA event types */
     avnd_evt_ava_finalize_evh,            /* AVND_EVT_AVA_AMF_FINALIZE */
diff --git a/src/amf/amfnd/mds.cc b/src/amf/amfnd/mds.cc
index 1ee24cf5b..3c07182db 100644
--- a/src/amf/amfnd/mds.cc
+++ b/src/amf/amfnd/mds.cc
@@ -45,14 +45,14 @@ const MDS_CLIENT_MSG_FORMAT_VER 
avnd_avd_msg_fmt_map_table[] = {
     AVSV_AVD_AVND_MSG_FMT_VER_1, AVSV_AVD_AVND_MSG_FMT_VER_2,
     AVSV_AVD_AVND_MSG_FMT_VER_3, AVSV_AVD_AVND_MSG_FMT_VER_4,
     AVSV_AVD_AVND_MSG_FMT_VER_4, AVSV_AVD_AVND_MSG_FMT_VER_6,
-    AVSV_AVD_AVND_MSG_FMT_VER_7};
+    AVSV_AVD_AVND_MSG_FMT_VER_7, AVSV_AVD_AVND_MSG_FMT_VER_8};
 
 /* messages from director */
 const MDS_CLIENT_MSG_FORMAT_VER avd_avnd_msg_fmt_map_table[] = {
     AVSV_AVD_AVND_MSG_FMT_VER_1, AVSV_AVD_AVND_MSG_FMT_VER_2,
     AVSV_AVD_AVND_MSG_FMT_VER_3, AVSV_AVD_AVND_MSG_FMT_VER_4,
     AVSV_AVD_AVND_MSG_FMT_VER_5, AVSV_AVD_AVND_MSG_FMT_VER_6,
-    AVSV_AVD_AVND_MSG_FMT_VER_7};
+    AVSV_AVD_AVND_MSG_FMT_VER_7, AVSV_AVD_AVND_MSG_FMT_VER_8};
 
 const MDS_CLIENT_MSG_FORMAT_VER avnd_avnd_msg_fmt_map_table[] = {
     AVSV_AVND_AVND_MSG_FMT_VER_1};
@@ -380,6 +380,8 @@ uint32_t avnd_mds_rcv(AVND_CB *cb, 
MDS_CALLBACK_RECEIVE_INFO *rcv_info) {
 
       if (msg.info.avd->msg_type == AVSV_D2N_COMPCSI_ASSIGN_MSG)
         type = AVND_EVT_AVD_COMPCSI_ASSIGN_MSG;
+      else if (msg.info.avd->msg_type == AVSV_D2N_CONTAINED_SU_MSG)
+        type = AVND_EVT_AVD_CONTAINED_SU_MSG;
       else
         type = static_cast<AVND_EVT_TYPE>(
             (msg.info.avd->msg_type - AVSV_D2N_NODE_UP_MSG) +
@@ -1035,6 +1037,23 @@ uint32_t avnd_mds_flat_ava_enc(AVND_CB *cb, 
MDS_CALLBACK_ENC_INFO *enc_info) {
                                 &cbk_info->param.pxied_comp_clean.comp_name);
           }
           break;
+
+        case AVSV_AMF_CONTAINED_COMP_INST:
+          if (osaf_is_an_extended_name(
+                  &cbk_info->param.contained_inst.comp_name)) {
+            osaf_encode_sanamet(enc_info->io_uba,
+                                &cbk_info->param.contained_inst.comp_name);
+          }
+          break;
+
+        case AVSV_AMF_CONTAINED_COMP_CLEAN:
+          if (osaf_is_an_extended_name(
+                  &cbk_info->param.contained_clean.comp_name)) {
+            osaf_encode_sanamet(enc_info->io_uba,
+                                &cbk_info->param.contained_clean.comp_name);
+          }
+          break;
+
         case AVSV_AMF_SC_STATUS_CHANGE:
           break;
 
diff --git a/src/amf/amfnd/proxy.cc b/src/amf/amfnd/proxy.cc
index 95d74b677..ff33e108a 100644
--- a/src/amf/amfnd/proxy.cc
+++ b/src/amf/amfnd/proxy.cc
@@ -546,7 +546,7 @@ uint32_t avnd_int_ext_comp_hdlr(AVND_CB *cb, 
AVSV_AMF_API_INFO *api_info,
          invocation handle in the response with the original one. Check
          function avnd_evt_avnd_avnd_cbk_msg_hdl()'s comments */
       resp->inv = cbk_rec->orig_opq_hdl;
-      avnd_comp_cbq_rec_pop_and_del(cb, o_comp, cbk_rec, false);
+      avnd_comp_cbq_rec_pop_and_del(cb, o_comp, cbk_rec->opq_hdl, false);
     }
 
     /* if(AVSV_AMF_RESP == api_info->type)  */
diff --git a/src/amf/amfnd/su.cc b/src/amf/amfnd/su.cc
index caa5356be..28e7a2a13 100644
--- a/src/amf/amfnd/su.cc
+++ b/src/amf/amfnd/su.cc
@@ -1044,3 +1044,11 @@ done:
   TRACE_LEAVE2("%u", rc);
   return rc;
 }
+
+bool AVND_SU::contained(void) const {
+  AVND_COMP *comp = m_AVND_COMP_FROM_SU_DLL_NODE_GET(
+       m_NCS_DBLIST_FIND_FIRST(&comp_list));
+  if ((comp != nullptr) && (comp->contained() == true))
+    return true;
+  return false;
+}
diff --git a/src/amf/amfnd/susm.cc b/src/amf/amfnd/susm.cc
index 324654838..b58945eac 100644
--- a/src/amf/amfnd/susm.cc
+++ b/src/amf/amfnd/susm.cc
@@ -1090,6 +1090,18 @@ static void 
su_finish_suRestart_escalation_or_admin_op(AVND_SU *su) {
   }
   TRACE_LEAVE();
 }
+
+static bool container_contained_shutdown(const AVND_SU *su) {
+  bool res(false);
+
+  if (su->contained()) {
+    // see if the associated container is being locked
+
+  }
+
+  return res;
+}
+
 /****************************************************************************
   Name          : avnd_su_si_oper_done
 
@@ -1175,6 +1187,7 @@ uint32_t avnd_su_si_oper_done(AVND_CB *cb, AVND_SU *su, 
AVND_SU_SI_REC *si) {
   /* Inform AMFD when assign are over. During surestart only for non 
restartable
      SU we need to inform AMFD.*/
   if (opr_done &&
+      !container_contained_shutdown(su) &&
       ((!(m_AVND_SU_IS_RESTART(su))) ||
        (m_AVND_SU_IS_RESTART(su) && (su_all_comps_restartable(*su) == false) &&
         (is_any_non_restartable_comp_assigned(*su) == true))) &&
@@ -2091,11 +2104,29 @@ uint32_t avnd_su_pres_uninst_suinst_hdler(AVND_CB *cb, 
AVND_SU *su,
       TRACE("%s", curr_comp->name.c_str());
       if (m_AVND_COMP_TYPE_IS_PREINSTANTIABLE(curr_comp) &&
           (curr_comp->pres == SA_AMF_PRESENCE_UNINSTANTIATED)) {
-        TRACE("Running the component CLC FSM ");
-        rc = avnd_comp_clc_fsm_run(cb, curr_comp,
-                                   AVND_COMP_CLC_PRES_FSM_EV_INST);
-        if (NCSCC_RC_SUCCESS != rc) goto done;
-        break;
+        if (curr_comp->contained()) {
+          AVND_COMP *container(
+            avnd_get_comp_from_csi(cb, curr_comp->saAmfCompContainerCsi));
+
+          if (container) {
+            // call the contained instantiate callback
+            rc = avnd_comp_clc_fsm_run(cb, curr_comp,
+                                       AVND_COMP_CLC_PRES_FSM_EV_INST);
+            if (rc != NCSCC_RC_SUCCESS) {
+              LOG_ER("failed to start contained fsm: %s",
+                     curr_comp->name.c_str());
+              goto done;
+            }
+          } else {
+            TRACE("no active container available; not instantiating 
contained");
+          }
+        } else {
+          TRACE("Running the component CLC FSM ");
+          rc = avnd_comp_clc_fsm_run(cb, curr_comp,
+                                     AVND_COMP_CLC_PRES_FSM_EV_INST);
+          if (NCSCC_RC_SUCCESS != rc) goto done;
+          break;
+        }
       }
     } /* for */
   }
@@ -4225,3 +4256,50 @@ static uint32_t 
avnd_su_pres_termfailed_comptermfail_or_compuninst(
   TRACE_LEAVE();
   return rc;
 }
+
+uint32_t avnd_evt_avd_contained_su_evh(AVND_CB *cb, AVND_EVT *evt) {
+  AVSV_D2N_CONTAINED_SU_MSG_INFO *info = 0;
+  AVND_SU *contained_su = 0, *container_su = 0;
+  uint32_t rc = NCSCC_RC_SUCCESS;
+  AVND_EVT *evt_ir = 0;
+
+  TRACE_ENTER();
+
+  if (!m_AVND_CB_IS_AVD_UP(cb)) {
+    TRACE("AVD is not yet up");
+    goto done;
+  }
+
+  if (m_AVND_IS_SHUTTING_DOWN(cb)) {
+    TRACE("AMFND is in SHUTDOWN state");
+    goto done;
+  }
+
+  info = &evt->info.avd->msg_info.d2n_contained_su_msg_info;
+
+  avnd_msgid_assert(info->msg_id);
+  cb->rcv_msg_id = info->msg_id;
+
+  container_su = avnd_sudb_rec_get(cb->sudb, 
Amf::to_string(&info->container_su_name));
+  if (!container_su) {
+    TRACE("SU'%s', not found in DB", 
osaf_extended_name_borrow(&info->container_su_name));
+    goto done;
+  }
+
+  contained_su = avnd_sudb_rec_get(cb->sudb, 
Amf::to_string(&info->contained_su_name));
+  if (!contained_su) {
+    TRACE("SU'%s', not found in DB", 
osaf_extended_name_borrow(&info->contained_su_name));
+    goto done;
+  }
+  contained_su->container_su_name = container_su->name;
+  TRACE("Sending to Imm thread.");
+  evt_ir = avnd_evt_create(cb, AVND_EVT_IR, 0, nullptr, 
&info->contained_su_name, 0, 0);
+  rc = m_NCS_IPC_SEND(&ir_cb.mbx, evt_ir, evt_ir->priority);
+  if (NCSCC_RC_SUCCESS != rc)
+         LOG_CR("AvND send event to IR mailbox failed, type = %u", 
evt_ir->type);
+  /* if failure, free the event */
+  if (NCSCC_RC_SUCCESS != rc && evt_ir) avnd_evt_destroy(evt_ir);
+done:
+  TRACE_LEAVE2("%u", rc);
+  return rc;
+}
-- 
2.14.4


------------------------------------------------------------------------------
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

Reply via email to