#!/bin/bash

# controlling script for iSoftGate (additional SG inside EntGW)
#
#Author: Mihai Dumitru <mihai-radu.dumitru.ext@unify.com>
#
#HOC:
#
#2017-09-09 - v0.1 - mihai
# - initial creation - OSFOURK-7503
#2017-09-14 - v0.2 - mihai
# - allow iSoftGate to run also for SurvEntGW
#2017-11-14 - v0.3 - mihai
# - improved deploy of rootfs without chroot
# - improved container start/stop
# - use dedicated LANs
#2017-11-25 - v0.4 - mihai
# - rt_runtime_us not needed for deploy RootFS
# - use iSoftGate name for container and log files
#     (sg2 is the internal name used on the hosting platform)
# - isolate deployrootfs from configure
# - isolate cleanrootfs from cleanup
#2017-11-27 - v0.5 - mihai
# - improved start/stop
# - added internal lan communication for licensing and redirected get_ali to run on plt
#2017-11-28 - v0.6 - mihai
# - ignore comments when parsing initialcfg XML files
# - fixed OSFOURK-7519
# - added API to UI for managing state and XML config for iSoftGate
# - include sample Portal configuration page for iSoftGate
#2017-12-01 - v0.7 - mihai
# - restart complete iSoftGate on initialcfg.xml changes and/or on LW Update of EntGW or iSoftGate which bring newer sg2d daemon script version
# - added initialcfg.xml to riso backup
# - bring back up vlan interfaces after container is stopped
#2017-12-08 - v0.8 - mihai
# - use different container name during deployrootfs not to collide with already running container instance
#2018-02-20 - v0.9 - mihai
# - use shared networks based on vSwitches as offered by /opt/soco-common/sw2vsw.sh
#2018-02-27 - v0.10 - mihai
# - artificial version increase just in case someone already made LW Update with L0-T4T.A0.050-005 which contains sg2d v0.9 with vSwitches and will not work
# - the sg2d v0.10 is part of L0-T4T.A0.050-006 which fixes then the issue and re-enables the dedicated LANs
#2018-03-11 - v0.11 - mihai
# - implemented LAN separation - ETH0-ETH3 for EntGW and ETH4-ETH7 for iSG ; consider also VLANs and BONDs ; also check if ETH4-ETH7 is used for HA/EntGW and refuse to start if so
# - make /var/opt/ha/conf directory from PLT accessible to iSoftGate so that it can read the haipsetup.xml
# - make /opt/webservice/scripts directory accessible to iSoftGate so that it can use the scripts - mostly gethaipsetupentry.sh
# - added "sg2d chroot <cmd>" API for executing commands inside iSoftGate - can be used also offline ; it will not have access to iSoftGate runtime information (like processes/socket) so only the filesystem
# - added internal LAN monitoring - dynamically add internal LAN leg into the iSoftGate
# - removed several WAs leftover from PoC : the mek key copy from EntGW, the webservice fake scripts, the modified haipsetup, the fake get_ali, 
#2018-03-18 - v0.12 - mihai
# - on enable stay insserved even if there are errors which prevent starting
#2018-03-18 - v0.13 - mihai
# - added extra location for update from ASyaps so that this script can be delivered also via PLT HF
#2018-03-20 - v0.14 - gregor
# - remove mount of /var/opt/webservice (OSFOURK-9640)
#2018-03-22 - v0.15 - mihai
# - remove "Hosted SG" sample configuration page from Portal (OSFOURK-9658)
#2018-03-22 - v0.16 - mihai
# - removed modification done to apache listen.conf ; now apache inside iSG will listen on *,0.0.0.0 (like default)
#2018-03-25 - v0.17 - mihai
# - improve logging ; add basic logrotate on start (OSFOURK-7525)
#2018-03-27 - v0.18 - mihai
# - make sure Integrated VPN service is disabled on EntGW in order not to disturb the instance running inside iSG (OSFOURK-9723)
#2018-03-27 - v0.19 - mihai
# - set iSG hostname to iSG-AP<ltu_nr> (OSFOURK-8890)
#2018-03-29 - v0.20 - gregor
# - do not cope with removal of soco_vpn_deploy_daemon, stmix_ifstatus and os_update_watchdog_daemon (OSFOURK-9775)
#2018-04-09 - v0.21 - gregor
# - mount the var/run/platform to support /usr/sbin/system-get-hwinfo (OSFOURK-9694)
#2018-04-13 - v0.22 - mihai
# - revert change done in OSFOURK-9694 - do not mount var/run/platform inside iSG container - (OSFOURK-9878)
#2018-06-12 - v0.23 - gregor
# - remove the old boarddat.xml of the vNCUI to prevent unwanted backannotation into initialcfg.xml in case of configure (OSFOURK-9420)
#2018-08-29 - v0.24 - mihai
# - reverted commit 13690 which disabled completely soco_vpn_deploy_daemon on iSG (OSFOURK-9724)
#2018-08-30 - v0.25 - mihai
# - OSFOURK-11299 - refactored to avoid usage of inotifywait
#2018-09-13 - v0.26 - mihai
# - OSFOURK-11511 - iSG WBM not accessible anymore after NUC update
#   Solution : call insserv_SG.sh as part of deployrootfs - this fixes the problem and keeps the fix done in OSFOURK-11173 still standing
#   Note : this sg2d script version is added also to PLT here : /opt/yaps/script/sg2d so that it can be delivered into OS4K VR2.22.0 without a new SG LW
#          later when newer versions of the sg2d script are committed to the LW this will become obsolete but it is highly recommended not to remove the script from YAPS before V9
#2018-09-28 - v0.27 - mihai
# - OSFOURK-11697 - Integrated SoftGate on EntGW - license not valid after NUC update to V8 R2.22.0
#2018-11-11 - v0.28 - mihai
# - OSFOURK-12005 - NA16228531 - no SSH Access to iSG of the EntGW over Assistant / Gateway Dashboard
#2019-05-23 - v0.29 - mihai
# - OSFOURK-13752 - NA16428924: SG licence error with Enterprise Gateway
#2020-06-01 - v0.30 - gregor
# - OSFOURK-9656 provide SNMP support for iSG@EntGW container
#2021-04-18 - v0.31 - mihai
# - OSFOURK-18091 SLES15 Prepare iSG on EntGW LXC container
#2021-04-21 - v0.32 - mihai
# - SLES15 changes - disable wicked network services, use dhcpcd directly on intlan, make sure /etc/init.d/after.local gets called
#2021-04-21 - v0.33 - mihai
# - adapted to script /opt/soco/native/os/linux/is_container.sh not working which leads to bogus apache config
#2021-05-16 - v1.0 - mihai
# - implemented basic functionality for SG on Duplex - OSFOURK-16959
#2021-05-24 - v1.1 - mihai
# - pass all available ETHs to SG@Duplex except special ones (ETH8, ETH10, RTMX vlan and Atlantic)
# - launch socod after network setup is done = not before - this is controlled via special /dev/iSG-lan-ready switch file
# - changed internal LAN address from dhcp to a static one - <int-lan-prefix>.99
# - integration with HA - iSG will be started from Bridge Internal RA using "at" command if /opt/.iSG.on.duplex.enabled is present
# - re-checked backward compatibility to older OS-es/OS4K versions - all new code is enabled by /dev/.sg2d-on-duplex both inside and outside the container
#2021-06-05 - v1.2 - mihai
# - added do_once_deployrootfs to run as isg_rootfs_deploy oneshot-type systemd service
#2021-06-16 - v1.3 - mihai
# - added reconfigure as a general configure-reconfigure method which also restarts the sg if necessary
#2021-06-24 - v1.4 - mihai
# - redeploy in reconfigure in case of errors
#2021-11-21 - v1.5 - mihai
# - OSFOURK-19927 V10R1 SG Branch - HFA load tests - Packet loss (receive socket sequence error)
#2022-01-21 - v1.6 - mihai
# - OSFOURK-20590 - GWM sees only one iSG as integrated from a duplex system
#2022-01-25 - v1.7 - mihai
# - OSFOURK-20121 - use --numeric-owner while unpacking Appliance RootFS
#2022-01-31 - v1.8 - mihai
# - make sure fast swupdated server is not deployed
#2022-02-12 - v1.9 - mihai
# - OSFOURK-20590 - bugfixed wrong code logic
#2022-02-16 - v1.10 - pavel k.
# - [OSFOURK-20612] - WBM for iSG not accessible from Assistant
#2022-02-20 - v1.11 - mihai
# - OSFOURK-19840 SG@Duplex core file handling broken
#2022-02-28 - v1.12 - mihai
# - do not fail to configure&/start iSG in case XLink is enabled ; just print a warning in messages
#2022-03-04 - v1.13 - pavel
# OSFOURK-20810 routing for iSG vs. Assistant finally fixed
#2022-03-24 - v1.14 - pavel
# OSFOURK-19519 improve detection of route to Assistant needed
#2022-05-12 - v1.15 - mihai
# - remove zypper repos ; set alias for tailf
#2022-05-22 - v1.16 - mihai
# - OSFOURK-14267 - Introduce bond and vlan over bond support for iSG
# - use same technique of ipvlan for all deployments (duplex and EntGW)
#2022-06-03 - v1.17 - mihai
# - do NOT restrict anymore the LAN interfaces usage eth0-3 for EntGW and eth4-7 for iSG
#2022-06-05 - v1.18 - mihai
# - support for dynamic VLAN tagging for iSG
#2022-06-08 - v1.19 - mihai
# - OSFOURK-21067 - protection - in case previous iSG deploy was ok only delete board data but not the complete container
#2022-06-13 - v1.20 - mihai
# - OSFOURK-21134 - EntGW V10R1.27.0 - After OS update from V10R1 the iSG is lost
#2022-06-15 - v1.21 - mihai
# - OSFOURK-22249 V10 R1.34 RC3 No HTTPS Access to iSG container
#2022-07-26 - v1.22 - pavel
# - OSFOURK-22110 - CiCA cannot connect to CSTA on iSG on Duplex when CSTA runs on the same node
#2022-09-13 - v1.23 - mihai
# - OSFOURK-22440 - No payload between EntGW and iSG in case both use same LAN interface for Voice
#2022-10-16 - v2.0 - mihai
# - OSFOURK-22543, OSFOURK-22442 - move sg2d from a rc script to a systemd unit
#2023-02-20 - v2.1 - mihai
# - OSFOURK-23878 - do not pass Atlantic/HA Interfaces to iSG
# - OSFOURK-23208 - SG2D access
# - do not start mistakenly insserved sg2d in case of Duplex
#2023-02-28 - v2.2 - mihai
# - OSFOURK-24092 - put iSG under HA control also on EntGW deployments
#2023-03-05 - v2.3 - mihai
# - OSFOURK-24176 - EntGW / XEGW V10R1 - After NUC to R1.42 the iSoftgate is not starting
#2023-03-07 - v2.4 - mihai
# - OSFOURK-24176 - EntGW / XEGW V10R1 - After NUC to R1.42 the iSoftgate is not starting
#2023-03-16 - v2.5 - mihai
# - OSFOURK-24281 PRB000066134: FT-V10 R1.42.0 Assistant can't connect to iSG on same Node as Assistant running
#2023-07-13 - v2.6 - mihai
# - OSFOURK-24708 PRB000067118: No IP connectivity between iSG and iSBC on Enterprise Gateway
#2023-09-20 - v2.7 - mihai
# - OSFOURK-25622 iSG container shall call Linux hardening

# Note : always increase with each relevant change - used by SG LW Update
SG2_SCRIPT_VERSION="2.7"

# /etc/init.d/sg2d
#
### BEGIN INIT INFO
# Provides: sg2d
# Required-Start: $network
# Required-Stop: $network
# Default-Start: 3 5
# Default-Stop: 0 1 2 6
# Description: iSoftGate (sg2) Daemon
### END INIT INFO

. /etc/profile
if [ -e /var/opt/soco/is_container_sg ] ; then
    # inside iSG container the iSG is a sysv init rc script
    . /etc/rc.status
else
    # on Host sg2d is hosted by systemd unit sg2dhome and its current status reflected by the systemd sg2d service
    . /etc/sg2d.emulate.rc.functions
fi

[ -e /tmp/.sg2d.dev.bash.dbg.on ] && set -x

#name of the hosted SG LXC Container
SG2_LXC_NAME=iSoftGate

#IMPORTANT Note : newer versions of this script must still be compatible to older SG versions. Currently SG is supported without modification. Lots of tests done on softgate-8-49.1.x86_64.rpm

#TODO - prio 2 - integrate XML in the firstinst-netw XML and support recover-4K
# - note: firstinst-netw call with "-w" does not backup config for the ETHs givwn to the iSoftGate while it is running - this may be a problem for RISO restore

#TODO - on 22.01.2018 - V8 R2.8.0 - change name to SoftGate

#TODO - increase range of flexible DNS mask config for DHCP range 130-131 to 130-134

#TODO - remove intlan from interfaces offered by the SG in the UI

#TODO - implement log rotate for iSoftGate logs

#TODO - prio 2 - check if ifup is needed on each ETH after iSG has been stopped - better simply gather the list of IFs and make them always up after the stop finishes

#TODO - offer simple one-cable solutions, also one bond solutions ; check also physical link state propagation
# - test the veth pair+bridging to avoid straps and reuse MACs from ETH6,7 on ETH0,1,2,3,4,5 accordingly -> single virtual "trunk" strap! :)
# - if OK then implement logic to remap interfaces

#################################################
# TEST history
# 28.11.2017 - tests executed on v0.5
# - WBM of all GWs EntGW, iSoftGate, vHFA, vSIP - ok
# - CLA & get_ali - ok
# - inventory and openvpn - ok
# - install iSoftGate on SurvivableEntGW - ok

# TEST history
# 02.12.2017 - using v0.6
# - enable, disable, reconfigure - ok
#  - install with xml + hsg on survEntGW - OK - all up&running after install - WBM ok
#  - portal page on non-EntGW and on EntGW - OK
#  - restart EntGW - iSoftGate remains up - OK
#  - openais restart - iSoftGate remains up - OK
#  - test with VLAN interface - OK

# 03.12.2017 - using v0.7
#  - LAN config change on SG (e.g. extra SIP interface), then restart from WBM then check that iSoftGate starts from scratch - OK
#  - lw update on EntGW with changed daemon, LW update on iSoftGate with changed daemon -> container must start from scratch - OK
#  - install without xml on survEntGW - OK
#  - make RISO backup then restore local - OK
#  - OS Update on StdEntGW - OK
#  - then RAR on StdEntGW - OK
#################################################


#################################################
# Functions
#################################################

function log() {
	echo " "
	echo `date` $*
	echo " "
	logger $0 $*
}

function log_rotate() {
    #do nothing [yet] if called inside iSG container
    [ -e /var/opt/soco/is_container_sg ] && return 0
    for alogfile in $(ls -1 /var/log/iSoftGate*log); do
        [ `du -hk $alogfile | awk '{print $1}'` -gt 10000 ] || continue
        rm -rf $alogfile.1
        cp $alogfile $alogfile.1
        >$alogfile
    done
    return 0
}

function daemon_exit() {
	log "Stopping $SG2_LXC_NAME container ..."
	lxc-stop -n $SG2_LXC_NAME
	log "$SG2_LXC_NAME container is now stopped."
	ip link del isgintl 1>/dev/null 2>/dev/null
	#execute post-stop commands, like for e.g. bring VLANs back up or check if all LANs are again up
	bash /dev/sg2-lxc-after.stop.cmds
	rm $MY_PIDFILE
	[ -e /sg2/tmp/.sg2d.client-rq.dir/restart ] && {
		log "$SG2_LXC_NAME container will be started again since it was stopped due to dead $SG2_LXC_NAME client daemon (sg2dplt)"
		sg2d start
	}
	exit 0
}

