Skip to content

Commit

Permalink
OP820:OPRASGS:Garrison:Hostboot IPL fails to halt during shutdown rec…
Browse files Browse the repository at this point in the history
…onfig

    -Added the ability to notify the istep dispacher discontinue
     executing isteps
    -Added call to stopIpl() api in sbe update path
    -Added internal graceful reboot request for SBE update and
     reconfigure re-ipl usage

Change-Id: I5682992802b0f373df91378a38187d032bb3a0b4
CQ:SW361886
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/27959
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Reviewed-by: William G. Hoffa <wghoffa@us.ibm.com>
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Matthew A. Ploetz <maploetz@us.ibm.com>
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/28574
Reviewed-by: Dean Sanner <dsanner@us.ibm.com>
  • Loading branch information
rjknight authored and dcrowell77 committed Feb 7, 2017
1 parent f986133 commit 6e0b348
Show file tree
Hide file tree
Showing 7 changed files with 188 additions and 34 deletions.
18 changes: 18 additions & 0 deletions src/include/usr/initservice/istepdispatcherif.H
Expand Up @@ -68,6 +68,24 @@ errlHndl_t sendIstepCompleteMsg ( void );
*/
bool isShutdownRequested ( void );

/**
* @brief This function is to be used by external code to tell
* this instance of istepdispatcher to stop executing steps
*
* @return Nothing
*/
void stopIpl( void );

#ifdef CONFIG_BMC_IPMI
/**
* @brief This function is to be used by external code to
* initate a system reboot via IPMI commands
*
* @return Nothing
*/
void requestReboot( void );
#endif

/**
* @brief This function is to be used by external code to tell
* this instance of istepdispatcher whether it should
Expand Down
10 changes: 9 additions & 1 deletion src/include/usr/ipmi/ipmiif.H
Expand Up @@ -54,8 +54,11 @@ namespace IPMI

MSG_STATE_GRACEFUL_SHUTDOWN,

// initate a reboot request
MSG_STATE_INITATE_POWER_CYCLE,

// Used to check range. Leave as last.
MSG_LAST_TYPE = MSG_STATE_GRACEFUL_SHUTDOWN,
MSG_LAST_TYPE = MSG_STATE_INITATE_POWER_CYCLE,
};

// chassis power off request types
Expand Down Expand Up @@ -345,6 +348,11 @@ namespace IPMI
*/
size_t max_buffer(void);

/**
* Tells ipmirp to start a graceful reboot sequence
*
*/
void initiateReboot();

