You are on page 1of 4

SNAP VMX

Try this cool script to display snapshot information from the service console shell called
SnapVMX
This program gathers information from the .vmx and .vmdk files of a VM and performs
the following operations:
• Displays the snapshots structure and the size of the snapshots for every disk on
that VM
• Calculates the free space needed to commit all those snapshots for the worst case
scenario
• Checks the CID chain of the analysed files and displays a warning when it finds a
broken link
What information does it gather from each file?:
• From the .vmx it gets the list of virtual disks attached to the VM
• From the .vmdk descriptor file it gets the name of the delta/flat file, its CID and
the CID and name of its parent disk if it exists.
• From the -flat.vmdk and -delta.vmdk files SnapVMX only gets the size of those
files through a normal "ls -l" on the directory, i.e. it does not touch them directly
in any case.
After you have defined the functions you just need to go to the VM directory and type
S
# SnapVMX VMName.vmx
It does not matter if the VM that the .vmx file represents is running and/or registered.
Let's see some examples.
If you point SnapVMX to a VM with no snapshots you will get only the list of disks with
their sizes
# SnapVMX bf_Ubuntu_nfs.vmx
Base Disk: Ubuntu-nfs.vmdk Size: 3.0G
----------------
Base Disk: Ubuntu-nfs_1.vmdk Size: 10G
----------------
Base Disk: Ubuntu-nfs_2.vmdk Size: 4.0G
----------------
If the VM has snapshots, they will be displayed together with their sizes and the space
needed to commit them all for the worst case scenario.
# SnapVMX PH-RHEL.vmx
PH-RHEL_1-000001.vmdk Size: 656M
PH-RHEL_1-000003.vmdk Size: 2.1G
PH-RHEL_1-000002.vmdk Size: 48M
Base Disk: PH-RHEL_1.vmdk Size: 8.0G
Space needed on this Datastore to delete all the snapshots of this disk
is: 3472.05 Megabytes = 3.39 Gigabytes
----------------
Cut and paste below into SSH session and simply run the SnapVMX command

#-----------------------------------------------------------------------
--
# Copyright (C) 2009 Ruben Miguelez Garcia
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see
<http://www.gnu.org/licenses/>.
#
#-----------------------------------------------------------------------
--
#-------- Helper functions --------------------
function CID () { grep -i '^CID' "$1" | awk -F'=' '{ print $2 }';
};
function ParentCID () { grep -i '^parentCID' "$1" | awk -F'=' '{ print
$2 }'; };
function ParentFile () { grep -i '^parentFileNameHint' "$1" | awk -
F'"' '{ print $2 }'; };
function Size () { ls -l "$1" | awk '{ print $5 }' ; };
function SizeH () { ls -lh "$1" | awk '{ print $5 }'; };
function DeltaOrFlat () { FPATH=`dirname "$1"`; echo -n "$FPATH/" ;
grep -i '^RW' "$1" | awk -F'"' '{ print $2 }'; };
function FileExists () { if [ -s "$1" ] ; then echo "true"; else echo
"false" ; fi; };
function SizeNeeded () {
# Usage: SizeNeeded [SnapN, SnapN-1,....,Snap2,Snap1,BaseDisk]
# Example: SizeNeeded [1,2,1,2,20,50]
python -c "R=$1; BD=R[-1]; R=R[:-1]; L=len(R)-1; SU=SN=0;
for i in range(L):
SU=min(((SU or R[i])+R[i+1]),BD);
SN=(SU-R[i+1])*((SU-R[i+1])>0)+SN;
#print 'Array of snapshots: ', R,'-- Base Disk: ',BD,' -- Space Needed:
', SN;
R_MB=SN/(1024.0*1024);R_GB=R_MB/1024; print '%.2f Megabytes = %.2f
Gigabytes' % (R_MB,R_GB) ;" ;}
function CID_chain_check () {
# Usage: CID_chain_check FILE.vmdk
# Check the CID chain between FILE.vmdk and its parent and display the
result (null if no mismatch)
FILE="$1";
FILE_PARENT=`ParentFile "$FILE"`;
if [ `ParentCID "$FILE"` != `CID "$FILE_PARENT"` ]; then echo -n "--
Warning: CID chain mismatch between \"$FILE\" and \"$FILE_PARENT\""; fi;
}
#------- SnapTree ------------------------------------------------------
--
function SnapTree () {
# Usage: SnapTree FILE.vmdk
# Follow the chain of files from FILE.vmdk down to the BaseDisk
displaying them.
FILE=$1;
TAB="";
SIZES="[ ";
HAS_SNAPSHOTS="0";
if [ `FileExists "$FILE"` = "false" ]; then echo "File
\"$FILE\" not found. Exiting."; return -1 ; fi;
# While the file is not the base disk
while [ `ParentCID "$FILE"` != "ffffffff" ]; do
HAS_SNAPSHOTS="1";
# Get size of delta file
DELTA=`DeltaOrFlat "$FILE"`;
if [ `FileExists "$DELTA"` = "true" ]; then
SIZE_H=`SizeH "$DELTA"`;
SIZES=$SIZES`Size "$DELTA"`",";
else
SIZE_H="Unknown -- Warning: Delta file
(\"$DELTA\") not found";
SIZES=$SIZES"0,";
fi;
# Check parent file
PARENT=`ParentFile "$FILE"`;
if [ `FileExists "$PARENT"` = "true" ]; then
# Check CID chain between this file and its
parent
RESULT_CID_chain_check=`CID_chain_check
"$FILE"`;
# Display file name and size in human format. If
the CID is broken say it as well.
echo -e "$TAB$FILE Size: $SIZE_H
$RESULT_CID_chain_check"
FILE=`ParentFile "$FILE"`;
TAB=$TAB" ";
else
echo -e "$TAB$FILE Size: $SIZE_H -- Warning:
Parent file (\"$PARENT\") not found. Unable to continue checking the
chain of snapshots. Exiting.";
return -1;
fi;
done;
FLAT=`DeltaOrFlat "$FILE"`;
SIZE_H=`SizeH "$FLAT"`;
SIZES=$SIZES`Size "$FLAT"`"]";
echo -e "$TAB Base Disk: $FILE Size: $SIZE_H"
if [ "$HAS_SNAPSHOTS" = "1" ] ; then echo 'Space needed on this
Datastore to delete all the snapshots of this disk is: ' `SizeNeeded
"$SIZES"`; fi; }

#------- SnapVMX -------------------------------------------------------


--
function SnapVMX () {
# Usage: SnapVMX FILE.vmx
# Extract the list of disks attached to the VM and pass them to the
SnapTree function.
if [ `FileExists "$1"` = "false" ]; then echo "VM Configuration
file \"$1\" not found. Exiting." ; return -1; fi;
# Get list of true SCSI
SCSI_TRUE_LIST=`egrep -i '^scsi[0-9]+:[0-9]+.present = "true"'
"$1" | awk -F'.' '{ print $1 }' `;
# Go through the list of disks on the VM
for SCSI in $SCSI_TRUE_LIST ; do
# Get Disk name
VMDK_VMX=`grep -i "^$SCSI.fileName" "$1" | awk -F'"' '{
print $2 }'` ;
SnapTree "$VMDK_VMX";
echo "----------------";
done;}
#-----------------------------------------------------------------------
--