How to move vmdk in ESXi/VMware

Post Reply
User avatar
LHammonds
Site Admin
Site Admin
Posts: 871
Joined: Fri Jul 31, 2009 6:27 pm
Are you a filthy spam bot?: No
Location: Behind You
Contact:

How to move vmdk in ESXi/VMware

Post: # 819Post LHammonds »

A project came up where I needed to detach a 10 terrabyte drive from a Windows 2008 server and attach it to a Windows 2012 server in VMware. I came up with a solution, tested it and documented it here in case I need to do this again in the future.

It is important to know the difference between a "copy" and "move" of data. A copy will always copy every last byte and duplicate it...meaning the more data there is, the longer it takes to duplicate. A move will not touch the actual bytes of data, just the reference to it...but only if the source and target are on the same partition. If data has to cross partition, the move command will then act exactly like the copy command. A move can complete its job in under a second whereas a copy can take hours or days to complete depending on the size of the data to duplicate.

For my situation, the storage was on the same partition in storage so a "copy" from one location to another was not needed...just a very quick move would be sufficient but there is nothing in the GUI that allows "moving" a disk from one machine to another. A vmotion migration would make a copy and then remove the original which would take a LONG time to complete and prone to various issues.

Using PuTTY to SSH into the ESXi host, you can issue commands to move the files VERY quickly if on the same storage system by using the unsupported and not recommended "mv" command. Once the disk(s) are offline'd in the OS and detached in VMware, you can then move the .vmdk files using "mv" and then use "vmfstools" command to rename the files once they reached their final destination.

EDIT: Found this search command for finding all snapshot-related files in your datastore:

Code: Select all

find /vmfs/volumes/ -name *-delta*;find /vmfs/volumes/ -name *-0000*

User avatar
LHammonds
Site Admin
Site Admin
Posts: 871
Joined: Fri Jul 31, 2009 6:27 pm
Are you a filthy spam bot?: No
Location: Behind You
Contact:

Procedure

Post: # 820Post LHammonds »

Here are the steps I came up with to follow once the migration was to start.

Here are the example data referenced in these steps and code:
  • Source server: OLD-PACS
  • Target server: NEW-PACS
  • Drive being moved - E:
  1. Disable local backup job(s) for OLD-PACS.
  2. Make sure E: does not exist on target server.
  3. Make sure no services that touch E: are running on the source nor the target.
  4. Verify that no snapshots exist on either server. (examine datastore)
  5. Verify that no orphan files exist on either server. (examine datastore)
  6. On source server, offline each disk of E: drive.
  7. Shutdown OLD-PACS.
  8. In VMware, detach all disks related to E: drive. in my case they are:
    - OLD-PACS_6.vmdk
    - OLD-PACS_4.vmdk
    - OLD-PACS_2.vmdk
    - OLD-PACS_10.vmdk
    - OLD-PACS_3.vmdk
    - OLD-PACS_1.vmdk
  9. SSH into ESXi host and run pacs-move.sh script which moves and renames the files.
  10. Attach all disks on the target drive. In my case, it are these files which were renamed in the move process to match the new server:
    - NEW-PACS_3.vmdk
    - NEW-PACS_4.vmdk
    - NEW-PACS_5.vmdk
    - NEW-PACS_6.vmdk
    - NEW-PACS_7.vmdk
    - NEW-PACS_8.vmdk
  11. In NEW-PACS Storage Manager, rescan all disks.
  12. In NEW-PACS Storage Manager, online each disk (if offline).
  13. In NEW-PACS Storage Manager, right-click on a disk and choose "Import Foreign Media."
  14. Create a snapshot of the NEW-PACS server.
  15. Finish the upgrade/migration of the server software.
  16. Verify completed upgrade and full functionality of new server.
  17. Remove the snapshot for NEW-PACS.
  18. Enable local backup job(s) NEW-PACS.
  19. Once local backup is completed in a few days, do another local backup to catch up.
  20. After 2nd local backup completes, disable local backup job for NEW-PACS.
  21. Start the offsite backup of NEW-PACS.
  22. Once offsite backup is done, re-enable local backup job(s) and stick to the normal schedule.

User avatar
LHammonds
Site Admin
Site Admin
Posts: 871
Joined: Fri Jul 31, 2009 6:27 pm
Are you a filthy spam bot?: No
Location: Behind You
Contact:

