#!/bin/bash

remoteCommand()
{
  ipaddress=$1
  cmd=$2
  #echo $cmd
  ssh -i /usr/lib/one/tm_commands/nfs/server vxadmin@$ipaddress "sudo $cmd" 2>/dev/null
}

verifyLock()
{
 hdPath=$1
 storagePath=${hdPath%/*}
 lenStoragePath=${#storagePath}
 lenHdpath=${#hdPath}
 lenhd=`expr $lenHdpath - $lenStoragePath`
 hdname=${hdPath:`expr $lenStoragePath + 1`:`expr $lenhd - 2`}
 ipaddress=$2
 cmd="ls "$storagePath"/. | grep "$hdname".lock | wc -l"
 #ssh root@192.168.123.101 "ls /mnt/storage/images/. | grep  testHd.lock | wc -l" 2>/dev/null
 remoteCommand $ipaddress "$cmd"
}

deleteLock()
{
 hdPath=$1
 storagePath=${hdPath%/*}
 lenStoragePath=${#storagePath}
 lenHdpath=${#hdPath}
 lenhd=`expr $lenHdpath - $lenStoragePath`
 hdname=${hdPath:`expr $lenStoragePath + 1`:`expr $lenhd - 2`}
 ipaddress=$2
 currentVmId=$3

 cmd="cat "$storagePath"/"$hdname".lock | grep vmname"
 lockVmName=`remoteCommand $ipaddress "$cmd"`
 lockVmId=${lockVmName#*-}

 #check weather vm exsists on compute node
 if [ "$currentVmId" = "$lockVmId" ]; then
 	cmd="cat "$storagePath"/"$hdname".lock | grep HostIp"
 	lockHostIpEntry=`remoteCommand $ipaddress "$cmd"`
 	lockHostIp=${lockHostIpEntry#*=}
 	sshReturnResult=`check_ssh $lockHostIp`
	sshResult=${sshReturnResult% -*}
 	if [ "$sshResult" = "SSH OK" ]; then
	     for (( i=1; i <= 30; i++ ))
	     do
		 cmd="ps -ef | grep kvm | grep one-"$lockVmId" |  wc -l"
                 result=`remoteCommand $lockHostIp "$cmd"`
	         if [ "$result" -eq "1" ];then
			break;
		 fi
                 sleep 30
	     done
	     if [ "$result" -eq "1" ];then
            	     cmd="rm "$storagePath"/"$hdname".lock"
       	    	     remoteCommand $lockHostIp "$cmd"
	     else
		     cmd="mv "$storagePath"/"$hdname".lock "$storagePath"/"$hdname".lock.stale"
       	     	     remoteCommand $lockHostIp "$cmd"
	     fi
	else
	     cmd="mv "$storagePath"/"$hdname".lock "$storagePath"/"$hdname".lock.stale"
       	     remoteCommand $ipaddress "$cmd"
        fi

 fi

 #check weather vm exsists on compute node :end
 #if [ "$currentVmId" = "$lockVmId" ]; then
 #     cmd="rm "$storagePath"/"$hdname".lock"
 #      remoteCommand $ipaddress "$cmd"
 #fi
}
createLock()
{
 #Get hardDisk name from $source_path
 #/mnt/storage/images/testHd0
 hdPath=$1
 storagePath=${hdPath%/*}
 lenStoragePath=${#storagePath}
 lenHdpath=${#hdPath}
 lenhd=`expr $lenHdpath - $lenStoragePath`
 hdname=${hdPath:`expr $lenStoragePath + 1`:`expr $lenhd - 2`}

 #Get Host address from DST_host
 ipaddress=$2

 #Get VMID from DST_Path
 #/var/lib/one//8/images

 dst_path=$3
 dstPathPart=${dst_path%/*}
 lenDstPathPart1=${#dstPathPart}
 dstPathPart=${dstPathPart%/*}
 lenDstPathPart2=${#dstPathPart}
 vmidPart=${dst_path:`expr $lenDstPathPart2 + 1`:`expr $lenDstPathPart1 - $lenDstPathPart2 - 1`}
 #this is done because of double slashes (//) in the path(As tomarrow it may be only one slash
 vmid=${vmidPart#/*}

 #Add metadata to lock file
 cmd="echo \"HostIp=$ipaddress \" >"$storagePath"/"$hdname".lock "
 remoteCommand $ipaddress "$cmd"
 cmd="echo \"hdname=$hdname\" >>"$storagePath"/"$hdname".lock "
 remoteCommand $ipaddress "$cmd"
 cmd="echo \"vmname=one-$vmid\" >>"$storagePath"/"$hdname".lock "
 remoteCommand $ipaddress "$cmd"
}

modifyLock()
{
 #/mnt/storage/images/testHd0
 hdPath=$1
 storagePath=${hdPath%/*}
 lenStoragePath=${#storagePath}
 lenHdpath=${#hdPath}
 lenhd=`expr $lenHdpath - $lenStoragePath`
 hdname=${hdPath:`expr $lenStoragePath + 1`:`expr $lenhd - 2`}

 
 #Get Host address from DST_host
 ipaddress=$2
 
 #Modify metadata of lock file
 lockFilePath="$storagePath/$hdname.lock"
 cmd="cat $lockFilePath | grep HostIp"
 oldHostIp=`remoteCommand $ipaddress "$cmd"`
 cmd="sed -i 's/$oldHostIp/HostIp=$ipaddress/g' $lockFilePath"
 remoteCommand $ipaddress "$cmd"
}

findStaleLock()
{
 hdPath=$1
 storagePath=${hdPath%/*}
 lenStoragePath=${#storagePath}
 lenHdpath=${#hdPath}
 lenhd=`expr $lenHdpath - $lenStoragePath`
 hdname=${hdPath:`expr $lenStoragePath + 1`:`expr $lenhd - 2`}
 ipaddress=$2
 cmd="ls "$storagePath"/. | grep "$hdname".lock.stale | wc -l"
 #ssh root@192.168.123.101 "ls /mnt/storage/images/. | grep  testHd.lock | wc -l" 2>/dev/null
 remoteCommand $ipaddress "$cmd"
}
verifyStaleLock()
{
 hdPath=$1
 storagePath=${hdPath%/*}
 lenStoragePath=${#storagePath}
 lenHdpath=${#hdPath}
 lenhd=`expr $lenHdpath - $lenStoragePath`
 hdname=${hdPath:`expr $lenStoragePath + 1`:`expr $lenhd - 2`}
 ipaddress=$2
 cmd="cat "$storagePath"/"$hdname".lock.stale | grep vmname"
 lockVmName=`remoteCommand $ipaddress "$cmd"`
 lockVmId=${lockVmName#*-}
 #check weather vm exsists on compute node
 cmd="cat "$storagePath"/"$hdname".lock.stale | grep HostIp"
 lockHostIpEntry=`remoteCommand $ipaddress "$cmd"`
 lockHostIp=${lockHostIpEntry#*=}
 sshReturnResult=`check_ssh $lockHostIp`
 sshResult=${sshReturnResult% -*}
 if [ "$sshResult" = "SSH OK" ]; then
         cmd="ps -ef | grep kvm | grep one-"$lockVmId" |  wc -l"
         result=`remoteCommand $lockHostIp "$cmd"`
         if [ "$result" -eq "1" ];then
                 cmd="rm "$storagePath"/"$hdname".lock.stale"
                 remoteCommand $lockHostIp "$cmd"
         else
                echo "fail"
         fi
 else
        echo "fail"

 fi
}

checkAndCreate()
{
SRC_PATH=$1
DST_HOST=$2
DST_DIR=$3

  echo $SRC_PATH | grep "/images/"
  if [ $? -eq 0 ]
  then
        lenSrcPath=${#SRC_PATH}
        hdnamePart=${SRC_PATH:`expr $lenSrcPath - 1`}
        log "hdnamepart = $hdnamePart"
        if [ "$hdnamePart" = "0" ]
        then
                lockval=`verifyLock $SRC_PATH $DST_HOST`
                log "lockvalue = $lockval"
                if [ "$lockval" -gt "0" ]
                then
                        stalelockval=`findStaleLock $SRC_PATH $DST_HOST`
                        log  "stalelockval=$stalelockval"
                        if [ "$stalelockval" -gt "0" ]
                        then
                                verifyStaleLock=`verifyStaleLock $SRC_PATH $DST_HOST $DST_DIR`
                                log "verifyStaleLock=$verifyStaleLock"
                                if [ "$verifyStaleLock" = "fail" ]
                                then
                                        echo "Disk is in use; Possible reason could be another instance of this server running" 1>&2
                                        exit 2
                                fi
                        else
                                echo "Disk is in use; Possible reason could be another instance of this server running" 1>&2
                                exit 2
                        fi
                fi
                createLock $SRC_PATH $DST_HOST $DST_DIR
        fi
  fi
}


if [ "$1" = "create" ]; then
        createLock $2 $3 $4
fi

if [ "$1" = "delete" ]; then
        deleteLock $2 $3 $4
fi

if [ "$1" = "verify" ]; then
        verifyLock $2 $3
fi

if [ "$1" = "modify" ]; then
        modifyLock $2 $3
fi

if [ "$1" = "verifyStaleLock" ]; then
        verifyStaleLock $2 $3 $4
fi

if [ "$1" = "checkAndCreate" ]; then
        checkAndCreate $2 $3 $4
fi

if [ "$1" = "findStaleLock" ]; then
        findStaleLock $2 $3
fi

