Hi,
One initial comment:
Since suMaintenanceCampaign is an attribute of SU, I think, function su->send_attribute_update() can still be used to send name of campaign as an attribute update to AMFND. New AMFND will update itself. Old AMFNDs are just logging for unsupported attribute and returning error to AMFD. AMFD is logging this as an error. This error can be converted into warning. With this, I think, there will not be any backward incompatibility problem and hence version update will not be required. I have prepared a patch (attached 2144_msg.patch on top of this patch) based on above idea.

Going through other changes...

Thanks,
Praveen



On 16-Dec-16 2:13 PM, praveen malviya wrote:
Hi,

I am going through this patch.

Thanks,
Praveen

On 01-Dec-16 2:06 AM, Alex Jones wrote:
 osaf/libs/common/amf/d2nedu.c                  |  15 ++++-
 osaf/libs/common/amf/d2nmsg.c                  |  12 ++++
 osaf/libs/common/amf/include/amf_d2nmsg.h      |  13 ++++
 osaf/services/saf/amf/amfd/comp.cc             |   2 +-
 osaf/services/saf/amf/amfd/include/su.h        |   2 +-
 osaf/services/saf/amf/amfd/include/util.h      |   1 +
 osaf/services/saf/amf/amfd/mds.cc              |   2 +-
 osaf/services/saf/amf/amfd/sgproc.cc           |   2 +-
 osaf/services/saf/amf/amfd/su.cc               |  35 +++++++++++-
 osaf/services/saf/amf/amfd/util.cc             |  74 ++++++++++++++++++++++++++
 osaf/services/saf/amf/amfnd/clc.cc             |  28 ++++++---
 osaf/services/saf/amf/amfnd/err.cc             |  20 +++++-
 osaf/services/saf/amf/amfnd/evt.cc             |   2 +
 osaf/services/saf/amf/amfnd/include/avnd_evt.h |   1 +
 osaf/services/saf/amf/amfnd/include/avnd_mds.h |   4 +-
 osaf/services/saf/amf/amfnd/include/avnd_su.h  |   3 +
 osaf/services/saf/amf/amfnd/main.cc            |   1 +
 osaf/services/saf/amf/amfnd/mds.cc             |   6 +-
 osaf/services/saf/amf/amfnd/su.cc              |  46 ++++++++++++++++
 osaf/services/saf/amf/amfnd/susm.cc            |  10 ++-
 20 files changed, 252 insertions(+), 27 deletions(-)


This patch implements section 3.11.1.4.2 of AMF spec (Restrictions to
Auto-Repair).

diff --git a/osaf/libs/common/amf/d2nedu.c b/osaf/libs/common/amf/d2nedu.c
--- a/osaf/libs/common/amf/d2nedu.c
+++ b/osaf/libs/common/amf/d2nedu.c
@@ -414,6 +414,16 @@ uint32_t avsv_edp_dnd_msg(EDU_HDL *hdl,
                {EDU_EXEC, avsv_edp_csi_attr_info, 0, 0, 0,
                 
(long)&((AVSV_DND_MSG*)0)->msg_info.d2n_compcsi_assign_msg_info.info.attrs, 0, 
NULL},

+               /*AVSV_D2N_SU_MAINTENANCE_MSG_INFO*/
+               {EDU_EXEC, ncs_edp_uns32, 0, 0, 0,
+        (long)&((AVSV_DND_MSG 
*)0)->msg_info.d2n_su_maintenance_msg_info.msg_id, 0, NULL},
+    {EDU_EXEC, m_NCS_EDP_SACLMNODEIDT, 0, 0, 0,
+        (long)&((AVSV_DND_MSG 
*)0)->msg_info.d2n_su_maintenance_msg_info.node_id, 0, NULL},
+               {EDU_EXEC, ncs_edp_sanamet, 0, 0, 0,
+                   
(long)&((AVSV_DND_MSG*)0)->msg_info.d2n_su_maintenance_msg_info.su, 0, NULL},
+               {EDU_EXEC, ncs_edp_sanamet, 0, 0, EDU_EXIT,
+                   
(long)&((AVSV_DND_MSG*)0)->msg_info.d2n_su_maintenance_msg_info.suMaintenanceCampaign,
 0, NULL},
+
                {EDU_END, 0, 0, 0, 0, 0, 0, NULL},
        };

@@ -482,7 +492,8 @@ int avsv_dnd_msg_test_type_fnc(NCSCONTEX
                LCL_JMP_OFFSET_AVSV_D2N_REBOOT_MSG = 123,
                LCL_JMP_OFFSET_AVSV_N2D_ND_SISU_STATE_INFO_MSG = 125,
                LCL_JMP_OFFSET_AVSV_N2D_ND_CSICOMP_STATE_INFO_MSG = 131,
-               LCL_JMP_OFFSET_AVSV_D2N_COMPCSI_ASSIGN_MSG = 137
+               LCL_JMP_OFFSET_AVSV_D2N_COMPCSI_ASSIGN_MSG = 137,
+               LCL_JMP_OFFSET_AVSV_D2N_SU_MAINTENANCE_MSG = 143
        };
        AVSV_DND_MSG_TYPE type;