pacs-move.sh

Post: # 821Post LHammonds »

Create the script file/location:

Code: Select all

mkdir /var/scripts
touch /var/scripts/pacs-move.sh
chmod 755 /var/scripts/pacs-move.sh
Copy and paste the contents of the script below into /var/scripts/pacs-move.sh

NOTE: The SourceName and TargetName are the names of the VMs which are also the names of the folders the VMs reside in and are the prefixes to the .vmdk files. The Source and Target are the full paths to each VMs file location. The names and amount of SourceFiles and TargetFiles will vary and needs to be adapted to each situation. The TargetFiles in particular need to be names of files that do NOT exist in the target location.

Code: Select all

#!/bin/sh
## BusyBox script       ##
## Author: LHammonds    ##
## Version: 1.0         ##
## Date: 2020-04-20     ##
## ESXi: 6.0.0          ##
## BusyBox: 1.20.2      ##
SourceName="OLD-PACS"
TargetName="NEW-PACS"
Source="/vmfs/volumes/123e45e6-efe789cb-b0c1-2345ef6a7c8f/${SourceName}"
Target="/vmfs/volumes/123e45e6-efe789cb-b0c1-2345ef6a7c8f/${TargetName}"
VMXFile="${Source}/${SourceName}.vmx"
LogFile="/var/scripts/pacs-move.log"

SourceFile1="${SourceName}_6"
SourceFile2="${SourceName}_4"
SourceFile3="${SourceName}_2"
SourceFile4="${SourceName}_10"
SourceFile5="${SourceName}_3"
SourceFile6="${SourceName}_1"

TargetFile1="${TargetName}_3"
TargetFile2="${TargetName}_4"
TargetFile3="${TargetName}_5"
TargetFile4="${TargetName}_6"
TargetFile5="${TargetName}_7"
TargetFile6="${TargetName}_8"

f_exit()
{
  ## Terminate the script.
  echo "`date +%Y-%m-%d_%H:%M:%S` - Script aborted." | tee -a ${LogFile}
  exit 1
}

f_testfolders()
{
  ## Make sure the source/target did not change.
  if [ -d ${Source} ];then
    echo "[INFO] Source directory exists." | tee -a ${LogFile}
  else
    echo "[ERROR] Source directory not found! ${Source}" | tee -a ${LogFile}
    f_exit
  fi
  if [ -d ${Target} ];then
    echo "[INFO] Target directory exists" | tee -a ${LogFile}
  else
    echo "[ERROR] Target directory not found! ${Target}" | tee -a ${LogFile}
    f_exit
  fi
  ## If VM configuration file not found, abort script.
  if [ ! -f ${VMXFile} ];then
    echo "[ERROR] ${VMXFile} does not exist." | tee -a ${LogFile}
    f_exit
  fi
}

f_testfiles()
{
  ## If snapshot exists, abort script.
  if [ -f ${Source}/${1}-??????.vmdk ];then
    echo "[ERROR] ${1}: Snapshot found." | tee -a ${LogFile}
    f_exit
  else
    echo "[INFO] ${1}: Snapshot not detected." | tee -a ${LogFile}
  fi
  ## If file still attached to VM, abort script.
  if grep -Fxq ${1} ${VMXFile}
  then
    echo "[ERROR] ${1}: File still attached to VM." | tee -a ${LogFile}
    f_exit
  else
    echo "[INFO] ${1}: File not attached to VM." | tee -a ${LogFile}
  fi
}

f_movefiles()
{
  ## Move the files.
  echo "[INFO] Moving ${1}" | tee -a ${LogFile}
  mv ${Source}/${1}.vmdk ${Target}/.
  mv ${Source}/${1}-flat.vmdk ${Target}/.
  ## If move did not work, display error but continue on.
  if [ ! -f ${Target}/${1}.vmdk ];then
    echo "[WARNING] {$1}.vmdk File not at target." | tee -a ${LogFile}
  fi
  if [ ! -f ${Target}/${1}-flat.vmdk ];then
    echo "[WARNING] {$1}-flat.vmdk File not at target." | tee -a ${LogFile}
  fi
}

