Convert A Linux Program To High Availability
The program is located at /opt/demo, consists of two scripts:
The program is installed to SC-1 and SC-2.
File /opt/demo/loop.sh.
counter=1
while true; do
logger "hello $counter"
((counter++))
sleep 5
done
File /opt/demo/main.sh.
program='/opt/demo/loop.sh'
pidfile='/var/run/demo.pid'
start() {
echo 'demo starting...'
logger 'demo starting...'
start-stop-daemon --start --background \
--make-pidfile --pidfile $pidfile \
--exec /bin/bash -- $program
echo 'demo started'
logger 'demo started'
}
stop() {
echo 'demo stopping...'
logger 'demo stopping...'
start-stop-daemon --stop --pidfile $pidfile \
--retry 5
echo 'stopped'
logger 'demo stopped'
}
status() {
if [ -f $pidfile ] \
&& start-stop-daemon --status --pidfile $pidfile;\
then
echo "running, pid: $(cat $pidfile)"
else
echo 'not running'
fi
}
case $1 in
start)
start;;
stop)
stop;;
status)
status;;
*)
echo 'Usage: main.sh {start|stop|status}'
exit 1;;
esac
exit 0
Permissions.
chmod +x /opt/demo/loop.sh
chmod +x /opt/demo/main.sh
classDiagram
class SafAmfAppBaseType {
dn: "safAppType=..."
}
class SafAmfSGBaseType {
dn: "safSgType=..."
}
class SafAmfSUBaseType {
dn: "safSuType=..."
}
classDiagram
class SaAmfSvcBaseType {
dn: "safSvcType=..."
}
class SaAmfCompBaseType {
dn: "safCompType=..."
}
class SaAmfCSBaseType {
dn: "safCSType=..."
}
# app
$ immcfg -c SaAmfAppBaseType safAppType=demo
# sg
$ immcfg -c SaAmfSGBaseType safSgType=demo
# su
$ immcfg -c SaAmfSUBaseType safSuType=demo
# si
$ immcfg -c SaAmfSvcBaseType safSvcType=demo
# comp
$ immcfg -c SaAmfCompBaseType safCompType=demo
# csi
$ immcfg -c SaAmfCSBaseType safCSType=demo
classDiagram
class SaAmfCompType {
dn: "safVersion=...,safCompType=..."
saAmfCtSwBundle
}
SaAmfCompType --> SaSmfSwBundle: saAmfCtSwBundle
class SaAmfAppType {
dn: "safVersion=...,safAppType=..."
saAmfApptSGTypes
}
SaAmfAppType --> SaAmfSGType: saAmfApptSGTypes
class SaAmfSGType {
dn: "safVersion=...,safSgType=..."
saAmfSgtValidSuTypes
}
SaAmfSGType --> SaAmfSUType: saAmfSgtValidSuTypes
class SaAmfSUType {
dn: "safVersion=...,safSuType=..."
saAmfSutProvidesSvcTypes
}
SaAmfSUType --> SaAmfSvcType: saAmfSutProvidesSvcTypes
class SaSmfSwBundle {
dn: "safSmfBundle=..."
}
class SaAmfSvcType {
dn: "safVersion=...,safSvcType=..."
}
classDiagram
class SaAmfCSType {
dn: "safVersion=...,safCSType=..."
}
# swbundle
$ immcfg -c SaSmfSwBundle safSmfBundle=demo
# csi
$ immcfg -c SaAmfCSType safVersion=1,safCSType=demo
# comp
$ immcfg -c SaAmfCompType \
-a saAmfCtCompCategory=8 \
-a saAmfCtSwBundle=safSmfBundle=demo \
-a saAmfCtDefClcCliTimeout=10000000000 \
-a saAmfCtRelPathInstantiateCmd='main.sh start' \
-a saAmfCtRelPathCleanupCmd='main.sh stop' \
-a saAmfCtRelPathTerminateCmd='main.sh stop' \
-a saAmfCtRelPathAmStartCmd='../../usr/local/sbin/amfpm --start' \
-a saAmfCtRelPathAmStopCmd='../../usr/local/sbin/amfpm --stop' \
-a saAmfCtDefRecoveryOnError=3 \
-a saAmfCtDefDisableRestart=0 \
safVersion=1,safCompType=demo
# si
$ immcfg -c SaAmfSvcType safVersion=1,safSvcType=demo
# su
$ immcfg -c SaAmfSUType \
-a saAmfSutIsExternal=0 \
-a saAmfSutDefSUFailover=1 \
-a saAmfSutProvidesSvcTypes=safVersion=1,safSvcType=demo \
safVersion=1,safSuType=demo
# sg
$ immcfg -c SaAmfSGType \
-a saAmfSgtRedundancyModel=1 \
-a saAmfSgtValidSuTypes=safVersion=1,safSuType=demo \
-a saAmfSgtDefAutoAdjustProb=10000000000 \
-a saAmfSgtDefCompRestartProb=4000000000 \
-a saAmfSgtDefCompRestartMax=10 \
-a saAmfSgtDefSuRestartProb=4000000000 \
-a saAmfSgtDefSuRestartMax=10 \
safVersion=1,safSgType=demo
# app
$ immcfg -c SaAmfAppType \
-a saAmfApptSGTypes=safVersion=1,safSgType=demo \
safVersion=1,safAppType=demo
classDiagram
class SaAmfSutCompType {
dn: "safMemberCompType=..."
}
SaAmfSutCompType --> SaAmfSUType: dn
SaAmfSutCompType --> SaAmfCompType: dn
class SaAmfCtCsType {
dn: "safSupportedCsType=..."
}
SaAmfCtCsType --> SaAmfCompType: dn
SaAmfCtCsType --> SaAmfCSType: dn
class SaAmfSvcTypeCSTypes {
dn: "safMemberCSType=..."
}
SaAmfSvcTypeCSTypes --> SaAmfSvcType: dn
SaAmfSvcTypeCSTypes --> SaAmfCSType: dn
# connect su - comp
$ immcfg -c SaAmfSutCompType \
'safMemberCompType=safVersion=1\,safCompType=demo,safVersion=1,safSuType=demo'
# connect comp - csi
$ immcfg -c SaAmfCtCsType \
-a saAmfCtCompCapability=1 \
'safSupportedCsType=safVersion=1\,safCSType=demo,safVersion=1,safCompType=demo'
# connect csi - si
$ immcfg -c SaAmfSvcTypeCSTypes \
'safMemberCSType=safVersion=1\,safCSType=demo,safVersion=1,safSvcType=demo'
classDiagram
class SaAmfApplication {
dn: "safApp=..."
}
class SaAmfSG {
dn: "safSg=...,safApp=..."
}
SaAmfSG --> SaAmfApplication: dn
class SaAmfSI {
dn: "safSi=...,safApp=..."
saAmfSIProtectedbySG
}
SaAmfSI --> SaAmfApplication: dn
SaAmfSI --> SaAmfSG: saAmfSIProtectedbySG
class SaAmfCSI {
dn: "safCsi=...,safSi=..."
}
SaAmfCSI --> SaAmfSI: dn
$ immcfg -c SaAmfApplication \
-a saAmfAppType=safVersion=1,safAppType=demo \
safApp=demo
$ immcfg -c SaAmfSG \
-a saAmfSGType=safVersion=1,safSgType=demo \
-a saAmfSGAutoRepair=0 \
-a saAmfSGAutoAdjust=0 \
-a saAmfSGNumPrefInserviceSUs=10 \
-a saAmfSGNumPrefAssignedSUs=10 \
safSg=demo,safApp=demo
$ immcfg -c SaAmfSI \
-a saAmfSvcType=safVersion=1,safSvcType=demo \
-a saAmfSIProtectedbySG=safSg=demo,safApp=demo \
-a saAmfSIRank=1 \
safSi=demo,safApp=demo
$ immcfg -c SaAmfCSI \
-a saAmfCSType=safVersion=1,safCSType=demo \
safCsi=demo,safSi=demo,safApp=demo
classDiagram
class SaAmfSU {
dn: "safSu=...,safSg=..."
saAmfSUHostNodeOrNodeGroup
}
SaAmfSU --> SaAmfNodeGroup: saAmfSUHostNodeOrNodeGroup
SaAmfSU --> SaAmfNode: saAmfSUHostNodeOrNodeGroup
class SaAmfNodeGroup {
dn:"safAmfNode=..."
safAmfNGNodeList
}
SaAmfNodeGroup o-- SaAmfNode: safAmfNGNodeList
class SaAmfNode {
dn: "safAmfNode=..."
}
class SaAmfComp {
dn: "safComp=...,safSu=..."
}
SaAmfComp --> SaAmfSU: dn
class SaAmfCompCsType {
dn: "safSupportedCsType=..."
}
SaAmfCompCsType --> SaAmfComp: dn
SaAmfCompCsType --> SaAmfCSType: dn
class SaAmfCSType {
dn: "safVersion=...,safCSType=..."
}
class SaAmfNodeSwBundle {
dn: "safInstalledSwBundle=..."
saAmfNodeSwBundlePathPrefix
}
SaAmfNodeSwBundle --> SaAmfNode: dn
$ immcfg -c SaAmfNodeSwBundle \
-a saAmfNodeSwBundlePathPrefix=/opt/demo \
safInstalledSwBundle=safSmfBundle=demo,safAmfNode=SC-1,safAmfCluster=myAmfCluster
$ immcfg -c SaAmfSU \
-a saAmfSUType=safVersion=1,safSuType=demo \
-a saAmfSUHostNodeOrNodeGroup=safAmfNode=SC-1,safAmfCluster=myAmfCluster \
-a saAmfSURank=1 \
-a saAmfSUAdminState=3 \
safSu=1,safSg=demo,safApp=demo
$ immcfg -c SaAmfComp \
-a saAmfCompType=safVersion=1,safCompType=demo \
safComp=demo,safSu=1,safSg=demo,safApp=demo
$ immcfg -c SaAmfCompCsType \
'safSupportedCsType=safVersion=1\,safCSType=demo,safComp=demo,safSu=1,safSg=demo,safApp=demo'
$ immcfg -c SaAmfNodeSwBundle \
-a saAmfNodeSwBundlePathPrefix=/opt/demo \
safInstalledSwBundle=safSmfBundle=demo,safAmfNode=SC-2,safAmfCluster=myAmfCluster
$ immcfg -c SaAmfSU \
-a saAmfSUType=safVersion=1,safSuType=demo \
-a saAmfSUHostNodeOrNodeGroup=safAmfNode=SC-2,safAmfCluster=myAmfCluster \
-a saAmfSURank=1 \
-a saAmfSUAdminState=3 \
safSu=2,safSg=demo,safApp=demo
$ immcfg -c SaAmfComp \
-a saAmfCompType=safVersion=1,safCompType=demo \
safComp=demo,safSu=2,safSg=demo,safApp=demo
$ immcfg -c SaAmfCompCsType \
'safSupportedCsType=safVersion=1\,safCSType=demo,safComp=demo,safSu=2,safSg=demo,safApp=demo'
Unlock SU for SC-1.
$ amf-adm unlock-in safSu=1,safSg=demo,safApp=demo
$ amf-adm unlock safSu=1,safSg=demo,safApp=demo
Check /var/log/syslog.
SC-1 osafamfnd[12182]: NO Assigning 'safSi=demo,safApp=demo' ACTIVE to 'safSu=1,safSg=demo,safApp=demo'
SC-1 osafamfnd[12182]: NO 'safSu=1,safSg=demo,safApp=demo' Presence State UNINSTANTIATED => INSTANTIATING
SC-1 root: demo starting...
SC-1 root: demo started
SC-1 osafamfnd[12182]: NO 'safSu=1,safSg=demo,safApp=demo' Presence State INSTANTIATING => INSTANTIATED
SC-1 osafamfnd[12182]: NO Assigned 'safSi=demo,safApp=demo' ACTIVE to 'safSu=1,safSg=demo,safApp=demo'
SC-1 root: hello 1
SC-1 root: hello 2
SC-1 root: hello 3
Check AMF state.
$ amf-state su
safSu=1,safSg=demo,safApp=demo
saAmfSUAdminState=UNLOCKED(1)
saAmfSUOperState=ENABLED(1)
saAmfSUPresenceState=INSTANTIATED(3)
saAmfSUReadinessState=IN-SERVICE(2)
safSu=2,safSg=demo,safApp=demo
saAmfSUAdminState=LOCKED-INSTANTIATION(3)
saAmfSUOperState=ENABLED(1)
saAmfSUPresenceState=UNINSTANTIATED(1)
saAmfSUReadinessState=OUT-OF-SERVICE(1)
$ amf-state si
safSi=demo,safApp=demo
saAmfSIAdminState=UNLOCKED(1)
saAmfSIAssignmentState=PARTIALLY_ASSIGNED(3)
$ amf-state comp
safComp=demo,safSu=1,safSg=demo,safApp=demo
saAmfCompOperState=ENABLED(1)
saAmfCompPresenceState=INSTANTIATED(3)
saAmfCompReadinessState=IN-SERVICE(2)
safComp=demo,safSu=2,safSg=demo,safApp=demo
saAmfCompOperState=ENABLED(1)
saAmfCompPresenceState=UNINSTANTIATED(1)
saAmfCompReadinessState=OUT-OF-SERVICE(1)
$ amf-state csiass
safCSIComp=safComp=demo\,safSu=1\,safSg=demo\,safApp=demo,safCsi=demo,safSi=demo,safApp=demo
saAmfCSICompHAState=ACTIVE(1)
saAmfCSICompHAReadinessState=READY_FOR_ASSIGNMENT(1)
Unlock SU for SC-2.
$ amf-adm unlock-in safSu=2,safSg=demo,safApp=demo
$ amf-adm unlock safSu=2,safSg=demo,safApp=demo
Check /var/log/syslog.
Oct 29 05:25:29 SC-2 osafamfnd[185]: NO Assigning 'safSi=demo,safApp=demo' STANDBY to 'safSu=2,safSg=demo,safApp=demo'
Oct 29 05:25:29 SC-2 osafamfnd[185]: NO Assigned 'safSi=demo,safApp=demo' STANDBY to 'safSu=2,safSg=demo,safApp=demo'
Check AMF state.
$ amf-state su
safSu=1,safSg=demo,safApp=demo
saAmfSUAdminState=UNLOCKED(1)
saAmfSUOperState=ENABLED(1)
saAmfSUPresenceState=INSTANTIATED(3)
saAmfSUReadinessState=IN-SERVICE(2)
safSu=2,safSg=demo,safApp=demo
saAmfSUAdminState=UNLOCKED(1)
saAmfSUOperState=ENABLED(1)
saAmfSUPresenceState=UNINSTANTIATED(1)
saAmfSUReadinessState=IN-SERVICE(2)
$ amf-state si
safSi=demo,safApp=demo
saAmfSIAdminState=UNLOCKED(1)
saAmfSIAssignmentState=FULLY_ASSIGNED(2)
$ amf-state comp
safComp=demo,safSu=1,safSg=demo,safApp=demo
saAmfCompOperState=ENABLED(1)
saAmfCompPresenceState=INSTANTIATED(3)
saAmfCompReadinessState=IN-SERVICE(2)
safComp=demo,safSu=2,safSg=demo,safApp=demo
saAmfCompOperState=ENABLED(1)
saAmfCompPresenceState=UNINSTANTIATED(1)
saAmfCompReadinessState=IN-SERVICE(2)
$ amf-state csiass
safCSIComp=safComp=demo\,safSu=2\,safSg=demo\,safApp=demo,safCsi=demo,safSi=demo,safApp=demo
saAmfCSICompHAState=STANDBY(2)
saAmfCSICompHAReadinessState=READY_FOR_ASSIGNMENT(1)
safCSIComp=safComp=demo\,safSu=1\,safSg=demo\,safApp=demo,safCsi=demo,safSi=demo,safApp=demo
saAmfCSICompHAState=ACTIVE(1)
saAmfCSICompHAReadinessState=READY_FOR_ASSIGNMENT(1)
If stop the program on SC-1, AMF will restart it on SC-2.
On SC-1, stop the program.
$ /opt/demo/main.sh stop
Check syslog of SC-1.
SC-1 root: demo stopping...
SC-1 osafamfnd[16640]: NO saAmfSUFailover is true for 'safSu=1,safSg=demo,safApp=demo'
SC-1 osafamfnd[16640]: NO Performing failover of 'safSu=1,safSg=demo,safApp=demo' (SU failover count: 2)
SC-1 osafamfnd[16640]: NO 'safComp=demo,safSu=1,safSg=demo,safApp=demo' recovery action escalated from 'noRecommendation' to 'suFailover'
SC-1 osafamfnd[16640]: NO 'safComp=demo,safSu=1,safSg=demo,safApp=demo' faulted due to 'passiveMonitorFailed' : Recovery is 'suFailover'
SC-1 osafamfnd[16640]: NO Terminating components of 'safSu=1,safSg=demo,safApp=demo'(abruptly & unordered)
SC-1 root: demo stopped
SC-1 osafamfnd[16640]: NO 'safSu=1,safSg=demo,safApp=demo' Presence State INSTANTIATED => TERMINATING
SC-1 osafamfnd[16640]: NO 'safSu=1,safSg=demo,safApp=demo' Presence State TERMINATING => TERMINATING
SC-1 root: demo stopping...
SC-1 root: demo stopped
SC-1 osafamfnd[16640]: NO Terminated all components in 'safSu=1,safSg=demo,safApp=demo'
SC-1 osafamfnd[16640]: NO Informing director of sufailover
SC-1 osafamfnd[16640]: NO 'safSu=1,safSg=demo,safApp=demo' Presence State TERMINATING => UNINSTANTIATED
Check syslog of SC-2.
C-2 osafamfnd[1028]: NO Assigning 'safSi=demo,safApp=demo' ACTIVE to 'safSu=2,safSg=demo,safApp=demo'
C-2 rsyslogd-2007: action 'action 9' suspended, next retry is Tue Oct 29 06:11:50 2024 [v8.16.0 try http://www.rsyslog.com/e/2007 ]
C-2 osafamfnd[1028]: NO 'safSu=2,safSg=demo,safApp=demo' Presence State UNINSTANTIATED => INSTANTIATING
C-2 root: demo starting...
C-2 root: demo started
C-2 osafamfnd[1028]: NO 'safSu=2,safSg=demo,safApp=demo' Presence State INSTANTIATING => INSTANTIATED
C-2 osafamfnd[1028]: NO Assigned 'safSi=demo,safApp=demo' ACTIVE to 'safSu=2,safSg=demo,safApp=demo'
C-2 root: hello 1
SC-2 root: hello 2
SC-2 root: hello 3
Check AMF state.
$ amf-state su
safSu=1,safSg=demo,safApp=demo
saAmfSUAdminState=UNLOCKED(1)
saAmfSUOperState=DISABLED(2)
saAmfSUPresenceState=UNINSTANTIATED(1)
saAmfSUReadinessState=OUT-OF-SERVICE(1)
safSu=2,safSg=demo,safApp=demo
saAmfSUAdminState=UNLOCKED(1)
saAmfSUOperState=ENABLED(1)
saAmfSUPresenceState=INSTANTIATED(3)
saAmfSUReadinessState=IN-SERVICE(2)