@@ -554,6 +565,8 @@ int avsv_dnd_msg_test_type_fnc(NCSCONTEX
                return LCL_JMP_OFFSET_AVSV_N2D_ND_CSICOMP_STATE_INFO_MSG ;
        case AVSV_D2N_COMPCSI_ASSIGN_MSG:
                return LCL_JMP_OFFSET_AVSV_D2N_COMPCSI_ASSIGN_MSG;
+       case AVSV_D2N_SU_MAINTENANCE_MSG:
+               return LCL_JMP_OFFSET_AVSV_D2N_SU_MAINTENANCE_MSG;

        default:
                break;
diff --git a/osaf/libs/common/amf/d2nmsg.c b/osaf/libs/common/amf/d2nmsg.c
--- a/osaf/libs/common/amf/d2nmsg.c
+++ b/osaf/libs/common/amf/d2nmsg.c
@@ -513,6 +513,15 @@ static void free_d2n_compcsi_info(AVSV_D

 }

+static void free_d2n_su_maintenance_info(AVSV_DND_MSG *su_maintenance_msg)
+{
+  AVSV_D2N_SU_MAINTENANCE_MSG_INFO *su_maintenance =
+    &su_maintenance_msg->msg_info.d2n_su_maintenance_msg_info;
+
+       osaf_extended_name_free(&su_maintenance->su);
+       osaf_extended_name_free(&su_maintenance->suMaintenanceCampaign);
+}
+
 /****************************************************************************
   Name          : avsv_dnd_msg_free

@@ -609,6 +618,9 @@ void avsv_dnd_msg_free(AVSV_DND_MSG *msg
        case AVSV_D2N_COMPCSI_ASSIGN_MSG:
                free_d2n_compcsi_info(msg);
                break;
+       case AVSV_D2N_SU_MAINTENANCE_MSG:
+               free_d2n_su_maintenance_info(msg);
+               break;
        default:
                break;
        }
diff --git a/osaf/libs/common/amf/include/amf_d2nmsg.h 
b/osaf/libs/common/amf/include/amf_d2nmsg.h
--- a/osaf/libs/common/amf/include/amf_d2nmsg.h
+++ b/osaf/libs/common/amf/include/amf_d2nmsg.h
@@ -51,6 +51,7 @@ extern "C" {
 #define AVSV_AVD_AVND_MSG_FMT_VER_5    5
 #define AVSV_AVD_AVND_MSG_FMT_VER_6    6
 #define AVSV_AVD_AVND_MSG_FMT_VER_7    7
+#define AVSV_AVD_AVND_MSG_FMT_VER_8    8

 /* Internode/External Components Validation result */
 typedef enum {
@@ -108,6 +109,7 @@ typedef enum {
        AVSV_N2D_ND_SISU_STATE_INFO_MSG,
        AVSV_N2D_ND_CSICOMP_STATE_INFO_MSG,
        AVSV_D2N_COMPCSI_ASSIGN_MSG,
+       AVSV_D2N_SU_MAINTENANCE_MSG,
        AVSV_DND_MSG_MAX
 } AVSV_DND_MSG_TYPE;

@@ -647,6 +649,16 @@ typedef struct avsv_d2n_compcsi_assign_m
        } info;
 } AVSV_D2N_COMPCSI_ASSIGN_MSG_INFO;

+/*
+ * Message structure to send updates to saAmfSUMaintenanceCampaign.
+ */
+typedef struct avsv_d2n_su_maintenance_msg {
+       uint32_t msg_id;
+       SaClmNodeIdT node_id;
+  SaNameT su;
+  SaNameT suMaintenanceCampaign;
+} AVSV_D2N_SU_MAINTENANCE_MSG_INFO;
+
 typedef struct avsv_dnd_msg {
        AVSV_DND_MSG_TYPE msg_type;
        union {
@@ -681,6 +693,7 @@ typedef struct avsv_dnd_msg {
                AVSV_D2N_HB_MSG_INFO d2n_hb_info;
                AVSV_D2N_REBOOT_MSG_INFO d2n_reboot_info;
                AVSV_D2N_COMPCSI_ASSIGN_MSG_INFO d2n_compcsi_assign_msg_info;
+               AVSV_D2N_SU_MAINTENANCE_MSG_INFO d2n_su_maintenance_msg_info;
        } msg_info;
 } AVSV_DND_MSG;

diff --git a/osaf/services/saf/amf/amfd/comp.cc 
b/osaf/services/saf/amf/amfd/comp.cc
--- a/osaf/services/saf/amf/amfd/comp.cc
+++ b/osaf/services/saf/amf/amfd/comp.cc
@@ -155,7 +155,7 @@ void AVD_COMP::avd_comp_pres_state_set(S
                 (saAmfCompPresenceState == 
SA_AMF_PRESENCE_TERMINATION_FAILED)) ||
                 ((node->saAmfNodeFailfastOnInstantiationFailure == true) &&
                  (saAmfCompPresenceState == SA_AMF_PRESENCE_INSTANTIATION_FAILED))) 
