Subject: Shutdownskript funktioniert nur bei "aktivem

Transcription

Subject: Shutdownskript funktioniert nur bei "aktivem
Subject: Shutdownskript funktioniert nur bei "aktivem Fenster"
Posted by alex[1] on Sun, 10 Feb 2013 17:10:47 GMT
View Forum Message <> Reply to Message
Hallo,
es gibt schon nen ältere Thread mit meinem Shutdownproblem.
Zwischenzeitlich hats mal funktioniert, mal nicht....habs aber nicht
verstanden was das Problem ist.
Situation: Eisfair1 auf einem VMware ESXi5. Backup des ESXi will den
Eisfair runterfahren, Skript startet auch den "shutdown" laut
Ereignisprotokoll des ESXi. Manchmal gehts, manchmal nicht.... Nun hab
ich herausgefunden, dass es immer geht, wenn das Consolenfenster des
Eisfair offen ist und auch "aktiv". Wenn das Fenster keinen Cursor hat
oder geschlossen ist, dann wird das Skript nicht ausgeführt.... Den
Effekt blick ich nicht, bin mir aber sehr sicher, dass hier einige
sofort ne Erklärung dafür haben:-)
(Vmware-Tools sind installiert. Das network-Skript wurde nicht gefunden,
weshalb ich dort als network-Skript das Skript /etc/init.d/halt des
Eisfair hinkopiert hab.)
Gruß
Alex
Subject: Re: Shutdownskript funktioniert nur bei "aktivem Fenster"
Posted by Thomas Bork on Sun, 10 Feb 2013 17:27:29 GMT
View Forum Message <> Reply to Message
Am 10.02.2013 18:10, schrieb Alex Busam:
> Situation: Eisfair1 auf einem VMware ESXi5. Backup des ESXi will den
> Eisfair runterfahren, Skript startet auch den "shutdown" laut
> Ereignisprotokoll des ESXi.
Genauer bitte, was _genau_ wird ausgeführt? Welcher Befehl, welches
Skript von welchem User mit welchen Rechten?
>
>
>
>
>
>
Manchmal gehts, manchmal nicht.... Nun hab
ich herausgefunden, dass es immer geht, wenn das Consolenfenster des
Eisfair offen ist und auch "aktiv". Wenn das Fenster keinen Cursor hat
oder geschlossen ist, dann wird das Skript nicht ausgeführt.... Den
Effekt blick ich nicht, bin mir aber sehr sicher, dass hier einige
sofort ne Erklärung dafür haben:-)
Was für ein Fenster _genau_ ist _wo_ offen, was ist in dem Fenster
_genau_ geöffnet, welches Skript _genau_?
> (Vmware-Tools sind installiert. Das network-Skript wurde nicht gefunden,
> weshalb ich dort als network-Skript das Skript /etc/init.d/halt des
Page 1 of 40 ---- Generated from
net(t)forum
> Eisfair hinkopiert hab.)
Tut mir leid, raten ist nicht meine Stärke.
-der tom
[eisfair-team]
Subject: Re: Shutdownskript funktioniert nur bei "aktivem Fenster"
Posted by alex[1] on Sun, 10 Feb 2013 19:04:30 GMT
View Forum Message <> Reply to Message
Am 10.02.2013 18:27, schrieb Thomas Bork:
> Am 10.02.2013 18:10, schrieb Alex Busam:
>
>> Situation: Eisfair1 auf einem VMware ESXi5. Backup des ESXi will den
>> Eisfair runterfahren, Skript startet auch den "shutdown" laut
>> Ereignisprotokoll des ESXi.
>
> Genauer bitte, was _genau_ wird ausgeführt? Welcher Befehl, welches
> Skript von welchem User mit welchen Rechten?
Auf der Console des ESXi als user root wird das Skript "ghettoVCB"
gestartet. Es ist so konfiguriert, dass es ein shutdown auslöst und die
VM Eisfair auf ein anderes datastore kopiert.
Rechte? root
>
>> Manchmal gehts, manchmal nicht.... Nun hab
>> ich herausgefunden, dass es immer geht, wenn das Consolenfenster des
>> Eisfair offen ist und auch "aktiv". Wenn das Fenster keinen Cursor hat
>> oder geschlossen ist, dann wird das Skript nicht ausgeführt.... Den
>> Effekt blick ich nicht, bin mir aber sehr sicher, dass hier einige
>> sofort ne Erklärung dafür haben:-)
>
> Was für ein Fenster _genau_ ist _wo_ offen, was ist in dem Fenster
> _genau_ geöffnet, welches Skript _genau_?
Consolenfenster auf dem vSphere Client. Entsprechend einem
"Hardware-Monitor". Dort bin ich als User root auf dem eisfair eingeloggt.
>
>> (Vmware-Tools sind installiert. Das network-Skript wurde nicht gefunden,
>> weshalb ich dort als network-Skript das Skript /etc/init.d/halt des
>> Eisfair hinkopiert hab.)
>
> Tut mir leid, raten ist nicht meine Stärke.
>
Das halt-Skript fährt ja auf der Console des Eisfair ausgeführt
normalerweise den Server herunter. Manuell tut er das auch.
GhettoVCB stoßt das Starten dieses Skripts vom Host aus an. Das Skript
wird jedoch nur ausgeführt, wenn ich am Eisfair eingeloggt bin und diese
Console "aktiv" ist.
Page 2 of 40 ---- Generated from
net(t)forum
Verstehe das verhalten nicht. Muss ich diesem halt-Skript was mitgeben,
damit es ohne eingeloggten User läuft?
Subject: Re: Shutdownskript funktioniert nur bei "aktivem Fenster"
Posted by Thomas Bork on Sun, 10 Feb 2013 19:39:18 GMT
View Forum Message <> Reply to Message
Am 10.02.2013 20:04, schrieb Alex Busam:
>
>
>
>
Auf der Console des ESXi als user root wird das Skript "ghettoVCB"
gestartet. Es ist so konfiguriert, dass es ein shutdown auslöst und die
VM Eisfair auf ein anderes datastore kopiert.
Rechte? root
Und der genaue Inhalt des Skriptes?
>> Was für ein Fenster _genau_ ist _wo_ offen, was ist in dem Fenster
>> _genau_ geöffnet, welches Skript _genau_?
> Consolenfenster auf dem vSphere Client. Entsprechend einem
> "Hardware-Monitor".
Darunter kann ich mir absolut _nichts_ vorstellen. Wie greift der
vSphere Client _genau_ auf eisfair zu und setzt dabei Befehle ab?
> Das halt-Skript fährt ja auf der Console des Eisfair ausgeführt
> normalerweise den Server herunter. Manuell tut er das auch.
So soll es sein.
>
>
>
>
>
GhettoVCB stoßt das Starten dieses Skripts vom Host aus an. Das Skript
wird jedoch nur ausgeführt, wenn ich am Eisfair eingeloggt bin und diese
Console "aktiv" ist.
Verstehe das verhalten nicht. Muss ich diesem halt-Skript was mitgeben,
damit es ohne eingeloggten User läuft?
Da Du uns die Unterschiede zwischen den vom vSphere Client und lokal
abgesetzten Befehlen nicht darstellst, fällt Hilfe immer noch schwer.
-der tom
[eisfair-team]
Subject: Re: Shutdownskript funktioniert nur bei "aktivem Fenster"
Posted by alex[1] on Sun, 10 Feb 2013 20:08:09 GMT
View Forum Message <> Reply to Message
> Und der genaue Inhalt des Skriptes?
siehe unten
Page 3 of 40 ---- Generated from
net(t)forum
>
>>> Was für ein Fenster _genau_ ist _wo_ offen, was ist in dem Fenster
>>> _genau_ geöffnet, welches Skript _genau_?
>> Consolenfenster auf dem vSphere Client. Entsprechend einem
>> "Hardware-Monitor".
>
> Darunter kann ich mir absolut _nichts_ vorstellen. Wie greift der
> vSphere Client _genau_ auf eisfair zu und setzt dabei Befehle ab?
Host greift über die auf dem eisfair installierten vmware-tools zu.
Nähere Details kenne ich nicht.
>
>
> Da Du uns die Unterschiede zwischen den vom vSphere Client und lokal
> abgesetzten Befehlen nicht darstellst, fällt Hilfe immer noch schwer.
>
Du hast genug Supporterfahrung, um zu wissen, dass ich Dir hier nichts
vorenthalte, sondern dass meine Kenntnisse begrenzt sind.
Wenn ich diese Frage beantworten könnte, dann bräuchte ich sie hier
nicht zu stellen.
../ghettoVCB.sh -f myeis.txt -c conf_myeis_DS5_alle -l
log/g_myeis_DS5_alle.log
# Author: William Lam
# Created Date: 11/17/2008
# http://www.virtuallyghetto.com/
# http://communities.vmware.com/docs/DOC-8760
##################################################################
# directory that all VM backups should go (e.g.
/vmfs/volumes/SAN_LUN1/mybackupdir)
#VM_BACKUP_VOLUME=/vmfs/volumes/DS5/BACKUP_VM
VM_BACKUP_VOLUME=
# Format output of VMDK backup
# zeroedthick
# 2gbsparse
# thin
# eagerzeroedthick
DISK_BACKUP_FORMAT=2gbsparse
# Number of backups for a given VM before deleting
VM_BACKUP_ROTATION_COUNT=3
# Shutdown guestOS prior to running backups and power them back on
afterwards
# This feature assumes VMware Tools are installed, else they will not
power down and loop forever
# 1=on, 0 =off
POWER_VM_DOWN_BEFORE_BACKUP=0
Page 4 of 40 ---- Generated from
net(t)forum
# enable shutdown code 1=on, 0 = off
ENABLE_HARD_POWER_OFF=0
# if the above flag "ENABLE_HARD_POWER_OFF "is set to 1, then will look
at this flag which is the # of iterations
# the script will wait before executing a hard power off, this will be a
multiple of 60seconds
# (e.g) = 3, which means this will wait up to 180seconds (3min) before
it just powers off the VM
ITER_TO_WAIT_SHUTDOWN=3
# Number of iterations the script will wait before giving up on powering
down the VM and ignoring it for backup
# this will be a multiple of 60 (e.g) = 5, which means this will wait up
to 300secs (5min) before it gives up
POWER_DOWN_TIMEOUT=5
# enable compression with gzip+tar 1=on, 0=off
ENABLE_COMPRESSION=0
############################
####### NEW PARAMS #########
############################
# Include VMs memory when taking snapshot
VM_SNAPSHOT_MEMORY=0
# Quiesce VM when taking snapshot (requires VMware Tools to be installed)
VM_SNAPSHOT_QUIESCE=0
##########################################################
# NON-PERSISTENT NFS-BACKUP ONLY
#
# ENABLE NON PERSISTENT NFS BACKUP 1=on, 0=off
ENABLE_NON_PERSISTENT_NFS=0
# umount NFS datastore after backup is complete 1=yes, 0=no
UNMOUNT_NFS=0
# IP Address of NFS Server
NFS_SERVER=
# Path of exported folder residing on NFS Server (e.g. /some/mount/point )
NFS_MOUNT=/
# Non-persistent NFS datastore display name of choice
NFS_LOCAL_NAME=DS6
# Name of backup directory for VMs residing on the NFS volume
Page 5 of 40 ---- Generated from
net(t)forum
NFS_VM_BACKUP_DIR=backup_ESXi
############################
######### EMAIL ############
############################
# Email debug 1=yes, 0=no
EMAIL_DEBUG=0
# Email log 1=yes, 0=no
EMAIL_LOG=0
# Email Delay Interval from NC (netcat) - default 1
EMAIL_DELAY_INTERVAL=1
# Email SMTP server
EMAIL_SERVER=10.1.1.55
# Email SMTP server port
EMAIL_SERVER_PORT=25
# Email FROM
EMAIL_FROM=ESXi@d.de
# Email RCPT
EMAIL_TO=alex@d.de
########################## DO NOT MODIFY PAST THIS LINE
##########################
# RSYNC LINK 1=yes, 0 = no
RSYNC_LINK=0
LOG_LEVEL="info"
VMDK_FILES_TO_BACKUP="all"
# default 15min timeout
SNAPSHOT_TIMEOUT=15
LAST_MODIFIED_DATE=2011_11_19
VERSION=1
VERSION_STRING=${LAST_MODIFIED_DATE}_${VERSION}
# Directory naming convention for backup rotations (please ensure there
are no spaces!)
VM_BACKUP_DIR_NAMING_CONVENTION="$(date +%F_%H-%M-%S)"
printUsage() {
echo
" ########################################################################
####### "
echo "#"
echo "# ghettoVCB for ESX/ESXi 3.5, 4.x+ and 5.0"
echo "# Author: William Lam"
Page 6 of 40 ---- Generated from
net(t)forum
echo "# http://www.virtuallyghetto.com/"
echo "# Documentation: http://communities.vmware.com/docs/DOC-8760"
echo "# Created: 11/17/2008"
echo "# Last modified: ${LAST_MODIFIED_DATE} Version ${VERSION}"
echo "#"
echo
" ########################################################################
####### "
echo
echo "Usage: $0 -f [VM_BACKUP_UP_LIST] -c [VM_CONFIG_DIR] -l
[LOG_FILE] -d [DEBUG_LEVEL] -g [GLOBAL_CONF] -e [VM_EXCLUSION_LIST]"
echo
echo "OPTIONS:"
echo " -a Backup all VMs on host"
echo " -f List of VMs to backup"
echo " -c VM configuration directory for VM backups"
echo " -g Path to global ghettoVCB configuration file"
echo " -l File to output logging"
echo " -d Debug level [info|debug|dryrun] (default: info)"
echo
echo "(e.g.)"
echo -e "\nBackup VMs stored in a list"
echo -e "\t$0 -f vms_to_backup"
echo -e "\nBackup all VMs residing on this host"
echo -e "\t$0 -a"
echo -e "\nBackup all VMs residing on this host except for the VMs in
the exclusion list"
echo -e "\t$0 -a -e vm_exclusion_list"
echo -e "\nBackup VMs based on specific configuration located in directory"
echo -e "\t$0 -f vms_to_backup -c vm_backup_configs"
echo -e "\nBackup VMs using global ghettoVCB configuration file"
echo -e "\t$0 -f vms_to_backup -g /global/ghettoVCB.conf"
echo -e "\nOutput will log to /tmp/ghettoVCB.log (consider
logging to local or remote datastore to persist logs)"
echo -e "\t$0 -f vms_to_backup -l
/vmfs/volume/local-storage/ghettoVCB.log"
echo -e "\nDry run (no backup will take place)"
echo -e "\t$0 -f vms_to_backup -d dryrun"
echo
exit 1
}
logger() {
LOG_TYPE=$1
MSG=$2
if [[ "${LOG_LEVEL}" == "debug" ]] && [[ "${LOG_TYPE}" == "debug" ]] ||
[[ "${LOG_TYPE}" == "info" ]] || [[ "${LOG_TYPE}" == "dryrun" ]]; then
TIME=$(date +%F" "%H:%M:%S)
if [ "${LOG_TO_STDOUT}" -eq 1 ]; then
echo -e "${TIME} -- ${LOG_TYPE}: ${MSG}"
fi
Page 7 of 40 ---- Generated from
net(t)forum
if [ -n "${LOG_OUTPUT}" ]; then
echo -e "${TIME} -- ${LOG_TYPE}: ${MSG}" >>
"${LOG_OUTPUT}"
fi
if [ "${EMAIL_LOG}" -eq 1 ]; then
echo -ne "${TIME} -- ${LOG_TYPE}: ${MSG}\r\n" >> "${EMAIL_LOG_OUTPUT}"
fi
fi
}
sanityCheck() {
NUM_OF_ARGS=$1
if [ "${USE_GLOBAL_CONF}" -eq 1 ]; then
reConfigureGhettoVCBConfiguration "${GLOBAL_CONF}"
fi
#always log to STDOUT, use "> /dev/null" to ignore output
LOG_TO_STDOUT=1
#if no logfile then provide default logfile in /tmp
if [ -z "${LOG_OUTPUT}" ]; then
LOG_OUTPUT="/tmp/ghettoVCB-$(date +%F_%H-%M-%S).log"
echo "Logging output to \"${LOG_OUTPUT}\" ..."
fi
touch "${LOG_OUTPUT}"
# REDIRECT is used by the "tail" trick, use REDIRECT=/dev/null
to redirect vmkfstool to STDOUT only
REDIRECT=${LOG_OUTPUT}
if [[ ${NUM_OF_ARGS} -lt 1 ]] || [[ ${NUM_OF_ARGS} -gt 12 ]]; then
logger "info" "ERROR: Incorrect number of arguments!"
printUsage
fi
if [[ ! -f "${VM_FILE}" ]] && [[ "${USE_VM_CONF}" -eq 0 ]] && [[
"${BACKUP_ALL_VMS}" -eq 0 ]]; then
logger "info" "ERROR: \"${VM_FILE}\" is not valid VM input file!"
printUsage
fi
if [[ ! -f "${VM_EXCLUSION_FILE}" ]] && [[ "${EXCLUDE_SOME_VMS}" -eq 1
]]; then
logger "info" "ERROR: \"${VM_EXCLUSION_FILE}\" is not valid VM
exclusion input file!"
printUsage
fi
if [[ ! -d "${CONFIG_DIR}" ]] && [[ "${USE_VM_CONF}" -eq 1 ]]; then
logger "info" "ERROR: \"${CONFIG_DIR}\" is not valid directory!"
printUsage
Page 8 of 40 ---- Generated from
net(t)forum
fi
if [[ ! -f "${GLOBAL_CONF}" ]] && [[ "${USE_GLOBAL_CONF}" -eq 1 ]]; then
logger "info" "ERROR: \"${GLOBAL_CONF}\" is not valid global
configuration file!"
printUsage
fi
if [ -f /usr/bin/vmware-vim-cmd ]; then
VMWARE_CMD=/usr/bin/vmware-vim-cmd
VMKFSTOOLS_CMD=/usr/sbin/vmkfstools
elif [ -f /bin/vim-cmd ]; then
VMWARE_CMD=/bin/vim-cmd
VMKFSTOOLS_CMD=/sbin/vmkfstools
else
logger "info" "ERROR: Unable to locate *vimsh*! You're
not running ESX(i) 3.5+, 4.x+ or 5.0!"
echo "ERROR: Unable to locate *vimsh*! You're not
running ESX(i) 3.5+, 4.x+ or 5.0!"
exit 1
fi
ESX_VERSION=$(vmware -v | awk '{print $3}')
if [[ "${ESX_VERSION}" == "5.0.0" ]]; then
VER=5
elif [[ "${ESX_VERSION}" == "4.0.0" ]] || [[ "${ESX_VERSION}"
== "4.1.0" ]]; then
VER=4
else
ESX_VERSION=$(vmware -v | awk '{print $4}')
if [[ "${ESX_VERSION}" == "3.5.0" ]] || [[
"${ESX_VERSION}" == "3i" ]]; then
VER=3
else
echo "You're not running ESX(i) 3.5, 4.x, 5.x!"
exit 1
fi
fi
NEW_VIMCMD_SNAPSHOT="no"
${VMWARE_CMD} vmsvc/snapshot.remove | grep "snapshotId" > /dev/null 2>&1
if [ $? -eq 0 ]; then
NEW_VIMCMD_SNAPSHOT="yes"
fi
if [[ "${EMAIL_LOG}" -eq 1 ]] && [[ -f /usr/bin/nc ]] || [[ -f /bin/nc
]]; then
if [ -f /usr/bin/nc ]; then
NC_BIN=/usr/bin/nc
elif [ -f /bin/nc ]; then
NC_BIN=/bin/nc
fi
Page 9 of 40 ---- Generated from
net(t)forum
else
EMAIL_LOG=0
fi
if [ ! $(whoami) == "root" ]; then
logger "info" "This script needs to be executed by
\"root\"!"
echo "ERROR: This script needs to be executed by \"root\"!"
exit 1
fi
}
startTimer() {
START_TIME=$(date)
S_TIME=$(date +%s)
}
endTimer() {
END_TIME=$(date)
E_TIME=$(date +%s)
DURATION=$(echo $((E_TIME - S_TIME)))
#calculate overall completion time
if [ ${DURATION} -le 60 ]; then
logger "info" "Backup Duration: ${DURATION} Seconds"
else
logger "info" "Backup Duration: $(awk 'BEGIN{ printf
"%.2f\n", '${DURATION}'/60}') Minutes"
fi
}
captureDefaultConfigurations() {
DEFAULT_VM_BACKUP_VOLUME="${VM_BACKUP_VOLUME}"
DEFAULT_DISK_BACKUP_FORMAT="${DISK_BACKUP_FORMAT}"
DEFAULT_VM_BACKUP_ROTATION_COUNT="${VM_BACKUP_ROTATION_COUNT}"
DEFAULT_POWER_VM_DOWN_BEFORE_BACKUP="${POWER_VM_DOWN_BEFORE_B
ACKUP}"
DEFAULT_ENABLE_HARD_POWER_OFF="${ENABLE_HARD_POWER_OFF}"
DEFAULT_ITER_TO_WAIT_SHUTDOWN="${ITER_TO_WAIT_SHUTDOWN}"
DEFAULT_POWER_DOWN_TIMEOUT="${POWER_DOWN_TIMEOUT}"
DEFAULT_SNAPSHOT_TIMEOUT="${SNAPSHOT_TIMEOUT}"
DEFAULT_ENABLE_COMPRESSION="${ENABLE_COMPRESSION}"
DEFAULT_VM_SNAPSHOT_MEMORY="${VM_SNAPSHOT_MEMORY}"
DEFAULT_VM_SNAPSHOT_QUIESCE="${VM_SNAPSHOT_QUIESCE}"
DEFAULT_VMDK_FILES_TO_BACKUP="${VMDK_FILES_TO_BACKUP}"
DEFAULT_EMAIL_LOG="${EMAIL_LOG}"
DEFAULT_EMAIL_DEBUG="${EMAIL_DEBUG}"
}
useDefaultConfigurations() {
VM_BACKUP_VOLUME="${DEFAULT_VM_BACKUP_VOLUME}"
DISK_BACKUP_FORMAT="${DEFAULT_DISK_BACKUP_FORMAT}"
Page 10 of 40 ---- Generated from
net(t)forum
VM_BACKUP_ROTATION_COUNT="${DEFAULT_VM_BACKUP_ROTATION_COUNT}"
POWER_VM_DOWN_BEFORE_BACKUP="${DEFAULT_POWER_VM_DOWN_BEFORE_B
ACKUP}"
ENABLE_HARD_POWER_OFF="${DEFAULT_ENABLE_HARD_POWER_OFF}"
ITER_TO_WAIT_SHUTDOWN="${DEFAULT_ITER_TO_WAIT_SHUTDOWN}"
POWER_DOWN_TIMEOUT="${DEFAULT_POWER_DOWN_TIMEOUT}"
SNAPSHOT_TIMEOUT="${DEFAULT_SNAPSHOT_TIMEOUT}"
ENABLE_COMPRESSION="${DEFAULT_ENABLE_COMPRESSION}"
VM_SNAPSHOT_MEMORY="${DEFAULT_VM_SNAPSHOT_MEMORY}"
VM_SNAPSHOT_QUIESCE="${DEFAULT_VM_SNAPSHOT_QUIESCE}"
VMDK_FILES_TO_BACKUP="all"
EMAIL_LOG=0
EMAIL_DEBUG=0
}
reConfigureGhettoVCBConfiguration() {
GLOBAL_CONF=$1
if [ -f "${GLOBAL_CONF}" ]; then
. "${GLOBAL_CONF}"
else
useDefaultConfigurations
fi
}
reConfigureBackupParam() {
VM=$1
if [ -e "${CONFIG_DIR}/${VM}" ]; then
logger "info" "CONFIG - USING CONFIGURATION FILE =
${CONFIG_DIR}/${VM}"
. "${CONFIG_DIR}/${VM}"
else
useDefaultConfigurations
fi
}
dumpHostInfo() {
VERSION=$(vmware -v)
logger "debug" "HOST VERSION: ${VERSION}"
echo ${VERSION} | grep "Server 3i" > /dev/null 2>&1
if [ $? -eq 1 ]; then
logger "debug" "HOST LEVEL: $(vmware -l)"
fi
logger "debug" "HOSTNAME: $(hostname)\n"
}
findVMDK() {
VMDK_TO_SEARCH_FOR=$1
#if [ "${USE_VM_CONF}" -eq 1 ]; then
logger "debug" "findVMDK() - Searching for VMDK:
Page 11 of 40 ---- Generated from
net(t)forum
\"${VMDK_TO_SEARCH_FOR}\" to backup"
OLD_IFS2="${IFS}"
IFS=","
for k in ${VMDK_FILES_TO_BACKUP}
do
VMDK_FILE=$(echo $k | sed -e
's/^[[:blank:]]*//;s/[[:blank:]]*$//')
if [ "${VMDK_FILE}" == "${VMDK_TO_SEARCH_FOR}" ]; then
logger "debug" "findVMDK() - Found VMDK! - \"${VMDK_TO_SEARCH_FOR}\"
to backup"
isVMDKFound=1
fi
done
IFS="${OLD_IFS2}"
#fi
}
getVMDKs() {
#get all VMDKs listed in .vmx file
VMDKS_FOUND=$(grep -iE '(scsi|ide)' "${VMX_PATH}" | grep -i
fileName | awk -F " " '{print $1}')
TMP_IFS=${IFS}
IFS=${ORIG_IFS}
#loop through each disk and verify that it's currently present
and create array of valid VMDKS
for DISK in ${VMDKS_FOUND};
do
#extract the SCSI ID and use it to check for valid vmdk disk
SCSI_ID=$(echo ${DISK%%.*})
grep -i "${SCSI_ID}.present" "${VMX_PATH}" | grep -i
"true" > /dev/null 2>&1
#if valid, then we use the vmdk file
if [ $? -eq 0 ]; then
#verify disk is not independent
grep -i "${SCSI_ID}.mode" "${VMX_PATH}" | grep -i "independent" >
/dev/null 2>&1
if [ $? -eq 1 ]; then
grep -i "${SCSI_ID}.deviceType" "${VMX_PATH}" | grep
-i "scsi-hardDisk" > /dev/null 2>&1
#if we find the device type is of scsi-disk,
then proceed
if [ $? -eq 0 ]; then
DISK=$(grep -i ${SCSI_ID}.fileName
"${VMX_PATH}" | awk -F "\"" '{print $2}')
echo "${DISK}" | grep "\/vmfs\/volumes" > /dev/null 2>&1
if [ $? -eq 0 ]; then
DISK_SIZE_IN_SECTORS=$(cat "${DISK}" | grep "VMFS" | grep ".vmdk"
| awk '{print $2}')
else
DISK_SIZE_IN_SECTORS=$(cat "${VMX_DIR}/${DISK}" | grep "VMFS" |
Page 12 of 40 ---- Generated from
net(t)forum
grep ".vmdk" | awk '{print $2}')
fi
DISK_SIZE=$(echo "${DISK_SIZE_IN_SECTORS}" | awk '{printf
"%.0f\n",$1*512/1024/1024/1024}')
VMDKS="${DISK}###${DISK_SIZE}:${VMDKS}"
TOTAL_VM_SIZE=$((TOTAL_VM_SIZE+DISK_SIZE))
else
#if the deviceType is NULL for IDE
which it is, thanks for the inconsistency VMware
#we'll do one more level of
verification by checking to see if an ext. of .vmdk exists
#since we can not rely on the
deviceType showing "ide-hardDisk"
grep -i ${SCSI_ID}.fileName
"${VMX_PATH}" | grep -i ".vmdk" > /dev/null 2>&1
if [ $? -eq 0 ]; then
DISK=$(grep -i ${SCSI_ID}.fileName
"${VMX_PATH}" | awk -F "\"" '{print $2}')
echo "${DISK}" | grep "\/vmfs\/volumes" > /dev/null 2>&1
if [ $? -eq 0 ]; then
DISK_SIZE_IN_SECTORS=$(cat "${DISK}" | grep "VMFS" | grep ".vmdk"
| awk '{print $2}')
else
DISK_SIZE_IN_SECTORS=$(cat "${VMX_DIR}/${DISK}" | grep "VMFS" |
grep ".vmdk" | awk '{print $2}')
fi
DISK_SIZE=$(echo "${DISK_SIZE_IN_SECTORS}" | awk '{printf
"%.0f\n",$1*512/1024/1024/1024}')
VMDKS="${DISK}###${DISK_SIZE}:${VMDKS}"
TOTAL_VM_SIZE=$((TOTAL_VM_SIZE_IN+DISK_SIZE))
fi
fi
else
#independent disks are not affected by snapshots, hence they can not
be backed up
DISK=$(grep -i ${SCSI_ID}.fileName "${VMX_PATH}" | awk -F "\""
'{print $2}')
echo "${DISK}" | grep "\/vmfs\/volumes" > /dev/null 2>&1
if [ $? -eq 0 ]; then
DISK_SIZE_IN_SECTORS=$(cat "${DISK}" | grep "VMFS" | grep ".vmdk" |
awk '{print $2}')
else
DISK_SIZE_IN_SECTORS=$(cat "${VMX_DIR}/${DISK}" | grep "VMFS" |
grep ".vmdk" | awk '{print $2}')
fi
DISK_SIZE=$(echo "${DISK_SIZE_IN_SECTORS}" | awk '{printf
"%.0f\n",$1*512/1024/1024/1024}')
INDEP_VMDKS="${DISK}###${DISK_SIZE}:${INDEP_VMDKS}"
fi
fi
done
Page 13 of 40 ---- Generated from
net(t)forum
IFS=${TMP_IFS}
logger "debug" "getVMDKs() - ${VMDKS}"
}
dumpVMConfigurations() {
logger "info" "CONFIG - VERSION = ${VERSION_STRING}"
logger "info" "CONFIG - GHETTOVCB_PID = ${GHETTOVCB_PID}"
logger "info" "CONFIG - VM_BACKUP_VOLUME = ${VM_BACKUP_VOLUME}"
if [ "${ENABLE_NON_PERSISTENT_NFS}" -eq 1 ]; then
logger "info" "CONFIG - ENABLE_NON_PERSISTENT_NFS =
${ENABLE_NON_PERSISTENT_NFS}"
logger "info" "CONFIG - UNMOUNT_NFS = ${UNMOUNT_NFS}"
logger "info" "CONFIG - NFS_SERVER = ${NFS_SERVER}"
logger "info" "CONFIG - NFS_MOUNT = ${NFS_MOUNT}"
fi
logger "info" "CONFIG - VM_BACKUP_ROTATION_COUNT =
${VM_BACKUP_ROTATION_COUNT}"
logger "info" "CONFIG - VM_BACKUP_DIR_NAMING_CONVENTION =
${VM_BACKUP_DIR_NAMING_CONVENTION}"
logger "info" "CONFIG - DISK_BACKUP_FORMAT = ${DISK_BACKUP_FORMAT}"
logger "info" "CONFIG - POWER_VM_DOWN_BEFORE_BACKUP =
${POWER_VM_DOWN_BEFORE_BACKUP}"
logger "info" "CONFIG - ENABLE_HARD_POWER_OFF =
${ENABLE_HARD_POWER_OFF}"
logger "info" "CONFIG - ITER_TO_WAIT_SHUTDOWN = ${ITER_TO_WAIT_SHUTDOWN}"
logger "info" "CONFIG - POWER_DOWN_TIMEOUT = ${POWER_DOWN_TIMEOUT}"
logger "info" "CONFIG - SNAPSHOT_TIMEOUT = ${SNAPSHOT_TIMEOUT}"
logger "info" "CONFIG - LOG_LEVEL = ${LOG_LEVEL}"
logger "info" "CONFIG - BACKUP_LOG_OUTPUT = ${LOG_OUTPUT}"
logger "info" "CONFIG - VM_SNAPSHOT_MEMORY = ${VM_SNAPSHOT_MEMORY}"
logger "info" "CONFIG - VM_SNAPSHOT_QUIESCE =
${VM_SNAPSHOT_QUIESCE}"
logger "info" "CONFIG - VMDK_FILES_TO_BACKUP =
${VMDK_FILES_TO_BACKUP}"
logger "info" "CONFIG - EMAIL_LOG = ${EMAIL_LOG}"
if [ "${EMAIL_LOG}" -eq 1 ]; then
logger "info" "CONFIG - EMAIL_DEBUG = ${EMAIL_DEBUG}"
logger "info" "CONFIG - EMAIL_SERVER = ${EMAIL_SERVER}"
logger "info" "CONFIG - EMAIL_SERVER_PORT = ${EMAIL_SERVER_PORT}"
logger "info" "CONFIG - EMAIL_DELAY_INTERVAL = ${EMAIL_DELAY_INTERVAL}"
logger "info" "CONFIG - EMAIL_FROM = ${EMAIL_FROM}"
logger "info" "CONFIG - EMAIL_TO = ${EMAIL_TO}"
fi
logger "info" ""
}
checkVMBackupRotation() {
local BACKUP_DIR_PATH=$1
local VM_TO_SEARCH_FOR=$2
#default rotation if variable is not defined
if [ -z ${VM_BACKUP_ROTATION_COUNT} ]; then
Page 14 of 40 ---- Generated from
net(t)forum
VM_BACKUP_ROTATION_COUNT=1
fi
LIST_BACKUPS=$(ls -t "${BACKUP_DIR_PATH}" | grep
" ${VM_TO_SEARCH_FOR}-[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}_[0-9]\{2\}-[0-9]\{2 \}-[0-9]\{2\} ")
BACKUPS_TO_KEEP=$(ls -t "${BACKUP_DIR_PATH}" | grep
" ${VM_TO_SEARCH_FOR}-[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}_[0-9]\{2\}-[0-9]\{2 \}-[0-9]\{2\} "
| head -"${VM_BACKUP_ROTATION_COUNT}")
ORIG_IFS=${IFS}
IFS='
'
for i in ${LIST_BACKUPS};
do
FOUND=0
for j in ${BACKUPS_TO_KEEP};
do
if [ $i == $j ]; then
FOUND=1
fi
done
if [ $FOUND -eq 0 ]; then
logger "debug" "Removing $BACKUP_DIR_PATH/$i"
rm -rf "$BACKUP_DIR_PATH/$i"
#NFS I/O error handling hack
if [ $? -ne 0 ]; then
NFS_IO_HACK_COUNTER=0
NFS_IO_HACK_STATUS=0
NFS_IO_HACK_FILECHECK="$BACKUP_DIR_PATH/nfs_io.check"
while [ "${NFS_IO_HACK_STATUS}" -eq 0 -a "${NFS_IO_HACK_COUNTER}"
-lt 60 ];
do
sleep 1
NFS_IO_HACK_COUNTER=$((NFS_IO_HACK_COUNTER+1))
touch "${NFS_IO_HACK_FILECHECK}"
if [ $? -eq 0 ]; then
NFS_IO_HACK_STATUS=1
fi
done
rm -rf "${NFS_IO_HACK_FILECHECK}"
if [ "${NFS_IO_HACK_STATUS}" -eq 1 ]; then
logger "info" "Slept ${NFS_IO_HACK_COUNTER} seconds to work around
NFS I/O error"
else
logger "info" "Slept ${NFS_IO_HACK_COUNTER} seconds but failed work
around for NFS I/O error"
Page 15 of 40 ---- Generated from
net(t)forum
fi
fi
fi
done
IFS=${ORIG_IFS}
}
storageInfo() {
SECTION=$1
#SOURCE DATASTORE
SRC_DATASTORE_CAPACITY=$($VMWARE_CMD hostsvc/datastore/info
"${VMFS_VOLUME}" | grep -i "capacity" | awk '{print $3}' | sed 's/,//g')
SRC_DATASTORE_FREE=$($VMWARE_CMD hostsvc/datastore/info
"${VMFS_VOLUME}" | grep -i "freespace" | awk '{print $3}' | sed 's/,//g')
SRC_DATASTORE_BLOCKSIZE=$($VMWARE_CMD hostsvc/datastore/info
"${VMFS_VOLUME}" | grep -i blockSizeMb | awk '{print $3}' | sed 's/,//g')
if [ -z ${SRC_DATASTORE_BLOCKSIZE} ]; then
SRC_DATASTORE_BLOCKSIZE="NA"
SRC_DATASTORE_MAX_FILE_SIZE="NA"
else
case ${SRC_DATASTORE_BLOCKSIZE} in
1)SRC_DATASTORE_MAX_FILE_SIZE="256 GB";;
2)SRC_DATASTORE_MAX_FILE_SIZE="512 GB";;
4)SRC_DATASTORE_MAX_FILE_SIZE="1024 GB";;
8)SRC_DATASTORE_MAX_FILE_SIZE="2048 GB";;
esac
fi
SRC_DATASTORE_CAPACITY_GB=$(echo "${SRC_DATASTORE_CAPACITY}" |
awk '{printf "%.1f\n",$1/1024/1024/1024}')
SRC_DATASTORE_FREE_GB=$(echo "${SRC_DATASTORE_FREE}" | awk
'{printf "%.1f\n",$1/1024/1024/1024}')
#DESTINATION DATASTORE
DST_VOL_1=$(echo "${VM_BACKUP_VOLUME#/*/*/}")
DST_DATASTORE=$(echo "${DST_VOL_1%%/*}")
DST_DATASTORE_CAPACITY=$($VMWARE_CMD hostsvc/datastore/info
"${DST_DATASTORE}" | grep -i "capacity" | awk '{print $3}' | sed 's/,//g')
DST_DATASTORE_FREE=$($VMWARE_CMD hostsvc/datastore/info
"${DST_DATASTORE}" | grep -i "freespace" | awk '{print $3}' | sed 's/,//g')
DST_DATASTORE_BLOCKSIZE=$($VMWARE_CMD hostsvc/datastore/info
"${DST_DATASTORE}" | grep -i blockSizeMb | awk '{print $3}' | sed 's/,//g')
if [ -z ${DST_DATASTORE_BLOCKSIZE} ]; then
DST_DATASTORE_BLOCKSIZE="NA"
DST_DATASTORE_MAX_FILE_SIZE="NA"
else
case ${DST_DATASTORE_BLOCKSIZE} in
1)DST_DATASTORE_MAX_FILE_SIZE="256 GB";;
2)DST_DATASTORE_MAX_FILE_SIZE="512 GB";;
4)DST_DATASTORE_MAX_FILE_SIZE="1024 GB";;
8)DST_DATASTORE_MAX_FILE_SIZE="2048 GB";;
esac
Page 16 of 40 ---- Generated from
net(t)forum
fi
DST_DATASTORE_CAPACITY_GB=$(echo "${DST_DATASTORE_CAPACITY}" |
awk '{printf "%.1f\n",$1/1024/1024/1024}')
DST_DATASTORE_FREE_GB=$(echo "${DST_DATASTORE_FREE}" | awk
'{printf "%.1f\n",$1/1024/1024/1024}')
logger "debug" "Storage Information ${SECTION} backup: "
logger "debug" "SRC_DATASTORE: ${VMFS_VOLUME}"
logger "debug" "SRC_DATASTORE_CAPACITY:
${SRC_DATASTORE_CAPACITY_GB} GB"
logger "debug" "SRC_DATASTORE_FREE: ${SRC_DATASTORE_FREE_GB} GB"
logger "debug" "SRC_DATASTORE_BLOCKSIZE:
${SRC_DATASTORE_BLOCKSIZE}"
logger "debug" "SRC_DATASTORE_MAX_FILE_SIZE:
${SRC_DATASTORE_MAX_FILE_SIZE}"
logger "debug" ""
logger "debug" "DST_DATASTORE: ${DST_DATASTORE}"
logger "debug" "DST_DATASTORE_CAPACITY:
${DST_DATASTORE_CAPACITY_GB} GB"
logger "debug" "DST_DATASTORE_FREE: ${DST_DATASTORE_FREE_GB} GB"
logger "debug" "DST_DATASTORE_BLOCKSIZE:
${DST_DATASTORE_BLOCKSIZE}"
logger "debug" "DST_DATASTORE_MAX_FILE_SIZE:
${DST_DATASTORE_MAX_FILE_SIZE}"
if [[ "${SRC_DATASTORE_BLOCKSIZE}" != "NA" ]] && [[
"${DST_DATASTORE_BLOCKSIZE}" != "NA" ]]; then
if [ "${SRC_DATASTORE_BLOCKSIZE}" -lt
"${DST_DATASTORE_BLOCKSIZE}" ]; then
logger "debug" ""
logger "debug" "SRC VMFS blocksze of
${SRC_DATASTORE_BLOCKSIZE}MB is less than DST VMFS blocksize of
${DST_DATASTORE_BLOCKSIZE}MB which can be an issue for VM snapshots"
fi
fi
logger "debug" ""
}
ghettoVCB() {
VM_INPUT=$1
VM_OK=0
VM_FAILED=0
VMDK_FAILED=0
dumpHostInfo
if [ ${ENABLE_NON_PERSISTENT_NFS} -eq 1 ]; then
VM_BACKUP_VOLUME="/vmfs/volumes/${NFS_LOCAL_NAME}/${NFS_VM_BACKUP_DIR}"
if [ "${LOG_LEVEL}" != "dryrun" ]; then
#1 = readonly
#0 = readwrite
logger "debug" "Mounting NFS:
Page 17 of 40 ---- Generated from
net(t)forum
${NFS_SERVER}:${NFS_MOUNT} to /vmfs/volume/${NFS_LOCAL_NAME}"
${VMWARE_CMD} hostsvc/datastore/nas_create "${NFS_LOCAL_NAME}"
"${NFS_SERVER}" "${NFS_MOUNT}" 0
fi
fi
captureDefaultConfigurations
if [ "${USE_GLOBAL_CONF}" -eq 1 ]; then
logger "info" "CONFIG - USING GLOBAL GHETTOVCB CONFIGURATION FILE =
${GLOBAL_CONF}"
fi
if [ "${USE_VM_CONF}" -eq 0 ]; then
dumpVMConfigurations
fi
#dump out all virtual machines allowing for spaces now
${VMWARE_CMD} vmsvc/getallvms | sed 's/[[:blank:]]\{3,\}/ /g' | awk
-F' ' '{print "\""$1"\";\""$2"\";\""$3"\""}' | sed 's/\] /\]\";\"/g'
| sed '1,1d' > /tmp/vms_list
if [ "${BACKUP_ALL_VMS}" -eq 1 ]; then
${VMWARE_CMD} vmsvc/getallvms | sed 's/[[:blank:]]\{3,\}/ /g' | awk
-F' ' '{print ""$2""}' | sed '1,1d' | sed '/^$/d' > "${VM_INPUT}"
fi
ORIG_IFS=${IFS}
IFS='
'
for VM_NAME in $(cat "${VM_INPUT}" | grep -v "#" | sed '/^$/d' | sed -e
's/^[[:blank:]]*//;s/[[:blank:]]*$//');
do
IGNORE_VM=0
if [ "${EXCLUDE_SOME_VMS}" -eq 1 ]; then
grep -E "${VM_NAME}" "${VM_EXCLUSION_FILE}" > /dev/null 2>&1
if [ $? -eq 0 ]; then
IGNORE_VM=1
fi
fi
VM_ID=$(grep -E "\"${VM_NAME}\"" /tmp/vms_list | awk -F ";" '{print
$1}' | sed 's/"//g')
#ensure default value if one is not selected or variable is null
if [ -z ${VM_BACKUP_DIR_NAMING_CONVENTION} ]; then
VM_BACKUP_DIR_NAMING_CONVENTION="$(date
+%F_%k-%M-%S)"
fi
if [[ "${USE_VM_CONF}" -eq 1 ]] && [[ ! -z ${VM_ID} ]]; then
reConfigureBackupParam "${VM_NAME}"
Page 18 of 40 ---- Generated from
net(t)forum
dumpVMConfigurations
fi
VMFS_VOLUME=$(grep -E "\"${VM_NAME}\"" /tmp/vms_list | awk -F ";"
'{print $3}' | sed 's/\[//;s/\]//;s/"//g')
VMX_CONF=$(grep -E "\"${VM_NAME}\"" /tmp/vms_list | awk -F ";" '{print
$4}' | sed 's/\[//;s/\]//;s/"//g')
VMX_PATH="/vmfs/volumes/${VMFS_VOLUME}/${VMX_CONF}"
VMX_DIR=$(dirname "${VMX_PATH}")
#storage info
if [[ ! -z ${VM_ID} ]] && [[ "${LOG_LEVEL}" != "dryrun" ]]; then
storageInfo "before"
fi
#ignore VM as it's in the exclusion list
if [ "${IGNORE_VM}" -eq 1 ]; then
logger "debug" "Ignoring ${VM_NAME} for backup since its located in
exclusion list\n"
#checks to see if we can pull out the VM_ID
elif [ -z ${VM_ID} ]; then
logger "info" "ERROR: failed to locate and extract VM_ID for
${VM_NAME}!\n"
VM_FAILED=1
elif [ "${LOG_LEVEL}" == "dryrun" ]; then
logger "dryrun" "###############################################"
logger "dryrun" "Virtual Machine: $VM_NAME"
logger "dryrun" "VM_ID: $VM_ID"
logger "dryrun" "VMX_PATH: $VMX_PATH"
logger "dryrun" "VMX_DIR: $VMX_DIR"
logger "dryrun" "VMX_CONF: $VMX_CONF"
logger "dryrun" "VMFS_VOLUME: $VMFS_VOLUME"
logger "dryrun" "VMDK(s): "
TOTAL_VM_SIZE=0
getVMDKs
OLD_IFS="${IFS}"
IFS=":"
for j in ${VMDKS};
do
J_VMDK=$(echo "${j}" | awk -F "###" '{print $1}')
J_VMDK_SIZE=$(echo "${j}" | awk -F "###" '{print $2}')
logger "dryrun" "\t${J_VMDK}\t${J_VMDK_SIZE} GB"
done
HAS_INDEPENDENT_DISKS=0
logger "dryrun" "INDEPENDENT VMDK(s): "
for k in ${INDEP_VMDKS};
do
HAS_INDEPENDENT_DISKS=1
K_VMDK=$(echo "${k}" | awk -F "###" '{print $1}')
K_VMDK_SIZE=$(echo "${k}" | awk -F "###" '{print $2}')
logger "dryrun" "\t${K_VMDK}\t${K_VMDK_SIZE} GB"
Page 19 of 40 ---- Generated from
net(t)forum
done
IFS="${OLD_IFS}"
VMDKS=""
INDEP_VMDKS=""
logger "dryrun" "TOTAL_VM_SIZE_TO_BACKUP: ${TOTAL_VM_SIZE} GB"
if [ ${HAS_INDEPENDENT_DISKS} -eq 1 ]; then
logger "dryrun" "Snapshots can not be taken for indepdenent disks!"
logger "dryrun" "THIS VIRTUAL MACHINE WILL NOT HAVE ALL ITS VMDKS
BACKED UP!"
fi
ls "${VMX_DIR}" | grep -q "\-delta\.vmdk" > /dev/null 2>&1;
if [ $? -eq 0 ]; then
logger "dryrun" "Snapshots found for this VM, please commit all
snapshots before continuing!"
logger "dryrun" "THIS VIRTUAL MACHINE WILL NOT BE BACKED UP DUE TO
EXISTING SNAPSHOTS!"
fi
if [ ${TOTAL_VM_SIZE} -eq 0 ]; then
logger "dryrun" "THIS VIRTUAL MACHINE WILL NOT BE BACKED UP DUE TO
EMPTY VMDK LIST!"
fi
logger "dryrun" "###############################################\n"
#checks to see if the VM has any snapshots to start with
elif ls "${VMX_DIR}" | grep -q "\-delta\.vmdk" >
/dev/null 2>&1; then
logger "info" "Snapshot found for ${VM_NAME}, backup
will not take place\n"
VM_FAILED=1
elif [[ -f "${VMX_PATH}" ]] && [[ ! -z "${VMX_PATH}"
]]; then
#nfs case and backup to root path of your NFS mount
if [ ${ENABLE_NON_PERSISTENT_NFS} -eq 1 ] ; then
BACKUP_DIR="/vmfs/volumes/${NFS_LOCAL_NAME}/${NFS_VM_BACKUP_DIR}/${VM_NA
ME} "
if [[ -z ${VM_NAME} ]] || [[ -z
${NFS_LOCAL_NAME} ]] || [[ -z ${NFS_VM_BACKUP_DIR} ]]; then
logger "info" "ERROR: Variable
BACKUP_DIR was not set properly, please ensure all required variables
for non-persistent NFS backup option has been defined"
exit 1
fi
#non-nfs (SAN,LOCAL)
else
BACKUP_DIR="${VM_BACKUP_VOLUME}/${VM_NAME}"
if [[ -z ${VM_BACKUP_VOLUME} ]]; then
logger "info" "ERROR: Variable
Page 20 of 40 ---- Generated from
net(t)forum
VM_BACKUP_VOLUME was not defined"
exit 1
fi
fi
#initial root VM backup directory
if [ ! -d "${BACKUP_DIR}" ]; then
mkdir -p "${BACKUP_DIR}"
if [ ! -d "${BACKUP_DIR}" ]; then
logger "info" "Unable to create \"${BACKUP_DIR}\"! - Ensure
VM_BACKUP_VOLUME was defined correctly"
exit 1
fi
fi
# directory name of the individual Virtual Machine backup followed by
naming convention followed by count
VM_BACKUP_DIR="${BACKUP_DIR}/${VM_NAME}-${VM_BACKUP_DIR_NAMING_CONVE
NTION} "
# Rsync relative path variable if needed
RSYNC_LINK_DIR="./${VM_NAME}-${VM_BACKUP_DIR_NAMING_CONVENTION}"
mkdir -p "${VM_BACKUP_DIR}"
cp "${VMX_PATH}" "${VM_BACKUP_DIR}"
#new variable to keep track on whether VM has independent disks
VM_HAS_INDEPENDENT_DISKS=0
#extract all valid VMDK(s) from VM
getVMDKs
if [ ! -z ${INDEP_VMDKS} ]; then
VM_HAS_INDEPENDENT_DISKS=1
fi
ORGINAL_VM_POWER_STATE=$(${VMWARE_CMD} vmsvc/power.getstate ${VM_ID}
| tail -1)
CONTINUE_TO_BACKUP=1
#section that will power down a VM prior to taking a snapshot and
backup and power it back on
if [ ${POWER_VM_DOWN_BEFORE_BACKUP} -eq 1 ]; then
START_ITERATION=0
logger "info" "Powering off initiated for ${VM_NAME}, backup will
not begin until VM is off..."
${VMWARE_CMD} vmsvc/power.shutdown ${VM_ID} > /dev/null 2>&1
while ${VMWARE_CMD} vmsvc/power.getstate ${VM_ID} | grep -i "Powered
on" > /dev/null 2>&1;
Page 21 of 40 ---- Generated from
net(t)forum
do
#enable hard power off code
if [ ${ENABLE_HARD_POWER_OFF} -eq 1 ]; then
if [ ${START_ITERATION} -ge ${ITER_TO_WAIT_SHUTDOWN} ]; then
logger "info" "Hard power off occured for ${VM_NAME}, waited for
$((ITER_TO_WAIT_SHUTDOWN*60)) seconds"
${VMWARE_CMD} vmsvc/power.off ${VM_ID} > /dev/null 2>&1
#this is needed for ESXi, even the hard power off did not take
affect right away
sleep 60
break
fi
fi
logger "info" "VM is still on - Iteration: ${START_ITERATION} sleeping for 60secs (Duration: $((START_ITERATION*60)) seconds)"
sleep 60
#logic to not backup this VM if unable to shutdown
#after certain timeout period
if [ ${START_ITERATION} -ge ${POWER_DOWN_TIMEOUT} ]; then
logger "info" "Unable to power off ${VM_NAME}, waited for
$((POWER_DOWN_TIMEOUT*60)) seconds! Ignoring ${VM_NAME} for backup!"
VM_FAILED=1
CONTINUE_TO_BACKUP=0
break
fi
START_ITERATION=$((START_ITERATION + 1))
done
if [ ${CONTINUE_TO_BACKUP} -eq 1 ]; then
logger "info" "VM is powerdOff"
fi
fi
if [ ${CONTINUE_TO_BACKUP} -eq 1 ]; then
logger "info" "Initiate backup for ${VM_NAME}"
startTimer
SNAP_SUCCESS=1
VM_VMDK_FAILED=0
#powered on VMs only
if [[ ! ${POWER_VM_DOWN_BEFORE_BACKUP} -eq 1
]] && [[ "${ORGINAL_VM_POWER_STATE}" != "Powered off" ]]; then
SNAPSHOT_NAME="ghettoVCB-snapshot-$(date +%F)"
logger "info" "Creating Snapshot \"${SNAPSHOT_NAME}\" for ${VM_NAME}"
${VMWARE_CMD} vmsvc/snapshot.create
${VM_ID} "${SNAPSHOT_NAME}" "${SNAPSHOT_NAME}" "${VM_SNAPSHOT_MEMORY}"
"${VM_SNAPSHOT_QUIESCE}" > /dev/null 2>&1
logger "debug" "Waiting for snapshot \"${SNAPSHOT_NAME}\" to be
created"
Page 22 of 40 ---- Generated from
net(t)forum
logger "debug" "Snapshot timeout set to: $((SNAPSHOT_TIMEOUT*60))
seconds"
START_ITERATION=0
while [ $(${VMWARE_CMD} vmsvc/snapshot.get ${VM_ID} | wc -l) -eq 1 ]
do
if [ ${START_ITERATION} -ge ${SNAPSHOT_TIMEOUT} ]; then
logger "info" "Snapshot timed out, failed to create snapshot:
\"${SNAPSHOT_NAME}\" for ${VM_NAME}"
SNAP_SUCCESS=0
echo "ERROR: Unable to backup ${VM_NAME} due to snapshot
creation" >> ${VM_BACKUP_DIR}/STATUS.error
break
fi
logger "debug" "Waiting for snapshot creation to be completed Iteration: ${START_ITERATION} - sleeping for 60secs (Duration:
$((START_ITERATION*30)) seconds)"
sleep 60
START_ITERATION=$((START_ITERATION + 1))
done
fi
if [ ${SNAP_SUCCESS} -eq 1 ]; then
OLD_IFS="${IFS}"
IFS=":"
for j in ${VMDKS};
do
VMDK=$(echo "${j}" | awk -F "###" '{print $1}')
isVMDKFound=0
findVMDK "${VMDK}"
if [[ $isVMDKFound -eq 1 ]] || [[ "${VMDK_FILES_TO_BACKUP}" ==
"all" ]]; then
#added this section to handle VMDK(s) stored in different
datastore than the VM
echo ${VMDK} | grep "^/vmfs/volumes" > /dev/null 2>&1
if [ $? -eq 0 ]; then
SOURCE_VMDK="${VMDK}"
DS_UUID="$(echo ${VMDK#/vmfs/volumes/*})"
DS_UUID="$(echo ${DS_UUID%/*/*})"
VMDK_DISK="$(echo ${VMDK##/*/})"
mkdir -p "${VM_BACKUP_DIR}/${DS_UUID}"
DESTINATION_VMDK="${VM_BACKUP_DIR}/${DS_UUID}/${VMDK_DISK}"
else
SOURCE_VMDK="${VMX_DIR}/${VMDK}"
DESTINATION_VMDK="${VM_BACKUP_DIR}/${VMDK}"
fi
#support for vRDM and deny pRDM
grep "vmfsPassthroughRawDeviceMap" "${SOURCE_VMDK}" > /dev/null 2>&1
Page 23 of 40 ---- Generated from
net(t)forum
if [ $? -eq 1 ]; then
FORMAT_OPTION="UNKNOWN"
if [ "${DISK_BACKUP_FORMAT}" == "zeroedthick" ]; then
if [[ "${VER}" == "4" ]] || [[ "${VER}" == "5" ]] ; then
FORMAT_OPTION="zeroedthick"
else
FORMAT_OPTION=""
fi
elif [ "${DISK_BACKUP_FORMAT}" ==
"2gbsparse" ]; then
FORMAT_OPTION="2gbsparse"
elif [ "${DISK_BACKUP_FORMAT}" == "thin" ];
then
FORMAT_OPTION="thin"
elif [ "${DISK_BACKUP_FORMAT}" ==
"eagerzeroedthick" ]; then
if [[ "${VER}" == "4" ]] || [[ "${VER}" == "5" ]] ; then
FORMAT_OPTION="eagerzeroedthick"
else
FORMAT_OPTION=""
fi
fi
if [ "${FORMAT_OPTION}" == "UNKNOWN" ]; then
logger "info" "ERROR: wrong DISK_BACKUP_FORMAT
\"${DISK_BACKUP_FORMAT}\ specified for ${VM_NAME}"
VM_VMDK_FAILED=1
else
VMDK_OUTPUT=$(mktemp /tmp/ghettovcb.XXXXXX)
tail -f "${VMDK_OUTPUT}" &
TAIL_PID=$!
ADAPTER_FORMAT=$(grep -i "ddb.adapterType" "${SOURCE_VMDK}" |
awk -F "=" '{print $2}' | sed -e
's/^[[:blank:]]*//;s/[[:blank:]]*$//;s/"//g')
if [ -z "${FORMAT_OPTION}" ] ; then
logger "debug" "${VMKFSTOOLS_CMD} -i \"${SOURCE_VMDK}\" -a
\"${ADAPTER_FORMAT}\" \"${DESTINATION_VMDK}\""
${VMKFSTOOLS_CMD} -i "${SOURCE_VMDK}" -a "${ADAPTER_FORMAT}"
"${DESTINATION_VMDK}" > "${VMDK_OUTPUT}" 2>&1
else
logger "debug" "${VMKFSTOOLS_CMD} -i \"${SOURCE_VMDK}\" -a
\"${ADAPTER_FORMAT}\" -d \"${FORMAT_OPTION}\" \"${DESTINATION_VMDK}\""
${VMKFSTOOLS_CMD} -i "${SOURCE_VMDK}" -a "${ADAPTER_FORMAT}"
-d "${FORMAT_OPTION}" "${DESTINATION_VMDK}" > "${VMDK_OUTPUT}" 2>&1
fi
VMDK_EXIT_CODE=$?
kill "${TAIL_PID}"
cat "${VMDK_OUTPUT}" >> "${REDIRECT}"
echo >> "${REDIRECT}"
Page 24 of 40 ---- Generated from
net(t)forum
echo
rm "${VMDK_OUTPUT}"
if [ "${VMDK_EXIT_CODE}" != 0 ] ; then
logger "info" "ERROR: error in backing up of
\"${SOURCE_VMDK}\" for ${VM_NAME}"
VM_VMDK_FAILED=1
fi
fi
else
logger "info" "WARNING: A physical
RDM \"${SOURCE_VMDK}\" was found for ${VM_NAME}, which will not be
backed up"
VM_VMDK_FAILED=1
fi
fi
done
IFS="${OLD_IFS}"
fi
#powered on VMs only w/snapshots
if [[ ${SNAP_SUCCESS} -eq 1 ]] && [[ !
${POWER_VM_DOWN_BEFORE_BACKUP} -eq 1 ]] && [[
"${ORGINAL_VM_POWER_STATE}" == "Powered on" ]] || [[
"${ORGINAL_VM_POWER_STATE}" == "Suspended" ]]; then
if [ "${NEW_VIMCMD_SNAPSHOT}" == "yes" ]; then
SNAPSHOT_ID=$(${VMWARE_CMD} vmsvc/snapshot.get ${VM_ID} | grep -E
'(Snapshot Name|Snapshot Id)' | grep -A1 ${SNAPSHOT_NAME} | grep
"Snapshot Id" | awk -F ":" '{print $2}' | sed -e
's/^[[:blank:]]*//;s/[[:blank:]]*$//')
${VMWARE_CMD} vmsvc/snapshot.remove ${VM_ID} ${SNAPSHOT_ID} >
/dev/null 2>&1
else
${VMWARE_CMD} vmsvc/snapshot.remove
${VM_ID} > /dev/null 2>&1
fi
#do not continue until all snapshots
have been committed
logger "info" "Removing snapshot from
${VM_NAME} ..."
while ls "${VMX_DIR}" | grep -q
"\-delta\.vmdk";
do
sleep 5
done
fi
if [[ ${POWER_VM_DOWN_BEFORE_BACKUP} -eq 1 ]] && [[
"${ORGINAL_VM_POWER_STATE}" == "Powered on" ]]; then
#power on vm that was powered off
prior to backup
Page 25 of 40 ---- Generated from
net(t)forum
logger "info" "Powering back on
${VM_NAME}"
${VMWARE_CMD} vmsvc/power.on ${VM_ID}
> /dev/null 2>&1
fi
TMP_IFS=${IFS}
IFS=${ORIG_IFS}
if [ ${ENABLE_COMPRESSION} -eq 1 ]; then
COMPRESSED_ARCHIVE_FILE="${BACKUP_DIR}/${VM_NAME}-${VM_BACKUP_DIR_NA
MING_CONVENTION}.gz "
logger "info" "Compressing VM backup
\"${COMPRESSED_ARCHIVE_FILE}\"..."
if [ ${IS_4I} -eq 1 ]; then
busybox tar -cz -C "${BACKUP_DIR}"
"${VM_NAME}-${VM_BACKUP_DIR_NAMING_CONVENTION}" -f
"${COMPRESSED_ARCHIVE_FILE}"
else
tar -cz -C "${BACKUP_DIR}"
"${VM_NAME}-${VM_BACKUP_DIR_NAMING_CONVENTION}" -f
"${COMPRESSED_ARCHIVE_FILE}"
fi
# verify compression
if [[ $? -eq 0 ]] && [[ -f "${COMPRESSED_ARCHIVE_FILE}" ]]; then
logger "info" "Successfully compressed backup for ${VM_NAME}!\n"
COMPRESSED_OK=1
else
logger "info" "Error in compressing ${VM_NAME}!\n"
COMPRESSED_OK=0
fi
rm -rf "${VM_BACKUP_DIR}"
checkVMBackupRotation "${BACKUP_DIR}" "${VM_NAME}"
else
checkVMBackupRotation "${BACKUP_DIR}"
"${VM_NAME}"
fi
IFS=${TMP_IFS}
VMDKS=""
INDEP_VMDKS=""
endTimer
if [ ${SNAP_SUCCESS} -ne 1 ]; then
logger "info" "ERROR: Unable to backup ${VM_NAME} due to snapshot
creation!\n"
[[ ${ENABLE_COMPRESSION} -eq 1 ]] && [[ $COMPRESSED_OK -eq 1 ]] ||
echo "ERROR: Unable to backup ${VM_NAME} due to snapshot creation" >>
${VM_BACKUP_DIR}/STATUS.error
VM_FAILED=1
elif [ ${VM_VMDK_FAILED} -ne 0 ]; then
Page 26 of 40 ---- Generated from
net(t)forum
logger "info" "ERROR: Unable to backup ${VM_NAME} due to error in
VMDK backup!\n"
[[ ${ENABLE_COMPRESSION} -eq 1 ]] && [[ $COMPRESSED_OK -eq 1 ]] ||
echo "ERROR: Unable to backup ${VM_NAME} due to error in VMDK backup" >>
${VM_BACKUP_DIR}/STATUS.error
VMDK_FAILED=1
elif [ ${VM_HAS_INDEPENDENT_DISKS} -eq 1 ]; then
logger "info" "WARN: ${VM_NAME} has some Independent VMDKs that can
not be backed up!\n";
[[ ${ENABLE_COMPRESSION} -eq 1 ]] && [[ $COMPRESSED_OK -eq 1 ]] ||
echo "WARN: ${VM_NAME} has some Independent VMDKs that can not be backed
up" > ${VM_BACKUP_DIR}/STATUS.warn
VMDK_FAILED=1
#experimental
#create symlink for the very
last backup to support rsync functionality for additinal replication
if [ "${RSYNC_LINK}" -eq 1 ]; then
SYMLINK_DST=${VM_BACKUP_DIR}
if [
${ENABLE_COMPRESSION} -eq 1 ]; then
SYMLINK_DST1="${RSYNC_LINK_DIR}.gz"
else
SYMLINK_DST1=${RSYNC_LINK_DIR}
fi
SYMLINK_SRC="$(echo
"${SYMLINK_DST%*-*-*-*_*-*-*}")-symlink"
logger "info" "Creating
symlink \"${SYMLINK_SRC}\" to \"${SYMLINK_DST1}\""
ln -sf
"${SYMLINK_DST1}" "${SYMLINK_SRC}"
fi
#storage info after backup
storageInfo "after"
else
logger "info" "Successfully completed backup for ${VM_NAME}!\n"
[[ ${ENABLE_COMPRESSION} -eq 1 ]] && [[ $COMPRESSED_OK -eq 1 ]] ||
echo "Successfully completed backup" > ${VM_BACKUP_DIR}/STATUS.ok
VM_OK=1
#experimental
#create symlink for the very last backup to support rsync
functionality for additinal replication
if [ "${RSYNC_LINK}" -eq 1 ]; then
SYMLINK_DST=${VM_BACKUP_DIR}
if [ ${ENABLE_COMPRESSION} -eq 1 ]; then
SYMLINK_DST1="${RSYNC_LINK_DIR}.gz"
else
SYMLINK_DST1=${RSYNC_LINK_DIR}
Page 27 of 40 ---- Generated from
net(t)forum
fi
SYMLINK_SRC="$(echo "${SYMLINK_DST%*-*-*-*_*-*-*}")-symlink"
logger "info" "Creating symlink \"${SYMLINK_SRC}\"
to \"${SYMLINK_DST1}\""
ln -sf "${SYMLINK_DST1}" "${SYMLINK_SRC}"
fi
#storage info after backup
storageInfo "after"
fi
else
if [ ${CONTINUE_TO_BACKUP} -eq 0 ]; then
logger "info" "ERROR: Failed to backup ${VM_NAME}!\n"
VM_FAILED=1
else
logger "info" "ERROR: Failed to lookup
${VM_NAME}!\n"
VM_FAILED=1
fi
fi
fi
done
unset IFS
if [[ ${ENABLE_NON_PERSISTENT_NFS} -eq 1 ]] && [[
${UNMOUNT_NFS} -eq 1 ]] && [[ "${LOG_LEVEL}" != "dryrun" ]]; then
logger "debug" "Sleeping for 30seconds before unmounting NFS volume"
sleep 30
${VMWARE_CMD} hostsvc/datastore/destroy ${NFS_LOCAL_NAME}
fi
}
getFinalStatus() {
if [[ "${LOG_TYPE}" == "dryrun" ]]; then
FINAL_STATUS="###### Final status: OK, only a dryrun. ######"
LOG_STATUS="OK"
EXIT=0
elif [[ $VM_OK == 1 ]] && [[ $VM_FAILED == 0 ]] && [[ $VMDK_FAILED == 0
]]; then
FINAL_STATUS="###### Final status: All VMs backed up OK! ######"
LOG_STATUS="OK"
EXIT=0
elif [[ $VM_OK == 1 ]] && [[ $VM_FAILED == 0 ]] && [[ $VMDK_FAILED == 1
]]; then
FINAL_STATUS="###### Final status: WARNING: All VMs backed up, but
some disk(s) failed! ######"
LOG_STATUS="WARNING"
EXIT=3
elif [[ $VM_OK == 1 ]] && [[ $VM_FAILED == 1 ]] && [[ $VMDK_FAILED == 0
]]; then
FINAL_STATUS="###### Final status: ERROR: Only some of the VMs backed
up! ######"
Page 28 of 40 ---- Generated from
net(t)forum
LOG_STATUS="ERROR"
EXIT=4
elif [[ $VM_OK == 1 ]] && [[ $VM_FAILED == 1 ]] && [[ $VMDK_FAILED == 1
]]; then
FINAL_STATUS="###### Final status: ERROR: Only some of the VMs backed
up, and some disk(s) failed! ######"
LOG_STATUS="ERROR"
EXIT=5
elif [[ $VM_OK == 0 ]] && [[ $VM_FAILED == 1 ]]; then
FINAL_STATUS="###### Final status: ERROR: All VMs failed! ######"
LOG_STATUS="ERROR"
EXIT=6
elif [[ $VM_OK == 0 ]]; then
FINAL_STATUS="###### Final status: ERROR: No VMs backed up! ######"
LOG_STATUS="ERROR"
EXIT=7
fi
logger "info" "$FINAL_STATUS\n"
}
buildHeaders() {
EMAIL_ADDRESS=$1
echo -ne "HELO $(hostname -s)\r\n" > "${EMAIL_LOG_HEADER}"
echo -ne "MAIL FROM: <${EMAIL_FROM}>\r\n" >> "${EMAIL_LOG_HEADER}"
echo -ne "RCPT TO: <${EMAIL_ADDRESS}>\r\n" >> "${EMAIL_LOG_HEADER}"
echo -ne "DATA\r\n" >> "${EMAIL_LOG_HEADER}"
echo -ne "From: ${EMAIL_FROM}\r\n" >> "${EMAIL_LOG_HEADER}"
echo -ne "To: ${EMAIL_ADDRESS}\r\n" >> "${EMAIL_LOG_HEADER}"
echo -ne "Subject: ghettoVCB - ${FINAL_STATUS}\r\n" >>
"${EMAIL_LOG_HEADER}"
echo -en ".\r\n" >> "${EMAIL_LOG_OUTPUT}"
echo -en "QUIT\r\n" >> "${EMAIL_LOG_OUTPUT}"
cat "${EMAIL_LOG_HEADER}" > "${EMAIL_LOG_CONTENT}"
cat "${EMAIL_LOG_OUTPUT}" >> "${EMAIL_LOG_CONTENT}"
}
sendMail() {
#close email message
if [ "${EMAIL_LOG}" -eq 1 ]; then
#validate firewall has email port open for ESXi 5
if [ "${VER}" == "5" ]; then
/sbin/esxcli network firewall ruleset rule list | grep
"${EMAIL_SERVER_PORT}" > /dev/null 2>&1
if [ $? -eq 1 ]; then
logger "info" "ERROR: Please enable firewall rule for email traffic
on port ${EMAIL_SERVER_PORT}\n"
logger "info" "Please refer to ghettoVCB documentation for ESXi 5
firewall configuration\n"
fi
Page 29 of 40 ---- Generated from
net(t)forum
fi
echo "${EMAIL_TO}" | grep "," > /dev/null 2>&1
if [ $? -eq 0 ]; then
ORIG_IFS=${IFS}
IFS=','
for i in ${EMAIL_TO};
do
buildHeaders ${i}
"${NC_BIN}" -i "${EMAIL_DELAY_INTERVAL}" "${EMAIL_SERVER}"
"${EMAIL_SERVER_PORT}" < "${EMAIL_LOG_CONTENT}" > /dev/null 2>&1
if [ $? -eq 1 ]; then
logger "info" "ERROR: Failed to email log output to
${EMAIL_SERVER}:${EMAIL_SERVER_PORT} to ${EMAIL_TO}\n"
fi
done
unset IFS
else
buildHeaders ${EMAIL_TO}
"${NC_BIN}" -i "${EMAIL_DELAY_INTERVAL}" "${EMAIL_SERVER}"
"${EMAIL_SERVER_PORT}" < "${EMAIL_LOG_CONTENT}" > /dev/null 2>&1
if [ $? -eq 1 ]; then
logger "info" "ERROR: Failed to email log
output to ${EMAIL_SERVER}:${EMAIL_SERVER_PORT} to ${EMAIL_TO}\n"
fi
fi
if [ "${EMAIL_DEBUG}" -eq 1 ]; then
logger "info" "Email log output will not be deleted and is stored in
${EMAIL_LOG_CONTENT}"
else
logger "info" "Removing ${EMAIL_LOG_OUTPUT} and ${EMAIL_LOG_HEADER}
and ${EMAIL_LOG_CONTENT}"
rm -f "${EMAIL_LOG_OUTPUT}"
rm -f "${EMAIL_LOG_HEADER}"
rm -f "${EMAIL_LOG_CONTENT}"
fi
fi
}
####################
# #
# Start of Script #
# #
####################
IS_4I=0
if [ ! -f /bin/bash ]; then
IS_4I=1
fi
Page 30 of 40 ---- Generated from
net(t)forum
USE_VM_CONF=0
USE_GLOBAL_CONF=0
BACKUP_ALL_VMS=0
EXCLUDE_SOME_VMS=0
EMAIL_LOG_HEADER=/tmp/ghettoVCB-email-$$.header
EMAIL_LOG_OUTPUT=/tmp/ghettoVCB-email-$$.log
EMAIL_LOG_CONTENT=/tmp/ghettoVCB-email-$$.content
#read user input
while getopts ":af:c:g:l:d:e:" ARGS; do
case $ARGS in
a)
BACKUP_ALL_VMS=1
VM_FILE="/tmp/backup_all_vms_on-$(hostname)"
touch "${VM_FILE}"
;;
f)
VM_FILE="${OPTARG}"
;;
e)
VM_EXCLUSION_FILE="${OPTARG}"
EXCLUDE_SOME_VMS=1
;;
c)
CONFIG_DIR="${OPTARG}"
USE_VM_CONF=1
;;
g)
GLOBAL_CONF="${OPTARG}"
USE_GLOBAL_CONF=1
;;
l)
LOG_OUTPUT="${OPTARG}"
;;
d)
LOG_LEVEL="${OPTARG}"
;;
:)
echo "Option -${OPTARG} requires an argument."
exit 1
;;
*)
printUsage
exit 1
;;
esac
done
#performs a check on the number of commandline arguments + verifies $2
is a valid file
sanityCheck $#
LOCKDIR=/tmp/ghettoVCB.lock
Page 31 of 40 ---- Generated from
net(t)forum
if mkdir "${LOCKDIR}"
then
GHETTOVCB_PID=$$
logger "info" "============================== ghettoVCB LOG START
==============================\n"
logger "debug" "Succesfully acquired lock directory - ${LOCKDIR}\n"
# Remove lockdir when the script finishes, or when it receives a signal
trap 'rm -rf "${LOCKDIR}"' 0 # remove directory when script finishes
trap "exit 2" 1 2 3 13 15
# terminate script when receiving signal
ghettoVCB ${VM_FILE}
getFinalStatus
logger "debug" "Succesfully removed lock directory - ${LOCKDIR}\n"
logger "info" "============================== ghettoVCB LOG END
================================\n"
sendMail
rm -rf "${LOCKDIR}"
exit $EXIT
else
logger "info" "Failed to acquire lock, another instance of script may
be running, giving up on ${LOCKDIR}\n"
exit 1
fi
Subject: Re: Shutdownskript funktioniert nur bei "aktivem Fenster"
Posted by Thomas Bork on Sun, 10 Feb 2013 21:02:23 GMT
View Forum Message <> Reply to Message
Am 10.02.2013 21:08, schrieb Alex Busam:
>> Und der genaue Inhalt des Skriptes?
[...]
>
#section that will power down a VM prior to taking a
> snapshot and backup and power it back on
>
if [ ${POWER_VM_DOWN_BEFORE_BACKUP} -eq 1 ]; then
>
START_ITERATION=0
>
logger "info" "Powering off initiated for ${VM_NAME},
> backup will not begin until VM is off..."
>
>
${VMWARE_CMD} vmsvc/power.shutdown ${VM_ID} > /dev/null
> 2>&1
>
while ${VMWARE_CMD} vmsvc/power.getstate ${VM_ID} |
> grep -i "Powered on" > /dev/null 2>&1;
Page 32 of 40 ---- Generated from
net(t)forum
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
do
#enable hard power off code
if [ ${ENABLE_HARD_POWER_OFF} -eq 1 ]; then
if [ ${START_ITERATION} -ge
${ITER_TO_WAIT_SHUTDOWN} ]; then
logger "info" "Hard power off occured for
${VM_NAME}, waited for $((ITER_TO_WAIT_SHUTDOWN*60)) seconds"
${VMWARE_CMD} vmsvc/power.off ${VM_ID} >
/dev/null 2>&1
#this is needed for ESXi, even the hard
power off did not take affect right away
sleep 60
break
fi
fi
logger "info" "VM is still on - Iteration:
${START_ITERATION} - sleeping for 60secs (Duration:
$((START_ITERATION*60)) seconds)"
sleep 60
Und was steht in vmsvc/power.shutdown?
-der tom
[eisfair-team]
Subject: Re: Shutdownskript funktioniert nur bei "aktivem Fenster"
Posted by alex[1] on Sun, 10 Feb 2013 21:28:13 GMT
View Forum Message <> Reply to Message
>
> Und was steht in vmsvc/power.shutdown?
>
das ist ein Parameter, der dem /usr/bin/vim-cmd übergeben wird. Dieser
Befehl wird auch ausgeführt. Das sieht man im vSphere Überwachungsfenster.
Auf dem Eisfair gibt es nach Installation der vmware-tools ein
Verzeichnis /etc/vmware-tools/scripts/vmware/
Dort ist eine leere Datei "network". Darüber wird beim Shutdown erstmal
das Netzwerk runtergefahren. Allerdings war die Datei nach Installation
leer, weil diese Komponente unter Eisfair irgendwie nicht erkannt wurde.
(hab keine Ahnung was da eigentlich drin stehen sollte. Steht aber so in
der Doku) Nun habe ich in "network" den Inhalt von /etc/init.d/halt
kopiert, hab ihr Rechte 777 gegeben. Das Runterfahren funktioniert auch,
jedoch nur wenn ich an der Console auch eingeloggt bin, während auf dem
ESXi5-Host das Backupskript den Shutdown auslöst.
"Wo" wird dieses Skript network (was ja dem halt entspricht) ausgeführt,
wenn root eingeloggt ist, wo wenn er nicht eingeloggt ist? kann ich das
Page 33 of 40 ---- Generated from
net(t)forum
innerhalb des Halt-Skripts beeinflussen?
(wie funktioniert ein halt per cron? da muss doch auch keiner eingeloggt
sein...)
Danke und Gruß
Alex
Subject: Re: Shutdownskript funktioniert nur bei "aktivem Fenster"
Posted by alex[1] on Sun, 10 Feb 2013 21:52:27 GMT
View Forum Message <> Reply to Message
>
> Und was steht in vmsvc/power.shutdown?
>
das ist ein Parameter, der dem /usr/bin/vim-cmd übergeben wird. Dieser
Befehl wird auch ausgeführt. Das sieht man im vSphere Überwachungsfenster.
Auf dem Eisfair gibt es nach Installation der vmware-tools ein
Verzeichnis /etc/vmware-tools/scripts/vmware/
Dort ist eine leere Datei "network". Darüber wird beim Shutdown erstmal
das Netzwerk runtergefahren. Allerdings war die Datei nach Installation
leer, weil diese Komponente unter Eisfair irgendwie nicht erkannt wurde.
(hab keine Ahnung was da eigentlich drin stehen sollte. Steht aber so in
der Doku) Nun habe ich in "network" den Inhalt von /etc/init.d/halt
kopiert, hab ihr Rechte 777 gegeben. Das Runterfahren funktioniert auch,
jedoch nur wenn ich an der Console auch eingeloggt bin, während auf dem
ESXi5-Host das Backupskript den Shutdown auslöst.
"Wo" wird dieses Skript network (was ja dem halt entspricht) ausgeführt,
wenn root eingeloggt ist, wo wenn er nicht eingeloggt ist? kann ich das
innerhalb des Halt-Skripts beeinflussen?
(wie funktioniert ein halt per cron? da muss doch auch keiner eingeloggt
sein...)
Danke und Gruß
Alex
Subject: Re: Shutdownskript funktioniert nur bei "aktivem Fenster"
Posted by Thomas Bork on Mon, 11 Feb 2013 00:43:52 GMT
View Forum Message <> Reply to Message
Am 10.02.2013 22:52, schrieb Alex Busam:
>> Und was steht in vmsvc/power.shutdown?
> das ist ein Parameter, der dem /usr/bin/vim-cmd übergeben wird. Dieser
> Befehl wird auch ausgeführt. Das sieht man im vSphere Überwachungsfenster.
Wenn das ein Parameter ist: Welchen Wert hat dieser Parameter? Was
heisst "Dieser Befehl wird auch ausgeführt."? Zeige _genau_, was
Page 34 of 40 ---- Generated from
net(t)forum
ausgeführt wird.
>
>
>
>
>
Auf dem Eisfair gibt es nach Installation der vmware-tools ein
Verzeichnis /etc/vmware-tools/scripts/vmware/
Dort ist eine leere Datei "network". Darüber wird beim Shutdown erstmal
das Netzwerk runtergefahren. Allerdings war die Datei nach Installation
leer, weil diese Komponente unter Eisfair irgendwie nicht erkannt wurde.
Ja klar, denn es gibt auf eisfair-1 kein "network".
> (hab keine Ahnung was da eigentlich drin stehen sollte. Steht aber so in
> der Doku)
Was steht da _genau_?
>
>
>
>
>
>
Nun habe ich in "network" den Inhalt von /etc/init.d/halt
kopiert, hab ihr Rechte 777 gegeben. Das Runterfahren funktioniert auch,
jedoch nur wenn ich an der Console auch eingeloggt bin, während auf dem
ESXi5-Host das Backupskript den Shutdown auslöst.
"Wo" wird dieses Skript network (was ja dem halt entspricht) ausgeführt,
wenn root eingeloggt ist, wo wenn er nicht eingeloggt ist?
Woraus schliesst Du, dass "halt" von eisfair-1 "network" von anderen
Systemen entspricht?
>
>
>
>
kann ich das
innerhalb des Halt-Skripts beeinflussen?
(wie funktioniert ein halt per cron? da muss doch auch keiner eingeloggt
sein...)
Es muss auch keiner eingeloggt sein, wenn nicht VMWare im Spiel ist.
Wenn Du nicht herausbekommst, was VMWare da genau veranstaltet, gibt es
wenig Aussicht, das Problem zu lösen.
-der tom
[eisfair-team]
Subject: Re: Shutdownskript funktioniert nur bei "aktivem Fenster"
Posted by Friedrich Bartel on Wed, 13 Feb 2013 18:00:52 GMT
View Forum Message <> Reply to Message
Am 10.02.2013 18:10, schrieb Alex Busam:
> Hallo,
>
> es gibt schon nen ältere Thread mit meinem Shutdownproblem.
> Zwischenzeitlich hats mal funktioniert, mal nicht....habs aber nicht
> verstanden was das Problem ist.
>
> Situation: Eisfair1 auf einem VMware ESXi5. Backup des ESXi will den
Page 35 of 40 ---- Generated from
net(t)forum
>
>
>
>
>
>
>
>
>
>
>
>
>
Eisfair runterfahren, Skript startet auch den "shutdown" laut
Ereignisprotokoll des ESXi. Manchmal gehts, manchmal nicht.... Nun hab
ich herausgefunden, dass es immer geht, wenn das Consolenfenster des
Eisfair offen ist und auch "aktiv". Wenn das Fenster keinen Cursor hat
oder geschlossen ist, dann wird das Skript nicht ausgeführt.... Den
Effekt blick ich nicht, bin mir aber sehr sicher, dass hier einige
sofort ne Erklärung dafür haben:-)
(Vmware-Tools sind installiert. Das network-Skript wurde nicht gefunden,
weshalb ich dort als network-Skript das Skript /etc/init.d/halt des
Eisfair hinkopiert hab.)
Gruß
Alex
Hi Alex,
soweit ich die Beschreibung des ghettoVCB Skripts
> http://communities.vmware.com/docs/DOC-8760
unter Configturations deute, muss die Eis-VM mittels Skript vor dem
Backup runter gefahren werden.
POWER_VM_DOWN_BEFORE_BACKUP=1
Danach wird das Backup gestartet. Vermutlich wurde das mal geändert.
Schau auch mal bei der Seite vorbei.
> http://www.windowspro.de/tool/ghettovcb-script-fuer-backup-von-esxi-51-v sphere-51
Gruß
Friedrich
Subject: Re: Shutdownskript funktioniert nur bei "aktivem Fenster"
Posted by alex[1] on Fri, 15 Feb 2013 19:56:29 GMT
View Forum Message <> Reply to Message
Am 11.02.2013 01:43, schrieb Thomas Bork:
> Am 10.02.2013 22:52, schrieb Alex Busam:
>
>>> Und was steht in vmsvc/power.shutdown?
>> das ist ein Parameter, der dem /usr/bin/vim-cmd übergeben wird. Dieser
>> Befehl wird auch ausgeführt. Das sieht man im vSphere
>> Überwachungsfenster.
>
> Wenn das ein Parameter ist: Welchen Wert hat dieser Parameter? Was
> heisst "Dieser Befehl wird auch ausgeführt."? Zeige _genau_, was
> ausgeführt wird.
Page 36 of 40 ---- Generated from
net(t)forum
Auf dem Host wird /usr/bin/vim-cmd vmsvc/power.shutdown ausgeführt. was
dahintersteckt weiß ich nicht. Ich nehme an es kommuniziert mit einer
Komponente der VMware-Tools in der VM und fährt die VM dann runter.
>
>> Auf dem Eisfair gibt es nach Installation der vmware-tools ein
>> Verzeichnis /etc/vmware-tools/scripts/vmware/
>> Dort ist eine leere Datei "network". Darüber wird beim Shutdown erstmal
>> das Netzwerk runtergefahren. Allerdings war die Datei nach Installation
>> leer, weil diese Komponente unter Eisfair irgendwie nicht erkannt wurde.
>
> Ja klar, denn es gibt auf eisfair-1 kein "network".
>
>> (hab keine Ahnung was da eigentlich drin stehen sollte. Steht aber so in
>> der Doku)
>
> Was steht da _genau_?
nichts. Sie ist leer.
>> Nun habe ich in "network" den Inhalt von /etc/init.d/halt
>> kopiert, hab ihr Rechte 777 gegeben. Das Runterfahren funktioniert auch,
>> jedoch nur wenn ich an der Console auch eingeloggt bin, während auf dem
>> ESXi5-Host das Backupskript den Shutdown auslöst.
>> "Wo" wird dieses Skript network (was ja dem halt entspricht) ausgeführt,
>> wenn root eingeloggt ist, wo wenn er nicht eingeloggt ist?
>
> Woraus schliesst Du, dass "halt" von eisfair-1 "network" von anderen
> Systemen entspricht?
Dsa habe ich nie behauptet. "network" ist jedoch das erste Script, das
von der VMware-Komponente beim Shutdown ausgeführt wird. "network" ist
jedoch nach der Installation der VMware-Komponente leer, weil es nach
Deiner Auskunft kein network auf eisfair1 gibt.
Deshalb war mein Versuch diese leere Datei als "halt" zu missbrauchen.
Und wenn ich auf der Konsole eingeloggt bin, dann funktioniert der
Shutdown auch.
Im Handbuch der VMware-Tools steht, dass der vmtoolsd als user "root"
läuft und dass scripts in einer vom angemeldeten Benutzer unabhängigen
Sitzung ausgeführt werden.
Subject: Re: Shutdownskript funktioniert nur bei "aktivem Fenster"
Posted by alex[1] on Sat, 16 Feb 2013 08:31:50 GMT
View Forum Message <> Reply to Message
>> Alex
>
> Hi Alex,
>
Page 37 of 40 ---- Generated from
net(t)forum
> soweit ich die Beschreibung des ghettoVCB Skripts
>
>> http://communities.vmware.com/docs/DOC-8760
>
> unter Configturations deute, muss die Eis-VM mittels Skript vor dem
> Backup runter gefahren werden.
>
> POWER_VM_DOWN_BEFORE_BACKUP=1
>
> Danach wird das Backup gestartet. Vermutlich wurde das mal geändert.
>
> Schau auch mal bei der Seite vorbei.
>
>> http://www.windowspro.de/tool/ghettovcb-script-fuer-backup-von-esxi-51-v sphere-51
>>
>
> Gruß
>
> Friedrich
Hi,
im Script läßt sich konfigurierren, ob GhettoVCB die VM runterfährt oder
mittels Snapshot von der laufenden VM ne Kopie anlegt. Ich verwende
beides. D.h. tägliches Backup ohne runterfahren, 1x pro Woche mit
runterfahren.
Beim Start des Skripts wird, abhängig von der Konfiguration, die VM
runtergefahren. Dies sehe ich im Statusfenster des ESXi5. Dort wird das
Runterfahren der VM angestoßen.
Doch wird der tatsächliche Befehl des "halt" nur ausgeführt, wenn ich
auf der Console oder mittels ssh als root eingeloggt bin.
gruß
Alex
Subject: verhalten
Posted by alex[1] on Sat, 16 Feb 2013 09:16:35 GMT
View Forum Message <> Reply to Message
Habe jetzt mal nen Eisfair2 zum Test installiert. Dort dann die
vmware-tools installiert.
Nun hab ich testweise vmtoolsd gekillt. Ein vom Host ausgelöster
shutdown funktioniert dann natürlich nicht. Wenn ich aber als
eingeloggter user root dann vmtoolsd starte, dann funktioniert der
shutdown, sprich, vmtoolsd nimmt den Befehl entgegen und führt ein halt
aus.
Daraus schließe ich, dass der daemon vmtoolsd auf meinem Problem-Eis die
Page 38 of 40 ---- Generated from
net(t)forum
Ursache ist. Die Gründe kann ich mir aber mangels näherer
Linuxkenntnisse nicht erklären.
Mit falsches User gestartet? eine nicht vorhandene Ausgabemöglichkeit
verhindert das Ausführen von Befehlen?
Habe also noch Hoffnung, dass sich jemand dieses Verhalten erklären kann:-)
Gruß
Alex
Subject: Re: Shutdownskript funktioniert nur bei "aktivem Fenster"
Posted by Friedrich Bartel on Sat, 16 Feb 2013 09:48:39 GMT
View Forum Message <> Reply to Message
Am 16.02.2013 09:31, schrieb Alex Busam:
>>> Alex
>>
>> Hi Alex,
>>
>> soweit ich die Beschreibung des ghettoVCB Skripts
>>
>>> http://communities.vmware.com/docs/DOC-8760
>>
>> unter Configturations deute, muss die Eis-VM mittels Skript vor dem
>> Backup runter gefahren werden.
>>
>> POWER_VM_DOWN_BEFORE_BACKUP=1
>>
>> Danach wird das Backup gestartet. Vermutlich wurde das mal geändert.
>>
>> Schau auch mal bei der Seite vorbei.
>>
>>> http://www.windowspro.de/tool/ghettovcb-script-fuer-backup-von-esxi-51-v sphere-51
>>>
>>>
>>
>> Gruß
>>
>> Friedrich
>
>
> Hi,
>
> im Script läßt sich konfigurierren, ob GhettoVCB die VM runterfährt oder
> mittels Snapshot von der laufenden VM ne Kopie anlegt. Ich verwende
> beides. D.h. tägliches Backup ohne runterfahren, 1x pro Woche mit
> runterfahren.
> Beim Start des Skripts wird, abhängig von der Konfiguration, die VM
> runtergefahren. Dies sehe ich im Statusfenster des ESXi5. Dort wird das
> Runterfahren der VM angestoßen.
> Doch wird der tatsächliche Befehl des "halt" nur ausgeführt, wenn ich
> auf der Console oder mittels ssh als root eingeloggt bin.
Page 39 of 40 ---- Generated from
net(t)forum
Systembedingte Sicherheit.
Halt geht beim Eis1 auch mit Plink. Die Befehlszeile wird abgesetzt und
der Eis1 fährt runter.
Bei mir einer Plink Verküpfung auf dem Desktop und folgendem Inhalt in
der Zeile Ziel:
> C:\Programme\Putty\plink.exe -ssh -pw RootPasswort root@192.168.x.x halt
Zeile Ausführen: Normales Fenster oder minimiert.
Will man nur einen Neustart dann in einer 2. Verknüpfung halt durch
reboot ersetzen.
Beim Eis2 gibt es für den Systemstop einen User shutdown, entsprechend
dann das Passwort ändern und den User.
> C:\Programme\Putty\plink.exe -ssh -pw shutdownPasswort shutdown@192.168.x.x halt
>
>
> gruß
> Alex
>
Friedrich
Page 40 of 40 ---- Generated from
net(t)forum