Hi Anders, please see my comments inlined. /Thanks HansN

On 06/30/2016 10:31 AM, Anders Widell wrote:
> Hi!
>
> Some initial thoughts on this:
>
> * In this patch the STONITH stuff is enabled by default, and the 
> PROMOTE_ACTIVE_TIMER is also enabled by default. I think we should 
> keep the default behaviour and not enable any of this by default.
[HansN] yes it should not be enabled, it is enabled in the patch to make 
it clearer what can be configured to test the patch.
>
> * It feels a bit odd that the opensaf_reboot script reads the fm 
> configuration file? opensaf_reboot is already intended to be 
> customized by the user, so I suppose the user could add some 
> configuration settings at the top of the opensaf_reboot file?
[HansN] Agree, but one env. variable FMS_USE_REMOTE_FENCING is used by 
both FM and the OpenSAF reboot script. Perhaps the configuration should 
be in PLM instead? It may involve more work.
>
> * You are re-using the ee_name script parameter to pass the CLM node 
> name when STONITH is enabled. Maybe instead add an extra parameter for 
> the node name? The script could use PLM if ee_name is non-empty, and 
> STONITH if CLM name is non-empty.
[HansN] If PLM is not used ee_name is empty and is used to check for PLM 
in the opensaf_reboot script so more changes are needed to add an extra 
parameter. Not sure if the opensaf_reboot script is called from other
sources as well?
>
> * Any thoughts about checking the result of the fencing (was it 
> successful or not)? I guess it depends on the safety requirements, but 
> if remote fencing is enabled and FM on the standby fails to fence the 
> (previous) active, then maybe the standby should not take over as 
> active? Instead it could re-try until fencing is successful, or maybe 
> reboot itself?
[HansN] The return code is checked in opensaf_reboot and log an error 
message in case of failure, but do not return any values to the caller 
today. Perhaps the use_fallback should be active when using remote 
fencing then?
>
> / Anders Widell
>
> On 06/23/2016 07:31 AM, Hans Nordeback wrote:
>> 00-README.conf                                  |   47 +++++++++
>>   osaf/services/infrastructure/fm/config/fmd.conf |    9 +-
>>   osaf/services/infrastructure/fm/fms/Makefile.am |    3 +-
>>   osaf/services/infrastructure/fm/fms/fm_cb.h     |    4 +
>>   osaf/services/infrastructure/fm/fms/fm_main.c   |  124 
>> +++++++++++++++++++++++-
>>   scripts/opensaf_reboot                          |   47 ++++++--
>>   6 files changed, 216 insertions(+), 18 deletions(-)
>>
>>
>> diff --git a/00-README.conf b/00-README.conf
>> --- a/00-README.conf
>> +++ b/00-README.conf
>> @@ -530,3 +530,50 @@ and not access any of its members direct
>>   saAisNameBorrow() access functions shall be used. The
>>   SA_MAX_UNEXTENDED_NAME_LENGTH constant can be used to refer to the 
>> maximum
>>   string length that can be stored in the unextended SaNameT type.
>> +
>> +Configuring remote fencing support using STONITH
>> +================================================
>> +
>> +In an virtualized enironment STONITH can be used to for remote 
>> fencing the other
>> +system controller in case of "link loss" or the peer system 
>> controller is "live hanging",
>> +this to avoid split-brains.
>> +Node self-fencing will also be used if e.g. the active controller 
>> loses connectivity to
>> +all other nodes in the cluster.
>> +
>> +Example installing on using Ubuntu 14.04,
>> +
>> +On each virtual node install stonith package:
>> +
>> +  sudo apt-get install cluster-glue
>> +
>> +The name of each virtual node should be the same as the clm node name,
>> +e.g. safNode=SC-2,safCluster=myClmCluster the virtual node name 
>> should be SC-2.
>> +
>> +If a firewall is used on the "hypervisor" host, the tcp port 16509
>> +has to be added. If ssh is used use ssh-keygen and generate ssh keys 
>> for each
>> +virtual node.
>> +
>> +To verify the installation virsh can be used, e.g:
>> +virsh --connect=qemu+tcp://192.168.122.1/system list --all
>> +
>> +Example of output:
>> +Id    Name                           State
>> +----------------------------------------------------
>> + 2     SC-1                           running
>> + 3     SC-2                           running
>> + 4     PL-3                           running
>> +
>> +Update the fmd.conf file:
>> +
>> +# The Promote active timer is set to delay the Standby controllers 
>> reboot request,
>> +# as the Active controller probably also are requesting reboot of 
>> the standby.
>> +# The resolution is in 10 ms units.
>> +export FMS_PROMOTE_ACTIVE_TIMER=300
>> +
>> +# Uncomment the next 5 lines and update acordingly to enable remote 
>> fencing
>> +# See also documentation for STONITH
>> +export FMS_USE_REMOTE_FENCING=1
>> +export FMS_FENCE_CMD="stonith"
>> +export FMS_DEVICE_TYPE="external/libvirt"
>> +export FMS_HYPERVISOR_URI="qemu+tcp://192.168.122.1/system"
>> +export FMS_FENCE_ACTION="reset"
>> diff --git a/osaf/services/infrastructure/fm/config/fmd.conf 
>> b/osaf/services/infrastructure/fm/config/fmd.conf
>> --- a/osaf/services/infrastructure/fm/config/fmd.conf
>> +++ b/osaf/services/infrastructure/fm/config/fmd.conf
>> @@ -17,7 +17,14 @@ export FM_CONTROLLER2_SUBSLOT=15
>>   export FMS_HA_ENV_HEALTHCHECK_KEY="Default"
>>     # Promote active timer
>> -export FMS_PROMOTE_ACTIVE_TIMER=0
>> +export FMS_PROMOTE_ACTIVE_TIMER=500
>> +
>> +# Uncomment the next 5 lines and update acordingly to enable remote 
>> fencing
>> +export FMS_USE_REMOTE_FENCING=1
>> +export FMS_FENCE_CMD="stonith"
>> +export FMS_DEVICE_TYPE="external/libvirt"
>> +export FMS_HYPERVISOR_URI="qemu+tcp://192.168.122.1/system"
>> +export FMS_FENCE_ACTION="reset"
>>     # FM will supervise transitions to the ACTIVE role when this 
>> variable is set to
>>   # a non-zero value. The value is the time in the unit of 10 ms to 
>> wait for a
>> diff --git a/osaf/services/infrastructure/fm/fms/Makefile.am 
>> b/osaf/services/infrastructure/fm/fms/Makefile.am
>> --- a/osaf/services/infrastructure/fm/fms/Makefile.am
>> +++ b/osaf/services/infrastructure/fm/fms/Makefile.am
>> @@ -46,4 +46,5 @@ osaffmd_SOURCES = \
>>   osaffmd_LDADD = \
>>       $(top_builddir)/osaf/libs/core/libopensaf_core.la \
>>       $(top_builddir)/osaf/libs/saf/libSaAmf/libSaAmf.la \
>> - $(top_builddir)/osaf/libs/agents/infrastructure/rda/librda.la
>> + $(top_builddir)/osaf/libs/agents/infrastructure/rda/librda.la \
>> +    $(top_builddir)/osaf/libs/saf/libSaClm/libSaClm.la
>> diff --git a/osaf/services/infrastructure/fm/fms/fm_cb.h 
>> b/osaf/services/infrastructure/fm/fms/fm_cb.h
>> --- a/osaf/services/infrastructure/fm/fms/fm_cb.h
>> +++ b/osaf/services/infrastructure/fm/fms/fm_cb.h
>> @@ -26,6 +26,7 @@
>>   #include "mds_papi.h"
>>   #include "rda_papi.h"
>>   #include "fm_amf.h"
>> +#include "saClm.h"
>>     #include <stdbool.h>
>>   #include <stdint.h>
>> @@ -102,6 +103,9 @@ typedef struct fm_cb {
>>       uint64_t cluster_size;
>>       struct timespec last_well_connected;
>>       struct timespec node_isolation_timeout;
>> +    SaClmHandleT clm_hdl;
>> +    bool use_remote_fencing;
>> +    SaNameT peer_clm_node_name;
>>   } FM_CB;
>>     extern char *role_string[];
>> diff --git a/osaf/services/infrastructure/fm/fms/fm_main.c 
>> b/osaf/services/infrastructure/fm/fms/fm_main.c
>> --- a/osaf/services/infrastructure/fm/fms/fm_main.c
>> +++ b/osaf/services/infrastructure/fm/fms/fm_main.c
>> @@ -32,6 +32,13 @@ This file contains the main() routine fo
>>   #include "fm.h"
>>   #include "osaf_time.h"
>>   +#define FM_CLM_API_TIMEOUT 10000000000LL
>> +
>> +static     SaVersionT clm_version = { 'B', 4, 1 };
>> +static const SaClmCallbacksT_4 clm_callbacks = {
>> +    0, 0
>> +};
>> +
>>   enum {
>>       FD_TERM = 0,
>>       FD_AMF = 1,
>> @@ -54,6 +61,8 @@ static uint32_t fm_get_args(FM_CB *);
>>   static uint32_t fms_fms_exchange_node_info(FM_CB *);
>>   static uint32_t fm_nid_notify(uint32_t);
>>   static uint32_t fm_tmr_start(FM_TMR *, SaTimeT);
>> +static SaAisErrorT get_peer_clm_node_name(NODE_ID);
>> +static SaAisErrorT fm_clm_init();
>>   static void fm_mbx_msg_handler(FM_CB *, FM_EVT *);
>>   static void fm_evt_proc_rda_callback(FM_CB*, FM_EVT*);
>>   static void fm_tmr_exp(void *);
>> @@ -313,6 +322,8 @@ uint32_t initialize_for_assignment(FM_CB
>>           LOG_ER("immd_mds_register FAILED %d", rc);
>>           goto done;
>>       }
>> +
>> +    cb->clm_hdl = 0;
>>       cb->fully_initialized = true;
>>   done:
>>       TRACE_LEAVE2("rc = %u", rc);
>> @@ -383,8 +394,17 @@ static uint32_t fm_agents_startup(void)
>> *****************************************************************************/
>>   static uint32_t fm_get_args(FM_CB *fm_cb)
>>   {
>> +    char *use_remote_fencing = NULL;
>>       char *value;
>>       TRACE_ENTER();
>> +
>> +    fm_cb->use_remote_fencing = false;
>> +    use_remote_fencing = getenv("FMS_USE_REMOTE_FENCING");
>> +    if (use_remote_fencing != NULL) {
>> +        fm_cb->use_remote_fencing = true;
>> +        LOG_NO("Remote fencing is enabled");
>> +    }
>> +
>>       value = getenv("EE_ID");
>>       if (value != NULL) {
>>           fm_cb->node_name.length = strlen(value);
>> @@ -474,6 +494,85 @@ void fm_proc_svc_down(FM_CB *cb, FM_EVT
>>   }
>> /****************************************************************************
>> +* Name          : fm_clm_init
>> +*
>> +* Description   : Initialize CLM.
>> +*
>> +* Arguments     : None.
>> +*
>> +* Return Values : None.
>> +*
>> +* Notes         : None.
>> +*****************************************************************************/
>>  
>>
>> +static SaAisErrorT get_peer_clm_node_name(NODE_ID node_id)
>> +{
>> +    SaAisErrorT rc = SA_AIS_OK;
>> +    SaClmClusterNodeT_4 cluster_node;
>> +
>> +    if ((rc = fm_clm_init()) != SA_AIS_OK) {
>> +        LOG_ER("clm init FAILED %d", rc);
>> +    } else {
>> +        LOG_NO("clm init OK");
>> +    }
>> +
>> +    if ((rc = saClmClusterNodeGet_4(fm_cb->clm_hdl, node_id, 
>> FM_CLM_API_TIMEOUT, &cluster_node)) == SA_AIS_OK) {
>> +        // Extract peer clm node name, e.g SC-2 from 
>> "safNode=SC-2,safCluster=myClmCluster"
>> +        // The peer clm node name will be passed to opensaf_reboot 
>> script to support remote fencing.
>> +        // The peer clm node name should correspond to the name of 
>> the virtual machine for that node.
>> +        char *node = NULL;
>> +        strtok((char*) cluster_node.nodeName.value, "=");
>> +        node = strtok(NULL, ",");
>> +        strncpy((char*) fm_cb->peer_clm_node_name.value, node, 
>> cluster_node.nodeName.length);
>> +        LOG_NO("Peer clm node name: %s", 
>> fm_cb->peer_clm_node_name.value);
>> +    } else {
>> +        LOG_WA("saClmClusterNodeGet_4 returned %u", (unsigned) rc);
>> +    }
>> +
>> +    if ((rc = saClmFinalize(fm_cb->clm_hdl)) != SA_AIS_OK) {
>> +        LOG_ER("clm finalize FAILED %d", rc);
>> +    }
>> +
>> +    return rc;
>> +}
>> +
>> +/****************************************************************************
>>  
>>
>> +* Name          : fm_clm_init
>> +*
>> +* Description   : Initialize CLM.
>> +*
>> +* Arguments     : None.
>> +*
>> +* Return Values : None.
>> +*
>> +* Notes         : None.
>> +*****************************************************************************/
>>  
>>
>> +static SaAisErrorT fm_clm_init()
>> +{
>> +    SaAisErrorT rc = SA_AIS_OK;
>> +
>> +    for (;;) {
>> +        rc = saClmInitialize_4(&fm_cb->clm_hdl, &clm_callbacks, 
>> &clm_version);
>> +        if (rc == SA_AIS_ERR_TRY_AGAIN ||
>> +            rc == SA_AIS_ERR_TIMEOUT ||
>> +            rc == SA_AIS_ERR_UNAVAILABLE) {
>> +            LOG_WA("saClmInitialize_4 returned %u", (unsigned) rc);
>> +
>> +            if (rc != SA_AIS_ERR_TRY_AGAIN) {
>> +                LOG_WA("saClmInitialize_4 returned %u",
>> +                    (unsigned) rc);
>> +            }
>> +            osaf_nanosleep(&kHundredMilliseconds);
>> +            continue;
>> +        }
>> +        if (rc == SA_AIS_OK) break;
>> +        LOG_ER("Failed to Initialize with CLM: %u", rc);
>> +        goto done;
>> +    }
>> +done:
>> +    return rc;
>> +}
>> +
>> +/****************************************************************************
>>  
>>
>>   * Name          : fm_mbx_msg_handler
>>   *
>>   * Description   : Processes Mail box messages between FM.
>> @@ -517,8 +616,13 @@ static void fm_mbx_msg_handler(FM_CB *fm
>>                        * but just that failover has been trigerred 
>> quicker than the
>>                        * node_down event has been received.
>>                        */
>> -                opensaf_reboot(fm_cb->peer_node_id, (char 
>> *)fm_cb->peer_node_name.value,
>> -                        "Received Node Down for peer controller");
>> +                if (fm_cb->use_remote_fencing) {
>> +                    opensaf_reboot(fm_cb->peer_node_id, (char 
>> *)fm_cb->peer_clm_node_name.value,
>> +                            "Received Node Down for peer controller");
>> +                } else {
>> +                    opensaf_reboot(fm_cb->peer_node_id, (char 
>> *)fm_cb->peer_node_name.value,
>> +                            "Received Node Down for peer controller");
>> +                }
>>                   if (!((fm_cb->role == PCS_RDA_ACTIVE) && 
>> (fm_cb->amf_state == (SaAmfHAStateT)PCS_RDA_ACTIVE))) {
>>                       fm_cb->role = PCS_RDA_ACTIVE;
>>                       LOG_NO("Controller Failover: Setting role to 
>> ACTIVE");
>> @@ -534,6 +638,10 @@ static void fm_mbx_msg_handler(FM_CB *fm
>>   /* Peer fm came up so sending ee_id of this node */
>>           if (fm_cb->node_name.length != 0)
>>               fms_fms_exchange_node_info(fm_cb);
>> +
>> +        if (fm_cb->use_remote_fencing) {
>> +            get_peer_clm_node_name(fm_mbx_evt->node_id);
>> +        }
>>           break;
>>       case FM_EVT_TMR_EXP:
>>   /* Timer Expiry event posted */
>> @@ -547,8 +655,16 @@ static void fm_mbx_msg_handler(FM_CB *fm
>>               fm_cb->role = PCS_RDA_ACTIVE;
>>                 LOG_NO("Reseting peer controller node id: %x", 
>> fm_cb->peer_node_id);
>> -            opensaf_reboot(fm_cb->peer_node_id, (char 
>> *)fm_cb->peer_node_name.value,
>> -                       "Received Node Down for Active peer");
>> +            if (fm_cb->use_remote_fencing) {
>> +                LOG_NO("saClmClusterNodeGet succeeded node_id 0x%X, 
>> clm peer node name %s",
>> +                    fm_mbx_evt->node_id, 
>> fm_cb->peer_clm_node_name.value);
>> +
>> +                opensaf_reboot(fm_cb->peer_node_id, (char 
>> *)fm_cb->peer_clm_node_name.value,
>> +                        "Received Node Down for peer controller");
>> +            } else {
>> +                opensaf_reboot(fm_cb->peer_node_id, (char 
>> *)fm_cb->peer_node_name.value,
>> +                           "Received Node Down for Active peer");
>> +            }
>>               fm_rda_set_role(fm_cb, PCS_RDA_ACTIVE);
>>           } else if (fm_mbx_evt->info.fm_tmr->type == 
>> FM_TMR_ACTIVATION_SUPERVISION) {
>>               opensaf_reboot(0, NULL, "Activation timer supervision "
>> diff --git a/scripts/opensaf_reboot b/scripts/opensaf_reboot
>> --- a/scripts/opensaf_reboot
>> +++ b/scripts/opensaf_reboot
>> @@ -26,13 +26,31 @@
>>   # through proprietary mechanisms, i.e. not through PLM. Node_id is 
>> (the only
>>   # entity) at the disposal of such a mechanism.
>>   +if [ -f "$pkgsysconfdir/fmd.conf" ]; then
>> +  . "$pkgsysconfdir/fmd.conf"
>> +fi
>> +
>>   NODE_ID_FILE=$pkglocalstatedir/node_id
>> +
>>   node_id=$1
>>   ee_name=$2
>>     # Run commands through sudo when not superuser
>>   test $(id -u) -ne 0 && icmd=$(which sudo 2> /dev/null)
>>   +## Use stonith for remote fencing
>> +opensaf_reboot_with_remote_fencing()
>> +{
>> +    "$FMS_FENCE_CMD" -t "$FMS_DEVICE_TYPE" hostlist="node:$ee_name" 
>> hypervisor_uri="$FMS_HYPERVISOR_URI" -T "$FMS_FENCE_ACTION" node
>> +
>> +    retval=$?
>> +    if [ $retval != 0 ]; then
>> +        logger -t "opensaf_reboot" "Rebooting remote node $ee_name 
>> using $FMS_FENCE_CMD failed, rc: $retval"
>> +        exit 1
>> +    fi
>> +}
>> +
>> +
>>   #if plm exists in the system,then the reboot is performed using the 
>> eename.
>>   opensaf_reboot_with_plm()
>>   {
>> @@ -86,17 +104,22 @@ if [ "$self_node_id" = "$node_id" ] || [
>>       # Reboot (not shutdown) system WITH file system sync
>>       $icmd /sbin/reboot -f
>>   else
>> -    if [ ":$ee_name" != ":" ]; then
>> -        plm_node_presence_state=`immlist $ee_name |grep 
>> saPlmEEPresenceState|awk '{print $3}'`
>> -        plm_node_state=`immlist $ee_name |grep saPlmEEAdminState|awk 
>> '{print $3}'`
>> -        if [ "$plm_node_presence_state" != 3 ] ; then
>> -            logger -t "opensaf_reboot" "Not rebooting remote node 
>> $ee_name as it is not in INSTANTIATED state"
>> -        elif [ $plm_node_state != 2 ]; then
>> -            opensaf_reboot_with_plm
>> -        else
>> -            logger -t "opensaf_reboot" "Not rebooting remote node 
>> $ee_name as it is already in locked state"
>> +    if [ "$FMS_USE_REMOTE_FENCING" = "1" ]; then
>> +        opensaf_reboot_with_remote_fencing
>> +    else
>> +        if [ ":$ee_name" != ":" ]; then
>> +
>> +            plm_node_presence_state=`immlist $ee_name |grep 
>> saPlmEEPresenceState|awk '{print $3}'`
>> +            plm_node_state=`immlist $ee_name |grep 
>> saPlmEEAdminState|awk '{print $3}'`
>> +            if [ "$plm_node_presence_state" != 3 ] ; then
>> +                logger -t "opensaf_reboot" "Not rebooting remote 
>> node $ee_name as it is not in INSTANTIATED state"
>> +            elif [ $plm_node_state != 2 ]; then
>> +                opensaf_reboot_with_plm
>> +            else
>> +                logger -t "opensaf_reboot" "Not rebooting remote 
>> node $ee_name as it is already in locked state"
>> +            fi
>> +        else
>> +                logger -t "opensaf_reboot" "Rebooting remote node in 
>> the absence of PLM is outside the scope of OpenSAF"
>>           fi
>> -    else
>> -            logger -t "opensaf_reboot" "Rebooting remote node in the 
>> absence of PLM is outside the scope of OpenSAF"
>> -    fi
>> +    fi
>>   fi
>


------------------------------------------------------------------------------
Attend Shape: An AT&T Tech Expo July 15-16. Meet us at AT&T Park in San
Francisco, CA to explore cutting-edge tech and listen to tech luminaries
present their vision of the future. This family event has something for
everyone, including kids. Get more information and register today.
http://sdm.link/attshape
_______________________________________________
Opensaf-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to