&&
-      (!su->saAmfSUMaintenanceCampaign.empty())) {
+      (su->saAmfSUMaintenanceCampaign.empty())) {

                saflog(LOG_NOTICE, amfSvcUsrName, "%s PresenceState %s => %s",
                                osaf_extended_name_borrow(&comp_info.name), 
avd_pres_state_name[old_state],
diff --git a/osaf/services/saf/amf/amfd/include/su.h 
b/osaf/services/saf/amf/amfd/include/su.h
--- a/osaf/services/saf/amf/amfd/include/su.h
+++ b/osaf/services/saf/amf/amfd/include/su.h
@@ -116,7 +116,7 @@ class AVD_SU {
        void set_term_state(bool state);
        void remove_from_model();
        void set_su_switch(SaToggleState state, bool wrt_to_imm = true);
-       AVD_AVND *get_node_ptr(void);
+       AVD_AVND *get_node_ptr(void) const;
        bool is_in_service(void);
        bool is_instantiable(void);
        void reset_all_comps_assign_flag();
diff --git a/osaf/services/saf/amf/amfd/include/util.h 
b/osaf/services/saf/amf/amfd/include/util.h
--- a/osaf/services/saf/amf/amfd/include/util.h
+++ b/osaf/services/saf/amf/amfd/include/util.h
@@ -102,5 +102,6 @@ extern const char *admin_op_name(SaAmfAd
 int compare_sanamet(const std::string& lhs, const std::string& rhs);
 uint32_t avd_snd_compcsi_msg(AVD_COMP *comp, AVD_CSI *csi,
                avd_comp_csi_rel_tag *compcsi, AVSV_COMPCSI_ACT act);
+uint32_t avd_snd_su_maintenance_msg(const AVD_SU&);

 #endif
diff --git a/osaf/services/saf/amf/amfd/mds.cc 
b/osaf/services/saf/amf/amfd/mds.cc
--- a/osaf/services/saf/amf/amfd/mds.cc
+++ b/osaf/services/saf/amf/amfd/mds.cc
@@ -46,7 +46,7 @@ const MDS_CLIENT_MSG_FORMAT_VER avd_avnd
        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 avd_avd_msg_fmt_map_table[] = {
diff --git a/osaf/services/saf/amf/amfd/sgproc.cc 
b/osaf/services/saf/amf/amfd/sgproc.cc
--- a/osaf/services/saf/amf/amfd/sgproc.cc
+++ b/osaf/services/saf/amf/amfd/sgproc.cc
@@ -804,7 +804,7 @@ void avd_su_oper_state_evh(AVD_CL_CB *cb
                                node->recvr_fail_sw = true;

         // if maintenance campaign is ongoing, disable node reboot
-        if (su->saAmfSUMaintenanceCampaign.empty())
+        if (!su->saAmfSUMaintenanceCampaign.empty())
           node_reboot_req = false;

                                switch 
(n2d_msg->msg_info.n2d_opr_state.rec_rcvr.raw) {
diff --git a/osaf/services/saf/amf/amfd/su.cc b/osaf/services/saf/amf/amfd/su.cc
--- a/osaf/services/saf/amf/amfd/su.cc
+++ b/osaf/services/saf/amf/amfd/su.cc
@@ -737,7 +737,7 @@ void AVD_SU::set_pres_state(SaAmfPresenc
                        (su_on_node->saAmfNodeFailfastOnTerminationFailure == true) 
&&
                        (sg_of_su->saAmfSGAutoRepair == true) &&
                        (su_on_node->saAmfNodeAutoRepair == true) &&
-      (!saAmfSUMaintenanceCampaign.empty()))
+      (saAmfSUMaintenanceCampaign.empty()))
                /* According to AMF B.04.01 Section 4.8 Page 214 if user 
configures
                   saAmfNodeFailfastOnTerminationFailure = true, AMF has to 
perform
                   node failfast recovery action. So mark SU to 
SA_AMF_PRESENCE_TERMINATION_FAILED
@@ -748,7 +748,7 @@ void AVD_SU::set_pres_state(SaAmfPresenc
                        (su_on_node->saAmfNodeFailfastOnInstantiationFailure == true) 
&&
                        (sg_of_su->saAmfSGAutoRepair == true) &&
                        (su_on_node->saAmfNodeAutoRepair == true) &&
-      (!saAmfSUMaintenanceCampaign.empty()))
+      (saAmfSUMaintenanceCampaign.empty()))
                /* According to AMF B.04.01 Section 4.6 Page 212 if user 
configures
                   saAmfNodeFailfastOnInstantiationFailure = true, AMF has to 
perform
                   node failfast recovery action. So mark SU to 
SA_AMF_PRESENCE_INSTANTIATION_FAILED
@@ -1782,6 +1782,32 @@ static SaAisErrorT su_ccb_completed_cb(C
        return rc;
 }

+static void sendMaintenanceUpdateToND(const AVD_SU& su) {
+  do {
+    auto it(nds_mds_ver_db.find(
+      su.su_on_node->node_info.nodeId));
+
+    if (it == nds_mds_ver_db.end())
+      break;
+
+    // Check if this amfnd is capable of this functionality.
+    if (it->second < AVSV_AVD_AVND_MSG_FMT_VER_8) {
+      TRACE_3("not sending to '%s' on :%x with mds version:'%u'",
+              su.name.c_str(),
+              su.su_on_node->node_info.nodeId,
+              it->second);
+      break;
+    }
+
+    TRACE_3("sending to '%s' on :%x with mds version:'%u'",
+            su.name.c_str(),
+            su.su_on_node->node_info.nodeId,
+            it->second);
+
+    avd_snd_su_maintenance_msg(su);
+  } while (false);
+}
+
 /*****************************************************************************
  * Function: avd_su_ccb_apply_modify_hdlr
  *
@@ -1840,6 +1866,9 @@ static void su_ccb_apply_modify_hdlr(str
                                TRACE("saAmfSUMaintenanceCampaign set to '%s' for 
'%s'",
                                          su->saAmfSUMaintenanceCampaign.c_str(), 
su->name.c_str());
                        }
+
+      if (avd_cb->avail_state_avd == SA_AMF_HA_ACTIVE)
+        sendMaintenanceUpdateToND(*su);
                } else if (!strcmp(attr_mod->modAttr.attrName, "saAmfSUType")) {
                        AVD_SUTYPE *sut;
                        SaNameT sutype_name = *(SaNameT*) 
attr_mod->modAttr.attrValues[0];
@@ -2165,7 +2194,7 @@ void AVD_SU::set_su_switch(SaToggleState
        m_AVSV_SEND_CKPT_UPDT_ASYNC_UPDT(avd_cb, this, AVSV_CKPT_SU_SWITCH);
 }

-AVD_AVND *AVD_SU::get_node_ptr(void) {
+AVD_AVND *AVD_SU::get_node_ptr(void) const {
         if (su_is_external == true)
                 return avd_cb->ext_comp_info.local_avnd_node;
         else
diff --git a/osaf/services/saf/amf/amfd/util.cc 
b/osaf/services/saf/amf/amfd/util.cc
--- a/osaf/services/saf/amf/amfd/util.cc
+++ b/osaf/services/saf/amf/amfd/util.cc
@@ -1764,6 +1764,14 @@ static void free_d2n_compcsi_info(AVSV_D
   }
 }

+static void free_d2n_su_maintenance_info(AVSV_DND_MSG *su_maintenance_msg) {
+  AVSV_D2N_SU_MAINTENANCE_MSG_INFO *su_maintenance(
+    &su_maintenance_msg->msg_info.d2n_su_maintenance_msg_info);
+
+  osaf_extended_name_free(&su_maintenance->su);
+  osaf_extended_name_free(&su_maintenance->suMaintenanceCampaign);
+}
+
 /****************************************************************************
   Name          : d2n_msg_free

@@ -1815,6 +1823,9 @@ void d2n_msg_free(AVSV_DND_MSG *msg)
        case AVSV_D2N_COMPCSI_ASSIGN_MSG:
                free_d2n_compcsi_info(msg);
                break;
+       case AVSV_D2N_SU_MAINTENANCE_MSG:
+               free_d2n_su_maintenance_info(msg);
+               break;
        default:
                break;
        }
@@ -2096,3 +2107,66 @@ uint32_t avd_snd_compcsi_msg(AVD_COMP *c
   return NCSCC_RC_SUCCESS;
 }

+/**
+ * @brief    Sends a message to AMFND for a change in SUMaintenanceCampaign
+ * @param    ptr to su
+ * @param    act(action of type AVSV_COMPCSI_ACT)
+ * @return   NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE.
+ */
+uint32_t avd_snd_su_maintenance_msg(const AVD_SU& su) {
+  TRACE_ENTER2("'%s', '%s'",
+               su.name.c_str(),
+               su.saAmfSUMaintenanceCampaign.c_str());
+
+  uint32_t rc(NCSCC_RC_SUCCESS);
+
+  do {
+    AVD_AVND *avnd(su.get_node_ptr());
+
+    if (avnd->node_state == AVD_AVND_STATE_ABSENT ||
+        avnd->node_state == AVD_AVND_STATE_GO_DOWN) {
+      break;
+    }
+
+    // Will be freed in free_d2n_su_maintenance_info()
+    SaNameT su_name;
+    osaf_extended_name_alloc(su.name.c_str(), &su_name);
+
+    // Will be freed in free_d2n_su_maintenance_info()
+    SaNameT suMaintenanceCampaign;
+    osaf_extended_name_alloc(su.saAmfSUMaintenanceCampaign.c_str(),
+                             &suMaintenanceCampaign);
+
+    // prepare the SU_MAINTENANCE message
+    AVD_DND_MSG *su_maintenance_msg(new AVSV_DND_MSG);
+    su_maintenance_msg->msg_type = AVSV_D2N_SU_MAINTENANCE_MSG;
+    su_maintenance_msg->msg_info.d2n_su_maintenance_msg_info.node_id =
+      avnd->node_info.nodeId;
+    su_maintenance_msg->msg_info.d2n_su_maintenance_msg_info.su = su_name;
+    
su_maintenance_msg->msg_info.d2n_su_maintenance_msg_info.suMaintenanceCampaign =
+      suMaintenanceCampaign;
+
+    // Generate new msg_id.
+    su_maintenance_msg->msg_info.d2n_su_maintenance_msg_info.msg_id =
+      ++(avnd->snd_msg_id);
+
+    // Send SU_MAINTENANCE message*/
+    TRACE("Sending %u to %x",
+          AVSV_D2N_SU_MAINTENANCE_MSG,
+          avnd->node_info.nodeId);
+
+    if (avd_d2n_msg_snd(avd_cb, avnd, su_maintenance_msg) != NCSCC_RC_SUCCESS) 
{
+      LOG_ER("Send to %x failed",avnd->node_info.nodeId);
+      --(avnd->snd_msg_id);
+      d2n_msg_free(su_maintenance_msg);
+      rc = NCSCC_RC_FAILURE;
+      break;
+    }
+
+    // Checkpoint to standby AMFD.
+    m_AVSV_SEND_CKPT_UPDT_ASYNC_UPDT(avd_cb, avnd, AVSV_CKPT_AVND_SND_MSG_ID);
+  } while (false);
+
+  TRACE_LEAVE();
+  return rc;
+}
diff --git a/osaf/services/saf/amf/amfnd/clc.cc 
b/osaf/services/saf/amf/amfnd/clc.cc
--- a/osaf/services/saf/amf/amfnd/clc.cc
+++ b/osaf/services/saf/amf/amfnd/clc.cc
@@ -970,19 +970,29 @@ uint32_t avnd_comp_clc_st_chng_prc(AVND_
        if (comp->su->is_ncs == true) {
                if(SA_AMF_PRESENCE_INSTANTIATION_FAILED == final_st) {
                        LOG_ER("'%s'got Inst failed", comp->name.c_str());
-                       opensaf_reboot(avnd_cb->node_info.nodeId,
-                                                       
osaf_extended_name_borrow(&avnd_cb->node_info.executionEnvironment),
-                                                       "NCS component Instantiation 
failed");
-                       LOG_ER("Amfnd is exiting (due to ncs comp inst failed) to 
aid fast reboot");
-                       exit(0);
+      if (comp->su->suMaintenanceCampaign.empty()) {
+                         opensaf_reboot(avnd_cb->node_info.nodeId,
+                                                         
osaf_extended_name_borrow(&avnd_cb->node_info.executionEnvironment),
+                                                         "NCS component 
Instantiation failed");
+                         LOG_ER("Amfnd is exiting (due to ncs comp inst failed) to 
aid fast reboot");
+                         exit(0);
+      } else {
+        LOG_NO("not rebooting as maintenance campaign is ongoing");
+        goto done;
+      }
                }
                if(SA_AMF_PRESENCE_TERMINATION_FAILED == final_st) {
                        LOG_ER("'%s'got Term failed", comp->name.c_str());
-                       opensaf_reboot(avnd_cb->node_info.nodeId,
+      if (comp->su->suMaintenanceCampaign.empty()) {
+                         opensaf_reboot(avnd_cb->node_info.nodeId,
                                                        
osaf_extended_name_borrow(&avnd_cb->node_info.executionEnvironment),
-                                                       "NCS component Termination 
failed");
-                       LOG_ER("Amfnd is exiting (due to ncs comp term failed) to 
aid fast reboot");
-                       exit(0);
+                                                         "NCS component Termination 
failed");
+                         LOG_ER("Amfnd is exiting (due to ncs comp term failed) to 
aid fast reboot");
+                         exit(0);
+      } else {
+        LOG_NO("not rebooting as maintenance campaign is ongoing");
+        goto done;
+      }
                }
        }

diff --git a/osaf/services/saf/amf/amfnd/err.cc 
b/osaf/services/saf/amf/amfnd/err.cc
--- a/osaf/services/saf/amf/amfnd/err.cc
+++ b/osaf/services/saf/amf/amfnd/err.cc
@@ -407,8 +407,14 @@ uint32_t avnd_err_process(AVND_CB *cb, A
                LOG_ER("%s Faulted due to:%s Recovery is:%s",
                       comp->name.c_str(), g_comp_err[comp->err_info.src], 
g_comp_rcvr[esc_rcvr - 1]);
                /* do the local node reboot for node_failfast or ncs component 
failure*/
-               opensaf_reboot(avnd_cb->node_info.nodeId, 
osaf_extended_name_borrow(&avnd_cb->node_info.executionEnvironment),
+    if (comp->su->suMaintenanceCampaign.empty()) {
+                 opensaf_reboot(avnd_cb->node_info.nodeId, 
osaf_extended_name_borrow(&avnd_cb->node_info.executionEnvironment),
                                "Component faulted: recovery is node failfast");
+    } else {
+      LOG_NO("not rebooting because maintenance campaign is set: %s",
+             comp->su->suMaintenanceCampaign.c_str());
+      goto done;
+    }
        }

        /* execute the recovery */
@@ -1038,11 +1044,17 @@ uint32_t avnd_err_rcvr_node_failover(AVN
                rc = avnd_comp_clc_fsm_run(cb, comp, 
AVND_COMP_CLC_PRES_FSM_EV_CLEANUP);
                if (rc != NCSCC_RC_SUCCESS) {
                        LOG_ER("'%s' termination failed", comp->name.c_str());
-                       opensaf_reboot(avnd_cb->node_info.nodeId,
+      if (comp->su->suMaintenanceCampaign.empty()) {
+                         opensaf_reboot(avnd_cb->node_info.nodeId,
                                                   
osaf_extended_name_borrow(&avnd_cb->node_info.executionEnvironment),
                                                   "Component termination failed at 
node failover");
-                       LOG_ER("Exiting (due to comp term failed) to aid fast node 
reboot");
-                       exit(1);
+                         LOG_ER("Exiting (due to comp term failed) to aid fast node 
reboot");
+                         exit(1);
+      } else {
+        LOG_NO("not rebooting because maintenance campaign is set: %s",
+               comp->su->suMaintenanceCampaign.c_str());
+        continue;
+      }
                }
                avnd_su_pres_state_set(cb, comp->su, 
SA_AMF_PRESENCE_TERMINATING);
        }
diff --git a/osaf/services/saf/amf/amfnd/evt.cc 
b/osaf/services/saf/amf/amfnd/evt.cc
--- a/osaf/services/saf/amf/amfnd/evt.cc
+++ b/osaf/services/saf/amf/amfnd/evt.cc
@@ -88,6 +88,7 @@ AVND_EVT *avnd_evt_create(AVND_CB *cb,
        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_SU_MAINTENANCE_MSG:
                evt->info.avd = (AVSV_DND_MSG *)info;
                break;

@@ -237,6 +238,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_SU_MAINTENANCE_MSG:
                if (evt->info.avd)
                        avsv_dnd_msg_free(evt->info.avd);
                break;
diff --git a/osaf/services/saf/amf/amfnd/include/avnd_evt.h 
b/osaf/services/saf/amf/amfnd/include/avnd_evt.h
--- a/osaf/services/saf/amf/amfnd/include/avnd_evt.h
+++ b/osaf/services/saf/amf/amfnd/include/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_SU_MAINTENANCE_MSG,
        AVND_EVT_AVD_MAX,

        /* AvA event types */
diff --git a/osaf/services/saf/amf/amfnd/include/avnd_mds.h 
b/osaf/services/saf/amf/amfnd/include/avnd_mds.h
--- a/osaf/services/saf/amf/amfnd/include/avnd_mds.h
+++ b/osaf/services/saf/amf/amfnd/include/avnd_mds.h
@@ -31,10 +31,10 @@
 #define 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/osaf/services/saf/amf/amfnd/include/avnd_su.h 
b/osaf/services/saf/amf/amfnd/include/avnd_su.h
--- a/osaf/services/saf/amf/amfnd/include/avnd_su.h
+++ b/osaf/services/saf/amf/amfnd/include/avnd_su.h
@@ -143,6 +143,8 @@ typedef struct avnd_su_tag {
        uint32_t si_active_cnt; /* no of active SIs assigned to this su */
        uint32_t si_standby_cnt;        /* no of standby SIs assigned to this 
su */

+  std::string suMaintenanceCampaign;
+
        /*
         * Ordered comp list (based on inst level). Note that as the
         * lexicographic key (comp-name) & the keys used for
@@ -417,5 +419,6 @@ extern AVND_SU *avnd_sudb_rec_get(AmfDb<
 extern AVND_SU *avnd_sudb_rec_get_next(AmfDb<std::string, AVND_SU>& sudb, const 
std::string& name);
 extern void sudb_rec_comp_add(AVND_SU *su, AVND_COMP *comp, uint32_t *rc);
 uint32_t avnd_evt_avd_compcsi_evh(struct avnd_cb_tag *cb, struct avnd_evt_tag 
*evt);
+uint32_t avnd_evt_avd_su_maintenance_evh(avnd_cb_tag *, AVND_EVT *);

 #endif
diff --git a/osaf/services/saf/amf/amfnd/main.cc 
b/osaf/services/saf/amf/amfnd/main.cc
--- a/osaf/services/saf/amf/amfnd/main.cc
+++ b/osaf/services/saf/amf/amfnd/main.cc
@@ -69,6 +69,7 @@ extern const AVND_EVT_HDLR g_avnd_func_l
        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_su_maintenance_evh, //AVND_EVT_AVD_SU_MAINTENANCE_MSG

        /* AvA event types */
        avnd_evt_ava_finalize_evh,      /* AVND_EVT_AVA_AMF_FINALIZE */
diff --git a/osaf/services/saf/amf/amfnd/mds.cc 
b/osaf/services/saf/amf/amfnd/mds.cc
--- a/osaf/services/saf/amf/amfnd/mds.cc
+++ b/osaf/services/saf/amf/amfnd/mds.cc
@@ -42,7 +42,7 @@ const MDS_CLIENT_MSG_FORMAT_VER avnd_avd
        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 */
@@ -50,7 +50,7 @@ const MDS_CLIENT_MSG_FORMAT_VER avd_avnd
        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[] = {
@@ -404,6 +404,8 @@ uint32_t avnd_mds_rcv(AVND_CB *cb, MDS_C

                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_SU_MAINTENANCE_MSG)
+                       type = AVND_EVT_AVD_SU_MAINTENANCE_MSG;
                else
                        type = 
static_cast<AVND_EVT_TYPE>((msg.info.avd->msg_type - AVSV_D2N_NODE_UP_MSG) + 
AVND_EVT_AVD_NODE_UP_MSG);
                break;
diff --git a/osaf/services/saf/amf/amfnd/su.cc 
b/osaf/services/saf/amf/amfnd/su.cc
--- a/osaf/services/saf/amf/amfnd/su.cc
+++ b/osaf/services/saf/amf/amfnd/su.cc
@@ -1042,4 +1042,50 @@ done:
   return rc;
 }

+/**
+ * @brief  Processes su maintenance message from AMFD.
+ * @param  cb (ptr to AVND_CB)
+ * @param  evt(ptr to AVND_EVT)
+ *
+ * @return NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE.
+ */
+uint32_t avnd_evt_avd_su_maintenance_evh(AVND_CB *cb, AVND_EVT *evt) {
+  uint32_t rc(NCSCC_RC_SUCCESS);

+  do {
+    AVSV_D2N_SU_MAINTENANCE_MSG_INFO *su_maintenance(
+      &evt->info.avd->msg_info.d2n_su_maintenance_msg_info);
+
+    const std::string su_name(Amf::to_string(&su_maintenance->su));
+    const std::string suMaintenanceCampaign(Amf::to_string(
+      &su_maintenance->suMaintenanceCampaign));
+
+    TRACE_ENTER2("'%s', '%s'", su_name.c_str(), suMaintenanceCampaign.c_str());
+
+    AVND_SU *su(avnd_sudb_rec_get(cb->sudb, su_name));
+
+    if (!su) {
+      LOG_ER("su: '%s' not found", su_name.c_str());
+      break;
+    }
+
+    if (cb->term_state == AVND_TERM_STATE_OPENSAF_SHUTDOWN_INITIATED ||
+        cb->term_state == AVND_TERM_STATE_OPENSAF_SHUTDOWN_STARTED) {
+      LOG_NO("Shutdown started : Ignoring setting of su maintenance'%s'",
+             su->name.c_str());
+      break;
+    }
+
+    avnd_msgid_assert(su_maintenance->msg_id);
+    cb->rcv_msg_id = su_maintenance->msg_id;
+
+    TRACE("setting suMaintenanceCampaign to %s for su: %s",
+          suMaintenanceCampaign.c_str(),
+          su_name.c_str());
+
+    su->suMaintenanceCampaign = suMaintenanceCampaign;
+  } while (false);
+
+  TRACE_LEAVE2("%u", rc);
+  return rc;
+}
diff --git a/osaf/services/saf/amf/amfnd/susm.cc 
b/osaf/services/saf/amf/amfnd/susm.cc
--- a/osaf/services/saf/amf/amfnd/susm.cc
+++ b/osaf/services/saf/amf/amfnd/susm.cc
@@ -2787,8 +2787,14 @@ uint32_t avnd_su_pres_terming_comptermfa

        if (true == su->is_ncs) {
                std::string reason = "SU '" + su->name + "' Termination-failed";
-               opensaf_reboot(avnd_cb->node_info.nodeId, 
osaf_extended_name_borrow(&avnd_cb->node_info.executionEnvironment),
-                               reason.c_str());
+    if (su->suMaintenanceCampaign.empty()) {
+                 opensaf_reboot(avnd_cb->node_info.nodeId, 
osaf_extended_name_borrow(&avnd_cb->node_info.executionEnvironment),
+                                 reason.c_str());
+    } else {
+      LOG_ER("%s", reason.c_str());
+      LOG_NO("not rebooting because su maintenance campaign is set: %s",
+             su->suMaintenanceCampaign.c_str());
+    }
        }

  done:


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

diff --git a/src/amf/amfd/ndproc.cc b/src/amf/amfd/ndproc.cc
--- a/src/amf/amfd/ndproc.cc
+++ b/src/amf/amfd/ndproc.cc
@@ -270,7 +270,7 @@ void avd_oper_req_evh(AVD_CL_CB *cb, AVD
                goto done;
        }
 
-       LOG_ER("Operation request FAILED, sender %x, '%s'",
+       LOG_WA("Operation request FAILED, sender %x, '%s'",
                n2d_msg->msg_info.n2d_op_req.node_id, 
osaf_extended_name_borrow(&n2d_msg->msg_info.n2d_op_req.param_info.name));
 
  done:
diff --git a/src/amf/amfd/su.cc b/src/amf/amfd/su.cc
--- a/src/amf/amfd/su.cc
+++ b/src/amf/amfd/su.cc
@@ -1816,6 +1816,7 @@ static SaAisErrorT su_ccb_completed_cb(C
 }
 
 static void sendMaintenanceUpdateToND(const AVD_SU& su) {
+       return;
   do {
     auto it(nds_mds_ver_db.find(
       su.su_on_node->node_info.nodeId));
@@ -1901,8 +1902,12 @@ static void su_ccb_apply_modify_hdlr(str
                                          
su->saAmfSUMaintenanceCampaign.c_str(), su->name.c_str());
                        }
 
-      if (avd_cb->avail_state_avd == SA_AMF_HA_ACTIVE)
-        sendMaintenanceUpdateToND(*su);
+                       if (avd_cb->avail_state_avd == SA_AMF_HA_ACTIVE) {
+                               su->sendMaintenanceUpdateToND_1();
+
+                               //TODO:remove below call.
+                               sendMaintenanceUpdateToND(*su);
+                       }
                } else if (!strcmp(attr_mod->modAttr.attrName, "saAmfSUType")) {
                        AVD_SUTYPE *sut;
                        SaNameT sutype_name = *(SaNameT*) 
attr_mod->modAttr.attrValues[0];
@@ -2137,6 +2142,15 @@ void AVD_SU::send_attribute_update(AVSV_
                        memcpy(&param.value[0], &sufailover, param.value_len);
                        break;
                }
+               case saAmfSUMaintenanceCampaign_Id:
+               {
+                       TRACE("Sending maintenanceCampaign name");
+                       param.attr_id = saAmfSUMaintenanceCampaign_Id;
+                       param.value_len = saAmfSUMaintenanceCampaign.length();
+                       
osaf_extended_name_alloc(saAmfSUMaintenanceCampaign.c_str(),
+                                       &param.name_sec);
+                       break;
+               }
                default:
                        osafassert(0);
                }
@@ -2647,3 +2661,6 @@ void AVD_SU::set_surestart(bool value)
 bool AVD_SU::get_surestart() const
 { return surestart; }
 
+void AVD_SU::sendMaintenanceUpdateToND_1() {
+       send_attribute_update(saAmfSUMaintenanceCampaign_Id);
+}
diff --git a/src/amf/amfd/su.h b/src/amf/amfd/su.h
--- a/src/amf/amfd/su.h
+++ b/src/amf/amfd/su.h
@@ -147,6 +147,7 @@ class AVD_SU {
        bool all_comps_in_presence_state(SaAmfPresenceStateT pres) const;
        void set_surestart(bool state);
        bool get_surestart() const;
+       void sendMaintenanceUpdateToND_1() ;
 
  private:
        void initialize();
diff --git a/src/amf/amfnd/sudb.cc b/src/amf/amfnd/sudb.cc
--- a/src/amf/amfnd/sudb.cc
+++ b/src/amf/amfnd/sudb.cc
@@ -226,6 +226,12 @@ uint32_t avnd_su_oper_req(AVND_CB *cb, A
                        osafassert(sizeof(uint32_t) == param->value_len);
                        su->sufailover = m_NCS_OS_NTOHL(*(uint32_t 
*)(param->value));
                        break;
+               case saAmfSUMaintenanceCampaign_Id:
+                       su->suMaintenanceCampaign = 
Amf::to_string(&param->name_sec);
+                       TRACE("setting suMaintenanceCampaign to %s for su: %s",
+                                       su->suMaintenanceCampaign.c_str(),
+                                       su->name.c_str());
+                       break;
                default:
                        LOG_NO("%s: Unsupported attribute %u", __FUNCTION__, 
param->attr_id);
                        goto done;
diff --git a/src/amf/common/amf_defs.h b/src/amf/common/amf_defs.h
--- a/src/amf/common/amf_defs.h
+++ b/src/amf/common/amf_defs.h
@@ -203,6 +203,7 @@ typedef enum
    saAmfSUParentSGName_ID = 12,
    saAmfSUIsExternal_ID = 13,
    saAmfSURestartCount_ID = 14,
+   saAmfSUMaintenanceCampaign_Id = 15,
 } AVSV_AMF_SU_ATTR_ID; 
 
 /* Attribute ID enum for the saAmfComp class */
------------------------------------------------------------------------------
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