Attaching the patches used.

Thanks,
Neel.
On 2017/03/03 03:15 PM, Neelakanta Reddy wrote:
Hi Alex,

The included patches are: latest #2144 patch provided by praveen with
latest #2145 patch.

The Rolling upgrade campaign to change the application version is failing.
This is basic application upgrade test.

   # smf-state camp
safSmfCampaign=Campaign1,safApp=safSmfService
          state=ERROR_DETECTED(7)
          error='safSu=dummy_2n_1,safSg=SG_dummy_2n,safApp=2nApp failed
after upgrade'

syslog:
Mar 27 08:10:57 SLES1 osafsmfd[29847]: NO PROC: Procedure init actions
completed
Mar 27 08:10:57 SLES1 osafsmfd[29847]: NO PROC: Start executing the steps
Mar 27 08:10:57 SLES1 osafsmfd[29847]: NO STEP: Executing AU restart
step
safSmfStep=0001,safSmfProc=amfClusterProc-1,safSmfCampaign=Campaign1,safApp=safSmfService
Mar 27 08:10:57 SLES1 osafsmfd[29847]: NO STEP: Online installation of
new software
Mar 27 08:10:57 SLES1 osafsmfnd[29845]: NO Successful start of command
execution: /hostfs/online_install.sh bundle-new, timeout 80000
Mar 27 08:10:57 SLES1 osafsmfnd[29845]: NO Command execution OK
Mar 27 08:10:57 SLES1 osafsmfd[29847]: NO STEP: Create new
SaAmfNodeSwBundle objects
Mar 27 08:10:57 SLES1 osafimmnd[29768]: NO Ccb 54 COMMITTED (SMFSERVICE)
Mar 27 08:10:57 SLES1 osafsmfd[29847]: NO STEP: Modify information model
and set maintenance status
Mar 27 08:10:57 SLES1 osafimmnd[29768]: NO Ccb 55 COMMITTED (SMFSERVICE)
Mar 27 08:10:57 SLES1 osafamfnd[29829]: NO saAmfCompType changed to
'safVersion=6.0.0,safCompType=Comp_2nApp_2n_1_1' for
'safComp=Norm1,safSu=dummy_2n_1,safSg=SG_dummy_2n,safApp=2nApp'
Mar 27 08:10:57 SLES1 osafimmnd[29768]: NO Ccb 56 COMMITTED (SMFSERVICE)
Mar 27 08:10:57 SLES1 osafsmfd[29847]: NO STEP: Restart activation units
Mar 27 08:10:57 SLES1 osafamfnd[29829]: NO Admin restart requested for
'safComp=Norm1,safSu=dummy_2n_1,safSg=SG_dummy_2n,safApp=2nApp'
Mar 27 08:10:57 SLES1 osafamfnd[29829]: NO not restarting comp because
maintenance campaign is set: safSmfCampaign=Campaign1,safApp=safSmfService
Mar 27 08:10:57 SLES1 osafsmfd[29847]: ER SU:
safSu=dummy_2n_1,safSg=SG_dummy_2n,safApp=2nApp failed after upgrade in
campaign

Thanks,
Neel.



On 2017/03/03 02:55 AM, Alex Jones wrote:
Hi Praveen,

    Both patches look fine except for one issue in the first patch
(02_2144.patch). See the comment below.