function geticfgxmlparam() {
	cat $2 | sed -ne '/<!--/ { :c; /-->/! { N; b c; }; /-->/s/<!--.*-->//g }; /^  *$/!p;' | grep \"$1\" | perl -e '$_=<STDIN>;s/.*value="([^"]+)".*//;print $1;'
}

function misc_code() {
	#TODO PRIO 3 : remember ETH assignments for the ETHs used by iSoftGate so that we restore them in case of container crash - might be needed for vlans ?
	for i in {0..7} 10 ; do
		theETH_PCIADDR=`grep eth$i /etc/udev/rules.d/70-persistent-net.rules | perl -e '$_=<STDIN>;s/.*KERNELS=="([^"]+)".*/$1/;print $1'`
		echo theETH_PCIADDR = $theETH_PCIADDR
		shouldETH_NAME=`grep eth$i /etc/udev/rules.d/70-persistent-net.rules | perl -e '$_=<STDIN>;s/.*NAME="([^"]+)".*/$1/;print $1'`
		echo shouldETH_NAME = $shouldETH_NAME
		theETHBYPCI=$(find '/sys/devices/pci0000:00' -type d -name "$theETH_PCIADDR" -exec find '{}' -type d -name net \;)
		theETHBYPCI=$(ls -1 $theETHBYPCI)
		echo theETHBYPCI = $theETHBYPCI
	done
}

function getallusedSGIFs() {
	local allSGIFPars=""
	local tmp=`geticfgxmlparam lanRedundancy $1`
	if [ "x$tmp" = "x0" ]; then
		allSGIFPars="lanInterface"
	else
		[ "x$tmp" = "x" ] || allSGIFPars="slave0 slave1"
	fi
	allSGIFPars="${allSGIFPars} xlinkLanInterface"
	tmp=`geticfgxmlparam lanRedundancyWAN $1`
	if [ "x$tmp" = "x0" ]; then
		allSGIFPars="${allSGIFPars} lanInterfaceWAN"
	else
		[ "x$tmp" = "x" ] || allSGIFPars="${allSGIFPars} slave0WAN slave1WAN"
	fi
	tmp=`geticfgxmlparam lanRedundancyAdmin $1`
	if [ "x$tmp" = "x0" ]; then
		allSGIFPars="${allSGIFPars} lanInterfaceAdmin"
	else
		[ "x$tmp" = "x" ] || allSGIFPars="${allSGIFPars} slave0Admin slave1Admin"
	fi
	tmp=`geticfgxmlparam lanRedundancySigSurvLAN $1`
	if [ "x$tmp" = "x0" ]; then
		allSGIFPars="${allSGIFPars} lanInterfaceSigSurvLAN"
	else
		[ "x$tmp" = "x" ] || allSGIFPars="${allSGIFPars} slave0SigSurvLAN slave1SigSurvLAN"
	fi
	tmp=`geticfgxmlparam lanRedundancyHFA $1`
	if [ "x$tmp" = "x0" ]; then
		allSGIFPars="${allSGIFPars} lanInterfaceHFA"
	else
		[ "x$tmp" = "x" ] || allSGIFPars="${allSGIFPars} slave0HFA slave1HFA"
	fi
	tmp=`geticfgxmlparam lanRedundancySIP $1`
	if [ "x$tmp" = "x0" ]; then
		allSGIFPars="${allSGIFPars} lanInterfaceSIP"
	else
		[ "x$tmp" = "x" ] || allSGIFPars="${allSGIFPars} slave0SIP slave1SIP"
	fi
	echo $allSGIFPars
}

function get_initialcfg_params_as_string() {
	local xmlFileToRead=/var/sg2/opt/soco/config/initialcfg.xml
	[ "x$1" = "x" ] || {
		[ -e "$1" ] && xmlFileToRead=$1
	}
	local resultStr="{"
	local parval=0
    #starting with OSFOURK-24092 the status is determined by the haipsetup field
	#1>/dev/null 2>&1 ls /etc/init.d/rc3.d/*sg2d* && parval=1
    mynode=1
    grep $(hostname) /var/opt/ha/conf/haipsetup.xml | grep -q system.name-node2 && mynode=2
    grep system.iSG.node$mynode /var/opt/ha/conf/haipsetup.xml | grep -q '>1<'  && parval=1
	resultStr="${resultStr}\"enabled\":\"${parval}\""
	parval="unconfigured"
	if [ -e $xmlFileToRead ]; then
		parval="stopped"
		[ -e /sg2/.sg2-service-state ] && parval=`cat /sg2/.sg2-service-state`
	fi
	[ "x$parval" = "x" ] && parval="error"
	resultStr="${resultStr},\"state\":\"${parval}\""
	[ -e $xmlFileToRead ] && {
		for asgpar in ipAddrEth netmaskEth defaultGateway ipAddrCCA ipAddrCCB ipAddrCCC ipAddrSig netmaskSig lanInterface lanInterfaceAdmin ltu; do
			parval=`geticfgxmlparam $asgpar $xmlFileToRead`
			resultStr="${resultStr},\"$asgpar\":\"${parval}\""
		done
	}
	#add all LANs available for iSoftGate as array
	fillInHAIFs
	fillInEntGWSGIFs
	allFreeSystemETHs="["
	allFSETHsShort=""
	#TODO - prio 2 - in a iSoftGate running state the ETHs used by iSoftGate will not be visible on PLT - so just append to the list the lanInterface and lanInterfaceAdmin if not already on the list
	# - later fix this by extending the list will all used ETHs
	for newif in `geticfgxmlparam lanInterface $xmlFileToRead` `geticfgxmlparam lanInterfaceAdmin $xmlFileToRead` $(ls -1d /sys/class/net/eth* /sys/class/net/vlan* /sys/class/net/bond* 2>/dev/null | sort -f ); do
		newif=${newif##*/}
		[ "x$newif" = "x" ] && continue
		[[ "${haIfs}" =~ ":${newif}:" ]] && continue
		[[ "${allusedEntGWSGETHs}" =~ ":${newif}:" ]] && continue
		[ "x$newif" = "xeth8" ] && continue
		[ "x$newif" = "xvlan4092" ] && continue
		[ "x$newif" = "xeth10" ] && continue
		
		if [ $allFreeSystemETHs = "[" ]; then
			allFreeSystemETHs="${allFreeSystemETHs}\"$newif\""
		else
			allFreeSystemETHs="${allFreeSystemETHs},\"$newif\""
		fi
		allFSETHsShort="${allFSETHsShort} $newif"
	done
	
	resultStr="${resultStr},\"allFreeETHs\":${allFreeSystemETHs}]}"
	echo $resultStr	
}

function set_initialcfg_params_from_string() {
	local allNewCfgParamsString="$1"
	local xmlFileToWrite=/var/sg2/opt/soco/config/initialcfg.xml
	local response="set_error"
	[ "x$1" = "x" ] || {
		[ -e "$1" ] && xmlFileToWrite=$1
	}
	local tempXmlFile=/opt/sg2/temp-newSG2initialcfgXml
	rm -rf $tempXmlFile
	if [ -e $xmlFileToWrite ]; then
		cp $xmlFileToWrite $tempXmlFile
	else
		#default XML file template is here
		cat >$tempXmlFile << '_EOF_TEMPLATE_INITIALCFG_'
<!-- initialcfg.xml --><softGateInitialConfiguration>

<!-- general settings -->
<Property name="lanRedundancy" value="0"/>
<Property name="lanInterface" value="eth1"/>
<Property name="slave0" value="eth0"/>
<Property name="slave1" value="eth1"/>
<Property name="ethLinkMode" value="0"/>
<Property name="hardwareType" value="0"/>

<!-- Base address (= payload/only for IPDA direct link) -->
<Property name="ipAddrEth" value="172.16.14.36"/>
<Property name="netmaskEth" value="255.255.0.0"/>
<Property name="mtuSizeEth" value="1500"/>
<Property name="vlanTag" value="0"/>
<Property name="vlanId" value="0"/>
<Property name="defaultGateway" value="172.16.0.254"/>

<!-- Signaling address (for direct link, identical with base address for IPDA networking) -->
<Property name="ipAddrSig" value="192.168.5.45"/>
<Property name="netmaskSig" value="255.255.255.0"/>
<Property name="serverPortSig" value="4000"/>
<Property name="tosLan" value="104"/>
<Property name="ipAddrCCA" value="172.16.14.10"/>
<Property name="ipAddrCCB" value="0.0.0.0"/>
<Property name="ipAddrCCC" value="0.0.0.0"/>

<!-- New entries for V6 -->
<Property name="ipV6AddressPayload" value="::"/>
<Property name="ipV6AddressPlPrefix" value="0"/>
<Property name="ipAddrNGS" value="0.0.0.0"/>
<Property name="useNGSClient" value="1"/>
<Property name="ip_v4_v6_mode" value="1"/>

<!-- New entries for loadbalancer -->
<Property name="provideLoadBalancer" value="0"/>
<Property name="ipAddrLoadbalancer" value="0.0.0.0"/>
<Property name="netmaskLoadbalancer" value="0.0.0.0"/>
<Property name="defGWLoadbalancer" value="0.0.0.0"/>
<Property name="vlanTagLoadbalancer" value="0"/>
<Property name="vlanIdLoadbalancer" value="0"/>

<!-- New entries for HiPath Access -->
<Property name="xlinkLanInterface" value=""/>

<Property name="osaXlinkNetwork" value="10.100.0.0"/>

<!--  WAN interface for HFA@Home -->
<Property name="slave0WAN" value=""/>
<Property name="slave1WAN" value=""/>
<Property name="lanRedundancyWAN" value="0"/>
<Property name="lanInterfaceWAN" value=""/>
<Property name="publicIPWAN" value="0.0.0.0"/>
<Property name="telnumEnabledWAN" value="0"/>

<!--  Admin LAN interface -->
<Property name="slave0Admin" value=""/>
<Property name="slave1Admin" value=""/>
<Property name="lanRedundancyAdmin" value="0"/>
<Property name="lanInterfaceAdmin" value=""/>

<!--  SigSurvLAN interface -->
<Property name="slave0SigSurvLAN" value=""/>
<Property name="slave1SigSurvLAN" value=""/>
<Property name="lanRedundancySigSurvLAN" value="0"/>
<!-- intentionally missing, added dynamically by FirstInstalllationData class
    <Property name="lanInterfaceSigSurvLAN"   value="" />
 -->

<!--  Signalling LAN interface for HFA -->
<Property name="slave0HFA" value=""/>
<Property name="slave1HFA" value=""/>
<Property name="lanRedundancyHFA" value="0"/>
<Property name="lanInterfaceHFA" value=""/>

<!--  Signalling LAN interface for SIP -->
<Property name="slave0SIP" value=""/>
<Property name="slave1SIP" value=""/>
<Property name="lanRedundancySIP" value="0"/>
<Property name="lanInterfaceSIP" value=""/>

<!-- Internal IP addresses for TUN-devices used for HSR connection -->
<Property name="ipTUN1SigSurvLAN" value="192.168.187.151"/>
<Property name="ipTUN2SigSurvLAN" value="192.168.187.152"/>

<!-- CSTA/CICA addresses -->
<Property name="ipAddrCentralCSTA" value="0.0.0.0"/>
<Property name="ipAddrApeCSTA" value="0.0.0.0"/>

<Property name="ltu" value="23"/>
  <Property name="lanInterfaceSigSurvLAN" value=""/>
</softGateInitialConfiguration>
_EOF_TEMPLATE_INITIALCFG_
	fi
	
	configBeforeSave=`2>/dev/null get_initialcfg_params_as_string $tempXmlFile`
	
	#action_probe,enabled_1,lanInterface_eth1,lanInterfaceAdmin_,ipAddrEth_172.16.14.36,netmaskEth_255.255.0.0,defaultGateway_172.16.0.254,ipAddrCCA_172.16.14.10,ipAddrCCB_ccbbb,ipAddrCCC_0.0.0.0,ipAddrSig_1234567,netmaskSig_255.255.255.0,ltu_23
	while [[ $allNewCfgParamsString =~ "_" ]]; do
		if [[ $allNewCfgParamsString =~ "," ]]; then
			aParSet=${allNewCfgParamsString%%,*}
			allNewCfgParamsString=${allNewCfgParamsString#*,}
		else
			aParSet=$allNewCfgParamsString
			allNewCfgParamsString=""
		fi
		par=${aParSet%_*}
		val=${aParSet#*_}
		eval export $par=$val
	done
	
	for asgpar in ipAddrEth netmaskEth defaultGateway ipAddrCCA ipAddrCCB ipAddrCCC ipAddrSig netmaskSig lanInterface lanInterfaceAdmin ltu; do
		eval export parVal='$'$asgpar
		1>/dev/null 2>/dev/null sed -i -e "s|\(\"$asgpar\".*value=\"\).*\(\".*\)|\1$parVal\2|" $tempXmlFile
	done

	configAfterSave=`2>/dev/null get_initialcfg_params_as_string $tempXmlFile`
	
	if 1>/dev/null 2>/dev/null sg2d status; then
		if [ "x$enabled" = "x1" ]; then
			if [ "x$configBeforeSave" = "x$configAfterSave" ]; then
				echo no_change
				return 0
			else
				response="resta_rt"
			fi
		else
			response="stop"
		fi
	else
		if [ "x$enabled" = "x1" ]; then
			response="start"
		else
			mkdir -p /var/sg2/opt/soco/config
			1>/dev/null 2>/dev/null cp $tempXmlFile $xmlFileToWrite
			echo same
			return 0
		fi
	fi

	if [ "x$action" = "xprobe" ]; then
		echo $response
		return 0
	fi

	mkdir -p /var/sg2/opt/soco/config
	1>/dev/null 2>/dev/null cp $tempXmlFile $xmlFileToWrite
	if [ "x$action" = "xset-and-restart" ] ; then
		echo ok_rs
		#fork action not to block the caller
		(
			exec 1>/dev/null
			exec 2>/dev/null
			[ "x$response" = "xstart" ] && response=enable
			[ "x$response" = "xstop" ] && response=disable
			[ "x$response" = "xresta_rt" ] && response=restart
			/usr/bin/setsid /bin/bash /bin/sg2d $response &
		)
	else
		echo ok_nrs
	fi
	return 0
}

function fillInHAIFs() {
	haIfs=":"
	for hapar in atlantic-lan.ethernet-interface-node1 atlantic-lan.ethernet-interface2-node1 customer-lan.ethernet-interface-node1 ipda-lan.ethernet-interface-node1 sbc-wan.ethernet-interface-node1; do
		newif=`/opt/webservice/scripts/gethaipsetupentry.sh $hapar`
		[ "x$newif" = "x" ] && continue
		[[ "${haIfs}" =~ ":${newif}:" ]] || haIfs="${haIfs}${newif}:"
		[ -e /proc/net/bonding/$newif ] || continue
		for anETH in $(cat /proc/net/bonding/$newif | grep -i slave | grep -i interface | awk '{print $NF}'); do
			[[ "${haIfs}" =~ ":${anETH}:" ]] || haIfs="${haIfs}${anETH}:"
		done
	done
}

function fillInEntGWSGIFs() {
	allUsedEntGWSGIFsNames=`getallusedSGIFs /var/opt/soco/config/initialcfg.xml`
	allusedEntGWSGETHs=":"
	for sgpar in $allUsedEntGWSGIFsNames ; do
		newif=`geticfgxmlparam $sgpar /var/opt/soco/config/initialcfg.xml`
		[ "x$newif" = "x" ] && continue
		[[ "${allusedEntGWSGETHs}" =~ ":${newif}:" ]] || allusedEntGWSGETHs="${allusedEntGWSGETHs}${newif}:"
		[ -e /proc/net/bonding/$newif ] || continue
		for anETH in $(cat /proc/net/bonding/$newif | grep -i slave | grep -i interface | awk '{print $NF}'); do
			[[ "${allusedEntGWSGETHs}" =~ ":${anETH}:" ]] || allusedEntGWSGETHs="${allusedEntGWSGETHs}${anETH}:"
		done
	done
}

function check_network() {
	local xmlFileToCheck=/var/sg2/opt/soco/config/initialcfg.xml
	[ "x$1" = "x" ] || {
		[ -e "$1" ] && xmlFileToCheck=$1
	}
	#make sure XLink is not used
	tmp=`geticfgxmlparam xlinkLanInterface $xmlFileToCheck`
	[ "x$tmp" = "x" ] || {
		log "WARNING : Configuration error : XLink is not allowed on $SG2_LXC_NAME. Continuing despite this ..."
		#exit 1
	}
    
    1>/dev/null 2>/dev/null /opt/webservice/scripts/is_ecoap
    isentgw=$?
    
    if [ -e /dev/.sg2d-on-duplex ]; then
        # for SG on Duplex we make completely different checks
        # check if lanInterface is the IPDA
        tmp=`geticfgxmlparam lanInterface $xmlFileToCheck`
        newif=`/opt/webservice/scripts/gethaipsetupentry.sh ipda-lan.ethernet-interface-node1`
        [ "x$tmp" = "x$newif" ] || {
            [ $isentgw -eq 1 ] || {
            log "Configuration error : LAN Interface $tmp on $SG2_LXC_NAME must be the same as HHS IPDA LAN $newif"
            exit 1
            }
        }
        allusedSG2SGETHs=":$tmp:"
        # check if Management LAN is the Customer
        tmp=`geticfgxmlparam lanInterfaceAdmin $xmlFileToCheck`
        newif=`/opt/webservice/scripts/gethaipsetupentry.sh customer-lan.ethernet-interface-node1`
        [ "x$tmp" = "x$newif" ] || {
            [ $isentgw -eq 1 ] || {
            log "Configuration error : MAN Interface $tmp on $SG2_LXC_NAME must be the same as HHS Customer LAN $newif"
            exit 1
            }
        }
        allusedSG2SGETHs="$allusedSG2SGETHs$tmp:"
        return 0
    fi
    
    # starting with V10R1.34 do not make the eth0-3 eth4-7 sepparation 
    return 0

	#collect all ETHs used by HA
	fillInHAIFs
	
	#collect all ETHs used by EntGW SG part
	fillInEntGWSGIFs
	
	#check if ETH4-ETH7 are not used for any HA or EntGW functions
	for newif in eth{4..7}; do
		[[ "${haIfs}" =~ ":${newif}:" ]] && {
			log "$SG2_LXC_NAME Configuration error : LAN interface $newif is already used by HA but it should be exclusively reserved for $SG2_LXC_NAME. Please reconfigure."
			exit 1
		}
		[[ "${allusedEntGWSGETHs}" =~ ":${newif}:" ]] && {
			log "$SG2_LXC_NAME Configuration error : LAN interface $newif is already used by EntGW SG part but it should be exclusively reserved for $SG2_LXC_NAME. Please reconfigure."
			exit 1
		}
	done
	
	#collect all ETHs used by SG2 part
	allUsedSG2SGIFsNames=`getallusedSGIFs $xmlFileToCheck`
	allusedSG2SGETHs=":"
	for sgpar in $allUsedSG2SGIFsNames ; do
		newif=`geticfgxmlparam $sgpar $xmlFileToCheck`
		[ "x$newif" = "x" ] && continue
		[[ "${allusedSG2SGETHs}" =~ ":${newif}:" ]] || allusedSG2SGETHs="${allusedSG2SGETHs}${newif}:"
		#check also for conflicts
		[[ "${haIfs}" =~ ":${newif}:" ]] && {
			log "$SG2_LXC_NAME Configuration error : LAN interface $newif to be used as $sgpar is already used by HA. Please reconfigure."
			exit 1
		}
		[[ "${allusedEntGWSGETHs}" =~ ":${newif}:" ]] && {
			log "$SG2_LXC_NAME Configuration error : LAN interface $newif to be used as $sgpar is already used by EntGW SG part. Please reconfigure."
			exit 1
		}
		[ "x$newif" = "xeth8" ] && {
			log "$SG2_LXC_NAME Configuration error : LAN interface ETH8 to be used as $sgpar is an internal LAN and can not be used for the $SG2_LXC_NAME. Please reconfigure."
			exit 1
		}
		[ "x$newif" = "xeth0" -o "x$newif" = "xeth1" -o "x$newif" = "xeth2" -o "x$newif" = "xeth3" ] && {
			log "$SG2_LXC_NAME Configuration error : LAN interface $newif is not allowed for $SG2_LXC_NAME. Please reconfigure and use ETH4->ETH7"
			exit 1
		}
	done
	return 0
}

function prepare_networks_and_configs() {

	check_network
    
	
	#TODO - prio 3 - set service state to config_error in case of errors ; cutrrently this does not work as it breaks the environment
#	(
#		check_network || exit 1
#		exit 0
#	) || {
#		rm -f /sg2/.sg2-service-state
#		echo config_error > /sg2/.sg2-service-state
#		exit 1
#	}
	>/dev/sg2-lxc-after.stop.cmds
	
	#will make haipsetup.xml visible inside container by making the complete /var/opt/ha/conf directory visible
	#make sure destination folder for haipsetup exists
	mkdir -p /var/sg2/opt/ha/conf
	
	#also make available inside container all webservice scripts
	mkdir -p /sg2/opt/webservice
	
	# re-deploy passwd and shadow at every start to solve expired root account situations
	cp -p /etc/shadow /etc/group /etc/passwd /sg2/etc/.
	log "INFO : re-deploy /etc/shadow /etc/group"
    
    #tiny sles15 fix for missing ethtool symbolic link
    [ -e /sg2/sbin/ethtool ] || ln -s /usr/sbin/ethtool /sg2/sbin/ethtool
    
    #sync modified ip tool from plt
    [ -e /usr/sbin/ip.sles15sp2 ] && cp /usr/sbin/ip /sg2/usr/sbin/ip

	[ -e /dev/.sg2d-on-duplex ] && {
        touch /sg2/opt/.sg2d-on-duplex
        rm -f /sg2/opt/.iSG.ipvlan.info /sg2/opt/.iSG.ipvlan.iSG-client-is-ready
        grep -q isg-wait-for-network /sg2/etc/init.d/socod || \
            sed -i -e 's|^SOCO_BIN_TIMEOUT|/etc/init.d/sg2dplt isg-wait-for-network\nSOCO_BIN_TIMEOUT|' /sg2/etc/init.d/socod
    }

    #also make available /var/opt/webservice since it contains server certificates needed by apache config
	mkdir -p /var/sg2/opt/webservice /var/crash

	cat > /sg2/$SG2_LXC_NAME.conf << _EOF_SG2_LXC_CONF_
lxc.utsname = $SG2_LXC_NAME
lxc.arch = x86_64
lxc.rootfs = /sg2
lxc.mount.auto = proc:mixed sys:mixed cgroup:mixed
lxc.mount.entry = /sys/fs/fuse/connections sys/fs/fuse/connections none bind,optional 0 0
lxc.mount.entry = /var/sg2 var none bind,create=dir 0 0
lxc.mount.entry = /var/opt/ha/conf var/opt/ha/conf none bind,create=dir 0 0
lxc.mount.entry = /opt/webservice opt/webservice none bind,create=dir 0 0
lxc.mount.entry = /var/crash var/crash none rw,bind,create=dir 0 0
# AppArmor settings
lxc.aa_allow_incomplete = 1
lxc.aa_profile = unconfined
_EOF_SG2_LXC_CONF_

	rm -f /sg2/etc/sysconfig/network/ifcfg-eth* /sg2/etc/sysconfig/network/ifcfg-intlan /sg2/etc/sysconfig/network/ifcfg-bond* /sg2/etc/sysconfig/network/ifcfg-vlan* 

	IFS=' :' read -a arrETHs <<< `echo $allusedSG2SGETHs`
	
	containerAddedBasedIFs=":"
    
    # starting with V10R1.34 do not make the eth0-3 eth4-7 sepparation 
    touch /dev/.sg2d-on-duplex
	
	i=0
	[ -e /dev/.sg2d-on-duplex ] || while [ $i -lt ${#arrETHs[@]} ]; do
		theETH=${arrETHs[$i]}
        [ "x$theETH" = "x" ] && {
            i=$(($i + 1))
            continue
        }
		#if bond then check base ETHs
		if [ -e /proc/net/bonding/$theETH ]; then
			newif=$theETH
			for anETH in $(cat /proc/net/bonding/$newif | grep -i slave | grep -i interface | awk '{print $NF}'); do
				newif=$anETH
				[ "x$newif" = "xeth0" -o "x$newif" = "xeth1" -o "x$newif" = "xeth2" -o "x$newif" = "xeth3" ] && {
					log "$SG2_LXC_NAME Configuration error : VLAN interface $theETH is based on a BOND containing $newif which is not allowed for $SG2_LXC_NAME. Please reconfigure and use VLANs/BONDs based on ETH4->ETH7"
					exit 1
				}
				[[ "${containerAddedBasedIFs}" =~ ":${newif}:" ]] || containerAddedBasedIFs="${containerAddedBasedIFs}${newif}:"
			done
		fi
		if [ -e /proc/net/vlan/$theETH ]; then
			#check if allowed, i.e. vlan is not based on some ETH which is not allowed
			(
				source /etc/sysconfig/network/ifcfg-$theETH
				newif=$ETHERDEVICE
				[ "x$newif" = "xeth0" -o "x$newif" = "xeth1" -o "x$newif" = "xeth2" -o "x$newif" = "xeth3" ] && {
					log "$SG2_LXC_NAME Configuration error : VLAN interface $theETH is based on $newif which is not allowed for $SG2_LXC_NAME. Please reconfigure and use VLANs based on ETH4->ETH7"
					exit 1
				}
				#if bond then check based ETHs
				[ -e /proc/net/bonding/$newif ] || {
					[[ "${containerAddedBasedIFs}" =~ ":${newif}:" ]] || containerAddedBasedIFs="${containerAddedBasedIFs}${newif}:"
					exit 0
				}
				for anETH in $(cat /proc/net/bonding/$newif | grep -i slave | grep -i interface | awk '{print $NF}'); do
					newif=$anETH
					[ "x$newif" = "xeth0" -o "x$newif" = "xeth1" -o "x$newif" = "xeth2" -o "x$newif" = "xeth3" ] && {
						log "$SG2_LXC_NAME Configuration error : VLAN interface $theETH is based on a BOND containing $newif which is not allowed for $SG2_LXC_NAME. Please reconfigure and use VLANs/BONDs based on ETH4->ETH7"
						exit 1
					}
					[[ "${containerAddedBasedIFs}" =~ ":${newif}:" ]] || containerAddedBasedIFs="${containerAddedBasedIFs}${newif}:"
				done
				exit 0
			) || exit 1
			log "INFO : Moving VLAN interface $theETH inside $SG2_LXC_NAME container ..."
			/sbin/service network stop $theETH
			echo "/sbin/service network start $theETH" >> /dev/sg2-lxc-after.stop.cmds
			(
				source /etc/sysconfig/network/ifcfg-$theETH
				echo lxc.network.type = vlan
				echo lxc.network.flags = up
				echo lxc.network.link = $ETHERDEVICE
				echo lxc.network.vlan.id = $VLAN_ID
				echo lxc.network.name = $theETH
			) 1>>/sg2/$SG2_LXC_NAME.conf
			cat > /sg2/etc/sysconfig/network/ifcfg-$theETH << '_EOF_IFCFG_EMPTY'
BOOTPROTO='static'
ONBOOT='yes'
STARTMODE='auto'
USERCONTROL='no'
NAME='I211 Gigabit Network Connection'
MTU=''
ETHTOOL_OPTIONS='autoneg on'
IPADDR='0.0.0.0/0'
_EOF_IFCFG_EMPTY
		else
			log "INFO : Moving interface $theETH inside $SG2_LXC_NAME container ..."
			(
				echo lxc.network.type = phys
				echo lxc.network.flags = up
				echo lxc.network.link = $theETH
				echo lxc.network.name = $theETH
			) 1>>/sg2/$SG2_LXC_NAME.conf
			#needed for bonds
			cp -p /etc/sysconfig/network/ifcfg-$theETH /sg2/etc/sysconfig/network/ifcfg-$theETH
			newif=$theETH
			[[ "${containerAddedBasedIFs}" =~ ":${newif}:" ]] || containerAddedBasedIFs="${containerAddedBasedIFs}${newif}:"
		fi
		i=$(($i + 1))
	done
	#add rest of ETHs inside container so that they are available in the WBM for reconfiguration
	[ -e /dev/.sg2d-on-duplex ] || for newif in eth{4..7}; do
		[[ "${containerAddedBasedIFs}" =~ ":${newif}:" ]] && continue
		log "INFO : Moving interface $newif inside $SG2_LXC_NAME container ..."
		(
			echo lxc.network.type = phys
			echo lxc.network.flags = up
			echo lxc.network.link = $newif
			echo lxc.network.name = $newif
		) 1>>/sg2/$SG2_LXC_NAME.conf
		cp -p /etc/sysconfig/network/ifcfg-$newif /sg2/etc/sysconfig/network/ifcfg-$newif
	done
		
	cat >>/sg2/$SG2_LXC_NAME.conf << _EOF_SG2_LXC_CONF_PART2_
lxc.pts = 1024
lxc.tty = 4
lxc.pivotdir = lxc_putold
#lxc.cgroup.cpu.rt_runtime_us = 400000
#lxc.cgroup.cpu.rt_period_us = 1000000
_EOF_SG2_LXC_CONF_PART2_
}

function get_all_derived_IFs() {
    theeth=$1
    allDerivedeths=":$1:"
    while [ 1 ] ; do
        thevlanbase=$(2>/dev/null cat /proc/net/vlan/$theeth | grep ^Device | awk '{print $NF}')
        if [ "x$thevlanbase" = "x" ] ; then
            bondslavestocheck=$theeth
        else
            #vlan found => add it to list and query base dev for bond slaves
            allDerivedeths=":$allDerivedeths :$thevlanbase:"
            bondslavestocheck=$thevlanbase
        fi
        for abondeth in $(2>/dev/null cat /proc/net/bonding/$bondslavestocheck | grep -i slave | grep -i interface | awk '{print $NF}') ; do
            allDerivedeths=":$allDerivedeths :$abondeth:"
        done
        
        #OSFOURK-25442 Secondary node stays in 4 because of Atlantic LAN interface issue
        # M. Leahu - search bond slaves also in ifcfg file as the dynamic config sometimes does not show them
        #TODO here ...
        
        break
    done
    #echo $allDerivedeths 
}

function get_HA_IF() {
    theHA_IF=""
    1>/dev/null 2>/dev/null pushd /sys/class/net
    for theeth in $(ls -1 .) ; do
        [ "x`2>/dev/null ip -4 addr show dev $theeth | grep -m 1 inet | awk '{print $2}' | cut -d/ -f1`" = "x" ] || {
            grep $(2>/dev/null ip -4 addr show dev $theeth | grep -m 1 inet | awk '{print $2}' | cut -d/ -f1) /etc/hosts | grep -q $(hostname)$ && theHA_IF=$theeth
        }
    done
    1>/dev/null 2>/dev/null popd
}


function setup_ipvlan_interfaces() {
    log "Will now setup ipvlan interfaces ..."
    #wait max 1 minute for container to be ready
    for i in {0..60}; do
        sleep 1
        [ -e /sg2/opt/.iSG.ipvlan.iSG-client-is-ready ] && {
            log "Client daemon inside iSoftGate is alive"
            break
        }
    done
    atlanticif=$(/opt/webservice/scripts/gethaipsetupentry.sh atlantic-lan.ethernet-interface-node1)
    
    #OSFOURK-23878 - do not pass Atlantic/HA Interfaces to iSG
    get_all_derived_IFs $atlanticif
    allDerivedAtlanticIFs=":${allDerivedeths}:"
    #in case of Duplex determine also the HA interface
    allDerivedHAIFs="::"
    1>/dev/null 2>/dev/null /opt/webservice/scripts/is_duplex
    [ $? -eq 1 ] && {
        get_HA_IF
        get_all_derived_IFs $theHA_IF
        allDerivedHAIFs=":${allDerivedeths}:"
    }
    ignATLTandHAifs=":${allDerivedAtlanticIFs}:${allDerivedHAIFs}:"
    
    for aneth in $(ls -1d /sys/class/net/eth* /sys/class/net/vlan* /sys/class/net/bond* 2>/dev/null | sort -f); do
        aneth=${aneth##*/}
        #ignore some special LANs on EcoServer/DSCXL
        [ "x$aneth" = "xeth8" ] && continue
        [ "x$aneth" = "xeth10" ] && continue
        [ "x$aneth" = "xvlan4092" ] && continue
        
        #ignore atlantic and corosync lans
        [[ "$ignATLTandHAifs" =~ ":$aneth:" ]] && {
            log "setup_ipvlan_interfaces : interface $aneth will be ignored by iSG because it is either Atlantic or HA related"
            continue
        }
        
        log "setup_ipvlan_interfaces : interface $aneth will be derived and passed also into iSG namespace"
        ip link add link $aneth name ipvl$aneth type ipvlan mode l2
        log "ipvlan add link rc : $?"
        ip link set dev ipvl$aneth netns `lxc-info -pHn $SG2_LXC_NAME` name $aneth
        log "set dev netns rc : $?"
    done
    log "setup ipvlan interfaces done."
    #write here local SWU CC address for iSoftGate to know it
    node=ccb
    grep system.name-node /var/opt/ha/conf/haipsetup.xml | grep `hostname` | grep -q system.name-node1 && node=cca
    /opt/webservice/scripts/gethaipsetupentry.sh ipda-lan.${node}-ip-address > /sg2/opt/.iSG.ipvlan.info
}

function try_init_sg2() {
	#start dummy LXC process so that LXC sysfs is filled in
	for i in {1..4}; do
		rm -f /sg2/tmp/sg2lxc.started
		echo 1 > /proc/sys/vm/drop_caches
		#create .screenrc file
		echo "logfile /var/log/$SG2_LXC_NAME-console.log" > /sg2/tmp/.screenrc
		echo "logfile flush 1" >> /sg2/tmp/.screenrc
		eval screen -S "$SG2_LXC_NAME" -d -m -c /sg2/tmp/.screenrc -L bash -c \'lxc-start -n $SG2_LXC_NAME --logfile=/var/log/$SG2_LXC_NAME-lxc.log --foreground -- /bin/touch /tmp/sg2lxc.started\'
		for j in {1..15}; do
			sleep 1
			[ -e /sg2/tmp/sg2lxc.started ] && break
		done
		[ -e /sg2/tmp/sg2lxc.started ] && break
		#adjust cpu.rt_runtime_us shares
		#echo 950000 > /sys/fs/cgroup/cpu/cpu.rt_runtime_us
		#echo 900000 > /sys/fs/cgroup/cpu/lxc/cpu.rt_runtime_us
		#Assistant and CSTA have 250000 each
		#echo 400000 > /sys/fs/cgroup/cpu/lxc/$SG2_LXC_NAME/cpu.rt_runtime_us
	done
}

function get_highest_sg2d_ver() {
	mkdir -p /sg2/opt/sg2
	
	#assume I still have this version $SG2_SCRIPT_VERSION
	cp $0 /sg2/opt/sg2/sg2d-plt-$SG2_SCRIPT_VERSION
	
	#me as external file
	eval export meext_`grep ^SG2_SCRIPT_VERSION /etc/init.d/sg2d`
	cp /etc/init.d/sg2d /sg2/opt/sg2/sg2d-plt-$meext_SG2_SCRIPT_VERSION
	
	#me from plt SG
	eval export mepltsg_`grep ^SG2_SCRIPT_VERSION /opt/soco/native/daemon/sg2d`
	cp /opt/soco/native/daemon/sg2d /sg2/opt/sg2/sg2d-plt-$mepltsg_SG2_SCRIPT_VERSION

	#me from yaps RPM
	[ -e /opt/yaps/script/sg2d ] && {
		eval export meyapssg_`grep ^SG2_SCRIPT_VERSION /opt/yaps/script/sg2d`
		cp /opt/yaps/script/sg2d /sg2/opt/sg2/sg2d-plt-$meyapssg_SG2_SCRIPT_VERSION
	}

	#me from client daemon
	eval export client_`grep ^SG2_SCRIPT_VERSION /sg2/etc/init.d/sg2d`
	cp /sg2/etc/init.d/sg2d /sg2/opt/sg2/sg2d-plt-$client_SG2_SCRIPT_VERSION
	
	#me from client SG
	eval export meclientsg_`grep ^SG2_SCRIPT_VERSION /sg2/opt/soco/native/daemon/sg2d`
	cp /sg2/opt/soco/native/daemon/sg2d /sg2/opt/sg2/sg2d-plt-$meclientsg_SG2_SCRIPT_VERSION
	
	highestVer=`ls -1v /sg2/opt/sg2/sg2d-plt* | tail -n 1`
	echo ${highestVer##*-}
}

function unblock_server_daemon_for_one_step() {
    local socket_file=/sg2/tmp/.inotifywait.simulation.socket
    [ -e /var/opt/soco/is_container_sg ] && socket_file=/tmp/.inotifywait.simulation.socket
    [ "x" = "x$INWSIM_COUNTER" ] && export INWSIM_COUNTER=0
    INWSIM_COUNTER=$(($INWSIM_COUNTER + 1))
    local inwccmdline="/tmp/.inotifywait.simulation.pl client_rq 5 $socket_file $$.$INWSIM_COUNTER"
    [ "x$1" = "xstop_server" ] && inwccmdline="/tmp/.inotifywait.simulation.pl stop_server 5 $socket_file $$.$INWSIM_COUNTER"
    [ "x$1" = "xwait_to_be_unblocked" ] && inwccmdline="/tmp/.inotifywait.simulation.pl wait_to_be_unblocked 30 $socket_file $$.$INWSIM_COUNTER"
    if [ "x$1" = "xwait_to_be_unblocked" ]; then
        #block the caller in this case
        if [ -e /tmp/.inotifywait.simulation.socket.trace ]; then
            echo "`date` `date +%s.%N` $inwccmdline" >>/tmp/.inotifywait.simulation.socket.trace
            1>>/tmp/.inotifywait.simulation.socket.trace 2>&1 $inwccmdline
        else
            1>/dev/null 2>&1 $inwccmdline
        fi
    else
        #do not block the caller
        if [ -e /tmp/.inotifywait.simulation.socket.trace ]; then
            echo "`date` `date +%s.%N` $inwccmdline" >>/tmp/.inotifywait.simulation.socket.trace
            ( 1>>/tmp/.inotifywait.simulation.socket.trace 2>&1 $inwccmdline & )
        else
            ( 1>/dev/null 2>&1 $inwccmdline & )
        fi
    fi
}

#calculate decimal value of IP address
function ipval()
{
	RES=`awk -F- -v arg="$1" '{
	split(arg, arr, ".");
	s=0;
	for (i=1; i<=length(arr); i++) { s += arr[i] * (256**(4-i)); }
		print s
	}' <<< '' `
	echo $RES
}

function host_enable_traffic_between_entgw_and_isg_on_same_lan_osfourk22440() {
    [ -e /var/opt/ha/conf/ ] || return 0
    #refresh EntGW IPs
    ip addr show | grep :pb21 > /var/opt/ha/conf/entgw.IPv4.payload-address
    #determine the Voice LAN
    entGWvoiceLAN="x `grep :pb21 /var/opt/ha/conf/entgw.IPv4.payload-address`"
    entGWvoiceLAN=${entGWvoiceLAN##* }
    entGWvoiceLAN=${entGWvoiceLAN%:*}
    [ "x$entGWvoiceLAN" = "x" ] && return 0
    #now look at the iSG
    [ -e /var/opt/ha/conf/iSG.IPv4.payload-addresses ] || return 0
    iSGvoiceLAN="x `grep :pb21 /var/opt/ha/conf/iSG.IPv4.payload-addresses`"
    iSGvoiceLAN=${iSGvoiceLAN##* }
    iSGvoiceLAN=${iSGvoiceLAN%:*}
    [ "x$iSGvoiceLAN" = "x" ] && return 0
    [ "x$iSGvoiceLAN" = "x$entGWvoiceLAN" ] || return 0
    #networks are the same => check the routes
    local srvintlanipaddr=$(/opt/webservice/scripts/gethaipsetupentry.sh internal-lan.listen-ip-address)
    isgintlanip=${srvintlanipaddr%1}99
    isgintlannet=${srvintlanipaddr%1}0
    cat /var/opt/ha/conf/iSG.IPv4.payload-addresses | while read aline ; do
        iSGBoardvoiceIP="x$aline"
        iSGBoardvoiceIP=${iSGBoardvoiceIP%%/*}
        iSGBoardvoiceIP=${iSGBoardvoiceIP##* }
        for atable in pb21 TABLE_SOCO2_IPDA main ; do
            ip route show table $atable | grep -q "^$iSGBoardvoiceIP via $isgintlanip dev br-intl" || {
                log "Adding rule for 22440 : table $atable : $iSGBoardvoiceIP via $isgintlanip dev br-intl"
                ip route add $iSGBoardvoiceIP/32 via $isgintlanip dev br-intl table $atable
                log "osf22440 : ip route add $iSGBoardvoiceIP/32 via $isgintlanip dev br-intl table $atable - rc $?"
            }
        done
        #also add internal LAN route to pb21
        ip route show table pb21 | grep -q "^$isgintlannet/24 dev br-intl" || {
            log "Adding rule for 22440 : table pb21 : $isgintlannet/24 dev br-intl"
            ip route add $isgintlannet/24 dev br-intl table pb21
            log "osf22440 : ip route add $isgintlannet/24 dev br-intl table pb21 - rc $?"
        }
    done

}

function host_enable_traffic_between_SBC_and_isg_on_same_lan_osfourk24708() {
    [ -e /var/opt/ha/conf/ ] || return 0
    #do not do anything unless customer and IPDA are the same and SBC is enabled
    grep system.sbc-enabled /var/opt/ha/conf/haipsetup.xml | grep -q 1 || return 0
    custnet=$(/opt/webservice/scripts/gethaipsetupentry.sh customer-lan.ethernet-interface-node1)
    ipdanet=$(/opt/webservice/scripts/gethaipsetupentry.sh ipda-lan.ethernet-interface-node1)
    [ "x$custnet" = "x$ipdanet" ] || return 0
    sbcIPAddr=$(/opt/webservice/scripts/gethaipsetupentry.sh customer-lan.sbc-ip-address)
    #now look at the iSG
    [ -e /var/opt/ha/conf/iSG.IPv4.payload-addresses ] || return 0
    #move iSG IP list to SBC share so that also SBC has access to it - for now this is not needed but it does not harm to be prepared for the future ;)
    cp /var/opt/ha/conf/iSG.IPv4.payload-addresses /var/opt/SBC/data/iSG.IPv4.payload-addresses
    iSGvoiceLAN="x `grep :pb21 /var/opt/SBC/data/iSG.IPv4.payload-addresses`"
    iSGvoiceLAN=${iSGvoiceLAN##* }
    iSGvoiceLAN=${iSGvoiceLAN%:*}
    [ "x$iSGvoiceLAN" = "x" ] && return 0
    [ "x$iSGvoiceLAN" = "x$custnet" ] || return 0
    #networks are the same => check the routes
    local srvintlanipaddr=$(/opt/webservice/scripts/gethaipsetupentry.sh internal-lan.listen-ip-address)
    isgintlanip=${srvintlanipaddr%1}99
    isgintlannet=${srvintlanipaddr%1}0
    #for now the SBC will by default go to br-cust for the complete IPDA network so the PLT will forward on br-intl the traffic to any IP address belonging to the iSG container
    cat /var/opt/SBC/data/iSG.IPv4.payload-addresses | while read aline ; do
        iSGBoardvoiceIP="x$aline"
        iSGBoardvoiceIP=${iSGBoardvoiceIP%%/*}
        iSGBoardvoiceIP=${iSGBoardvoiceIP##* }
        for atable in pb21 TABLE_SOCO2_IPDA main ; do
            ip route show table $atable | grep -q "^$iSGBoardvoiceIP via $isgintlanip dev br-intl" || {
                log "Adding rule for 22440 : table $atable : $iSGBoardvoiceIP via $isgintlanip dev br-intl"
                ip route add $iSGBoardvoiceIP/32 via $isgintlanip dev br-intl table $atable
                log "osf22440 : ip route add $iSGBoardvoiceIP/32 via $isgintlanip dev br-intl table $atable - rc $?"
            }
        done
        #also add internal LAN route to pb21
        ip route show table pb21 | grep -q "^$isgintlannet/24 dev br-intl" || {
            log "Adding rule for 22440 : table pb21 : $isgintlannet/24 dev br-intl"
            ip route add $isgintlannet/24 dev br-intl table pb21
            log "osf22440 : ip route add $isgintlannet/24 dev br-intl table pb21 - rc $?"
        }
    done
}

function enable_traffic_between_entgw_and_isg_on_same_lan_osfourk22440() {
    [ -e /var/opt/ha/conf/ ] || return 0
    #refresh list of IPs
    ip addr show | grep :pb > /var/opt/ha/conf/iSG.IPv4.payload-addresses.tmp
    mv /var/opt/ha/conf/iSG.IPv4.payload-addresses.tmp /var/opt/ha/conf/iSG.IPv4.payload-addresses
    #determine the Voice LAN
    iSGvoiceLAN="x `grep :pb21 /var/opt/ha/conf/iSG.IPv4.payload-addresses`"
    iSGvoiceLAN=${iSGvoiceLAN##* }
    iSGvoiceLAN=${iSGvoiceLAN%:*}
    [ "x$iSGvoiceLAN" = "x" ] && return 0
    #now look at the host
    [ -e /var/opt/ha/conf/entgw.IPv4.payload-address ] || return 0
    entGWvoiceLAN="x `grep :pb21 /var/opt/ha/conf/entgw.IPv4.payload-address`"
    entGWvoiceLAN=${entGWvoiceLAN##* }
    entGWvoiceLAN=${entGWvoiceLAN%:*}
    [ "x$entGWvoiceLAN" = "x" ] && return 0
    [ "x$iSGvoiceLAN" = "x$entGWvoiceLAN" ] || return 0
    entGWvoiceIP="x`grep :pb21 /var/opt/ha/conf/entgw.IPv4.payload-address | awk '{print $2}'`"
    entGWvoiceIP=${entGWvoiceIP#x}
    entGWvoiceIP=${entGWvoiceIP%%/*}
    #networks are the same => check the routes
    local srvintlanipaddr=$(/opt/webservice/scripts/gethaipsetupentry.sh internal-lan.listen-ip-address)
    isgintlannet=${srvintlanipaddr%1}0
    ( cat /var/opt/ha/conf/iSG.IPv4.payload-addresses ; echo ":main" ) | while read aline ; do
        pbcaddr=${aline##*:}
        ip route show table $pbcaddr | grep -q "^$entGWvoiceIP via $srvintlanipaddr dev intlan" || {
            log "Adding rule for 22440 : table $pbcaddr : $entGWvoiceIP via $srvintlanipaddr dev intlan"
            ip route add $entGWvoiceIP/32 via $srvintlanipaddr dev intlan table $pbcaddr
            log "osf22440 : ip route add $entGWvoiceIP/32 via $srvintlanipaddr dev intlan table $pbcaddr - rc $?"
        }
        ip route show table $pbcaddr | grep -q "^$srvintlanipaddr dev intlan" || {
            log "Adding rule for 22440 : table $pbcaddr : $srvintlanipaddr dev intlan"
            ip route add $srvintlanipaddr dev intlan table $pbcaddr
            log "osf22440 : ip route add $srvintlanipaddr dev intlan table $pbcaddr - rc $?"
        }
        #also add internal LAN route to $pbcaddr
        ip route show table $pbcaddr | grep -q "^$isgintlannet/24 dev intlan" || {
            log "Adding rule for 22440 : table $pbcaddr : $isgintlannet/24 dev intlan"
            ip route add $isgintlannet/24 dev intlan table $pbcaddr
            log "osf22440 : ip route add $isgintlannet/24 dev intlan table $pbcaddr - rc $?"
        }
    done
}

function enable_traffic_between_sbc_and_isg_on_same_lan_osfourk24708() {
    [ -e /var/opt/ha/conf/ ] || return 0
    #do not do anything unless customer and IPDA are the same and SBC is enabled
    grep system.sbc-enabled /var/opt/ha/conf/haipsetup.xml | grep -q 1 || return 0
    custnet=$(/opt/webservice/scripts/gethaipsetupentry.sh customer-lan.ethernet-interface-node1)
    ipdanet=$(/opt/webservice/scripts/gethaipsetupentry.sh ipda-lan.ethernet-interface-node1)
    [ "x$custnet" = "x$ipdanet" ] || return 0
    sbcIPAddr=$(/opt/webservice/scripts/gethaipsetupentry.sh customer-lan.sbc-ip-address)
    #refresh list of IPs
    ip addr show | grep :pb > /var/opt/ha/conf/iSG.IPv4.payload-addresses.tmp
    mv /var/opt/ha/conf/iSG.IPv4.payload-addresses.tmp /var/opt/ha/conf/iSG.IPv4.payload-addresses
    #determine the Voice LAN
    iSGvoiceLAN="x `grep :pb21 /var/opt/ha/conf/iSG.IPv4.payload-addresses`"
    iSGvoiceLAN=${iSGvoiceLAN##* }
    iSGvoiceLAN=${iSGvoiceLAN%:*}
    [ "x$iSGvoiceLAN" = "x" ] && return 0
    [ "x$iSGvoiceLAN" = "x$custnet" ] || return 0
    #networks are the same => check the routes
    local srvintlanipaddr=$(/opt/webservice/scripts/gethaipsetupentry.sh internal-lan.listen-ip-address)
    isgintlannet=${srvintlanipaddr%1}0
    
    ( cat /var/opt/ha/conf/iSG.IPv4.payload-addresses ; echo ":main" ) | while read aline ; do
        pbcaddr=${aline##*:}
        ip route show table $pbcaddr | grep -q "^$sbcIPAddr via $srvintlanipaddr dev intlan" || {
            log "Adding rule for 22440 : table $pbcaddr : $sbcIPAddr via $srvintlanipaddr dev intlan"
            ip route add $sbcIPAddr/32 via $srvintlanipaddr dev intlan table $pbcaddr
            log "osf22440 : ip route add $sbcIPAddr/32 via $srvintlanipaddr dev intlan table $pbcaddr - rc $?"
        }
        ip route show table $pbcaddr | grep -q "^$srvintlanipaddr dev intlan" || {
            log "Adding rule for 22440 : table $pbcaddr : $srvintlanipaddr dev intlan"
            ip route add $srvintlanipaddr dev intlan table $pbcaddr
            log "osf22440 : ip route add $srvintlanipaddr dev intlan table $pbcaddr - rc $?"
        }
        #also add internal LAN route to $pbcaddr
        ip route show table $pbcaddr | grep -q "^$isgintlannet/24 dev intlan" || {
            log "Adding rule for 22440 : table $pbcaddr : $isgintlannet/24 dev intlan"
            ip route add $isgintlannet/24 dev intlan table $pbcaddr
            log "osf22440 : ip route add $isgintlannet/24 dev intlan table $pbcaddr - rc $?"
        }
    done
}

#################################################
# MAIN begins here
#################################################

#sanity check not to allow script to run on not-EntGW deployments
[ -e /tmp/.sg2d.dev.bash.dbg.on -o -e /tmp/.sg2d.dev.bash.disableentgwlimitation.on ] || {
( [ "`/opt/webservice/scripts/gethaipsetupentry.sh system.multiNodeSystem`" = "70" ] || [ "`/opt/webservice/scripts/gethaipsetupentry.sh system.multiNodeSystem`" = "71" ] ) || {
    #enable script also for duplex
    [ -e /dev/.sg2d-on-duplex ] || {
        1>/dev/null 2>/dev/null /opt/webservice/scripts/is_duplex
        [ $? -eq 1 ] && touch /dev/.sg2d-on-duplex
    }
    [ -e /dev/.sg2d-on-duplex ] || {
	echo "$0 ERROR : this script runs only on EntGW deployments or duplex."
	exit 1
    }
}
}

#on sles15 make it always like on duplex
if ( uname -r | grep -q ^3 ) || ( uname -r | grep -q ^4 ) ; then
    #sles11 - keep everything the same
    true
else
    #sles15 or above => use ipvlan
    touch /dev/.sg2d-on-duplex
fi

MY_PIDFILE=/var/run/sg2.pid

#ensure existence of sg2 dir on PLT in all cases
[ -e /var/opt/soco/is_container_sg ] || mkdir -p /opt/sg2

rc_reset
case "$1" in
	chroot)
		shift
		touch /tmp/.sg2dplt.chroot.lock
		/usr/bin/flock -w 60 -x /tmp/.sg2dplt.chroot.lock /bin/bash $0 _chroot_locked_ $*
		exit $?
		;;
	_chroot_locked_)
		[ -e /var/opt/soco/is_container_sg ] && {
			log "ERROR : $0 $* call can NOT be made inside $SG2_LXC_NAME container"
			exit 1
		}
		shift
		trap "umount /sg2/var" EXIT
		mount --bind /var/sg2 /sg2/var
		chroot /sg2 $*
		exit $?
		;;
	exec_on_plt)
		shift
		touch /tmp/.sg2dplt.exec_on_plt.lock
		/usr/bin/flock -w 20 -x /tmp/.sg2dplt.exec_on_plt.lock /bin/bash /etc/init.d/sg2dplt _exec_on_plt_locked_ $*
		exit $?
		;;
	_exec_on_plt_locked_)
		[ -e /var/opt/soco/is_container_sg ] || {
			log "ERROR : $0 $* call can be made only inside $SG2_LXC_NAME container"
			exit 1
		}
		shift
		cmdrc=127
		ts=`date +%s`
		echo $* > /tmp/.sg2d.client-rq.dir/sg2-exec-cmd-request.$ts
        unblock_server_daemon_for_one_step
		#timeout after 1 minute
		for i in {0..59}; do
			sleep 1
			[ -e /tmp/.sg2d.client-rq.dir/shutdown-in-progress ] && exit 126
			[ -e /tmp/.sg2d.client-rq.dir/sg2-exec-cmdresponse.serverrc.$ts ] && {
				cat /tmp/.sg2d.client-rq.dir/sg2-exec-cmdresponse.serverstdout.$ts
				cat /tmp/.sg2d.client-rq.dir/sg2-exec-cmdresponse.serverstderr.$ts 1>&2
				cmdrc=$(cat /tmp/.sg2d.client-rq.dir/sg2-exec-cmdresponse.serverrc.$ts)
				rm -f /tmp/.sg2d.client-rq.dir/sg2-exec-cmdresponse.serverrc.$ts /tmp/.sg2d.client-rq.dir/sg2-exec-cmdresponse.serverstdout.$ts /tmp/.sg2d.client-rq.dir/sg2-exec-cmdresponse.serverstderr.$ts
                # ? unblock_server_daemon_for_one_step
				exit $cmdrc
			}
		done
		log "WARNING exec_on_plt timed out without an response within 1 minute since request was made. Command was $*"
		exit $cmdrc
		;;
	client_daemon_ssh_port_fwd)
		[ -e /var/opt/soco/is_container_sg ] || {
			log "ERROR : $0 $* call can be made only inside $SG2_LXC_NAME container"
			exit 1
		}
		i=0
		while [ 1 ]; do
			sleep 5
			[ -e /tmp/.sg2d.client-rq.dir/shutdown-in-progress ] && break
		done
		exit 0
		;;
    isg-wait-for-network)
		[ -e /var/opt/soco/is_container_sg ] || {
			log "ERROR : $0 $* call can be made only inside $SG2_LXC_NAME container"
			exit 1
		}
        log "Will wait max 1 minute for the confirmation that the network interfaces have been made available ..."
        for i in {0..60}; do
            [ -e /run/socod-start-can-continue ] && break
            sleep 1
        done
        exit 0
        ;;
	client_daemon)
		[ -e /var/opt/soco/is_container_sg ] || {
			log "ERROR : $0 $* call can be made only inside $SG2_LXC_NAME container"
			exit 1
		}
		mkdir -p /var/opt/soco/log
		exec 1>>/var/opt/soco/log/$SG2_LXC_NAME-client-daemon.log
		exec 2>&1
        cat > /root/ifcfg-zero << '_EOF_IFCFG_ZERO'
BOOTPROTO='static'
ONBOOT='yes'
STARTMODE='auto'
USERCONTROL='no'
NAME='Gigabit Network Connection'
MTU=''
ETHTOOL_OPTIONS=''
IPADDR='0.0.0.0/0'
_EOF_IFCFG_ZERO
		srvintlanipaddr=$(/opt/webservice/scripts/gethaipsetupentry.sh internal-lan.listen-ip-address)
		assistantipaddr=$(/opt/webservice/scripts/gethaipsetupentry.sh customer-lan.assistant-ip-address)
		log "Server Internal LAN addr is : $srvintlanipaddr"
		assintlanip=${srvintlanipaddr%.*}.100
        
        for afile in $(find /opt/soco/config/templates/apache -name \*xml); do
            sed -i -e 's/localhost/127.0.0.1/g' $afile
        done

        #here we bring up the IFs when we get indication file from PLT via /opt/.iSG.ipvlan.info
        [ -e /opt/.sg2d-on-duplex ] && (
            exec 1>>/var/log/iSoftGate-duplex-route-monitor-isg.log
            exec 2>&1
            #set -x
            rm -f /opt/.iSG.ipvlan.info
            #create indication file that we started
            touch /opt/.iSG.ipvlan.iSG-client-is-ready
            #wait max 1 minute for info file
            i=0
            while [ 1 ]; do
                [ -e /tmp/.sg2d.client-rq.dir/shutdown-in-progress ] && break
                sleep 1
                i=$(($i + 1))
                [ $i -gt 60 ] && {
                    log "ERROR : timeout waiting for indication file /opt/.iSG.ipvlan.info"
                    #best effort = wait again
                    i=0
                }
                [ -e /opt/.iSG.ipvlan.info ] && {
                    #create ifconfig files and bring all ifs up via ifconfig <dev> 0.0.0.0/0 up
                    #the LANs should be already visible under /sys/class/net/... so take them from there
                    for aneth in $(ls -1d /sys/class/net/eth* /sys/class/net/vlan* /sys/class/net/bond* 2>/dev/null | sort -f); do
                        aneth=${aneth##*/}
                        log "Bring up $aneth LAN interface ..."
                        cp /root/ifcfg-zero /etc/sysconfig/network/ifcfg-$aneth
                        ifconfig $aneth 0.0.0.0/0 up
                    done
                    #create indication file for SG start to continue
                    touch /run/socod-start-can-continue
                    break
                }
            done
            #periodic monitoring of routing table both main and pb21 for local swu cc
            ccipaddr=$(cat /opt/.iSG.ipvlan.info)
            while [ 1 ] ; do
                [ -e /tmp/.sg2d.client-rq.dir/shutdown-in-progress ] && break
                sleep 10
                enable_traffic_between_entgw_and_isg_on_same_lan_osfourk22440
                enable_traffic_between_sbc_and_isg_on_same_lan_osfourk24708
                for atable in main pb21; do
                    rm -f /run/.isg.cc-route.exists
                    (
                        ip route show table $atable | while read aline; do
                            set -- $aline
                            [ "x$1" = "x$ccipaddr" ] || continue
                            #check if already set
                            [[ "x$aline" =~ intlan ]] && touch /run/.isg.cc-route.exists && break
                            log "The following route entry in table $atable will be adapted : $aline"
                            ip route del $aline table $atable
                            log "Route deletion rc : $?"
                            ip route add $ccipaddr via $srvintlanipaddr dev intlan table $atable
                            log "ip route add $ccipaddr via $srvintlanipaddr dev intlan table $atable rc : $?"
                        done
                        [ "x$atable" = "xmain" ] || continue
                        #do the rest of code only for main table
                        #TODO - add route to Portal IP like this: (necessary for openvpn to be able to connect)
                        #  ip route add 10.140.22.99 via 192.168.187.1
                        #but only if running on Primary ; otherwise delete the route if in the meanwhile the situation has changed
                    )
                    [ -e /run/.isg.cc-route.exists ] || {
                        log "SWU CC route to $ccipaddr not found. Will set it now ..."
                        ip route add $ccipaddr via $srvintlanipaddr dev intlan table $atable
                        log "ip route add $ccipaddr via $srvintlanipaddr dev intlan table $atable rc : $?"
                    }
                done
				#if Assistant runs on the same node and we are in the same subnet (regardless of IPDA/CLAN relation) we must define route through ILAN
                atable=main
				#calculate CLAN subnet borders
				AssVal=$(ipval $assistantipaddr)
				CLANmask=$(ipval $(/opt/webservice/scripts/gethaipsetupentry.sh customer-lan.netmask))
				StartVal=$(( $AssVal & $CLANmask ))
				EndVal=$(( $StartVal + ($CLANmask ^ 0xffffffff) ))
				ipAddrEth=`geticfgxmlparam ipAddrEth /var/opt/soco/config/initialcfg.xml`
                #OSFOURK-24281 PRB000066134: FT-V10 R1.42.0 Assistant can't connect to iSG on same Node as Assistant running
                mgmtipaddr=$(/opt/soco/native/os/linux/get_mgmt_address.sh)
                [ "x$mgmtipaddr" = "x$ipAddrEth" ] || {
                    #use mgmtipaddr if it is really set
                    if ip route show table local | grep "^local" | grep -E -o "([0-9]{1,3}[\.]){3}[0-9]{1,3}" | grep -e "^$mgmtipaddr$" ; then
                        log "Management IP [$mgmtipaddr] is configured and will be used for routes to Assistant"
                        ipAddrEth=$mgmtipaddr
                    else
                        log "Management IP [$mgmtipaddr] is configured but IP not present on any of the interfaces"
                    fi
                }
				val=$(ipval $ipAddrEth)
                rm -f /run/.isg.duplex-assistant-route.exists
				#is Assistant here and is within the same CLAN subnet?
				log "is SG IP: $ipAddrEth ($val) in <$StartVal,$EndVal> ?"
                if [ -e /opt/.iSG-assist-here ] && (( val >= StartVal )) && (( val <= EndVal )); then
					log "Assistant is here and is in the same subnet, verify/add its route ..."
					ip route show table $atable | while read aline; do
						[[ "$aline" =~ ^$assistantipaddr.*intlan ]] && {
							touch /run/.isg.duplex-assistant-route.exists
							log "The route $aline is present, nothing to do."
							break
						}
					done
					[ -e /run/.isg.duplex-assistant-route.exists ] || {
						ip rule del to $assistantipaddr 2>&-
						ip rule add to $assistantipaddr pref 19000 lookup $atable
						ip route del $assistantipaddr 2>&-
						ip route add $assistantipaddr via $assintlanip dev intlan table $atable
						log "ip route add $assistantipaddr via $assintlanip dev intlan table $atable rc=$?"
                    }
					#search all local vHG IP addresses in the same subnet
					ip route show table local | grep "^local" | grep -E -o "([0-9]{1,3}[\.]){3}[0-9]{1,3}" | sort | uniq | while read myip; do
						#calculate decimal value of the IP address
						val=$(ipval $myip)
						#and check if within CLAN subnet
						if (( val >= StartVal )) && (( val <= EndVal )); then
							echo -n "$myip:"
						fi
					done > /tmp/iSG-duplex-local.ip
					#provide addresses and also request refresh of Assistant status, for the case of Duplex node switchover
					mv /tmp/iSG-duplex-local.ip /tmp/.sg2d.client-rq.dir/assist-here
				else
					log "Assistant is not here or is not in the same subnet, delete its route if present ..."
					ip rule del to $assistantipaddr 2>&-
					ip route del $assistantipaddr 2>&-
					#request refresh of Assistant status, for the case of Duplex node switchover
					touch /tmp/.sg2d.client-rq.dir/assist-here
				fi
				#OSFOURK-22110
				VPN_SERVER_IP=`grep "^remote" /etc/openvpn/*.conf | grep -o -E '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'`
				log "VPN_SERVER_IP=$VPN_SERVER_IP"	
				host_intl=$(/opt/webservice/scripts/gethaipsetupentry.sh internal-lan.listen-ip-address)
				log "host_intl=$host_intl"
                if [ -e /opt/.iSG-vpn-here ]; then
					log "VPN server is here, add route to VPN server IP through ILAN"
					ip route add $VPN_SERVER_IP via $host_intl && log "Route for $VPN_SERVER_IP through ILAN added."
				else
					log "VPN server is not here, remove route for VPN server IP through ILAN."
					ip route del $VPN_SERVER_IP via $host_intl && log "Route for $VPN_SERVER_IP through ILAN deleted."
				fi
				#request refresh of VPN server status, for the case of Duplex node switchover
				touch /tmp/.sg2d.client-rq.dir/vpn-here
            done
        ) &
		#make sure inventory and vpn daemon run within 1 minute from boot
		( sleep 65 ; service inventoryd stop ; service inventoryd start ; service soco_vpn_deploy_daemon stop; service soco_vpn_deploy_daemon start ) &
		#ensure internal LAN connectivity
		(
			sleep 10
			failedpings=0
			while [ 1 ]; do
                [ -e /tmp/.sg2d.client-rq.dir/shutdown-in-progress ] && break
                #replace set_virt_ip script of SG if needed
                grep -q isg_get_vlanif /opt/soco/native/os/linux/set_virt_ip.sh || cp /opt/.isg.set_virt_ip.with.dyn.support /opt/soco/native/os/linux/set_virt_ip.sh
				[ $failedpings -eq 0 ] && {
					log "Acquiring IP address for intlan over DHCP ..."
					1>/dev/null 2>/dev/null ls /sys/class/net/intlan && {
						cp /root/ifcfg-zero /etc/sysconfig/network/ifcfg-intlan
						#make directly DHCP - wicked services are disabled as they kill unknown IP addresses of vHGs
                        # dhcpcd intlan
                        # set static address to internal-lan-prefix.99 - this is backward compatible => no need to do it only for new SG@duplex
                        intlanprefix=${srvintlanipaddr%1}
                        sed -i -e "s/IPADDR.*/IPADDR=${intlanprefix}99\/24/" /etc/sysconfig/network/ifcfg-intlan
                        ifconfig intlan ${intlanprefix}99/24 up
                        echo 1 > /proc/sys/net/ipv4/conf/intlan/forwarding
					}
					sleep 5
				}
				if 1>/dev/null 2>/dev/null ping -c 1 -w 1 $srvintlanipaddr; then
					touch /tmp/.sg2d.ping_to_internal_lan_ok
					failedpings=1
				else
					failedpings=$(($failedpings + 1))
				fi
				[ $failedpings -eq 4 ] && failedpings=0
				sleep 10
			done
		) &
        
        #OSFOURK-25622 iSG container shall call Linux hardening
        [ -e /opt/_isg_do_linux_hardening_once_on_boot_ ] && {
            rm -f /opt/_isg_do_linux_hardening_once_on_boot_
            log "Calling linux hardening once during first boot ..."
            /opt/linux-hardening/Start_modify.sh -x -g
            log "Calling linux hardening finished with rc : $?"
        }
        
		(
			#start SSHD daemon locally only to use it as TCP-port forwarding tool - #TODO : PRIO 4 improve - use iptables
			chattr -i /etc/ssh/sshd_config
			sed -i -e /ListenAddress/d /etc/ssh/sshd_config
			sed -i -e /AllowTcpForwarding/d /etc/ssh/sshd_config
			sed -i -e /GatewayPorts/d /etc/ssh/sshd_config
			sed -i -e /^Port/d /etc/ssh/sshd_config
			echo " " >> /etc/ssh/sshd_config
			echo Port 2022 >> /etc/ssh/sshd_config
			echo ListenAddress 127.0.0.1 >> /etc/ssh/sshd_config
			echo AllowTcpForwarding yes >> /etc/ssh/sshd_config
			echo GatewayPorts yes >> /etc/ssh/sshd_config
			#make sure no hardening touches this file as we have enabled some unorthodox settings ;) but this is still safe as the SSH Daemon only listens on localhost and untypical port 2022
			chattr +i /etc/ssh/sshd_config
			service sshd restart
			sleep 1
			mkdir /root/.ssh
			chmod 700 /root/.ssh
			#generate new keys for root
			ssh-keygen -t rsa -f /root/.ssh/id_rsa -P ''
			cp /root/.ssh/id_rsa.pub /root/.ssh/authorized_keys
			chmod 600 /root/.ssh/authorized_keys
			>/root/.ssh/known_hosts
			chmod 644 /root/.ssh/known_hosts
			#this is needed so that iSoftGate can connect to CLA running outside
			#OSFOURK-12005 - NA16228531 - no SSH Access to iSG of the EntGW over Assistant / Gateway Dashboard
			# - here make a tcp port forward for port 22 on any address to the EntGW SSH Daemon using internal LAN
			ssh -p 2022 -o LogLevel=Error -o StrictHostKeyChecking=no -f -L 61740:$srvintlanipaddr:61740 -L 0.0.0.0:22:$srvintlanipaddr:22 root@localhost bash /etc/init.d/sg2dplt client_daemon_ssh_port_fwd
			log "CLA port TCP tunnel on internal LAN is started."
		) &
		(
			#setup default gateway so that inventory can reach the system; but wait one minute for SG to be for sure started already
			sleep 40
			while [ 1 ]; do
				[ -e /tmp/.sg2d.client-rq.dir/shutdown-in-progress ] && break
				sleep 20
				[ -e /tmp/.sg2d.client-rq.dir/shutdown-in-progress ] && break
				should_defgwrt=`geticfgxmlparam defaultGateway /var/opt/soco/config/initialcfg.xml`
				current_defgw=`ip route show | grep ^default | awk '{print $3}'`
				[ "x$should_defgwrt" = "x$current_defgw" ] || {
					log "Setting default route using \"defaultGateway\" parameter from SG initialcfg.xml : $should_defgwrt"
					ip route del default
					ip route add default via $should_defgwrt
				}
			done
		) &
        
        #OSFOURK-24176 - EntGW / XEGW V10R1 - After NUC to R1.42 the iSoftgate is not starting
        (
            secs_since_socod_not_running=0
            secs_since_socod_running=0
            while [ 1 ]; do
                [ -e /tmp/.sg2d.client-rq.dir/shutdown-in-progress ] && break
                sleep 20
                if systemctl status --no-pager socod ; then
                    #socod running => check if running stable for at least 5 minutes before quitting
                    [ $secs_since_socod_not_running -eq 0 ] || log "OSFOURK-24176 : socod was NOT running 20 seconds ago but now it is started"
                    secs_since_socod_not_running=0
                    secs_since_socod_running=$(($secs_since_socod_running + 20))
                    if [ $secs_since_socod_running -gt 300 ] ; then
                        log "OSFOURK-24176 : socod is running since more than 5 minutes -> do nothing"
                        break
                    fi
                else
                    #socod not running => check the rpm file
                    [ $secs_since_socod_running -eq 0 ] || log "OSFOURK-24176 : socod was running 20 seconds ago but now it is stopped"
                    secs_since_socod_running=0
                    secs_since_socod_not_running=$(($secs_since_socod_not_running + 20))
                fi
                if [ -e /var/opt/soco2/sg_repo_forced/softgate.rpm ] ; then
                    if [ $secs_since_socod_not_running -gt 300 ] ; then
                        #since more than 5 minutes socod is not running and the RPM file exists => delete the RPM and restart the container
                        log "OSFOURK-24176 : will remove the /var/opt/soco2/sg_repo_forced/softgate.rpm and restart the container"
                        rm -f /var/opt/soco2/sg_repo_forced/softgate.rpm
                        #this touch will cause all sub-daemons to exit
                        touch /tmp/.sg2d.client-rq.dir/shutdown-in-progress
                        #stopping the client daemon will cause the outside daemon to stop and restart the container
                        service sg2dplt stop
                        break
                    fi
                else
                    #rpm does not exist => do nothing
                    log "OSFOURK-24176 : /var/opt/soco2/sg_repo_forced/softgate.rpm does not exist -> do nothing"
                    break
                fi
            done
        ) &
        
		cd /tmp/.sg2d.server-rq.dir
		while [ 1 ]; do
			sleep 2
			arq=`ls -1 rq* 2>/dev/null | head -n 1`
			[ "x$arq" = "x" ] && {
				sleep 0.1
				continue
			}
			[ -e $arq ] || {
				sleep 0.1
				continue
			}
			rm -f $arq
			#shutdown
			[[ $arq =~ SHUTDOWN ]] && {
				log "SG2D Client daemon got request to gracefully shut down"
				#notify also server to know we are in shutdown
				touch /tmp/.sg2d.client-rq.dir/shutdown-in-progress
                unblock_server_daemon_for_one_step
				service inventoryd stop
				service soco_vpn_deploy_daemon stop
				service inventoryd stop
				service soco_vpn_deploy_daemon stop
				/sbin/init 0
			}
		done
		exit 0
		;;
	launch_client)
		[ -e /var/opt/soco/is_container_sg ] || {
			log "ERROR : $0 $* call can be made only inside $SG2_LXC_NAME container"
			exit 1
		}
		rm -f /.sg2-service-state
		echo running > /.sg2-service-state
		/usr/bin/setsid /bin/bash /etc/init.d/sg2dplt client_daemon &
		exit 0
		;;
	wait_start)
		[ -e /var/opt/soco/is_container_sg ] && {
			log "ERROR : $0 $* call can NOT be made inside $SG2_LXC_NAME container"
			exit 1
		}
		rm -f /sg2/.sg2-service-state
		echo starting > /sg2/.sg2-service-state
		for i in {0..24}; do
			sleep 5
			[ -e /sg2/tmp/sg2lxc.booted.after.local ] && {
                [ -e /dev/.sg2d-on-duplex ] && setup_ipvlan_interfaces
				logger $0 "$SG2_LXC_NAME started"
                #also indicate to sg2d service it is started even if start call was made from within the sg2d service unit itself
                service sg2d start &
				exit 0
			}
			checkproc -p $MY_PIDFILE /bin/bash || break
			echo -en "."
		done
		if lxc-ls -f | grep $SG2_LXC_NAME | grep -i run; then
			log "$SG2_LXC_NAME start is slow. Continuing to wait ..."
		else
			log "$SG2_LXC_NAME did not start. Will retry one more time ..."
			rm $MY_PIDFILE
			sleep 12
			rm -f /sg2/tmp/sg2lxc.booted.after.local
			0</dev/null 1>/dev/null 2>&1 startproc -f -p $MY_PIDFILE /bin/bash /bin/sg2d _daemon_
		fi
		for i in {0..24}; do
			sleep 10
			[ -e /sg2/tmp/sg2lxc.booted.after.local ] && {
                [ -e /dev/.sg2d-on-duplex ] && setup_ipvlan_interfaces
				logger $0 "$SG2_LXC_NAME started after 2nd attempt"
                #also indicate to sg2d service it is started even if start call was made from within the sg2d service unit itself
                service sg2d start &
				exit 0
			}
			echo -en "."
		done
		log "ERROR : $SG2_LXC_NAME start timeout. $SG2_LXC_NAME did not start."
		lxc-ls -f | grep $SG2_LXC_NAME
		exit 1
		;;
	wait_stop)
		[ -e /var/opt/soco/is_container_sg ] && {
			log "ERROR : $0 $* call can NOT be made inside $SG2_LXC_NAME container"
			exit 1
		}
		rm -f /sg2/.sg2-service-state
		echo stopping > /sg2/.sg2-service-state
		bGracefulSthudown=true
		for i in {0..24}; do
			sleep 5
			$bGracefulSthudown && [ $i -gt 2 ] && {
				[ -e /sg2/tmp/.sg2d.client-rq.dir/shutdown-in-progress ] || {
					bGracefulSthudown=false
					#after 15 seconds send kill signal to begin lxc-stop since client did not confirm the shutdown
					log "$SG2_LXC_NAME client did respond to nice shutdown. Initialiting brutal container shutdown."
					killproc -p $MY_PIDFILE /bin/bash
				}
			}
			$bGracefulSthudown && [ $i -gt 18 ] && {
				bGracefulSthudown=false
				#after 90 seconds send kill signal to begin lxc-stop
				log "$SG2_LXC_NAME did not stop nicely after 90 seconds. Initialiting brutal container shutdown."
				killproc -p $MY_PIDFILE /bin/bash
			}
			lxc-ls -f | grep $SG2_LXC_NAME | grep -q -i run || {
				logger $0 "$SG2_LXC_NAME stopped"
				rm -f /sg2/.sg2-service-state
				echo stopped > /sg2/.sg2-service-state
                #at this moment also indicate to the sg2d service it is stopped by simply calling stop -> this will properly update the status even if call was made from inside sg2d service unit
                service sg2d stop &
				exit 0
			}
			echo -en "."
		done
		log "ERROR : $SG2_LXC_NAME stop timeout."
		lxc-ls -f | grep $SG2_LXC_NAME
		rm -f /sg2/.sg2-service-state
		echo stop_error > /sg2/.sg2-service-state
		exit 1
		;;
	get_highest_sg2d_ver)
		[ -e /var/opt/soco/is_container_sg ] && {
			log "ERROR : $0 $* call can NOT be made inside $SG2_LXC_NAME container"
			exit 1
		}
		get_highest_sg2d_ver
		exit 0
		;;
    safe_stop)
        systemctl --no-pager status sg2d.service && service sg2d stop
        #if there is already a wait_stop process then do not call the stop again ... trust that it will work fine
        i=0
        while [ $i -lt 300 ] ; do
            ps -eo cmd | grep sg2d | grep -q wait_stop || break
			log "INFO : $0 $* another wait_stop process is in progress ..."
            sleep 5
            i=$(($i + 5))
        done
        if [ $i -lt 300 ] ; then
			log "INFO : $0 $* calling stop ..."
            sg2d stop
			log "INFO : $0 $* stop rc : $?"
        else
			log "ERROR : $0 $* call timed out"
        fi
    	exit 0
		;;
    reconfigure)
		[ -e /var/opt/soco/is_container_sg ] && {
			log "ERROR : $0 $* call can NOT be made inside $SG2_LXC_NAME container"
			exit 1
		}
		log "Called with $* ..."
        #on duplex we do this deferred
        1>/dev/null 2>/dev/null /opt/webservice/scripts/is_duplex
        if [ $? -eq 1 ] ; then
            #update timestamp files to prevent HA from calling start/stop in the meanwhile
            touch /opt/.iSG-last-deferred-start-ts
            touch /opt/.iSG-last-deferred-stop-ts
            if [ "x$3" = "x_deferred_" ] ; then
                #deferred call => continue
                true
            else
                #setup deferred call here and exit
                log "Duplex Node : will configure and start iSG in 2 minutes from now ..."
                service atd start
                echo "sg2d reconfigure $2 _deferred_" | at now +2 minutes
                exit 0
            fi
        fi
        #update timestamp files once more
        touch /opt/.iSG-last-deferred-start-ts
        touch /opt/.iSG-last-deferred-stop-ts
        sg2d status
        wasrunning=$?
        [ $wasrunning -eq 0 ] && sg2d safe_stop
        #update timestamp files also after stop
        touch /opt/.iSG-last-deferred-start-ts
        touch /opt/.iSG-last-deferred-stop-ts
        
        #check and redeploy in reconfigure in case not deployed
        isgdeplrc=$(2>/dev/null cat /var/log/webservice/sg2d.deployrootfs.rc)
        [ "x$isgdeplrc" = "x0" ] || {
            #something went wrong - will redeploy container
            log "Problem detected wiht container deploy rc $isgdeplrc - will redeploy ..."
            sg2d do_once_deployrootfs
            isgdeplrc=$(2>/dev/null cat /var/log/webservice/sg2d.deployrootfs.rc)
            log "Redeploy finished with rc $isgdeplrc"
        }
        
        sg2d configure $2
        1>/dev/null 2>/dev/null /opt/webservice/scripts/is_duplex
        if [ $? -eq 1 ] ; then
            #on duplex just start the iSG without enable because we are under HA control
            sg2d start
        else
            #on non-duplex we need to enable so that iSG runs also on boot
            sg2d enable
        fi
        exit 0
        ;;
    deferred_start)
        #to be used from inside HA - will initiate the start of iSG without blocking the caller
        #double call avoidance - do this unless there is a flag file more recent than 5 minutes ago
        while [ 1 ]; do
            [ -e /opt/.iSG-last-deferred-start-ts ] || {
                touch /opt/.iSG-last-deferred-start-ts
                break
            }
            curdatets=$(date +%s)
            lastfilets=$(stat -c %Y /opt/.iSG-last-deferred-start-ts)
            [ $(($lastfilets + 300)) -lt $curdatets ] && break
            #detected that last start was more recent than than 5 minuted ago => do nothing
            exit 0
        done
        #update timestamp file and schedule iSG start
        touch /opt/.iSG-last-deferred-start-ts
        log "Will launch iSG in 2 minutes from now ..."
        service atd start
        echo "sg2d start" | at now +2 minutes
        exit 0
        ;;
    deferred_stop)
        #to be used from inside HA - will initiate the stop of iSG without blocking the caller
        #double call avoidance - do this unless there is a flag file more recent than 5 minutes ago
        while [ 1 ]; do
            [ -e /opt/.iSG-last-deferred-stop-ts ] || {
                touch /opt/.iSG-last-deferred-stop-ts
                break
            }
            curdatets=$(date +%s)
            lastfilets=$(stat -c %Y /opt/.iSG-last-deferred-stop-ts)
            [ $(($lastfilets + 300)) -lt $curdatets ] && break
            #detected that last stop was more recent than than 5 minuted ago => do nothing
            exit 0
        done
        #update timestamp file and schedule iSG stop
        touch /opt/.iSG-last-deferred-stop-ts
        log "Will stop iSG in 2 minutes from now ..."
        service atd start
        echo "sg2d safe_stop" | at now +2 minutes
        exit 0
        ;;
    sg2dhome)
        log_rotate
        rm -f /dev/shm/.isg.sg2dhome.fifo
        touch /dev/shm/.isg.sg2dhome.timer.lock
        mkfifo /dev/shm/.isg.sg2dhome.fifo
        #some simple 5min-periodic timer mechanism to wake up the main task for proper status update of sg2d service
        ( /usr/bin/flock -w 0 -x /dev/shm/.isg.sg2dhome.timer.lock sleep 300 || exit 0 ; echo "timer" > /dev/shm/.isg.sg2dhome.fifo ) &
        while [ 1 ] ; do
            read aline < /dev/shm/.isg.sg2dhome.fifo
            #reset timer ; if another request came in = not a timer then it does not matter as the flock will ensure the timer will happen only once
            ( /usr/bin/flock -w 0 -x /dev/shm/.isg.sg2dhome.timer.lock sleep 300 || exit 0 ; echo "timer" > /dev/shm/.isg.sg2dhome.fifo ) &
            [[ "x$aline" =~ start ]] && {
                #start it only when the bridge internal is there - try after 30 seconds ...
                ls /sys/class/net/br-intl || {
                    log "INFO : $0 $* internal bridge not present yet ... will re-schedule the start after 30 seconds ..."
                    sleep 1
                    ( sleep 33 ; echo "start" > /dev/shm/.isg.sg2dhome.fifo ) &
                }
                log "INFO : $0 $* calling start now directly via sg2d command ..."
                #indicate to sg2d that this is the correct context in which it can start ; all other calls to start should end-up as a request to sg2dhome
                export __SG2DHOME_SPECIAL_START__=1
                sg2d start
            }
            [[ "x$aline" =~ stop ]] && {
                log "INFO : $0 $* calling stop now directly via sg2d command ..."
                sg2d stop
            }
            [[ "x$aline" =~ timer ]] && {
                #reflect correct status for sg2d service in case something changed
                if sg2d status ; then
                    systemctl --no-pager status sg2d.service || {
                        log "INFO : $0 $* sg2d running but service sg2d dead => starting sg2d service in order to reflect correct status ..."
                        service sg2d start &
                        log "INFO : $0 $* sg2d service start rc : $?"
                    }
                else
                    systemctl --no-pager status sg2d.service && {
                        log "INFO : $0 $* sg2d NOT running but service sg2d alive => stopping sg2d service in order to reflect correct status ..."
                        service sg2d stop &
                        log "INFO : $0 $* sg2d service stop rc : $?"
                    }
                fi
                #start sg2d container on boot on first timer in case insserved
        # this part was commented out as starting with OSFOURK-24092 the sg2d on EntGW will be launched by HA like on Duplex
#                [ -e /dev/shm/.isg.sg2dhome.first_timer ] || {
#                    touch /dev/shm/.isg.sg2dhome.first_timer
#                    if ls -1 /etc/init.d/rc3.d/*sg2d ; then
#                        #do not start mistakenly insserved sg2d in case of Duplex
#                        /opt/webservice/scripts/is_duplex
#                        [ $? -eq 1 ] || {
#                          log "INFO : $0 $* will NOW start sg2d service because it is insserv-ed ..."
#                          service sg2d start &
#                        }
#                    else
#                        log "INFO : $0 $* will leave sg2d stopped because it is NOT insserv-ed ..."
#                    fi
#                }
            }
        done
        exit 0
        ;;
    sg2dservice)
        log_rotate
        #wait max 1 min for the fifo to appear
        for i in {0..59}; do
            [ -e /dev/shm/.isg.sg2dhome.fifo ] && break
            log "WARNING : $0 (pid $$) $* pipe file to send messages to sg2dhome service not found ... still waiting for it ..."
            sleep 1
        done
        [ -e /dev/shm/.isg.sg2dhome.fifo ] || {
            log "ERROR : $0 (pid $$) $* pipe file to send messages to sg2dhome service not found"
            exit 3
        }
        #send start
        log "INFO : $0 (pid $$) $* sending start command to sg2dhome service ..."
        echo start > /dev/shm/.isg.sg2dhome.fifo
        #now wait for service to be running
        while [ 1 ] ; do
            sg2d status && {
                log "INFO : $0 (pid $$) $* service sg2d is now running. Will not do anything anymore here but sleep ..."
                systemd-notify --ready --status="SG2D is now running ..."
                break
            }
            sleep 5
        done
        #now just wait and do nothing ...
        while [ 1 ] ; do
            sleep 123
        done
        exit 0
        ;;
    sg2dstopservice)
        log_rotate
        [ -e /dev/shm/.isg.sg2dhome.fifo ] || {
            log "ERROR : $0 (pid $$) $* pipe file to send messages to sg2dhome service not found"
            exit 3
        }
        #send stop
        log "INFO : $0 (pid $$) $* sending stop command to sg2dhome service ..."
        echo stop > /dev/shm/.isg.sg2dhome.fifo
        #now wait max 5 minutes for service to be really dead, meaning no _daemon_ process
        i=0
        while [ $i -lt 300 ] ; do
            ps -o cmd -p $(cat /var/run/sg2.pid) | grep -q _daemon_ || break
            sleep 5
            i=$(($i + 5))
        done
        exit 0
        ;;
    start)
        log_rotate
		if [ -e /var/opt/soco/is_container_sg ]; then
			bash /etc/init.d/sg2dplt launch_client &
			exit 0
		fi
        [ -e /dev/.sg2d-on-duplex ] && echo -en "\n\n!!! WARNING !!! Manual start/stop for iSG may collide with HA - you should really be careful and know what you are doing ...\n\n"
        #update also deferred_start file to prevent any automatic HA actions in case start was called manually
        touch /opt/.iSG-last-deferred-start-ts
		if lxc-ls -f | grep $SG2_LXC_NAME; then
			if checkproc -p $MY_PIDFILE /bin/bash; then
				echo -n "Service $SG2_LXC_NAME already running "
				true
				rc_status -v
			else
                #send request to sg2dhome service in case call was not made from there
                [ "x$__SG2DHOME_SPECIAL_START__" = "x" ] && {
                    log "INFO : $0 (pid $$) $* sg2d start was called from outside of sg2dhome => using service sg2d to launch the iSG ..."
                    systemctl --no-pager status sg2d.service || {
                        service sg2d start &
                        sleep 30
                    }
                    if sg2d status ; then
                        log "INFO : $0 (pid $$) $* sg2d start was successful."
                        exit 0
                    else
                        log "WARNING : $0 (pid $$) $* sg2d start via service command failed => will try sending the start command directly to sg2dhome ..."
                        if [ -e /dev/shm/.isg.sg2dhome.fifo ] ; then
                            ( echo "start" > /dev/shm/.isg.sg2dhome.fifo ) &
                            sleep 30
                            if sg2d status ; then
                                log "ERROR : $0 (pid $$) $* sg2d start via direct write to sg2dhome pipe was successful. iSG is now running ..."
                                exit 0
                            else
                                log "ERROR : $0 (pid $$) $* sg2d start via direct write to sg2dhome pipe also failed."
                                exit 3
                            fi
                        else
                            log "ERROR : $0 (pid $$) $* sg2d start can not be done because sg2dhome pipe not found"
                            exit 3
                        fi
                    fi
                }
                #OSFOURK-19927 V10R1 SG Branch - HFA load tests - Packet loss (receive socket sequence error)
                #need to do this also in sg2d in order to cover iSG on Duplex (the other deployments are covered via socod LSB script)
                for ksirqdpid in $(/usr/bin/pgrep ksoftirqd) ; do
                    # raise priority of ksoftirqd to realtime
                    /usr/bin/chrt -p 90 $ksirqdpid
                    logger "sg2d increased ksoftirqd PID $ksirqdpid priority to -91"
                done

				echo -n "Starting $SG2_LXC_NAME daemon version $SG2_SCRIPT_VERSION ... "
				if [ "x`get_highest_sg2d_ver`" = "x$SG2_SCRIPT_VERSION" ]; then
					true
				else
					log "Found higher version of iSoftGate script : `get_highest_sg2d_ver`. Will use that one instead."
					cp `ls -1v /sg2/opt/sg2/sg2d-plt* | tail -n 1` $0
					exec /bin/bash /bin/sg2d start
				fi
				prepare_networks_and_configs
				rm -f /sg2/tmp/sg2lxc.booted.after.local
				0</dev/null 1>/dev/null 2>&1 startproc -f -p $MY_PIDFILE /bin/bash /bin/sg2d _daemon_
				#wait and make sure the start is OK
				sg2d wait_start
				rc_status -v
			fi
		else
			log "$SG2_LXC_NAME not configured. Use \"sg2d configure\" first."
			false
			rc_status -v
		fi
        ;;
    stop)
		if [ -e /var/opt/soco/is_container_sg ]; then
			touch /tmp/.sg2d.server-rq.dir/rqSHUTDOWN
			exit 0
		fi
        [ -e /dev/.sg2d-on-duplex ] && echo -en "\n\n!!! WARNING !!! Manual start/stop for iSG may collide with HA - you should really be careful and know what you are doing ...\n\n"
        #update also deferred_stop file to prevent any automatic HA actions in case stop was called manually
        touch /opt/.iSG-last-deferred-stop-ts
        if checkproc -p $MY_PIDFILE /bin/bash; then
            echo -n "Shutting down $SG2_LXC_NAME daemon "
			if 1>/dev/null 2>&1 ls /sg2/tmp/.sg2d.server-rq.dir; then
				#indicate nice stop first
				touch /sg2/tmp/.sg2d.server-rq.dir/rqSHUTDOWN
			else
				killproc -p $MY_PIDFILE /bin/bash
			fi
			#waits that the container appears as stopped
			sg2d wait_stop
            rc_status -v
        else
            echo -n "Service $SG2_LXC_NAME not running "
            true
            rc_status -v
        fi
        ;;
    restart)
		[ -e /var/opt/soco/is_container_sg ] && {
			log "ERROR : $0 $* call can NOT be made inside $SG2_LXC_NAME container"
			exit 1
		}
        sg2d safe_stop
        sg2d start
        rc_status
        ;;
    reload)
		[ -e /var/opt/soco/is_container_sg ] && {
			log "ERROR : $0 $* call can NOT be made inside $SG2_LXC_NAME container"
			exit 1
		}
        sg2d safe_stop
        sg2d start
        rc_status
        ;;
    status)
		[ -e /var/opt/soco/is_container_sg ] && exit 0
        echo -n "Checking for $SG2_LXC_NAME daemon "
        if checkproc -p $MY_PIDFILE /bin/bash; then
			lxc-ls -f | grep $SG2_LXC_NAME
			true
			rc_status -v
		else
			false
			rc_status -v
		fi
        ;;
	console)
		[ -e /var/opt/soco/is_container_sg ] && {
			log "ERROR : $0 $* call can NOT be made inside $SG2_LXC_NAME container"
			exit 1
		}
		if screen -ls | grep -q $SG2_LXC_NAME; then
			screen -x $SG2_LXC_NAME
		else
			echo "No screen console found for $SG2_LXC_NAME."
			sg2d status
			exit $?
		fi
		exit 0
		;;
    enable_on_entgw)
        1>/dev/null 2>/dev/null /opt/webservice/scripts/is_duplex
        [ $? -eq 1 ] && exit 0
        /opt/yapp/writehaipxml.sh system.iSG.node1=1
        exit 0
        ;;
    disable_on_entgw)
        1>/dev/null 2>/dev/null /opt/webservice/scripts/is_duplex
        [ $? -eq 1 ] && exit 0
        /opt/yapp/writehaipxml.sh system.iSG.node1=0
        exit 0
        ;;
	enable)
		[ -e /var/opt/soco/is_container_sg ] && {
			log "ERROR : $0 $* call can NOT be made inside $SG2_LXC_NAME container"
			exit 1
		}
		sg2d status && {
			#OSFOURK-24092
            sg2d enable_on_entgw
			exit 0
		}
        #OSFOURK-24092
        sg2d enable_on_entgw
		exit $?
		;;
	disable)
		[ -e /var/opt/soco/is_container_sg ] && {
			log "ERROR : $0 $* call can NOT be made inside $SG2_LXC_NAME container"
			exit 1
		}
        #OSFOURK-24092
        sg2d disable_on_entgw
		exit 0
		;;
	isg_get_vlanif)
		[ -e /var/opt/soco/is_container_sg ] && {
			log "ERROR : $0 $* call can NOT be made inside $SG2_LXC_NAME container"
			exit 1
		}
		log "Called with $* ..."
        basicif=$2
        vlanid=$3
        #check all VLANs and if one already existing then pass it to the container
        cd /proc/net/vlan
        for avlan in $(echo vlan*) notfound; do
            [ -e $avlan ] || break
            avdev=$(grep ^Device $avlan | awk '{print $NF}')
            avid=$(grep ^vlan $avlan | awk '{print $3}')
            [ "x$avdev" = "x$basicif" -a "x$avid" = "x$vlanid" ] && break
        done
        [ -e $avlan ] || {
            log "VLAN $basicif ID $vlanid not existing => creating ..."
            vconfig add $basicif $vlanid
            avlan=vlan$vlanid
            sleep 1
            if [ -e $avlan ] ; then
                log "VLAN IF $avlan created ok."
            else
                log "ERROR : VLAN IF $avlan not present."
                exit 1
            fi
        }
        #bring the vlan ip up
        ifconfig vlan$vlanid up
        log "Passing VLAN IF $avlan to the container using the ifname vlan$vlanid ..."
        if [ -e /sys/class/net/ipvlvlan$vlanid ] ; then
            log "IPVLAN VLAN IF ipvlvlan$vlanid already exists => re-use it."
            ip link delete dev ipvlvlan$vlanid
        else
            log "Setting up IPVLAN VLAN IF ipvlvlan$vlanid ..."
        fi
        ip link add link vlan$vlanid name ipvlvlan$vlanid type ipvlan mode l2
        ip link set dev ipvlvlan$vlanid netns `lxc-info -pHn $SG2_LXC_NAME` name vlan$vlanid
        log "VLAN IF $avlan passed to iSG container with rc $?"
        exit 0
        ;;
	configure)
		[ -e /var/opt/soco/is_container_sg ] && {
			log "ERROR : $0 $* call can NOT be made inside $SG2_LXC_NAME container"
			exit 1
		}
		log "Called with $* ..."
		#<path_to_initialcfg.xml> (will also make enable)
		sg2xml="$2"
		[ "x" = "x$sg2xml" ] && {
			log "ERROR : configure requires an argument"
			bash $0 help
			exit 2
		}
		[ -e $sg2xml ] || {
			log "ERROR : File not found $2"
			exit 2
		}
		log "Checking config file $sg2xml ..."
		check_network $sg2xml
		log "Config file $sg2xml is ok."
		bash $0 deployrootfs /sg2:/var/sg2
		dplrc=$?
		if [ $dplrc -eq 101 ]; then
			true
		else
			[ $dplrc -eq 0 ] || exit 1
		fi
		mkdir -p /opt/sg2
		rm -rf /opt/sg2/initialcfg.xml
		cp $sg2xml /opt/sg2/initialcfg.xml
		mkdir -p /var/sg2/opt/soco/config/
		cp /opt/sg2/initialcfg.xml /var/sg2/opt/soco/config/initialcfg.xml
		# remove the old boarddat.xml of the vNCUI to prevent unwanted backannotation
		rm -f /var/sg2/opt/soco/pbc_21/boarddat.xml
		log "Configuration done."
		echo "Now the $SG2_LXC_NAME can be enabled via \"sg2d enable\" command (this will also start it) or just started via \"start\" command."
		exit 0
		;;
    do_once_deployrootfs)
        touch /run/do_once_deployrootfs.is.running
        touch /opt/.isg.do_once_deployrootfs.called.$(date +%s)
        #update also duplex timestamps to avoid collisions
        touch /opt/.iSG-last-deferred-start-ts
        touch /opt/.iSG-last-deferred-stop-ts
        mkdir -p /var/log/webservice
        #OSFOURK-21067 - protection - in case previous deploy was ok only delete board data but not the complete container
        if [ -e /sg2/opt/.isg.deploy.done ] ; then
            echo "`date` /sg2 in this version is already deployed `cat /sg2/opt/.isg.deploy.done`"
            echo "will only delete following board data : "
            find /var/opt/soco -name board\*xml
            find /var/opt/soco -name board\*xml -delete
            echo 0 > /var/log/webservice/sg2d.deployrootfs.rc
            echo "`date` deployrootfs finished."
            exit 0
        fi
        echo "`date` /sg2 before deploy `2>&1 ls -al /sg2`"
        echo "`date` /var/sg2 before deploy `2>&1 ls -al /var/sg2`"
        rm -rf /sg2 /var/sg2 /var/log/webservice/sg2d.deployrootfs.rc
        sg2d deployrootfs /sg2:/var/sg2 1>>/var/log/webservice/sg2d.deployrootfs.out 2>&1
        echo $? > /var/log/webservice/sg2d.deployrootfs.rc
        echo "`date` deployrootfs finished."
        exit 0
        ;;
	deployrootfs)
		[ -e /var/opt/soco/is_container_sg ] && {
			log "ERROR : $0 $* call can NOT be made inside $SG2_LXC_NAME container"
			exit 1
		}
		rootdir=${2%:*}
		vardir=${2#*:}
		[ "x$rootdir" = "x" ] && rootdir=/sg2
		[ "x$vardir" = "x" ] && vardir=/var/sg2
		[ -e ${vardir}/opt/soco/is_container_sg ] && {
			echo "INFO : Already deployed."
			exit 101
		}
		#[ -e /instmedia/hp4kv6appl/HiPath_4000.Appliance.Image.tar.gz ] || {
		[ -e /instmedia/hp4kv6appl/iSG_STMIX.Appliance.Image.tar.xz ] || {
			log "ERROR : iSG OS Kit not found."
			exit 1
		}
		log "Deploying $SG2_LXC_NAME root filesystem ..."
		[ -e ${rootdir} ] && {
			log "ERROR : ${rootdir} must not exist. Call cleanup first"
			exit 1
		}
		[ -e ${vardir} ] && {
			log "ERROR : ${vardir} must not exist. Call cleanup first"
			exit 1
		}
		mkdir -p ${rootdir}/var
		mkdir -p ${vardir}
		mount --bind ${vardir} ${rootdir}/var
		cd ${rootdir}
		nice -n 10 ionice -c 3 xz -dc /instmedia/hp4kv6appl/iSG_STMIX.Appliance.Image.tar.xz | nice -n 10 ionice -c 3 tar -x --numeric-owner -f -
        #OSFOURK-21134 - EntGW V10R1.27.0 - After OS update from V10R1 the iSG is lost
        cp /instmedia/hp4kv6appl/unionfs-del-before-iSG-Delta-installed.sh ${rootdir}/tmp/
        chroot ${rootdir} bash /tmp/unionfs-del-before-iSG-Delta-installed.sh
		nice -n 10 ionice -c 3 xz -dc /instmedia/hp4kv6appl/iSG-delta-installed.Appliance.Image.tar.xz | nice -n 10 ionice -c 3 tar -x --numeric-owner -f -
        
		
        mkdir -p /var/crash
        
		touch /var/log/$SG2_LXC_NAME-daemon.log
		
		[ -e ${rootdir}/tmp/fixup-from-pltimage2sg2image.done ] || {
			umount dev
			umount ${rootdir}/var
			rm -f ${rootdir}/config /var/lib/lxc/d$SG2_LXC_NAME
			log "ERROR : [DEPLOY_NEW_OS_IMAGE]: Fixup script execution has timed out"
			exit 1
		}
		
		log "Unpacked RootFS for $SG2_LXC_NAME to ${rootdir}. Used space on HD : `du -hs ${rootdir}`"
		log "Generating $SG2_LXC_NAME container config files ..."
        
		cp -p /etc/shadow /etc/group /etc/passwd ${rootdir}/etc/

        #copy set_virt_ip.sh patched script into the container rootfs
        cp -v /opt/yaps/script/isg-set_virt_ip.with-vlan.sh ${rootdir}/opt/.isg.set_virt_ip.with.dyn.support
        
        #OSFOURK-25622 iSG container shall call Linux hardening
        touch ${rootdir}/opt/_isg_do_linux_hardening_once_on_boot_
        
        #OSFOURK-21067 create deploy success indication file /opt/.isg.deploy.done
        ( chroot ${rootdir} getydata -v ) > ${rootdir}/opt/.isg.deploy.done

		umount ${rootdir}/var
		
	cat > ${rootdir}/$SG2_LXC_NAME.conf << _EOF_SG2_LXC_CONF_
lxc.utsname = $SG2_LXC_NAME
lxc.arch = x86_64
lxc.rootfs = /sg2
lxc.mount.auto = proc:mixed sys:mixed cgroup:mixed
lxc.mount.entry = /sys/fs/fuse/connections sys/fs/fuse/connections none bind,optional 0 0
lxc.mount.entry = /var/sg2 var none bind,create=dir 0 0
lxc.mount.entry = /var/opt/ha/conf var/opt/ha/conf none bind,create=dir 0 0
lxc.mount.entry = /opt/webservice opt/webservice none bind,create=dir 0 0
lxc.mount.entry = /var/crash var/crash none rw,bind,create=dir 0 0
# AppArmor settings
lxc.aa_allow_incomplete = 1
lxc.aa_profile = unconfined
_EOF_SG2_LXC_CONF_

		rm -f ${rootdir}/config
		ln -s ${rootdir}/$SG2_LXC_NAME.conf ${rootdir}/config
		ln -s ${rootdir} /var/lib/lxc/$SG2_LXC_NAME

		log "$SG2_LXC_NAME RootFS installation done."
		exit 0
		;;
	cleanrootfs)
		[ -e /var/opt/soco/is_container_sg ] && {
			log "ERROR : $0 $* call can NOT be made inside $SG2_LXC_NAME container"
			exit 1
		}
		rootdir=${2%:*}
		vardir=${2#*:}
		[ "x$rootdir" = "x" ] && rootdir=/sg2
		[ "x$vardir" = "x" ] && vardir=/var/sg2
		grep ${rootdir} /proc/self/mount* && {
			log "ERROR : $SG2_LXC_NAME root dir still mounted."
			exit 1
		}
		grep ${vardir} /proc/self/mount* && {
			log "ERROR : $SG2_LXC_NAME var dir still mounted."
			exit 1
		}
		rm -f ${rootdir}/config /var/lib/lxc/$SG2_LXC_NAME
        chattr -i ${rootdir}/etc/ssh/sshd_config
		nice -n 10 ionice -c 3 rm -rf ${vardir}
		nice -n 10 ionice -c 3 rm -rf ${rootdir}
		log "$SG2_LXC_NAME deleted."
		exit 0
		;;
	cleanup)
		[ -e /var/opt/soco/is_container_sg ] && {
			log "ERROR : $0 $* call can NOT be made inside $SG2_LXC_NAME container"
			exit 1
		}
        touch /opt/.isg.cleanup.called.$(date +%s)
		sg2d stop
		(
		umount /sg2/dev/pts/*
		umount /sg2/dev/pts
		umount /sg2/dev
		umount /sg2/*
		umount /var/sg2
		) 1>/dev/null 2>/dev/null
		grep sg2 /proc/self/mount* && {
			log "ERROR : $SG2_LXC_NAME still mounted."
			exit 1
		}
		#backup config before cleanup
		cp /var/sg2/opt/soco/config/initialcfg.xml /opt/sg2/initialcfg-before-cleanup.xml
		sg2d cleanrootfs /sg2:/var/sg2
		exit $?
		;;
	backup)
		[ -e /var/opt/soco/is_container_sg ] && {
			log "ERROR : $0 $* call can NOT be made inside $SG2_LXC_NAME container"
			exit 1
		}
		mount --bind /var/sg2/ /sg2/var
		rm -f /sg2/.sg2.rpm.version.backed.up
		(chroot /sg2 rpm -q softgate) 1>/sg2/.sg2.rpm.version.backed.up
		umount /sg2/var
		cd /
		tar -czf $2/sg2-`cat /sg2/.sg2.rpm.version.backed.up`-generic-config-bkp.tgz /var/sg2/opt/soco/config/initialcfg.xml /var/sg2/opt/soco/config/pbc_21/mekdata /sg2/opt/soco/tones/extann/ /var/sg2/opt/soco/config/tones/extann/ /sg2/.sg2.rpm.version.backed.up
		tar -czf $2/sg2-`cat /sg2/.sg2.rpm.version.backed.up`-all-config-bkp.tgz /var/sg2/opt/soco/config/ /sg2/opt/soco/tones/extann/ /sg2/.sg2.rpm.version.backed.up
		exit 0
		;;
	restore)
		[ -e /var/opt/soco/is_container_sg ] && {
			log "ERROR : $0 $* call can NOT be made inside $SG2_LXC_NAME container"
			exit 1
		}
		mount --bind /var/sg2/ /sg2/var
		rm -f /sg2/.sg2.rpm.version.to.restore
		(chroot /sg2 rpm -q softgate) 1>/sg2/.sg2.rpm.version.to.restore
		umount /sg2/var
		cd /
		if ls $2/sg2-`cat /sg2/.sg2.rpm.version.to.restore`-all-config-bkp.tgz; then 
			tar -xzf $2/sg2-`cat /sg2/.sg2.rpm.version.to.restore`-all-config-bkp.tgz
		else
			tar -xzf $2/sg2*generic-config-bkp.tgz
		fi
		exit 0
		;;
	check_network)
		[ -e /var/opt/soco/is_container_sg ] && {
			log "ERROR : $0 $* call can NOT be made inside $SG2_LXC_NAME container"
			exit 1
		}
		check_network $2 && echo "SG2_NETWORK_OK_NO_CONFLICTS"
		exit 0
		;;
	phys_lans_not_used_by_entgw)
		[ -e /var/opt/soco/is_container_sg ] && {
			log "ERROR : $0 $* call can NOT be made inside $SG2_LXC_NAME container"
			exit 1
		}
		exec 3>&1
		exec 4>&2
		exec 1>/dev/null
		exec 2>/dev/null
		get_initialcfg_params_as_string
		exec 1>&3
		exec 2>&4
		echo $allFSETHsShort
		exit 0
		;;
	get_initialcfg_params_as_string)
		[ -e /var/opt/soco/is_container_sg ] && {
			log "ERROR : $0 $* call can NOT be made inside $SG2_LXC_NAME container"
			exit 1
		}
		get_initialcfg_params_as_string $2
		exit $?
		;;
	set_initialcfg_params_from_string)
		[ -e /var/opt/soco/is_container_sg ] && {
			log "ERROR : $0 $* call can NOT be made inside $SG2_LXC_NAME container"
			exit 1
		}
		shift
		set_initialcfg_params_from_string $*
		exit $?
		;;
	_in_cleanupip_)
		[ -e /var/opt/soco/is_container_sg ] || {
			log "ERROR : $0 $* call can be made only inside $SG2_LXC_NAME container"
			exit 1
		}
		#do nothing when called during SG stop
		ps -eo pid,ppid,cmd | grep socod | grep -q stop && exit 0
		1>/dev/null 2>/dev/null log "INFO : $0 $* called to check if restart is needed"
		#create trigger file so that sg2d plt server checks if restart is needed due to LW update or config change
		ts=`date +%s`
		echo $* > /tmp/.sg2d.client-rq.dir/sg2-check-for-restart-request.$ts
        unblock_server_daemon_for_one_step
		#wait max 15 seconds for confirmation and if not continue in order not to block the caller
		for i in {0..15}; do
			sleep 1
			[ -e /tmp/.sg2d.client-rq.dir/sg2-check-for-restart-response.$ts ] && {
				sleep 0.5
				if grep -q _wait_for_restart_ /tmp/.sg2d.client-rq.dir/sg2-check-for-restart-response.$ts; then
					rm -f /tmp/.sg2d.client-rq.dir/sg2-check-for-restart-response.$ts
                    # ? unblock_server_daemon_for_one_step
					#wait to go down
					sleep 300
					1>/dev/null 2>/dev/null log "WARNING : $0 $* I am still alive at 5 minutes after restart was confirmed by the server. Will continue despite this strange situation."
				else
					rm -f /tmp/.sg2d.client-rq.dir/sg2-check-for-restart-response.$ts
                    # ? unblock_server_daemon_for_one_step
				fi
				exit 0
			}
		done
		1>/dev/null 2>/dev/null log "WARNING : $0 $* server did not answer - continuing"
		exit 0
		;;
	#always keep _daemon_ part as last block in the script so that the bash is forced to read the script completely up to that part - reduces the side-effects on overwrite
	_daemon_)
		[ -e /var/opt/soco/is_container_sg ] && {
			log "ERROR : $0 $* call can NOT be made inside $SG2_LXC_NAME container"
			exit 1
		}
		
		echo $$ > $MY_PIDFILE
		exec 1>>/var/log/$SG2_LXC_NAME-daemon.log
		exec 2>&1

		#fixing the OSFOURK-7519 in a Gandalf way - see this for details :) - .../ims_main/media_server/src/ims/native/mfw/src/MediaControl/dispatch/MfwRTPMain.cpp
		[ -x /usr/bin/killall.origsg2 ] || {
			cp -p /usr/bin/killall /usr/bin/killall.origsg2
			rm -rf /usr/bin/killall.new
			cat >/usr/bin/killall.new << '_EOF_KILLALL_GDF_'
#!/bin/bash
_my_ppid="`ps -o ppid= -p $$`"
_my_ppid_cmdline="`ps -o cmd= -p $_my_ppid`"
_b_UseDefaultKillall=true
[[ "x$_my_ppid_cmdline" =~ com.sen.esy.lcd.softgate.SoftGate ]] && _b_UseDefaultKillall=false
[[ "x$_my_ppid_cmdline" =~ setup_SG_HSR_tun.sh ]] && _b_UseDefaultKillall=false
$_b_UseDefaultKillall && {
 1>/dev/null 2>/dev/null mount --bind /usr/bin/killall.origsg2 /usr/bin/killall
 /usr/bin/killall $@
 _rc_k_a_=$?
 1>/dev/null 2>/dev/null umount /usr/bin/killall
 exit $_rc_k_a_
}
while [ "x$2" != "x" ]; do shift ; done
for _a_pid in $(/usr/bin/pgrep $1); do
 if 1>/dev/null 2>/dev/null /usr/bin/grep /lxc/ /proc/$_a_pid/cgroup; then
  /bin/logger killall skipped PID $_a_pid which belongs to the `/usr/bin/grep -m 1 /lxc/ /proc/$_a_pid/cgroup | /usr/bin/sed -e 's/.*\///'` container
 else
  [ -e /proc/$_a_pid ] && kill -9 $_a_pid
 fi
done
exit 0
_EOF_KILLALL_GDF_
			chmod 755 /usr/bin/killall.new
			mv /usr/bin/killall.new /usr/bin/killall
		}
		[ -x /usr/bin/pgrep.origsg2 ] || {
			cp -p /usr/bin/pgrep /usr/bin/pgrep.origsg2
			cat >/usr/bin/pgrep.new << '_EOF_PGREP_GDF_'
#!/bin/bash
_my_ppid="`ps -o ppid= -p $$`"
_my_ppid_cmdline="`ps -o cmd= -p $_my_ppid`"
_b_UseUnmodifiedPGrep=true
[[ "x$_my_ppid_cmdline" =~ com.sen.esy.lcd.softgate.SoftGate ]] && _b_UseUnmodifiedPGrep=false
[[ "x$*" =~ nativeRTPunit ]] && _b_UseUnmodifiedPGrep=false
$_b_UseUnmodifiedPGrep && exec /usr/bin/pgrep.origsg2 $@
for _a_pid in $(/usr/bin/pgrep.origsg2 $@); do
 if 1>/dev/null 2>/dev/null /usr/bin/grep /lxc/ /proc/$_a_pid/cgroup; then
  1>/dev/null 2>/dev/null /bin/logger pgrep skipped PID $_a_pid which belongs to the `/usr/bin/grep -m 1 /lxc/ /proc/$_a_pid/cgroup | /usr/bin/sed -e 's/.*\///'` container
 else
  echo $_a_pid
 fi
done
exit 0
_EOF_PGREP_GDF_
			chmod 755 /usr/bin/pgrep.new
			mv /usr/bin/pgrep.new /usr/bin/pgrep
		}

		log "Starting $SG2_LXC_NAME container ..."
		trap daemon_exit EXIT
		#create .screenrc file
		echo "logfile /var/log/$SG2_LXC_NAME-console.log" > /sg2/tmp/.screenrc
		echo "logfile flush 1" >> /sg2/tmp/.screenrc
		/etc/init.d/boot.cgroup start
		
		#start in container sg2 client daemon
		cp /opt/yaps/script/sg2d /sg2/etc/init.d/sg2dplt
		chmod 755 /sg2/etc/init.d/sg2dplt
		sed -i -e "/s\/Provides/d" /sg2/etc/init.d/sg2dplt
		sed -i -e "s/Provides:.*/Provides: sg2dplt/" /sg2/etc/init.d/sg2dplt
		chroot /sg2 /sbin/insserv sg2dplt
		
        isgltunr=`grep -i ltu /var/sg2/opt/soco/config/initialcfg.xml`
        isgltunr=${isgltunr#*value=\"}
        isgltunr=${isgltunr%%\"*}
        
        sed -i -e /127.0.0.1/d /sg2/etc/hosts
        echo "127.0.0.1       localhost iSG-AP$isgltunr" >> /sg2/etc/hosts
        
        #OSFOURK-23208 SG2D access
        [ -e /root/.bashrc ] || {
            touch /root/.bashrc
            chmod 755 /root/.bashrc
        }
        grep -q iSoftGate /root/.bashrc || {
            cat >>/root/.bashrc << '_EOF_ISG_BASHRC'
( set -- $SSH_CONNECTION ; _int_lan_list_ip_=$(/opt/webservice/scripts/gethaipsetupentry.sh internal-lan.listen-ip-address) ; _int_lan_list_ip_=${_int_lan_list_ip_%1} ; [ "x$1" = "x${_int_lan_list_ip_}99" ] && exit 0 ; exit 1 ; ) && { export SSH_CONNECTION="" ; screen -x iSoftGate ; exit 0 ; }
_EOF_ISG_BASHRC
        }
        grep -q "same password like" /sg2/etc/issue || {
            rm /sg2/etc/issue
            touch /sg2/etc/issue
            chmod 644 /sg2/etc/issue
            cat >>/sg2/etc/issue << '_EOF_ISG_ISSUE'

  !! Welcome to the iSoftGate container console !!
  
  Login using "root" and same password like the Linux Platform.
  After logging out you can exit the terminal using "CTRL-a" then press "d".
  
_EOF_ISG_ISSUE
        }
        
        for afile in $(find /sg2/opt/soco/config/templates/apache -name \*xml); do
            sed -i -e 's/localhost/127.0.0.1/g' $afile
        done

		cat >/sg2/etc/init.d/after.local << _EOF_SG2_AFTERLOCAL_
#!/bin/bash
. /etc/profile
echo "after.local start P[$*] R[`who -r`]"
echo Setting hostname to iSG-AP$isgltunr ...
hostname iSG-AP$isgltunr
echo configuring SNMP master daemon snmpd.conf by adding agentXSocket option
/opt/subagents/snmp-syslog-agent/configSnmpSystem.sh
echo Indicating that container has booted ...
touch /tmp/sg2lxc.booted.after.local
echo "after.local done"
_EOF_SG2_AFTERLOCAL_
        chmod 755 /sg2/etc/init.d/after.local
        grep -q /etc/init.d/after.local /var/spool/cron/tabs/root || \
            echo '@reboot /etc/init.d/after.local' >> /var/spool/cron/tabs/root

		cat >/sg2/etc/fstab << '_EOF_FSTAB'
proc                 /proc                proc       defaults              0 0
sysfs                /sys                 sysfs      noauto                0 0
debugfs              /sys/kernel/debug    debugfs    noauto                0 0
usbfs                /proc/bus/usb        usbfs      noauto                0 0
devpts               /dev/pts             devpts     mode=0620,gid=5       0 0
_EOF_FSTAB

		#necessary so that virtual ETHs are visible inside container
		echo "mount -t sysfs sysfs /sys" > /sg2/etc/init.d/boot.local
		echo "hostname iSG-AP$isgltunr" >> /sg2/etc/init.d/boot.local

		rm -f /sg2/tmp/.sg2d.dev.bash.dbg.on
		[ -e /tmp/.sg2d.dev.bash.dbg.on ] && touch /sg2/tmp/.sg2d.dev.bash.dbg.on
		#so that sg2d client daemon script can run inside iSoftGate
		touch /sg2/tmp/.sg2d.dev.bash.disableentgwlimitation.on

		try_init_sg2
		[ -e /sg2/tmp/sg2lxc.started ] || {
			log "`date` ERROR : $SG2_LXC_NAME pre-start failed after all attempts"
			exit 1
		}
		#give some time for lxc continer to finish stopping, i.e. do not immediately re-launch it
		sleep 10
		
		#some directories used for the client-server communication
		rm -rf /sg2/tmp/.sg2d.server-rq.dir /sg2/tmp/.sg2d.client-rq.dir
		mkdir -p /sg2/tmp/.sg2d.server-rq.dir
		mkdir -p /sg2/tmp/.sg2d.client-rq.dir
        
        rm -rf /tmp/.inotifywait.simulation.pl /sg2/tmp/.inotifywait.simulation.pl
        #create perl script for inotifywait simulation
        cat > /tmp/.inotifywait.simulation.pl << '_EOF_INOTIFYWAIT_SIMULATION_PL_'
#! /usr/bin/perl -w

use strict;

use IO::Socket::UNIX qw( SOCK_STREAM SOMAXCONN );

#handle SIGPIPE signals so that server does not crash in case it sends information to dead clients
$SIG{'PIPE'} = 'dummySigpipe';

sub dummySigpipe {
#do nothing
print " got SIGPIPE signal, meaning some client has died before getting results from Server.";
}

#called like one of these
#    these are clients
# /tmp/.inotifywait.simulation.pl client_rq 5 $socket_file $$.$INWSIM_COUNTER
# /tmp/.inotifywait.simulation.pl stop_server 5 $socket_file $$.$INWSIM_COUNTER
# /tmp/.inotifywait.simulation.pl wait_to_be_unblocked 30 $socket_file $$.$INWSIM_COUNTER
#    this is the server
# /tmp/.inotifywait.simulation.pl start_server 0 /tmp/.inotifywait.simulation.socket 0

my $action = $ARGV[0];
my $timeout = $ARGV[1];
my $socket_path = $ARGV[2];
my $action_id = $ARGV[3];

my @QActions = ();

print STDERR "Called with $action $timeout $socket_path $action_id \n";

if ( $action =~ /start_server/ ) {
    unlink($socket_path);
    my $srvsock = IO::Socket::UNIX->new(
      Type   => SOCK_STREAM,
      Local  => $socket_path,
      Listen => SOMAXCONN,
    ) or die("Can't create server socket: $!\n");
    my $waiting_client;
    my $has_waiting_client = 0;

    while () {
        my $clnsocket = $srvsock->accept() or die("Can't accept connection: $!\n");

        my $clnaction = <$clnsocket>;
        chomp($clnaction);
        print STDOUT "SRV : Got $clnaction\n";
        
        if ( $clnaction =~ /stop_server/ ) {
            print $clnsocket "OK_GOOD_BYE\n";
            close $clnsocket;
            close $srvsock;
            exit(0);
        }
        
        if ( $clnaction =~ /wait_to_be_unblocked/ ) {
            #if there is some action in the queue then give it, if not simply put client on hold
            if ( @QActions ) {
                my $nextaction = $QActions[0];
                print $clnsocket $nextaction."\n";
                #now check if pending client dead in order to know if he got the reply, if not then we need to keep it for the next
                my $cln2line = <$clnsocket>;
                if ( defined($cln2line) && ($cln2line =~ /ok_got_it_ty/ ) ) {
                    print $clnsocket "super_ty\n";
                    close $clnsocket;
                    #take out action from the list as we have successfully sent it
                    shift @QActions;
                } else {
                    print STDOUT "SRV : WARNING - dead waiting client right after it connected to the server\n";
                    #keep action in the queue for the next waiting client ; do not do anything else with this one but just try closing the socket
                    close $clnsocket;
                }
            } else {
                print STDOUT "SRV : No pending action. Putting waiting_client on hold.\n";
                $has_waiting_client = 1;
                $waiting_client = $clnsocket;
            }
        } else {
            push @QActions, $clnaction;
            print $clnsocket "OK_GOT_IT\n";
            close $clnsocket;
            if ( $has_waiting_client == 1 ) {
                #unblock waiting client
                my $nextaction = $QActions[0];
                print $waiting_client $nextaction."\n";
                #now check if pending client dead in order to know if he got the reply, if not then we need to keep it for the next
                my $cln2line = <$waiting_client>;
                if ( defined($cln2line) && ($cln2line =~ /ok_got_it_ty/ ) ) {
                    print $waiting_client "super_ty\n";
                    close $waiting_client;
                    $has_waiting_client = 0;
                    #take out action from the list as we have successfully sent it
                    shift @QActions;
                } else {
                    print STDOUT "SRV : WARNING - dead waiting client\n";
                    #keep action in the queue for the next waiting client ; do not do anything else with this one but just try closing the socket
                    close $waiting_client;
                    #also consider we do not have a waiting client anymore due to the previous error
                    $has_waiting_client = 0;
                }
            }
        }
    }
    exit(0);
}

#clients

$SIG{ALRM} = sub {
    print STDERR "ERROR: SOCKET_TIMEOUT";
    exit(1);
};

alarm $timeout; 

my $clnsocket = IO::Socket::UNIX->new(
  Type => SOCK_STREAM,
  Peer => $socket_path,
) or die("Can't connect to server: $!\n");

print $clnsocket "$action_id $action\n";
my $line = <$clnsocket>;
print STDOUT "RESP:$line\n";
#in case of wait_to_be_unblocked write a second line to server to help server detect if we are dead in the meanwhile due to timeout
if ( $action =~ /wait_to_be_unblocked/ ) {
  print $clnsocket "ok_got_it_ty\n";
  $line = <$clnsocket>;
  print STDOUT "RESP2:$line\n";
}
close $clnsocket;

_EOF_INOTIFYWAIT_SIMULATION_PL_
        cp /tmp/.inotifywait.simulation.pl /sg2/tmp/.inotifywait.simulation.pl
		chmod 755 /tmp/.inotifywait.simulation.pl /sg2/tmp/.inotifywait.simulation.pl
        
		#speed up waiting for interfaces inside iSoftGate
		sed -i -e "s/WAIT_FOR_INTERFACES=.*/WAIT_FOR_INTERFACES=10/" /sg2/etc/sysconfig/network/config
		
		#TODO - PRIO 3 - compare versions of the two scripts and update inside script if older
		cp -p /opt/inventory/inventory-client.sh /sg2/opt/inventory/inventory-client.sh
				
		#update timezone
		rm -f /sg2/etc/localtime
		if file /etc/localtime | grep -i symbolic | grep -i link; then
			ln -s `readlink -f /etc/localtime` /sg2/etc/localtime
		else
			cp -p /etc/localtime /sg2/etc/localtime
		fi
        
        # make sure apache plt config is not present and /opt/soco/native/os/linux/is_container.sh reports it is container
        # will fix this also inside SG LW
        rm -fv /sg2/etc/apache2/vhosts.d/vhost-soco2.conf
        # patch sg script if not already in the right version
        grep ksoftirq /sg2/opt/soco/native/os/linux/is_container.sh || {
            rm -fv /sg2/opt/soco/native/os/linux/is_container.sh
            ln -sf /bin/false /sg2/opt/soco/native/os/linux/is_container.sh
		}
        
		#remember iSoftGate initialcfg on start so that we can compare if it changed on restarts
		cp /var/sg2/opt/soco/config/initialcfg.xml /dev/.sg2.last.initialcfg.xml
        
        #remember also the SG LW version so that we restart the container on LW update
		grep ^Version /sg2/opt/soco/version.properties > /dev/.sg2.last.lw.version
		
		grep /etc/init.d/sg2dplt /sg2/opt/soco/native/os/linux/cleanup_ip_config.sh || {
			#TODO - Prio 1 - request from SG explicit CALL to indicate to sg2d SG coming-up so that check can be made if complete Container restart is necessary
			# current hack is not clean - if HFA if is changed and then LW Update the LW Update would fail
			sed -i -e 's|SUBVERSION=\(.*\)|SUBVERSION=\1\n\n[ -x /etc/init.d/sg2dplt ] \&\& /etc/init.d/sg2dplt _in_cleanupip_|' /sg2/opt/soco/native/os/linux/cleanup_ip_config.sh
		}
		
		#pass internal ip address to the iSoftGate to use
		# not needed anymore as now the haipsetup is available in the container so it can be directly read from there
		#  ip addr show br-intl | grep -m 1 inet | awk '{print $2}' | cut -d/  -f1 > /sg2/tmp/.sg2d.server-int-lan-ip-addr
		
		eval screen -S "$SG2_LXC_NAME" -d -m -c /sg2/tmp/.screenrc -L bash -c \'lxc-start -n $SG2_LXC_NAME --logfile=/var/log/$SG2_LXC_NAME-lxc.log --foreground\'
		
		#check all the time client PID - if it is dead unexpected then we stop the whole container and start it back
		(
			trap - EXIT
			myparentpid=`2>/dev/null cat /var/run/sg2.pid`
			i=120
			while [ -e $MY_PIDFILE ]; do
				sleep 10
                #periodically update /etc/init.d/sg2d with the content from YAPS RPM as this is now the most up2date - this covers LW update issues
                1>/dev/null 2>/dev/null diff /opt/yaps/script/sg2d /etc/init.d/sg2d || cp /opt/yaps/script/sg2d /etc/init.d/sg2d
				[ -e /proc/`2>/dev/null cat /var/run/sg2.pid` ] || break
				[ "x$myparentpid" = "x`2>/dev/null cat /var/run/sg2.pid`" ] || break
				#monitor and tear down and re-add internal LAN if internal bridge is not up
				# check if there is already in place an internal IF and if so then since how long a ping from iSG to PLT has been executed and if more than 1 minute then simply tear down the lan and recreate it and also indicate this to the iSG
				bNeedRecreateIlanIF=false
				if [ -e /sg2/tmp/.sg2d.ping_to_internal_lan_ok ]; then
					if [ $((`stat -c %Y /sg2/tmp/.sg2d.ping_to_internal_lan_ok` + 60)) -lt `date +%s` ]; then
						log "INFO : $SG2_LXC_NAME Internal LAN needs to be re-added since it did not signal to be alive since more than 1 minute"
						bNeedRecreateIlanIF=true
					fi
				else
					log "INFO : $SG2_LXC_NAME Internal LAN needs to be added"
					bNeedRecreateIlanIF=true
				fi
				if $bNeedRecreateIlanIF; then
					if 1>/dev/null 2>&1 ls /sys/class/net/br-intl; then
						log "INFO : SOCO2 internal LAN Bridge (br-intl) is present. Will connect $SG2_LXC_NAME to it."
						#Hint : we use on PLT side the name isgintl because it is already hidden by the Portal LAN Configuration page in the selections for possible LAN interfaces for various functions
						ip link del isgintl 1>/dev/null 2>/dev/null
						sleep 1
						ip link add name isgintl type veth peer name isgilan
						sleep 1
						brctl addif br-intl isgintl
						sleep 1
						ifconfig isgintl 0.0.0.0 up
						sleep 1
						ip link set dev isgilan netns `lxc-info -pHn $SG2_LXC_NAME` name intlan
						#give the chance for one minute for the container to resume normal monitoring by setting the timestamp of the flag file to now so that we do not immediately re-add the internal lan
						touch /sg2/tmp/.sg2d.ping_to_internal_lan_ok
					else
						log "WARNING : SOCO2 internal LAN Bridge (br-intl) not present. $SG2_LXC_NAME does not have at the moment access to Internal LAN"
					fi
				fi
                #periodic monitoring of TABLE_SOCO2_IPDA routing table to adapt for local iSG@duplex
                [ -e /dev/.sg2d-on-duplex ] && (
                    exec 1>>/var/log/iSoftGate-duplex-route-monitor-hhs.log
                    exec 2>&1
                    #set -x
                    srvintlanipaddr=$(/opt/webservice/scripts/gethaipsetupentry.sh internal-lan.listen-ip-address)
                    sigipaddr=`geticfgxmlparam ipAddrSig /var/sg2/opt/soco/config/initialcfg.xml`
                    ip route show table TABLE_SOCO2_IPDA | while read aline; do
                        set -- $aline
                        [ "x$1" = "x$sigipaddr" ] || continue
                        #check if already set
                        [[ "x$aline" =~ br-intl ]] && continue
                        log "Following route in table TABLE_SOCO2_IPDA will be adapted : $aline"
                        ip route del $aline table TABLE_SOCO2_IPDA
                        log "Route deletion rc : $?"
                        ip route add ${aline%via*} via ${srvintlanipaddr%1}99 dev br-intl table TABLE_SOCO2_IPDA
                        log "ip route add ${aline%via*} via ${srvintlanipaddr%1}99 dev br-intl table TABLE_SOCO2_IPDA rc : $?"
                    done
                )
				#enable this check only 2 minutes after the start
				if [ $i -eq 0 ]; then
                
                    host_enable_traffic_between_entgw_and_isg_on_same_lan_osfourk22440
                    host_enable_traffic_between_SBC_and_isg_on_same_lan_osfourk24708
                
					touch /sg2/tmp/.sg2d.client-rq.dir/internal_check_client
                    unblock_server_daemon_for_one_step
				else
					i=$(($i - 10))
					[ -e /sg2/tmp/sg2lxc.booted.after.local ] || continue
				fi
			done
		) &
		
		#TODO - prio 2 - checkin newer inventory client RPM in SG
        
        #launch inotifywait server
        /tmp/.inotifywait.simulation.pl start_server 0 /sg2/tmp/.inotifywait.simulation.socket 0 &
		
		#server part to handle requests is here as they come in /sg2/tmp/.sg2d.client-rq.dir
		cd /sg2/tmp/.sg2d.client-rq.dir
		while [ -e $MY_PIDFILE ]; do
			#1>/dev/null 2>/dev/null /usr/bin/inotifywait /sg2/tmp/.sg2d.client-rq.dir
            unblock_server_daemon_for_one_step wait_to_be_unblocked
			#shutdown initiated
			[ -e /sg2/tmp/.sg2d.client-rq.dir/shutdown-in-progress ] && {
				log "Graceful $SG2_LXC_NAME shutdown requested ..."
				break
			}
			#handle config and script version recheck on iSoftGate boot
			arq=$(ls -1 /sg2/tmp/.sg2d.client-rq.dir/sg2-check-for-restart-request.* 2>/dev/null | sort -f | head -n 1)
			if [ "x$arq" = "x" ]; then
				true
			else
				ts=${arq##*\.}
				rm -f $arq
                # ? unblock_server_daemon_for_one_step
				bNeedRestart=false
				if [ "x`get_highest_sg2d_ver`" = "x$SG2_SCRIPT_VERSION" ]; then
					diff /var/sg2/opt/soco/config/initialcfg.xml /dev/.sg2.last.initialcfg.xml || {
						bNeedRestart=true
						log "Difference identified in SG config since last restart. Will restart complete iSoftGate container now to use the new configuration."
					}
				else
					log "Higher script version found : `get_highest_sg2d_ver`. Will restart complete iSoftGate container now to use the new version."
					bNeedRestart=true
				fi
                grep ^Version /sg2/opt/soco/version.properties > /dev/.sg2.actual.lw.version
                if diff /dev/.sg2.actual.lw.version /dev/.sg2.last.lw.version ; then
                    log "LW Version is the same as on startup => no restart needed"
                    true
                else
                    log "LW Version has changed from `cat /dev/.sg2.last.lw.version` to `cat /dev/.sg2.actual.lw.version` => container restart needed"
                    bNeedRestart=true
                fi

				if $bNeedRestart; then
					#indicate nice stop first
					touch /sg2/tmp/.sg2d.server-rq.dir/rqSHUTDOWN
					#indicate to client to wait for the restart
					echo _wait_for_restart_ > /sg2/tmp/.sg2d.client-rq.dir/sg2-check-for-restart-response.$ts
                    # ? unblock_server_daemon_for_one_step
					#wait for the nice stopping for max 30 seconds
					for i in {0..30}; do
						sleep 1
						[ -e /sg2/tmp/.sg2d.client-rq.dir/shutdown-in-progress ] && {
							log "Graceful $SG2_LXC_NAME shutdown requested ..."
							break
						}
					done
					if [ -e /sg2/tmp/.sg2d.client-rq.dir/shutdown-in-progress ]; then
						#TODO - prio 4 - improve - in case shutdown gets stuck then no one would kill anymore the container in this case
						touch /sg2/tmp/.sg2d.client-rq.dir/restart
                        # ? unblock_server_daemon_for_one_step
					else
						log "WARNING : No reaction from $SG2_LXC_NAME client daemon (sg2dplt) - will restart using hard method"
						(
							trap - EXIT
							lxc-stop -n $SG2_LXC_NAME &
						)
					fi
					break
				else
					#no special indication to the client - just continue
					touch /sg2/tmp/.sg2d.client-rq.dir/sg2-check-for-restart-response.$ts
                    # ? unblock_server_daemon_for_one_step
				fi
			fi
			#handle internal_check_client
			[ -e /sg2/tmp/.sg2d.client-rq.dir/internal_check_client ] && {
				rm -f /sg2/tmp/.sg2d.client-rq.dir/internal_check_client
                # ? unblock_server_daemon_for_one_step
				[ "x0" = "x`ps -ef | grep -v client_daemon_ssh_port_fwd | grep sg2dplt | grep -v grep | wc -l`" ] && {
					log "WARNING : $SG2_LXC_NAME client daemon (sg2dplt) is dead - will restart complete $SG2_LXC_NAME"
					(
						trap - EXIT
						lxc-stop -n $SG2_LXC_NAME &
					)
					touch /sg2/tmp/.sg2d.client-rq.dir/restart
                    # ? unblock_server_daemon_for_one_step
					break
				}
			}
			#handle exec_on_plt requests here
			arq=$(ls -1 /sg2/tmp/.sg2d.client-rq.dir/sg2-exec-cmd-request.* 2>/dev/null | sort -f | head -n 1)
			if [ "x$arq" = "x" ]; then
				true
			else
				ts=${arq##*\.}
				rqcmdline=$(cat $arq)
				$rqcmdline 1>/sg2/tmp/.sg2d.client-rq.dir/sg2-exec-cmdresponse.serverstdout.$ts 2>/sg2/tmp/.sg2d.client-rq.dir/sg2-exec-cmdresponse.serverstderr.$ts
				echo $? > /sg2/tmp/.sg2d.client-rq.dir/sg2-exec-cmdresponse.serverrc.$ts
				rm -f $arq
                # ? unblock_server_daemon_for_one_step
			fi
			#handle assist-here request
			[ -e /sg2/tmp/.sg2d.client-rq.dir/assist-here ] && {
				log "Processing assist-here request from iSG ..."
				#ASSIST_HERE=`/usr/sbin/crm_mon -1 | grep rsc4k_Assistant | grep -Po '(?<=Started ).*'`
				#mihai : using lxc-ls command here to determine if Assistant is running in order to minimize HA-pverload caused by periodic call to crm_mon
				if /usr/bin/lxc-ls --running -f | grep -q Assistant ; then
					touch /sg2/opt/.iSG-assist-here
					log "Assistant is here"
					log "GW IPs to be routed inside Assistant:" `cat /sg2/tmp/.sg2d.client-rq.dir/assist-here`
					mv /sg2/tmp/.sg2d.client-rq.dir/assist-here /var/fsshr/host/iSG-duplex-local.ip
					chmod 644 /var/fsshr/host/iSG-duplex-local.ip
				else
					log "Assistant is not here, clear flag"
					#clear request message
					rm -f /sg2/tmp/.sg2d.client-rq.dir/assist-here
					#clear flag for iSG 
					rm -f /sg2/opt/.iSG-assist-here
					#clear IP list for AShg3550m in Assistant
					rm -f /var/fsshr/host/iSG-duplex-local.ip
				fi
			}
			#OSFOURK-22110
			#handle vpn-here request
			[ -e /sg2/tmp/.sg2d.client-rq.dir/vpn-here ] && {
				log "Processing vpn-here request from iSG ..."
				#VPN_HERE=`/usr/sbin/crm_mon -1 | grep rsc4k_vpn | grep -Po '(?<=Started ).*'`
				#mihai : using ps command to search for openvpn process in order to minimize HA-overload caused by periodic calling of crm_mon
				if ps -wweo cmd | grep openvpn | grep -q OS4K-InternalVpn-Server ; then
					log "VPN server is here, set the flag"
					touch /sg2/opt/.iSG-vpn-here
				else
					log "VPN server is not here, clear flag"
					#clear flag for iSG 
					rm -f /sg2/opt/.iSG-vpn-here
				fi
				#clear request message
				rm -f /sg2/tmp/.sg2d.client-rq.dir/vpn-here
			}
		done
        #tell inotifywait server to stop
        unblock_server_daemon_for_one_step stop_server
		while [ 1 ]; do
			lxc-ls -f | grep $SG2_LXC_NAME | grep -q -i run || break
		done
		ip link del isgintl 1>/dev/null 2>/dev/null
		exit 0
		;;
	#always keep _daemon_ part as last block in the script so that the bash is forced to read the script completely up to that part - reduces the side-effects on overwrite
	*)
        echo "Usage as service : service sg2d {start|stop|status|reload|restart}"
        echo "Usage for managing the $SG2_LXC_NAME : sg2d {enable|disable|console|configure <initialcfg.xml>|cleanup|backup <output-path>|restore <input-path>|check_network [xml-file]}"
        echo "Usage for $SG2_LXC_NAME RootFS operations : sg2d {deployrootfs <rootdir>:<vardir>|cleanrootfs <rootdir>:<vardir>}"
        exit 1
        ;;
esac
rc_exit