/**
* Structure to return BMC/IPMI information in
Expand Down
94 changes: 82 additions & 12 deletions src/usr/initservice/istepdispatcher/istepdispatcher.C
Expand Up @@ -66,7 +66,7 @@
#include <pnor/pnorif.H>
#include <ipmi/ipmiwatchdog.H> //IPMI watchdog timer
#include <ipmi/ipmipowerstate.H> //IPMI System ACPI Power State
#include <ipmi/ipmichassiscontrol.H>
#include <ipmi/ipmichassiscontrol.H>
#include <config.h>
#include <ipmi/ipmisensor.H>
#include <ipmi/ipmiif.H>
Expand Down Expand Up @@ -116,7 +116,8 @@ IStepDispatcher::IStepDispatcher() :
iv_istepToCompleteBeforeShutdown(0),
iv_substepToCompleteBeforeShutdown(0),
iv_acceptIstepMessages(true),
iv_newGardRecord(false)
iv_newGardRecord(false),
iv_stopIpl(false)

{
mutex_init(&iv_bkPtMutex);
Expand Down Expand Up @@ -377,6 +378,25 @@ errlHndl_t IStepDispatcher::executeAllISteps()
substep = 0;
while (substep < g_isteps[istep].numitems)
{
if( iv_stopIpl == true )
{
#ifdef CONFIG_BMC_IPMI
// if we came in here and we are connected to a BMC, then
// we are in the process of an orderly shutdown, reset the
// watchdog to give ample time for the graceful shutdown
// to proceed.
errlHndl_t err_ipmi = IPMIWATCHDOG::resetWatchDogTimer();
if(err_ipmi)
{
TRACFCOMP(g_trac_initsvc,
"init: ERROR: reset IPMI watchdog Failed");
err_ipmi->collectTrace("INITSVC", 1024);
errlCommit(err_ipmi, INITSVC_COMP_ID );
}
#endif
stop();
}

err = doIstep(istep, substep, l_doReconfig);

if (l_doReconfig)
Expand Down Expand Up @@ -564,26 +584,24 @@ errlHndl_t IStepDispatcher::executeAllISteps()
"not increment reboot count.");
}

// discontinue isteps
iv_stopIpl = true;

// Request BMC to do power cycle that sends shutdown
// and reset the host
err = IPMI::chassisControl
(IPMI::CHASSIS_POWER_CYCLE);
if (err)
{
TRACFCOMP(g_trac_initsvc, ERR_MRK
"FAIL executing chassisControl command");
break;
}
requestReboot();

#endif
#ifdef CONFIG_CONSOLE
CONSOLE::displayf(NULL,
"System Shutting Down "
"To Perform Reconfiguration\n");
"To Perform Reconfiguration");
CONSOLE::flush();
#endif
#ifndef CONFIG_BMC_IPMI
shutdownDuringIpl();
#endif

}
}
// else return the error from doIstep
Expand Down Expand Up @@ -616,6 +634,29 @@ errlHndl_t IStepDispatcher::executeAllISteps()
return err;
}



//-----------------------------------------------------------------------------
// IStepDispatcher::stop()
// ---------------------------------------------------------------------------
void IStepDispatcher::stop()
{

#ifdef CONFIG_CONSOLE
CONSOLE::displayf(NULL,"Stopping istep dispatcher");
CONSOLE::flush();
#endif

TRACFCOMP(g_trac_initsvc, "IStepDispatcher::stop() - Stopping istep"
"dispatcher.");

printk( "IStepDispatcher stopping" );
while(1)
{
task_yield();
}
}

// ----------------------------------------------------------------------------
// IStepDispatcher::doIstep()
// ----------------------------------------------------------------------------
Expand Down Expand Up @@ -1333,7 +1374,12 @@ void IStepDispatcher::handleShutdownMsg(msg_t * & io_pMsg)
TRACFCOMP(g_trac_initsvc, EXIT_MRK"IStepDispatcher::handleShutdownMsg");
}


#ifdef CONFIG_BMC_IPMI
void IStepDispatcher::requestReboot()
{
IPMI::initiateReboot();
}
#endif
// ----------------------------------------------------------------------------
// IStepDispatcher::shutdownDuringIpl()
// ----------------------------------------------------------------------------
Expand Down Expand Up @@ -1387,6 +1433,20 @@ void IStepDispatcher::shutdownDuringIpl()
}

}
// -----------------------------------------------------------------------------
// IStepDispatcher::setStopIpl()
// -----------------------------------------------------------------------------
void IStepDispatcher::setStopIpl()
{
TRACDCOMP(g_trac_initsvc, ENTER_MRK"IStepDispatcher::setStopIpl");

mutex_lock(&iv_mutex);
iv_stopIpl = true;
mutex_unlock(&iv_mutex);

TRACDCOMP(g_trac_initsvc, EXIT_MRK"IStepDispatcher::setStopIpl");
return;
}

// ----------------------------------------------------------------------------
// IStepDispatcher::iStepBreakPoint()
Expand Down Expand Up @@ -2008,6 +2068,16 @@ void setNewGardRecord()
{
return IStepDispatcher::getTheInstance().setNewGardRecord();
}
#ifdef CONFIG_BMC_IPMI
void requestReboot()
{
IStepDispatcher::getTheInstance().requestReboot();
}
#endif
void stopIpl()
{
return IStepDispatcher::getTheInstance().setStopIpl();
}

// ----------------------------------------------------------------------------
// IStepDispatcher::getIstepInfo()
Expand Down
23 changes: 23 additions & 0 deletions src/usr/initservice/istepdispatcher/istepdispatcher.H
Expand Up @@ -203,6 +203,25 @@ public:
*/
void setNewGardRecord();

/**
* @brief This function will set a boolean true which tells the istep
* dispacher to stop executing steps
*/
void setStopIpl();

/**
* @brief This function will stop the istep dispacher from continuing to
* execute steps
*/
void stop();
#ifdef CONFIG_BMC_IPMI
/**
* @brief This function will trigger a reboot via ipmi commands
*/
void requestReboot();
#endif


protected:

/**
Expand Down Expand Up @@ -424,6 +443,10 @@ private:
// Instance variable to state if a new gard record was committed
bool iv_newGardRecord;

// Instance variable to state if a power off is in progress and
// the istep dispatcher should stop executing steps
bool iv_stopIpl;

// Message Queue for receiving message from SP or SPless user console
msg_q_t iv_msgQ;

Expand Down
5 changes: 5 additions & 0 deletions src/usr/ipmi/ipmichassiscontrol.C
Expand Up @@ -36,6 +36,7 @@
#include <errl/errlentry.H>
#include <ipmi/ipmichassiscontrol.H>
#include <ipmi/ipmiif.H>
#include <initservice/istepdispatcherif.H>

/******************************************************************************/
// Globals/Constants
Expand Down Expand Up @@ -75,6 +76,10 @@ errlHndl_t chassisControl(const uint8_t i_chassisControlState )
IPMI_TRAC("Chassis control : BMC returned not ok CC[%x]",cc);
}

// power off command has been sent to the BMC, tell the istep dispacher to
// stop executing steps.
INITSERVICE::stopIpl();

return err_ipmi;
}
} // namespace
Expand Down
47 changes: 45 additions & 2 deletions src/usr/ipmi/ipmirp.C
Expand Up @@ -40,6 +40,7 @@
#include <sys/task.h>
#include <initservice/taskargs.H>
#include <initservice/initserviceif.H>
#include <initservice/istepdispatcherif.H>
#include <sys/vfs.h>

#include <targeting/common/commontargeting.H>
Expand Down Expand Up @@ -459,6 +460,9 @@ void IpmiRP::handlePowerMessage( IPMI::oemSEL* i_event )
break;
}

// tell the istep dispacher to stop executing isteps
INITSERVICE::stopIpl();

// register for the post memory flush callback
INITSERVICE::registerShutdownEvent(iv_msgQ,
IPMI::MSG_STATE_GRACEFUL_SHUTDOWN,
Expand All @@ -470,6 +474,7 @@ void IpmiRP::handlePowerMessage( IPMI::oemSEL* i_event )
// initiate the shutdown processing in the background
INITSERVICE::doShutdown(SHUTDOWN_STATUS_GOOD,true);


} while (0);

}
Expand Down Expand Up @@ -563,6 +568,7 @@ void IpmiRP::execute(void)

while (true)
{

msg_t* msg = msg_wait(iv_msgQ);

const IPMI::msg_type msg_type =
Expand Down Expand Up @@ -682,15 +688,41 @@ void IpmiRP::execute(void)

iv_shutdown_msg = msg; // Reply to this message


#ifdef CONFIG_CONSOLE
CONSOLE::displayf(NULL, "IPMI: shutdown complete");
CONSOLE::displayf(NULL, "IPMI: shutdown complete\n");
CONSOLE::flush();
#endif

}
break;

// begin a graceful reboot initated by us
case IPMI::MSG_STATE_INITATE_POWER_CYCLE:
{
msg_free(msg);

#ifdef CONFIG_CONSOLE
CONSOLE::displayf(NULL, "IPMI: Initiate power cycle");
CONSOLE::flush();
#endif
// setup the power cmd modifier to tell the bmc to
// do a power reset
iv_chassis_power_mod = IPMI::CHASSIS_POWER_RESET;

// register for the post memory flush callback
INITSERVICE::registerShutdownEvent(iv_msgQ,
IPMI::MSG_STATE_GRACEFUL_SHUTDOWN,
INITSERVICE::POST_MEM_FLUSH_NOTIFY_LAST);

iv_graceful_shutdown_pending = true;
lwsync();

// initiate the shutdown processing in the background
INITSERVICE::doShutdown(SHUTDOWN_STATUS_GOOD,true);

}
break;

};

// There's a good chance the interface will be idle right after
Expand Down Expand Up @@ -1046,6 +1078,17 @@ namespace IPMI
return err;
}

///
/// @brief kick off a reboot
///
void initiateReboot()
{
static msg_q_t mq = Singleton<IpmiRP>::instance().msgQueue();
msg_t * msg = msg_allocate();
msg->type = IPMI::MSG_STATE_INITATE_POWER_CYCLE;
msg_send(mq, msg);
}

///
/// @brief Maximum buffer for data (max xport - header)
///
Expand Down

0 comments on commit 6e0b348

Please sign in to comment.