Post on 18-Nov-2014
description
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;} #-------------------------------------------------------------------------