Neel, do you have any comments for the SMF patch?

    If both of you guys are OK, then I will push the AMF (my original and
Praveen's 2 later ones) and SMF patches tomorrow.

Alex

diff --git a/src/amf/amfd/sgproc.cc b/src/amf/amfd/sgproc.cc
--- a/src/amf/amfd/sgproc.cc
+++ b/src/amf/amfd/sgproc.cc
@@ -2092,13 +2092,17 @@ void avd_node_down_mw_susi_failover(AVD_
     * one loop as more than one MW SU per SG in one node is not supported.
     */
    osafassert(avnd->list_of_ncs_su.empty() != true);
-
+ bool campaign_set = avnd->is_campaign_set_for_all_sus();
    for (const auto& i_su : avnd->list_of_ncs_su) {
+   if ((avnd->saAmfNodeAdminState != SA_AMF_ADMIN_LOCKED_INSTANTIATION) ||
+       (campaign_set == false)) {
+     i_su->set_oper_state(SA_AMF_OPERATIONAL_DISABLED);
+     i_su->disable_comps(SA_AIS_ERR_TIMEOUT);
+   }

[Alex] The following line needs to be removed.
      i_su->set_oper_state(SA_AMF_OPERATIONAL_DISABLED);
[Alex] Done comment
      i_su->set_pres_state(SA_AMF_PRESENCE_UNINSTANTIATED);

On 03/01/2017 04:10 AM, praveen malviya wrote:
------------------------------------------------------------------------
NOTICE: This email was received from an EXTERNAL sender
------------------------------------------------------------------------

Hi Alex,

Change in comp.cc looks fine.

I guess other changes are related to the node reboot case in the context
of a campaign which performs upgrade by rebooting the node. In this case
since amfnd is freshly coming up, SUs on this node will not have their
sumaintenance attribute set (amfnd does not read su config from IMM)
which was set before SMF orders node reboot. If this is the case then I
think this can still be achieved without updating AMFD and AMFND MDS
versions and without including it in SU_REG message.

How to do it: AMFD still can send campaign name by calling
su->set_su_maintenance_campaign() for each SU when it gets response from
amfnd for SU_REG successful and before it sends instantiation message
for any SU. By this time AMFND has already all the information of SU
hosted on it, so it will update the su_db with campaign name. Attached
is the patch based on this idea (2144_update.patch).

Thanks,
Praveen


On 01-Mar-17 3:01 AM, Alex Jones wrote:
src/amf/amfd/mds.cc | 2 +-
src/amf/amfd/mds.h | 4 ++--
src/amf/amfd/util.cc | 5 +++++
src/amf/amfnd/avnd_mds.h | 4 ++--
src/amf/amfnd/comp.cc | 2 +-
src/amf/amfnd/mds.cc | 4 ++--
src/amf/amfnd/sudb.cc | 2 ++
src/amf/common/amf_d2nmsg.h | 2 ++
src/amf/common/d2nedu.c | 6 ++++++
src/amf/common/d2nmsg.c | 2 ++
10 files changed, 25 insertions(+), 8 deletions(-)


This patch adds support for Section 3.11.1.4.2 of AMF B.04.01 spec:
Restrictions
to Auto-Repair.

diff --git a/src/amf/amfd/mds.cc b/src/amf/amfd/mds.cc
--- a/src/amf/amfd/mds.cc
+++ b/src/amf/amfd/mds.cc
@@ -47,7 +47,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/src/amf/amfd/mds.h b/src/amf/amfd/mds.h
--- a/src/amf/amfd/mds.h
+++ b/src/amf/amfd/mds.h
@@ -33,10 +33,10 @@

/* In Service upgrade support */
#define AVD_MDS_SUB_PART_VERSION_4 4
-#define AVD_MDS_SUB_PART_VERSION 7
+#define AVD_MDS_SUB_PART_VERSION 8

#define AVD_AVND_SUBPART_VER_MIN 1
-#define AVD_AVND_SUBPART_VER_MAX 7
+#define AVD_AVND_SUBPART_VER_MAX 8

#define AVD_AVD_SUBPART_VER_MIN 1
#define AVD_AVD_SUBPART_VER_MAX 6
diff --git a/src/amf/amfd/util.cc b/src/amf/amfd/util.cc
--- a/src/amf/amfd/util.cc
+++ b/src/amf/amfd/util.cc
@@ -483,6 +483,10 @@ static void reg_su_msg_init_su_info(AVD_
su_info->su_is_external = su->su_is_external;
su_info->su_failover = su->saAmfSUFailover;

+ SaNameT suCampaign;
+ osaf_extended_name_alloc(su->saAmfSUMaintenanceCampaign.c_str(),
&suCampaign);
+ su_info->suMaintenanceCampaign = suCampaign;
+
su_info->next = su_msg->msg_info.d2n_reg_su.su_list;
su_msg->msg_info.d2n_reg_su.su_list = su_info;
su_msg->msg_info.d2n_reg_su.num_su++;
@@ -1671,6 +1675,7 @@ static void free_d2n_su_msg_info(AVSV_DN
su_info = su_msg->msg_info.d2n_reg_su.su_list;
su_msg->msg_info.d2n_reg_su.su_list = su_info->next;
osaf_extended_name_free(&su_info->name);
+ osaf_extended_name_free(&su_info->suMaintenanceCampaign);
delete su_info;
}
}
diff --git a/src/amf/amfnd/avnd_mds.h b/src/amf/amfnd/avnd_mds.h
--- a/src/amf/amfnd/avnd_mds.h
+++ b/src/amf/amfnd/avnd_mds.h
@@ -31,10 +31,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/comp.cc b/src/amf/amfnd/comp.cc
--- a/src/amf/amfnd/comp.cc
+++ b/src/amf/amfnd/comp.cc
@@ -2675,7 +2675,7 @@ uint32_t comp_restart_initiate(AVND_COMP
if (NCSCC_RC_SUCCESS != rc)
goto done;

- if (!comp->su->suMaintenanceCampaign.empty()) {
+ if (!comp->su->suMaintenanceCampaign.empty() && !comp->admin_oper) {
LOG_NO("not restarting comp because maintenance campaign is set: %s",
comp->su->suMaintenanceCampaign.c_str());

diff --git a/src/amf/amfnd/mds.cc b/src/amf/amfnd/mds.cc
--- a/src/amf/amfnd/mds.cc
+++ b/src/amf/amfnd/mds.cc
@@ -43,7 +43,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 */
@@ -51,7 +51,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[] = {
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
@@ -52,6 +52,7 @@ AVND_SU *avnd_sudb_rec_add(AVND_CB *cb,
{
AVND_SU *su = 0;
const std::string info_name = Amf::to_string(&info->name);
+ const std::string info_campaign =
Amf::to_string(&info->suMaintenanceCampaign);
TRACE_ENTER2("SU'%s'", info_name.c_str());
/* verify if this su is already present in the db */
@@ -80,6 +81,7 @@ AVND_SU *avnd_sudb_rec_add(AVND_CB *cb,
su->is_ncs = info->is_ncs;
su->su_is_external = info->su_is_external;
su->sufailover = info->su_failover;
+ su->suMaintenanceCampaign = info_campaign;

/*
* Update the rest of the parameters with default values.
diff --git a/src/amf/common/amf_d2nmsg.h b/src/amf/common/amf_d2nmsg.h
--- a/src/amf/common/amf_d2nmsg.h
+++ b/src/amf/common/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 {
@@ -137,6 +138,7 @@ typedef struct avsv_su_info_msg {
bool is_ncs;
bool su_is_external; /*indicates if this SU is external */
bool su_failover;
+ SaNameT suMaintenanceCampaign;
struct avsv_su_info_msg *next;
} AVSV_SU_INFO_MSG;

diff --git a/src/amf/common/d2nedu.c b/src/amf/common/d2nedu.c
--- a/src/amf/common/d2nedu.c
+++ b/src/amf/common/d2nedu.c
@@ -635,6 +635,7 @@ uint32_t avsv_edp_su_info_msg(EDU_HDL *h
AVSV_SU_INFO_MSG *struct_ptr = NULL, **d_ptr = NULL;
uint16_t ver2 = AVSV_AVD_AVND_MSG_FMT_VER_2;
uint16_t ver5 = AVSV_AVD_AVND_MSG_FMT_VER_5;
+ uint16_t ver8 = AVSV_AVD_AVND_MSG_FMT_VER_8;

EDU_INST_SET avsv_su_info_msg_rules[] = {
{EDU_START, avsv_edp_su_info_msg, EDQ_LNKLIST, 0, 0,
@@ -665,6 +666,11 @@ uint32_t avsv_edp_su_info_msg(EDU_HDL *h
{EDU_EXEC, ncs_edp_ncs_bool, 0, 0, 0,
(long)&((AVSV_SU_INFO_MSG *)0)->su_failover, 0, NULL},

+ /* Include suMaintenanceCampaign in version 8 and higher */
+ {EDU_VER_GE, NULL, 0, 0, 2, 0, 0, (EDU_EXEC_RTINE)((uint16_t
*)(&(ver8)))},
+ {EDU_EXEC, ncs_edp_sanamet, 0, 0, 0,
+ (long)&((AVSV_SU_INFO_MSG *)0)->suMaintenanceCampaign, 0, NULL},
+
{EDU_TEST_LL_PTR, avsv_edp_su_info_msg, 0, 0, 0,
(long)&((AVSV_SU_INFO_MSG *)0)->next, 0, NULL},
{EDU_END, 0, 0, 0, 0, 0, 0, NULL},
diff --git a/src/amf/common/d2nmsg.c b/src/amf/common/d2nmsg.c
--- a/src/amf/common/d2nmsg.c
+++ b/src/amf/common/d2nmsg.c
@@ -49,6 +49,7 @@ static void free_d2n_su_msg_info(AVSV_DN
su_info = su_msg->msg_info.d2n_reg_su.su_list;
su_msg->msg_info.d2n_reg_su.su_list = su_info->next;
osaf_extended_name_free(&su_info->name);
+ osaf_extended_name_free(&su_info->suMaintenanceCampaign);
free(su_info);
}
}
@@ -85,6 +86,7 @@ static uint32_t cpy_d2n_su_msg(AVSV_DND_

memcpy(d_su_info, s_su_info, sizeof(AVSV_SU_INFO_MSG));
osaf_extended_name_alloc(osaf_extended_name_borrow(&s_su_info->name),
&d_su_info->name);
+
osaf_extended_name_alloc(osaf_extended_name_borrow(&s_su_info->suMaintenanceCampaign),
&d_su_info->suMaintenanceCampaign);
d_su_info->next = d_su_msg->msg_info.d2n_reg_su.su_list;
d_su_msg->msg_info.d2n_reg_su.su_list = d_su_info;



------------------------------------------------------------------------------
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
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

diff --git a/src/amf/amfd/comp.cc b/src/amf/amfd/comp.cc
--- a/src/amf/amfd/comp.cc
+++ b/src/amf/amfd/comp.cc
@@ -156,7 +156,8 @@ void AVD_COMP::avd_comp_pres_state_set(S
                (((node->saAmfNodeFailfastOnTerminationFailure == true) && 
                 (saAmfCompPresenceState == 
SA_AMF_PRESENCE_TERMINATION_FAILED)) ||
                 ((node->saAmfNodeFailfastOnInstantiationFailure == true) && 
-                 (saAmfCompPresenceState == 
SA_AMF_PRESENCE_INSTANTIATION_FAILED)))) {
+                 (saAmfCompPresenceState == 
SA_AMF_PRESENCE_INSTANTIATION_FAILED))) &&
+               (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/src/amf/amfd/ndproc.cc b/src/amf/amfd/ndproc.cc
--- a/src/amf/amfd/ndproc.cc
+++ b/src/amf/amfd/ndproc.cc
@@ -152,6 +152,20 @@ void avd_reg_su_evh(AVD_CL_CB *cb, AVD_E
                /* the node has been successfully updated with SU information */
                avd_node_state_set(node, AVD_AVND_STATE_NCS_INIT);
 
+               //Before any SU gets instantiated, send Maintenance campaign 
update.
+               for (const auto& su : node->list_of_ncs_su) {
+                       if (su->saAmfSUMaintenanceCampaign.empty() == false) {
+                               TRACE("Sending Maintenance campaign info for 
'%s'",su->name.c_str());
+                               su->set_su_maintenance_campaign();
+                       }
+               }
+               for (const auto& su : node->list_of_su) {
+                        if (su->saAmfSUMaintenanceCampaign.empty() == false) {
+                                TRACE("Sending Maintenance campaign info for 
'%s'",su->name.c_str());
+                                su->set_su_maintenance_campaign();
+                        }
+                }
+
                /* Instantiate all OpenSAF SUs on this node */
                for (const auto& su : node->list_of_ncs_su) {
                        if ((su->saAmfSUAdminState == SA_AMF_ADMIN_UNLOCKED) ||
diff --git a/src/amf/amfd/node.cc b/src/amf/amfd/node.cc
--- a/src/amf/amfd/node.cc
+++ b/src/amf/amfd/node.cc
@@ -1587,4 +1587,16 @@ void avd_node_constructor(void)
        avd_class_impl_set("SaAmfNode", nullptr, node_admin_op_cb,
                        node_ccb_completed_cb, node_ccb_apply_cb);
 }
-
+bool AVD_AVND::is_campaign_set_for_all_sus() const {
+  if (std::all_of(list_of_ncs_su.begin(), list_of_ncs_su.end(),
+    [&](AVD_SU *su) -> bool {return su->saAmfSUMaintenanceCampaign.empty() == 
false;})) {
+    if (std::all_of(list_of_su.begin(), list_of_su.end(),
+      [&](AVD_SU *su) -> bool {return su->saAmfSUMaintenanceCampaign.empty() 
== false;})) {
+      return true;
+    } else {
+      return false;
+    }
+  } else {
+    return false;
+  }
+}
diff --git a/src/amf/amfd/node.h b/src/amf/amfd/node.h
--- a/src/amf/amfd/node.h
+++ b/src/amf/amfd/node.h
@@ -143,7 +143,7 @@ class AVD_AVND {
   AVD_AMF_NG *admin_ng; /* points to the nodegroup on which admin operation is 
going on.*/
   uint16_t node_up_msg_count; /* to count of node_up msg that director had 
received from this node */
   bool reboot;
-
+  bool is_campaign_set_for_all_sus() const;
   //Member functions.
   void node_sus_termstate_set(bool term_state) const;
  private:
diff --git a/src/amf/amfd/ntf.cc b/src/amf/amfd/ntf.cc
--- a/src/amf/amfd/ntf.cc
+++ b/src/amf/amfd/ntf.cc
@@ -29,6 +29,28 @@
 #include "base/osaf_time.h"
 #include <queue>
 
+static uint32_t sendAlarmNotificationAvd(AVD_CL_CB *avd_cb,
+                              const std::string& ntf_object,
+                              SaUint8T *add_text,
+                              SaUint16T majorId,
+                              SaUint16T minorId,
+                              uint32_t probableCause,
+                              uint32_t perceivedSeverity,
+                              NCSCONTEXT add_info,
+                              bool add_info_is_present);
+
+static uint32_t sendStateChangeNotificationAvd(AVD_CL_CB *avd_cb,
+                                    const std::string& ntf_object,
+                                    SaUint8T *add_text,
+                                    SaUint16T majorId,
+                                    SaUint16T minorId,
+                                    uint32_t sourceIndicator,
+                                    SaUint16T stateId,
+                                    SaUint16T oldstate,
+                                    SaUint16T newState,
+                                    NCSCONTEXT add_info,
+                                    bool additional_info_is_present);
+
 /*****************************************************************************
   Name          :  avd_send_comp_inst_failed_alarm
 
@@ -231,9 +253,11 @@ void avd_send_admin_state_chg_ntf(const 
   Notes         :
 *****************************************************************************/
 void avd_send_oper_chg_ntf(const std::string& name, SaAmfNotificationMinorIdT 
minor_id,
-               SaAmfOperationalStateT old_state, SaAmfOperationalStateT 
new_state)
+               SaAmfOperationalStateT old_state, SaAmfOperationalStateT 
new_state,
+               const std::string *maintenanceCampaign)
 {
        const std::string add_text("Oper state " + name + " changed");
+       const SaNameTWrapper mc(maintenanceCampaign ? *maintenanceCampaign : 
"");
 
        TRACE_ENTER();
 
@@ -246,8 +270,8 @@ void avd_send_oper_chg_ntf(const std::st
                                        SA_AMF_OP_STATE,
                                        old_state,
                                        new_state,
-                                       nullptr,
-                                       false);
+                                       (NCSCONTEXT)static_cast<const 
SaNameT*>(mc),
+                                       maintenanceCampaign ? 
!maintenanceCampaign->empty() : false);
        TRACE_LEAVE();
 }
 
@@ -464,7 +488,7 @@ void avd_alarm_clear(const std::string& 
        TRACE_LEAVE();
 }
 
-SaAisErrorT fill_ntf_header_part_avd(SaNtfNotificationHeaderT 
*notificationHeader,
+static SaAisErrorT fill_ntf_header_part_avd(SaNtfNotificationHeaderT 
*notificationHeader,
                              SaNtfEventTypeT eventType,
                              const std::string &comp_name,
                              SaUint8T *add_text,
@@ -472,7 +496,7 @@ SaAisErrorT fill_ntf_header_part_avd(SaN
                              SaUint16T minorId,
                              SaInt8T *avd_name,
                              NCSCONTEXT add_info,
-                             int additional_info_is_present,
+                             bool additional_info_is_present,
                              SaNtfNotificationHandleT notificationHandle)
 {
 
@@ -512,7 +536,11 @@ SaAisErrorT fill_ntf_header_part_avd(SaN
                                notificationHeader->additionalInfo[0].infoId = 
SA_AMF_SI_NAME;
                                notificationHeader->additionalInfo[0].infoType 
= SA_NTF_VALUE_LDAP_NAME;
 
-                       }
+                       } else if (minorId == SA_AMF_NTFID_SU_OP_STATE) {
+                               /* maintenance campaign */
+                               notificationHeader->additionalInfo[0].infoId   
= SA_AMF_MAINTENANCE_CAMPAIGN_DN;
+                               notificationHeader->additionalInfo[0].infoType 
= SA_NTF_VALUE_LDAP_NAME;
+      }
 
                        ret = saNtfPtrValAllocate(notificationHandle,
                                        sizeof (SaNameT) + 1,
@@ -590,7 +618,7 @@ uint32_t sendAlarmNotificationAvd(AVD_CL
                               uint32_t probableCause,
                               uint32_t perceivedSeverity,
                               NCSCONTEXT add_info,
-                              int type)
+                              bool add_info_is_present)
 {
        uint32_t status = NCSCC_RC_FAILURE;
        SaUint16T add_info_items = 0;
@@ -608,7 +636,7 @@ uint32_t sendAlarmNotificationAvd(AVD_CL
        }
        NtfSend *job = new NtfSend{};
 
-       if (type != 0) {
+       if (add_info_is_present) {
                add_info_items = 1;
                allocation_size = SA_NTF_ALLOC_SYSTEM_LIMIT;
        }
@@ -643,7 +671,7 @@ uint32_t sendAlarmNotificationAvd(AVD_CL
                                 minorId,
                                 const_cast<SaInt8T*>(AMF_NTF_SENDER),
                                 add_info,
-                                type,
+                                add_info_is_present,
                                 
job->myntf.notification.alarmNotification.notificationHandle);
        
        if (status != SA_AIS_OK) {
@@ -665,7 +693,7 @@ uint32_t sendAlarmNotificationAvd(AVD_CL
 
 }
 
-uint32_t sendStateChangeNotificationAvd(AVD_CL_CB *avd_cb,
+static uint32_t sendStateChangeNotificationAvd(AVD_CL_CB *avd_cb,
                                     const std::string& ntf_object,
                                     SaUint8T *add_text,
                                     SaUint16T majorId,
@@ -675,7 +703,7 @@ uint32_t sendStateChangeNotificationAvd(
                                     SaUint16T oldstate,
                                     SaUint16T newState,
                                     NCSCONTEXT add_info,
-                                    int additional_info_is_present)
+                                    bool additional_info_is_present)
 {
        uint32_t status = NCSCC_RC_FAILURE;
        SaUint16T add_info_items = 0;
diff --git a/src/amf/amfd/ntf.h b/src/amf/amfd/ntf.h
--- a/src/amf/amfd/ntf.h
+++ b/src/amf/amfd/ntf.h
@@ -55,7 +55,8 @@ void avd_send_comp_proxy_status_unproxie
 void avd_send_admin_state_chg_ntf(const std::string& name, 
SaAmfNotificationMinorIdT minor_id,
                                        SaAmfAdminStateT old_state, 
SaAmfAdminStateT new_state);
 void avd_send_oper_chg_ntf(const std::string& name, SaAmfNotificationMinorIdT 
minor_id, 
-                                       SaAmfOperationalStateT old_state, 
SaAmfOperationalStateT new_state);
+                                       SaAmfOperationalStateT old_state, 
SaAmfOperationalStateT new_state,
+                                       const std::string *maintenanceCampaign 
= 0);
 void avd_send_su_pres_state_chg_ntf(const std::string& su_name, 
SaAmfPresenceStateT old_state,
                                        SaAmfPresenceStateT new_state);
 void avd_send_su_ha_state_chg_ntf(const std::string& su_name, const 
std::string& si_name,
@@ -67,39 +68,6 @@ void avd_send_si_assigned_ntf(const std:
 void avd_send_comp_proxy_status_proxied_ntf(const std::string& comp_name,
                                        SaAmfProxyStatusT old_state, 
SaAmfProxyStatusT new_state);
 
-/* general functions */
-SaAisErrorT fill_ntf_header_part(SaNtfNotificationHeaderT *notificationHeader,
-                                  SaNtfEventTypeT eventType,
-                                  const std::string& comp_name,
-                                  SaUint8T *add_text,
-                                  SaUint16T majorId,
-                                  SaUint16T minorId,
-                                  SaInt8T *avnd_name,
-                                  NCSCONTEXT add_info,
-                                  int type); /* add_info 0 --> no,  1--> 
node_name, 2--> si_name*/
-
-uint32_t sendAlarmNotificationAvd(AVD_CL_CB *avd_cb,
-                                       const std::string& comp_name,
-                                       SaUint8T *add_text,
-                                       SaUint16T majorId,
-                                       SaUint16T minorId,
-                                       uint32_t probableCause,
-                                       uint32_t perceivedSeverity,
-                                       NCSCONTEXT add_info,
-                                       int type); /* add_info 0 --> no,  1--> 
node_name, 2--> si_name*/
-
-uint32_t sendStateChangeNotificationAvd(AVD_CL_CB *avd_cb,
-                                             const std::string& comp_name,
-                                             SaUint8T *add_text,
-                                             SaUint16T majorId,
-                                             SaUint16T minorId,
-                                             uint32_t sourceIndicator,
-                                             SaUint16T stateId,
-                                             SaUint16T oldState,
-                                             SaUint16T newState,
-                                             NCSCONTEXT add_info,
-                                             int type); /* add_info 0 --> no,  
1--> node_name, 2--> si_name*/
-
 /* Clearing of alarms */
 void avd_alarm_clear(const std::string& name, SaUint16T minorId, uint32_t 
probableCause);
 
diff --git a/src/amf/amfd/sgproc.cc b/src/amf/amfd/sgproc.cc
--- a/src/amf/amfd/sgproc.cc
+++ b/src/amf/amfd/sgproc.cc
@@ -286,7 +286,8 @@ void su_try_repair(const AVD_SU *su)
        if ((su->sg_of_su->saAmfSGAutoRepair) && (su->saAmfSUFailover) &&
                        (su->saAmfSUOperState == SA_AMF_OPERATIONAL_DISABLED) &&
                        (su->saAmfSUPresenceState != 
SA_AMF_PRESENCE_INSTANTIATION_FAILED) && 
-                       (su->saAmfSUPresenceState != 
SA_AMF_PRESENCE_TERMINATION_FAILED)) {
+                       (su->saAmfSUPresenceState != 
SA_AMF_PRESENCE_TERMINATION_FAILED) &&
+                       (su->saAmfSUMaintenanceCampaign.empty())) {
 
                saflog(LOG_NOTICE, amfSvcUsrName, "Ordering Auto repair of '%s' 
as sufailover repair action",
                                su->name.c_str());
@@ -615,6 +616,11 @@ static void perform_nodeswitchover_recov
                if (su->list_of_susi == nullptr)
                        continue;
 
+               if (!su->saAmfSUMaintenanceCampaign.empty()) {
+                       node_reboot = false;
+                       continue;
+               }
+
                if (su_recover_from_fault(su) == NCSCC_RC_FAILURE) {
                        LOG_ER("%s:%d %s", __FUNCTION__, __LINE__, 
su->name.c_str());
                        goto done;
@@ -754,6 +760,15 @@ void avd_su_oper_state_evh(AVD_CL_CB *cb
                        TRACE("Component in %s requested FAILFAST", 
su->name.c_str());
                }
 
+               if (!su->saAmfSUMaintenanceCampaign.empty()) {
+                       saflog(LOG_NOTICE,
+                               amfSvcUsrName,
+                               "Node Fail-Fast disabled because maintenance 
campaign %s is set for su: %s",
+                               su->saAmfSUMaintenanceCampaign.c_str(),
+                               su->name.c_str());
+                       goto done;
+               }
+
                avd_nd_ncs_su_failed(cb, node);
                goto done;
        }
@@ -793,6 +808,16 @@ void avd_su_oper_state_evh(AVD_CL_CB *cb
                 */
                if (su->sg_of_su->sg_ncs_spec == true) {
                        su->set_oper_state(SA_AMF_OPERATIONAL_DISABLED);
+
+               if (!su->saAmfSUMaintenanceCampaign.empty()) {
+                       saflog(LOG_NOTICE,
+                               amfSvcUsrName,
+                               "Node Fail-Fast disabled because maintenance 
campaign %s is set for su: %s",
+                               su->saAmfSUMaintenanceCampaign.c_str(),
+                               su->name.c_str());
+                       goto done;
+               }
+
                        avd_nd_ncs_su_failed(cb, node);
                        goto done;
                }
@@ -831,10 +856,16 @@ void avd_su_oper_state_evh(AVD_CL_CB *cb
                                 */
                                avd_node_oper_state_set(node, 
SA_AMF_OPERATIONAL_DISABLED);
                                node->recvr_fail_sw = true;
+
+                               // if maintenance campaign is ongoing, disable 
node reboot
+                               if (!su->saAmfSUMaintenanceCampaign.empty())
+                                       node_reboot_req = false;
+
                                switch 
(n2d_msg->msg_info.n2d_opr_state.rec_rcvr.raw) {
                                case SA_AMF_NODE_FAILOVER:
                                        if ((node->node_info.nodeId == 
cb->node_id_avd) && 
-                                                       
(node->saAmfNodeAutoRepair)) {
+                                                       
(node->saAmfNodeAutoRepair) &&
+                                                       
(su->saAmfSUMaintenanceCampaign.empty())) {
                                                /* This is a case when Act ctlr 
is rebooting. Don't do appl failover
                                                   as of now because during 
appl failover if Act controller reboots,
                                                   then there may be packet 
losses. Anyway, this controller is
@@ -1614,12 +1645,17 @@ void avd_su_si_assign_evh(AVD_CL_CB *cb,
 
                /* We are checking only application components as on payload 
all ncs comp are in no_red model.
                   We are doing the same thing for controller also. */
+               bool maintenanceCampaignSet(false);
+
+               if (su && !su->saAmfSUMaintenanceCampaign.empty())
+                       maintenanceCampaignSet = true;
+
                for (const auto& temp_su : node->list_of_su) {
                        if (nullptr != temp_su->list_of_susi) {
                                all_su_unassigned = false;
                        }
                }
-               if (true == all_su_unassigned) {
+               if (true == all_su_unassigned && !maintenanceCampaignSet) {
                        /* All app su got unassigned, Safe to reboot the blade 
now. */
                        node_try_repair(node);
                }
@@ -2056,13 +2092,16 @@ void avd_node_down_mw_susi_failover(AVD_
         * one loop as more than one MW SU per SG in one node is not supported.
         */
        osafassert(avnd->list_of_ncs_su.empty() != true);
-
+       bool campaign_set = avnd->is_campaign_set_for_all_sus();
        for (const auto& i_su : avnd->list_of_ncs_su) {
-               i_su->set_oper_state(SA_AMF_OPERATIONAL_DISABLED);
+               if ((avnd->saAmfNodeAdminState != 
SA_AMF_ADMIN_LOCKED_INSTANTIATION) || 
+                               (campaign_set == false)) {
+                       i_su->set_oper_state(SA_AMF_OPERATIONAL_DISABLED);
+                       i_su->disable_comps(SA_AIS_ERR_TIMEOUT);
+               }
                i_su->set_pres_state(SA_AMF_PRESENCE_UNINSTANTIATED);
                i_su->set_readiness_state(SA_AMF_READINESS_OUT_OF_SERVICE);
                i_su->complete_admin_op(SA_AIS_ERR_TIMEOUT);
-               i_su->disable_comps(SA_AIS_ERR_TIMEOUT);
 
                /* Now analyze the service group for the new HA state
                 * assignments and send the SU SI assign messages
@@ -2106,14 +2145,18 @@ void avd_node_down_appl_susi_failover(AV
 {
        TRACE_ENTER2("'%s'", avnd->name.c_str());
 
+       bool campaign_set = avnd->is_campaign_set_for_all_sus();
        /* Run through the list of application SUs make all of them O.O.S. 
         */
        for (const auto& i_su : avnd->list_of_su) {
-               i_su->set_oper_state(SA_AMF_OPERATIONAL_DISABLED);
+               if ((avnd->saAmfNodeAdminState != 
SA_AMF_ADMIN_LOCKED_INSTANTIATION) || 
+                               (campaign_set == false)) {
+                       i_su->set_oper_state(SA_AMF_OPERATIONAL_DISABLED);
+                       i_su->disable_comps(SA_AIS_ERR_TIMEOUT);
+               }
                i_su->set_pres_state(SA_AMF_PRESENCE_UNINSTANTIATED);
                i_su->set_readiness_state(SA_AMF_READINESS_OUT_OF_SERVICE);
                i_su->complete_admin_op(SA_AIS_ERR_TIMEOUT);
-               i_su->disable_comps(SA_AIS_ERR_TIMEOUT);
        }
 
        /* If the AvD is in AVD_APP_STATE run through all the application SUs 
and 
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
@@ -738,7 +738,8 @@ void AVD_SU::set_pres_state(SaAmfPresenc
        else if ((pres_state == SA_AMF_PRESENCE_TERMINATION_FAILED) &&
                        (su_on_node->saAmfNodeFailfastOnTerminationFailure == 
true) &&
                        (sg_of_su->saAmfSGAutoRepair == true) &&
-                       (su_on_node->saAmfNodeAutoRepair == true)) 
+                       (su_on_node->saAmfNodeAutoRepair == true) &&
+                       (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 +749,8 @@ void AVD_SU::set_pres_state(SaAmfPresenc
        else if ((pres_state == SA_AMF_PRESENCE_INSTANTIATION_FAILED) &&
                        (su_on_node->saAmfNodeFailfastOnInstantiationFailure == 
true) &&
                        (sg_of_su->saAmfSGAutoRepair == true) &&
-                       (su_on_node->saAmfNodeAutoRepair == true)) 
+                       (su_on_node->saAmfNodeAutoRepair == true) &&
+                       (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
@@ -812,7 +814,7 @@ void AVD_SU::set_oper_state(SaAmfOperati
        saAmfSUOperState = oper_state;
 
        avd_send_oper_chg_ntf(name, SA_AMF_NTFID_SU_OP_STATE, old_state,
-               saAmfSUOperState);
+               saAmfSUOperState, &saAmfSUMaintenanceCampaign);
 
        avd_saImmOiRtObjectUpdate(name, "saAmfSUOperState",
                SA_IMM_ATTR_SAUINT32T, &saAmfSUOperState);
@@ -1885,6 +1887,7 @@ static void su_ccb_apply_modify_hdlr(str
                                TRACE("saAmfSUMaintenanceCampaign set to '%s' 
for '%s'",
                                          
su->saAmfSUMaintenanceCampaign.c_str(), su->name.c_str());
                        }
+                       su->set_su_maintenance_campaign();
                } else if (!strcmp(attr_mod->modAttr.attrName, "saAmfSUType")) {
                        AVD_SUTYPE *sut;
                        SaNameT sutype_name = *(SaNameT*) 
attr_mod->modAttr.attrValues[0];
@@ -2119,6 +2122,13 @@ void AVD_SU::send_attribute_update(AVSV_
                        memcpy(&param.value[0], &sufailover, param.value_len);
                        break;
                }
+               case saAmfSUMaintenanceCampaign_ID:
+               {
+                       param.attr_id = saAmfSUMaintenanceCampaign_ID;
+                       param.value_len = saAmfSUMaintenanceCampaign.length();
+                       memcpy(&param.value[0], 
saAmfSUMaintenanceCampaign.data(), param.value_len);
+                       break;
+               }
                default:
                        osafassert(0);
                }
@@ -2138,6 +2148,10 @@ void AVD_SU::set_su_failover(bool value)
        send_attribute_update(saAmfSUFailOver_ID);
 }
 
+void AVD_SU::set_su_maintenance_campaign(void) {
+       send_attribute_update(saAmfSUMaintenanceCampaign_ID);
+}
+
 /**
  * Delete all SUSIs assigned to the SU.
  *
@@ -2210,7 +2224,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/src/amf/amfd/su.h b/src/amf/amfd/su.h
--- a/src/amf/amfd/su.h
+++ b/src/amf/amfd/su.h
@@ -97,6 +97,7 @@ class AVD_SU {
        AVD_SU *su_list_su_type_next;
 
        void set_su_failover(bool value);
+       void set_su_maintenance_campaign(void);
        void dec_curr_stdby_si();
        void inc_curr_stdby_si();
        void inc_curr_act_si();
@@ -117,7 +118,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/src/amf/amfnd/avnd_su.h b/src/amf/amfnd/avnd_su.h
--- a/src/amf/amfnd/avnd_su.h
+++ b/src/amf/amfnd/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 
diff --git a/src/amf/amfnd/clc.cc b/src/amf/amfnd/clc.cc
--- a/src/amf/amfnd/clc.cc
+++ b/src/amf/amfnd/clc.cc
@@ -971,19 +971,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);
+                               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/src/amf/amfnd/comp.cc b/src/amf/amfnd/comp.cc
--- a/src/amf/amfnd/comp.cc
+++ b/src/amf/amfnd/comp.cc
@@ -2679,6 +2679,21 @@ uint32_t comp_restart_initiate(AVND_COMP
        if (NCSCC_RC_SUCCESS != rc)
                goto done;
 
+  if (!comp->su->suMaintenanceCampaign.empty()) {
+    LOG_NO("not restarting comp because maintenance campaign is set: %s",
+    comp->su->suMaintenanceCampaign.c_str());
+
+    m_AVND_COMP_OPER_STATE_SET(comp, SA_AMF_OPERATIONAL_DISABLED);
+    rc = avnd_comp_oper_state_avd_sync(cb, comp);
+
+    /* update su oper state */
+    if (m_AVND_SU_OPER_STATE_IS_ENABLED(comp->su)) {
+      m_AVND_SU_OPER_STATE_SET(comp->su, SA_AMF_OPERATIONAL_DISABLED);
+      avnd_di_uns32_upd_send(AVSV_SA_AMF_SU, saAmfSUOperState_ID, 
comp->su->name, comp->su->oper);
+    }
+    goto done;
+  }
+
        rc = avnd_comp_clc_fsm_run(cb, comp, AVND_COMP_CLC_PRES_FSM_EV_RESTART);
        if (NCSCC_RC_SUCCESS != rc)
                goto done;
diff --git a/src/amf/amfnd/err.cc b/src/amf/amfnd/err.cc
--- a/src/amf/amfnd/err.cc
+++ b/src/amf/amfnd/err.cc
@@ -457,8 +457,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 */
@@ -701,6 +707,8 @@ uint32_t avnd_err_rcvr_su_restart(AVND_C
        if (NCSCC_RC_SUCCESS != rc)
                goto done;
 
+       avnd_di_uns32_upd_send(AVSV_SA_AMF_SU, saAmfSUOperState_ID, su->name, 
su->oper);
+
        set_suRestart_flag(su);
 
        if (su_all_comps_restartable(*su) == true) {
@@ -724,6 +732,13 @@ uint32_t avnd_err_rcvr_su_restart(AVND_C
                rc = avnd_su_si_unmark(cb, su);
                if (NCSCC_RC_SUCCESS != rc)
                        goto done;
+
+               if (!su->suMaintenanceCampaign.empty()) {
+                       LOG_NO("not restarting su because maintenance campaign 
is set: %s",
+                               su->suMaintenanceCampaign.c_str());
+                       goto done;
+               }
+
                rc = avnd_su_pres_fsm_run(cb, su, 0, 
AVND_SU_PRES_FSM_EV_RESTART);
                if (NCSCC_RC_SUCCESS != rc)
                        goto done;
@@ -747,6 +762,12 @@ uint32_t avnd_err_rcvr_su_restart(AVND_C
                TODO:In future when AMF supports comp-failover in spec 
compliance then this 
                        case should be alligned with that.
                */
+               if (!su->suMaintenanceCampaign.empty()) {
+                       LOG_NO("not restarting su because maintenance campaign 
is set: %s",
+                               su->suMaintenanceCampaign.c_str());
+                       goto done;
+               }
+
                if (m_AVND_SU_IS_PREINSTANTIABLE(su)) {
                        if (m_AVND_COMP_TYPE_IS_PREINSTANTIABLE(failed_comp))
                                rc = avnd_comp_clc_fsm_run(cb, failed_comp, 
AVND_COMP_CLC_PRES_FSM_EV_CLEANUP);
@@ -1056,11 +1077,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/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 = std::string(param->value, 
param->value_len);
+                       if (su->suMaintenanceCampaign.length() > 0)
+                               TRACE("suMaintenanceCampaign for '%s' changed 
to '%s'",
+                                               su->name.c_str(), 
su->suMaintenanceCampaign.c_str());
+                       break;
                default:
                        LOG_NO("%s: Unsupported attribute %u", __FUNCTION__, 
param->attr_id);
                        goto done;
diff --git a/src/amf/amfnd/susm.cc b/src/amf/amfnd/susm.cc
--- a/src/amf/amfnd/susm.cc
+++ b/src/amf/amfnd/susm.cc
@@ -2832,8 +2832,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:
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
@@ -204,6 +204,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 */
 src/smf/smfd/SmfCampState.cc       |   68 ++++++++++
 src/smf/smfd/SmfCampState.h        |    7 +
 src/smf/smfd/SmfCampaignThread.cc  |  233 ++++++++++++++++++++++++++++++++++++-
 src/smf/smfd/SmfCampaignThread.h   |   15 ++
 src/smf/smfd/SmfStepTypes.cc       |   32 ++--
 src/smf/smfd/SmfUpgradeCampaign.cc |   20 +++
 src/smf/smfd/SmfUpgradeCampaign.h  |    7 +
 7 files changed, 363 insertions(+), 19 deletions(-)


This patch adds support for section 4.2.1.3 of SMF A.01.02 spec.

diff --git a/src/smf/smfd/SmfCampState.cc b/src/smf/smfd/SmfCampState.cc
--- a/src/smf/smfd/SmfCampState.cc
+++ b/src/smf/smfd/SmfCampState.cc
@@ -191,6 +191,18 @@ SmfCampState::commit(SmfUpgradeCampaign 
 }
 
 
//------------------------------------------------------------------------------
+// asyncFailure()
+//------------------------------------------------------------------------------
+SmfCampResultT 
+SmfCampState::asyncFailure(SmfUpgradeCampaign *  i_camp)
+{
+       TRACE_ENTER();
+       LOG_NO("SmfCampState::asyncFailure default implementation. No state 
change");
+       TRACE_LEAVE();
+        return SMF_CAMP_DONE;
+}
+
+//------------------------------------------------------------------------------
 // procResult()
 
//------------------------------------------------------------------------------
 SmfCampResultT 
@@ -926,6 +938,37 @@ SmfCampStateExecuting::suspend(SmfUpgrad
 }
 
 
//------------------------------------------------------------------------------
+// asyncFailure()
+//------------------------------------------------------------------------------
+SmfCampResultT 
+SmfCampStateExecuting::asyncFailure(SmfUpgradeCampaign * i_camp)
+{
+       TRACE_ENTER();
+       TRACE("SmfCampStateExecuting::asyncFailure implementation");
+
+       /* Send suspend message to all procedures */
+        std::vector<SmfUpgradeProcedure*> procedures = i_camp->getProcedures();
+
+       std::vector < SmfUpgradeProcedure * >::iterator iter;
+
+       for (iter = procedures.begin(); iter != procedures.end(); ++iter) {
+                TRACE("SmfCampStateExecuting::Procedure %s, send suspend",
+                      (*iter)->getProcName().c_str());
+                SmfProcedureThread *procThread = (*iter)->getProcThread();
+                PROCEDURE_EVT *evt = new PROCEDURE_EVT();
+                evt->type = PROCEDURE_EVT_SUSPEND;
+                procThread->send(evt);
+       }
+
+        i_camp->m_noOfProcResponses = 0;
+        changeState(i_camp, SmfCampStateErrorDetected::instance());
+        /* Wait for suspend responses from all procedures 
(SmfCampStateSuspendingExec::procResult) */
+
+       TRACE_LEAVE();
+        return SMF_CAMP_SUSPENDING; 
+}
+
+//------------------------------------------------------------------------------
 // procResult()
 
//------------------------------------------------------------------------------
 SmfCampResultT 
@@ -1215,6 +1258,19 @@ SmfCampStateSuspendingExec::execute(SmfU
 }
 
 
//------------------------------------------------------------------------------
+// asyncFailure()
+//------------------------------------------------------------------------------
+SmfCampResultT
+SmfCampStateSuspendingExec::asyncFailure(SmfUpgradeCampaign * i_camp)
+{
+       TRACE_ENTER();
+       TRACE("SmfCampStateSuspendingExec::asyncFailure implementation");
+       changeState(i_camp, SmfCampStateErrorDetectedInSuspending::instance());
+       TRACE_LEAVE();
+       return SMF_CAMP_DONE;
+}
+
+//------------------------------------------------------------------------------
 // procResult()
 
//------------------------------------------------------------------------------
 SmfCampResultT 
@@ -1991,6 +2047,18 @@ SmfCampRollingBack::suspend(SmfUpgradeCa
 }
 
 
//------------------------------------------------------------------------------
+// asyncFailure()
+//------------------------------------------------------------------------------
+SmfCampResultT 
+SmfCampRollingBack::asyncFailure(SmfUpgradeCampaign * i_camp)
+{
+       TRACE_ENTER();
+       TRACE("SmfCampRollingBack::asyncFailure implementation");
+
+  return SmfCampRollingBack::suspend(i_camp);
+}
+
+//------------------------------------------------------------------------------
 // procResult()
 
//------------------------------------------------------------------------------
 SmfCampResultT 
diff --git a/src/smf/smfd/SmfCampState.h b/src/smf/smfd/SmfCampState.h
--- a/src/smf/smfd/SmfCampState.h
+++ b/src/smf/smfd/SmfCampState.h
@@ -72,6 +72,8 @@ class SmfCampState {
 
        virtual SmfCampResultT commit(SmfUpgradeCampaign * i_camp);
 
+       virtual SmfCampResultT asyncFailure(SmfUpgradeCampaign * i_camp);
+
        virtual SmfCampResultT procResult(SmfUpgradeCampaign *  i_camp,
                                           SmfUpgradeProcedure * i_procedure,
                                           SmfProcResultT        i_result);
@@ -132,6 +134,8 @@ class SmfCampStateExecuting:public SmfCa
 
        virtual SmfCampResultT suspend(SmfUpgradeCampaign * i_camp);
 
+       virtual SmfCampResultT asyncFailure(SmfUpgradeCampaign * i_camp);
+
        virtual SmfCampResultT procResult(SmfUpgradeCampaign *  i_camp,
                                           SmfUpgradeProcedure * i_procedure,
                                           SmfProcResultT        i_result);
@@ -182,6 +186,8 @@ class SmfCampStateSuspendingExec:public 
 
        virtual SmfCampResultT execute(SmfUpgradeCampaign * i_camp);
 
+       virtual SmfCampResultT asyncFailure(SmfUpgradeCampaign * i_camp);
+
        virtual SmfCampResultT procResult(SmfUpgradeCampaign *  i_camp,
                                           SmfUpgradeProcedure * i_procedure,
                                           SmfProcResultT        i_result);
@@ -345,6 +351,7 @@ class SmfCampRollingBack:public SmfCampS
        virtual SmfCampResultT rollbackSingleMergeProc(SmfUpgradeCampaign * 
i_camp);
        virtual SmfCampResultT rollbackInit(SmfUpgradeCampaign * i_camp);
        virtual SmfCampResultT suspend(SmfUpgradeCampaign * i_camp);
+       virtual SmfCampResultT asyncFailure(SmfUpgradeCampaign * i_camp);
        virtual SmfCampResultT procResult(SmfUpgradeCampaign *  i_camp,
                                           SmfUpgradeProcedure * i_procedure,
                                           SmfProcResultT        i_result);
diff --git a/src/smf/smfd/SmfCampaignThread.cc 
b/src/smf/smfd/SmfCampaignThread.cc
--- a/src/smf/smfd/SmfCampaignThread.cc
+++ b/src/smf/smfd/SmfCampaignThread.cc
@@ -40,6 +40,7 @@
 #include "smf/smfd/smfd_long_dn.h"
 
 SmfCampaignThread *SmfCampaignThread::s_instance = NULL;
+SaNtfSubscriptionIdT SmfCampaignThread::operStateSubId(1);
 
 #define SMF_RDA_RETRY_COUNT 25 /* This is taken as the csi's are assigned in 
parallel */
 
@@ -141,7 +142,12 @@ void SmfCampaignThread::main(NCSCONTEXT 
 SmfCampaignThread::~SmfCampaignThread()
 {
        TRACE_ENTER();
-       SaAisErrorT rc = saNtfFinalize(m_ntfHandle);
+       SaAisErrorT rc(saNtfNotificationUnsubscribe(operStateSubId));
+       if (rc != SA_AIS_OK) {
+               LOG_ER("Failed to unsubscribe to oper state notifications %u", 
rc);
+       }
+
+       rc = saNtfFinalize(m_ntfHandle);
        if (rc != SA_AIS_OK) {
                LOG_ER("Failed to finalize NTF handle %u", rc);
        }
@@ -304,10 +310,14 @@ int SmfCampaignThread::initNtf(void)
 {
        SaAisErrorT rc = SA_AIS_ERR_TRY_AGAIN;
        SaVersionT ntfVersion = { 'A', 1, 1 };
+       SaNtfCallbacksT callbacks = {
+               ntfNotificationCallback,
+               0
+       };
        unsigned int numOfTries = 50;
 
        while (rc == SA_AIS_ERR_TRY_AGAIN && numOfTries > 0) {
-               rc = saNtfInitialize(&m_ntfHandle, NULL, &ntfVersion);
+               rc = saNtfInitialize(&m_ntfHandle, &callbacks, &ntfVersion);
                if (rc != SA_AIS_ERR_TRY_AGAIN) {
                        break;
                }
@@ -320,9 +330,200 @@ int SmfCampaignThread::initNtf(void)
                return -1;
        }
 
+       // subscribe to operational state change notifications generated by AMF
+       rc = initNtfSubscriptions();
+       if (rc != SA_AIS_OK) {
+               LOG_ER("initNtfSubscriptions FAILED rc=%s", saf_error(rc));
+               return -1;
+       }
+
        return 0;
 }
 
+SaAisErrorT SmfCampaignThread::initNtfSubscriptions(void) {
+  TRACE_ENTER();
+  SaAisErrorT rc(SA_AIS_OK);
+
+  do {
+    SaNtfStateChangeNotificationFilterT stateChangeFilter;
+
+    SaAisErrorT rc(saNtfStateChangeNotificationFilterAllocate(
+      m_ntfHandle,
+      &stateChangeFilter,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0));
+
+    if (rc != SA_AIS_OK) {
+      LOG_ER("saNtfAttributeChangeNotificationFilterAllocate FAILED rc=%s",
+             saf_error(rc));
+      break;
+    }
+
+    SaNtfNotificationTypeFilterHandlesT notificationFilterHandles = {
+      0,
+      0,
+      stateChangeFilter.notificationFilterHandle,
+      0,
+      0
+    };
+
+    rc = saNtfNotificationSubscribe(&notificationFilterHandles, 
operStateSubId);
+
+    if (rc != SA_AIS_OK) {
+      LOG_ER("saNtfNotificationSubscribe FAILED rc=%s", saf_error(rc));
+      break;
+    }
+
+    rc = 
saNtfNotificationFilterFree(stateChangeFilter.notificationFilterHandle);
+    if (rc != SA_AIS_OK) {
+      LOG_ER("saNtfNotificationFilterFree FAILED rc=%s", saf_error(rc));
+      break;
+    }
+  } while (false);
+
+  TRACE_LEAVE();
+  return rc;
+}
+
+bool SmfCampaignThread::isAMFOperState(const SaNtfClassIdT& classId) const {
+  TRACE_ENTER();
+  bool status(false);
+
+  if (classId.vendorId == SA_NTF_VENDOR_ID_SAF &&
+      classId.majorId == SA_SVC_AMF &&
+      classId.minorId == SA_AMF_NTFID_SU_OP_STATE) {
+    status = true;
+  }
+
+  TRACE_LEAVE2("%i", status);
+  return status;
+}
+
+void SmfCampaignThread::handleStateChangeNotification(
+  const SaNtfStateChangeNotificationT& stateChangeNotification) {
+  TRACE_ENTER();
+  if (stateChangeNotification.notificationHeader.eventType) {
+    if (*stateChangeNotification.notificationHeader.eventType ==
+          SA_NTF_OBJECT_STATE_CHANGE) {
+      handleObjectStateChangeNotification(stateChangeNotification);
+    } else {
+      TRACE("ignoring state change notification with event type: %i",
+            *stateChangeNotification.notificationHeader.eventType);
+    }
+  }
+  TRACE_LEAVE();
+}
+
+void SmfCampaignThread::handleAmfObjectStateChangeNotification(
+  const SaNtfStateChangeNotificationT& stateChangeNotification) {
+  TRACE_ENTER();
+
+  do {
+    bool disabled(false);
+
+    // see if this is a failure of an upgraded SU
+    for (SaUint16T i(0); i < stateChangeNotification.numStateChanges; i++) {
+      if (stateChangeNotification.changedStates[i].newState ==
+            SA_AMF_OPERATIONAL_DISABLED) {
+        disabled = true;
+        break;
+      }
+    }
+
+    if (!disabled) {
+      TRACE("state change is not to DISABLED -- ignoring");
+      break;
+    }
+
+    for (SaUint16T i(0);
+         i < stateChangeNotification.notificationHeader.numAdditionalInfo;
+         i++) {
+      if (stateChangeNotification.notificationHeader.additionalInfo[i].infoId 
!=
+            SA_AMF_MAINTENANCE_CAMPAIGN_DN ||
+          stateChangeNotification.notificationHeader.additionalInfo[i].infoType
+            != SA_NTF_VALUE_LDAP_NAME) {
+        continue;
+      }
+
+      SaNameT *name(0);
+      SaUint16T dataSize(0);
+
+      SaAisErrorT rc(saNtfPtrValGet(
+        stateChangeNotification.notificationHandle,
+        
&stateChangeNotification.notificationHeader.additionalInfo[i].infoValue,
+        reinterpret_cast<void **>(&name),
+        &dataSize));
+
+      if (rc == SA_AIS_OK) {
+        SaConstStringT maintenanceCampaign(saAisNameBorrow(name));
+
+        if (!strcmp(maintenanceCampaign,
+                    s_instance->m_campaign->getDn().c_str())) {
+          LOG_ER("SU: %s failed after upgrade in campaign",
+                 
saAisNameBorrow(stateChangeNotification.notificationHeader.notificationObject));
+          s_instance->m_campaign->getUpgradeCampaign()->asyncFailure();
+
+          std::string error(saAisNameBorrow(
+            stateChangeNotification.notificationHeader.notificationObject));
+
+          error += " failed after upgrade";
+          s_instance->m_campaign->setError(error);
+        } else {
+          LOG_ER("maintenance campaign received from AMF (%s) is not the "
+                 "same as ours (%s)",
+                 maintenanceCampaign,
+                 s_instance->m_campaign->getDn().c_str());
+        }
+      } else {
+        LOG_ER("saNtfPtrValGet failed: %d", rc);
+      }
+    }
+  } while (false);
+
+  TRACE_LEAVE();
+}
+
+void SmfCampaignThread::handleObjectStateChangeNotification(
+  const SaNtfStateChangeNotificationT& stateChangeNotification) {
+  TRACE_ENTER();
+
+  if (stateChangeNotification.notificationHeader.notificationClassId &&
+      
isAMFOperState(*stateChangeNotification.notificationHeader.notificationClassId))
 {
+    handleAmfObjectStateChangeNotification(stateChangeNotification);
+  } else {
+    TRACE("ignoring non-AMF state change notification");
+  }
+
+  TRACE_LEAVE();
+}
+
+void SmfCampaignThread::ntfNotificationCallback(
+  SaNtfSubscriptionIdT subId,
+  const SaNtfNotificationsT *notification) {
+  TRACE_ENTER();
+
+  do {
+    if (subId != operStateSubId) {
+      TRACE("unknown subscription id received in ntfNotificationCallback: %d",
+            subId);
+      break;
+    }
+
+    if (notification->notificationType == SA_NTF_TYPE_STATE_CHANGE) {
+      s_instance->handleStateChangeNotification(
+        notification->notification.stateChangeNotification);
+    } else {
+      TRACE("ignoring NTF notification of type: %i",
+            notification->notificationType);
+    }
+  } while (false);
+
+  TRACE_LEAVE();
+}
 /** 
  * SmfCampaignThread::send
  * send event to the thread.
@@ -673,18 +874,31 @@ int SmfCampaignThread::handleEvents(void
 {
        TRACE_ENTER();
        NCS_SEL_OBJ mbx_fd = ncs_ipc_get_sel_obj(&m_mbx);
-       struct pollfd fds[1];
+
+       SaSelectionObjectT ntfSelObj(0);
+
+       SaAisErrorT rc(saNtfSelectionObjectGet(m_ntfHandle, &ntfSelObj));
+       if (rc != SA_AIS_OK) {
+               LOG_ER("saNtfSelectionObjectGet FAILED - %s", saf_error(rc));
+               return 1;
+       }
+
+       struct pollfd fds[2];
 
        /* Set up all file descriptors to listen to */
        fds[0].fd = mbx_fd.rmv_obj;
        fds[0].events = POLLIN;
        fds[0].revents = 0;
 
+       fds[1].fd = ntfSelObj;
+       fds[1].events = POLLIN;
+       fds[1].revents = 0;
+
        TRACE("Campaign thread %s waiting for events", 
m_campaign->getDn().c_str());
 
        while (m_running) {
 
-                int ret = poll(fds, 1, SMF_UPDATE_ELAPSED_TIME_INTERVAL);
+               int ret = poll(fds, sizeof(fds) / sizeof(pollfd), 
SMF_UPDATE_ELAPSED_TIME_INTERVAL);
 
                if (ret == -1) {
                        if (errno == EINTR)
@@ -700,7 +914,16 @@ int SmfCampaignThread::handleEvents(void
                        processEvt();
                }
 
-                m_campaign->updateElapsedTime();
+               if (fds[1].revents & POLLIN) {
+                       // dispatch NTF events
+                       rc = saNtfDispatch(m_ntfHandle, SA_DISPATCH_ALL);
+
+                       if (rc != SA_AIS_OK) {
+                               LOG_ER("saNtfDispatch FAILED - %s", 
saf_error(rc));
+                       }
+               }
+
+               m_campaign->updateElapsedTime();
        }
        TRACE_LEAVE();
        return 0;
diff --git a/src/smf/smfd/SmfCampaignThread.h b/src/smf/smfd/SmfCampaignThread.h
--- a/src/smf/smfd/SmfCampaignThread.h
+++ b/src/smf/smfd/SmfCampaignThread.h
@@ -190,9 +190,24 @@ class SmfCampaignThread {
 
        SaAisErrorT createImmHandle(SmfCampaign * i_campaign);
        SaAisErrorT deleteImmHandle();
+  SaAisErrorT initNtfSubscriptions(void);
+
+  void handleStateChangeNotification(const SaNtfStateChangeNotificationT&);
+
+  void handleObjectStateChangeNotification(
+    const SaNtfStateChangeNotificationT&);
+
+  void handleAmfObjectStateChangeNotification(
+    const SaNtfStateChangeNotificationT&);
+
+  bool isAMFOperState(const SaNtfClassIdT&) const;
+
+  static void ntfNotificationCallback(SaNtfSubscriptionIdT,
+                                      const SaNtfNotificationsT *);
 
        static void main(NCSCONTEXT info);
        static SmfCampaignThread *s_instance;
+  static SaNtfSubscriptionIdT operStateSubId;
 
        NCSCONTEXT m_task_hdl;
        SYSF_MBX m_mbx;         /* mailbox */
diff --git a/src/smf/smfd/SmfStepTypes.cc b/src/smf/smfd/SmfStepTypes.cc
--- a/src/smf/smfd/SmfStepTypes.cc
+++ b/src/smf/smfd/SmfStepTypes.cc
@@ -1247,8 +1247,8 @@ SmfStepTypeNodeReboot::execute()
                 return false;
         }
 
-        /* Modify information model and set maintenance status */
-        LOG_NO("STEP: Modify information model and set maintenance status");
+        /* Modify information model */
+        LOG_NO("STEP: Modify information model");
         if (m_step->modifyInformationModel() != SA_AIS_OK) {
                 LOG_ER("Failed to Modify information model in 
step=%s",m_step->getRdn().c_str());
                 return false;
@@ -1261,11 +1261,6 @@ SmfStepTypeNodeReboot::execute()
                 return false;
        }
 
-        if (m_step->setMaintenanceStateActUnits() == false) {
-                LOG_ER("Failed to set maintenance state in 
step=%s",m_step->getRdn().c_str());
-                return false;
-        }
-
         /* The action below is an add on to 
SMF.---------------------------------------*/
         /* See if any of the software bundles installed at online installation 
has the */
         /* saSmfBundleInstallOfflineScope attribute set to 
SA_SMF_CMD_SCOPE_PLM_EE     */
@@ -1372,6 +1367,13 @@ SmfStepTypeNodeReboot::execute()
         /* the units in the same state as before locking                       
          */
         m_step->copyDuInitStateToAu();
 
+        /* Now that the node is up, set the maintenance status */
+        LOG_NO("STEP: Set Maintenance Status");
+        if (m_step->setMaintenanceStateActUnits() == false) {
+                LOG_ER("Failed to set maintenance state in 
step=%s",m_step->getRdn().c_str());
+                return false;
+        }
+
         /* Instantiate activation units */
         LOG_NO("STEP: Instantiate activation units");
         if (m_step->instantiateActivationUnits() == false) {
@@ -1685,8 +1687,8 @@ SmfStepTypeNodeRebootAct::execute()
                 return false;
         }
 
-        /* Modify information model and set maintenance status */
-        LOG_NO("STEP: Modify information model and set maintenance status");
+        /* Modify information model */
+        LOG_NO("STEP: Modify information model");
         if (m_step->modifyInformationModel() != SA_AIS_OK) {
                 LOG_ER("Failed to Modify information model in 
step=%s",m_step->getRdn().c_str());
                 return false;
@@ -1699,11 +1701,6 @@ SmfStepTypeNodeRebootAct::execute()
                 return false;
        }
 
-        if (m_step->setMaintenanceStateActUnits() == false) {
-                LOG_ER("Failed to set maintenance state in 
step=%s",m_step->getRdn().c_str());
-                return false;
-        }
-
         /* Offline installation of new software */
         LOG_NO("STEP: Offline installation of new software");
         if (m_step->offlineInstallNewBundles() == false) {
@@ -1746,6 +1743,13 @@ SmfStepTypeNodeRebootAct::execute()
         /* the units in the same state as before locking                       
          */
         m_step->copyDuInitStateToAu();
 
+        /* Now that the node is up, set the maintenance status */
+        LOG_NO("STEP: Set Maintenance Status");
+        if (m_step->setMaintenanceStateActUnits() == false) {
+                LOG_ER("Failed to set maintenance state in 
step=%s",m_step->getRdn().c_str());
+                return false;
+        }
+
         /* Instantiate activation units */
         LOG_NO("STEP: Instantiate activation units");
         if (m_step->instantiateActivationUnits() == false) {
diff --git a/src/smf/smfd/SmfUpgradeCampaign.cc 
b/src/smf/smfd/SmfUpgradeCampaign.cc
--- a/src/smf/smfd/SmfUpgradeCampaign.cc
+++ b/src/smf/smfd/SmfUpgradeCampaign.cc
@@ -942,6 +942,26 @@ SmfUpgradeCampaign::commit()
 }
 
 
//------------------------------------------------------------------------------
+// asyncFailure()
+//------------------------------------------------------------------------------
+void 
+SmfUpgradeCampaign::asyncFailure()
+{
+       TRACE_ENTER();
+        SmfCampResultT campResult;
+
+        while (1) {
+                campResult = m_state->asyncFailure(this);
+
+                if (campResult != SMF_CAMP_CONTINUE) {
+                        break;
+                }
+        }
+
+       TRACE_LEAVE();
+}
+
+//------------------------------------------------------------------------------
 // procResult()
 
//------------------------------------------------------------------------------
 void 
diff --git a/src/smf/smfd/SmfUpgradeCampaign.h 
b/src/smf/smfd/SmfUpgradeCampaign.h
--- a/src/smf/smfd/SmfUpgradeCampaign.h
+++ b/src/smf/smfd/SmfUpgradeCampaign.h
@@ -354,6 +354,13 @@ void verify();
        void commit();
 
 ///
+/// Purpose: Report Async failure
+/// @param   None.
+/// @return  None.
+///
+       void asyncFailure();
+
+///
 /// Purpose: Procedure result.
 /// @param   None.
 /// @return  None.


------------------------------------------------------------------------------
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
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to