f_renamefiles()
{
  cd ${Target}
  echo "[INFO] Renaming ${1} to ${2}" | tee -a ${LogFile}
  vmkfstools -E ${1} ${2}
  ## If rename did not work, display error but continue on.
  if [ ! -f ${2} ];then
    echo "[WARNING] ${2} does not exist." | tee -a ${LogFile}
  fi
}

echo "`date +%Y-%m-%d_%H:%M:%S` - Script started" | tee -a ${LogFile}

f_testfolders
f_testfiles ${SourceFile1}
f_testfiles ${SourceFile2}
f_testfiles ${SourceFile3}
f_testfiles ${SourceFile4}
f_testfiles ${SourceFile5}
f_testfiles ${SourceFile6}

echo "[INFO] Move started." | tee -a ${LogFile}
f_movefiles ${SourceFile1}
f_movefiles ${SourceFile2}
f_movefiles ${SourceFile3}
f_movefiles ${SourceFile4}
f_movefiles ${SourceFile5}
f_movefiles ${SourceFile6}

## Rename the files to match the new VM.
echo "[INFO] Rename started." | tee -a ${LogFile}
f_renamefiles ${SourceFile1}.vmdk ${TargetFile1}.vmdk
f_renamefiles ${SourceFile2}.vmdk ${TargetFile2}.vmdk
f_renamefiles ${SourceFile3}.vmdk ${TargetFile3}.vmdk
f_renamefiles ${SourceFile4}.vmdk ${TargetFile4}.vmdk
f_renamefiles ${SourceFile5}.vmdk ${TargetFile5}.vmdk
f_renamefiles ${SourceFile6}.vmdk ${TargetFile6}.vmdk

echo "`date +%Y-%m-%d_%H:%M:%S` - Script completed" | tee -a ${LogFile}
exit 0
Example log results when a snapshots exists:

Code: Select all

2020-04-20_15:05:28 - Script started
[INFO] Source directory exists.
[INFO] Target directory exists
[ERROR] OLD-PACS_6: Snapshot found.
2020-04-20_15:05:28 - Script aborted.
Example log results when the .vmdk had not been detached:

Code: Select all

2020-04-20_15:08:01 - Script started
[INFO] Source directory exists.
[INFO] Target directory exists
[INFO] OLD-PACS_6: Snapshot not detected.
[ERROR] OLD-PACS_6: File still attached to VM.
2020-04-20_15:08:01 - Script aborted.
Example log results when it works as expected:

Code: Select all

2020-04-20_15:10:01 - Script started
[INFO] Source directory exists.
[INFO] Target directory exists
[INFO] OLD-PACS_6: Snapshot not detected.
[INFO] OLD-PACS_6: File not attached to VM.
[INFO] OLD-PACS_4: Snapshot not detected.
[INFO] OLD-PACS_4: File not attached to VM.
[INFO] OLD-PACS_2: Snapshot not detected.
[INFO] OLD-PACS_2: File not attached to VM.
[INFO] OLD-PACS_10: Snapshot not detected.
[INFO] OLD-PACS_10: File not attached to VM.
[INFO] OLD-PACS_3: Snapshot not detected.
[INFO] OLD-PACS_3: File not attached to VM.
[INFO] OLD-PACS_1: Snapshot not detected.
[INFO] OLD-PACS_1: File not attached to VM.
[INFO] Move started.
[INFO] Moving OLD-PACS_6
[INFO] Moving OLD-PACS_2
[INFO] Moving OLD-PACS_2
[INFO] Moving OLD-PACS_10
[INFO] Moving OLD-PACS_3
[INFO] Moving OLD-PACS_1
[INFO] Rename started.
[INFO] Renaming OLD-PACS_6.vmdk to NEW-PACS_3.vmdk
[INFO] Renaming OLD-PACS_4.vmdk to NEW-PACS_4.vmdk
[INFO] Renaming OLD-PACS_2.vmdk to NEW-PACS_5.vmdk
[INFO] Renaming OLD-PACS_10.vmdk to NEW-PACS_6.vmdk
[INFO] Renaming OLD-PACS_3.vmdk to NEW-PACS_7.vmdk
[INFO] Renaming OLD-PACS_1.vmdk to NEW-PACS_8.vmdk
2020-04-20_15:10:01 - Script completed

Post Reply