缩小 vmdk Virtualbox 磁盘映像
Shrink a vmdk Virtualbox disk image
VirtualBox 能够压缩(减小大小).vdi
个图像,但不能压缩 .vmdk
个磁盘图像。但是我们可以压缩 .vmdk
个文件,如果我们:
- 分离
- 转换为
.vdi
- 紧凑
- 转换回
.vmdk
- 再次连接到原来的虚拟机
所以我尝试用这个脚本缩小我的 VirtualBox 图像:
#/bin/bash
VM_PATH=~/VirtualBox\ VMs
cd "$VM_PATH"
VM="$(ls ffnord-example_gc-gw0_* -d -1|head -n 1)"
cd "$VM"
VM_VDMK_NAME="$(ls *.vmdk -1|head -n 1)"
VM_NAME="$VM_PATH/$VM/$VM_VDMK_NAME"
echo reducing size of "$VM_NAME"
ls -lah "$VM_NAME"
set -x
vboxmanage showvminfo "${VM}"
vboxmanage storageattach "${VM}" --storagectl SATA --port 0 --device 0 --type hdd --medium none
vboxmanage clonehd --format vdi "${VM_NAME}" /tmp/VM-disk.vdi
vboxmanage closemedium disk "${VM_NAME}" --delete
vboxmanage modifyhd /tmp/VM-disk.vdi --compact
vboxmanage clonehd --format vmdk /tmp/VM-disk.vdi "${VM_NAME}"
vboxmanage closemedium disk /tmp/VM-disk.vdi --delete
vboxmanage storageattach "${VM}" --storagectl SATA --port 0 --device 0 --type hdd --medium 4/VMs/VM-disk1.vmdk
我改编了 this script from crysol 但似乎这不适用于 Ubuntu?第一个 vboxmanage storageattach
立即以错误开始:
VBoxManage: error: Could not find a controller named 'SATA'
如果我尝试 "SATA Controller"
:
vboxmanage storageattach "${VM}" --storagectl "SATA Controller" --port 0 --device 0 --type hdd --medium none
我收到这个错误:
VBoxManage: error: No storage device attached to device slot 0 on port 0 of controller 'SATA Controller'
VBoxManage: error: Details: code VBOX_E_OBJECT_NOT_FOUND (0x80bb0001), component SessionMachine, interface IMachine, callee nsISupports
VBoxManage: error: Context: "DetachDevice(Bstr(pszCtl).raw(), port, device)" at line 381 of file VBoxManageStorageController.cpp
如果我注释掉那些 vboxmanage storageattach
行,脚本工作正常,但生成的 VM 大小与以前相同,并且不再启动。
我找到了 solution:
首先在 VM 中用零填充所有空闲 space:
cat /dev/zero > zero.fill;sync;sleep 1;sync;rm -f zero.fill
在您的主机中,从 VMware Knowledge Base:
安装 vmware-vdiskmanager
cd /tmp/
wget http://kb.vmware.com/selfservice/viewAttachment.do?attachID=1023856-vdiskmanager-linux.7.0.1.zip&documentID=1023856
unp 1023856-vdiskmanager-linux-7.0.1.zip
mv 1023856-vmware-vdiskmanager-linux.7.0.1 /usr/bin/vmware-vdiskmanager
chmod +x /usr/bin/vmware-vdiskmanager
请注意,您有足够的可用磁盘-space在开始之前,您需要在此过程中将 MV 增长到两倍大小。
然后压缩:
/usr/bin/vmware-vdiskmanager -k ~/VirtualBox\ VMs/<virtual disk.vmdk>
我无法让 rubo77s 解决方案高于 vmware-vdiskmanager 解决方案,我相信它依赖于 vmware 工作站或 vmware 播放器,我没有,我确实找到了可执行文件,但它给了我错误。
我用他的零命令解决了这个问题
cat /dev/zero > zero.fill;sync;sleep 1;sync;rm -f zero.fill
然后使用 virtualboxes 导出到 .ova 工具。
这将导致 ova stripping/compressing 归零 space。
然后你可以重新导入它。
我不需要安装 VMWare 也不需要转换回 VMDK,所以我使用了
主机内部:
sudo yum clean all
sudo dd if=/dev/zero of=/EMPTY bs=1M
sudo rm -f /EMPTY
cat /dev/null > ~/.bash_history && history -c && exit
那么客户机关闭后:
$ vboxmanage clonehd --format vdi centos-7-1-1.x86_64.vmdk newdisk.vdi
$ ls -lh
-rwx------+ 1 Chloe None 39G Mar 26 14:52 centos-7-1-1.x86_64.vmdk
-rwx------+ 1 Chloe None 22G Mar 26 15:01 newdisk.vdi
它也允许稍后压缩
$ vboxmanage modifyhd newdisk.vdi --compact
在 VirtualBox GUI 中,我 selected 'Choose Virtual Hard Disk File' 到 select 新文件。
我得到了这个 oooold 脚本,它允许您清除分区 Windows 内所有不必要的数据。它是用 VBscript 编写的:
`REM This script is published under the BSD Licence
REM http://www.opensource.org/licenses/bsd-license.php
Option Explicit
Const sDefaultDir = "C:\"
Const sDefaultFilename = "overwrite.garbage"
Const lStartBlockSize = 32768
Call Main
Sub Main()
Dim sPath, sFilename
Dim oArgs, oFS, oDrive, oRegExp, oMatches
ShowStartMsg
Set oArgs = WScript.Arguments
Set oFS = CreateObject("Scripting.FileSystemObject")
If oArgs.Count = 1 Then
If oArgs(0) = "/?" Then
ShowHelp true
End If
End If
If oArgs.Count > 2 Then
ShowMsg "ERROR: Invalid command line parameters (too many parameters specified)", true, true
End If
If oArgs.Count > 0 Then
sPath = oFS.GetAbsolutePathName(oArgs(0))
Else
sPath = ""
End If
If oFS.FolderExists(sPath) Then
WScript.Echo "Checking folder " & Chr(34) & sPath & Chr(34) & ": OK"
If Right(sPath, 1) <> "\" Then
sPath = sPath & "\"
End If
Else
WScript.Echo "Checking folder " & Chr(34) & sPath & Chr(34) & ": FAILED"
sPath = sDefaultDir
WScript.Echo "INFO: Using default folder " & Chr(34) & sPath & Chr(34)
End If
If oArgs.Count = 2 Then
sFilename = oArgs(1)
If sFilename = "" Then
ShowMsg "ERROR: Filename must not be empty", true, true
End If
Else
sFilename = sDefaultFilename
WScript.Echo "INFO: Using default filename " & Chr(34) & sFilename & Chr(34)
End If
Set oRegExp = new RegExp
oRegExp.Pattern = "[\\/\:\*\?\" & Chr(34) & "\<\>\|]"
Set oMatches = oRegExp.Execute(sFilename)
If oMatches.Count = 0 Then
WScript.Echo "Validating filename: OK"
Else
WScript.Echo "Validating filename: FAILED"
ShowMsg "ERROR: Filename must not contain the following characters:"_
& " \ / : * ? " & Chr(34) & " < > |", true, true
End If
If oFS.FileExists(sPath & sFilename) = False Then
WScript.Echo "Ensuring that file " & Chr(34) & sFilename & Chr(34) &_
" does not exist: OK"
Else
WScript.Echo "Ensuring that file " & Chr(34) & sFilename & Chr(34) &_
" does not exist: FAILED"
ShowMsg "ERROR: File " & Chr(34) & sPath & sFilename & Chr(34) & " already exists", true, true
End If
Set oDrive = oFS.GetDrive(oFS.GetDriveName(sPath))
If UCase(oDrive.FileSystem) = "NTFS" Then
WScript.Echo "Checking for NTFS: OK"
Else
WScript.Echo "Checking for NTFS: FAILED"
ShowMsg "ERROR: " & oDrive.FileSystem & " file system not supported", true, true
End If
Select Case oDrive.DriveType
Case 1, 2
WScript.Echo "Checking drive type: OK"
Case Else
WScript.Echo "Checking drive type: FAILED"
Select Case oDrive.DriveType
Case 3
ShowMsg "ERROR: Network drives are not supported", true, true
Case 4
ShowMsg "ERROR: CD-ROM drives are not supported", true, true
Case 5
ShowMsg "ERROR: RAM Disk drives are not supported", true, true
Case Else
ShowMsg "ERROR: Unkown drives are not supported", true, true
End Select
End Select
If oDrive.FreeSpace > 0 Then
WScript.Echo "Checking for free space: OK"
Else
WScript.Echo "Checking for free space: FAILED"
WScript.Echo "INFO: No free space available (no action required)"
ShowMsg "INFO: Exiting Overwrite Script...", false, true
End If
WScript.Echo "Creating garbage file " & Chr(34) & sPath & sFilename & Chr(34) & "..."
CreateGarbageFile sPath & sFilename, oFS
WScript.Echo "Garbage file successfully created!"
WScript.Echo "INFO: " & oDrive.AvailableSpace & " byte(s) remained which could not be overwritten"
WScript.Echo "Deleting garbage file..."
oFS.DeleteFile sPath & sFilename
WScript.Echo "Garbage file successfully deleted!"
WScript.Echo "Exiting Overwrite Script..."
WScript.Quit
End Sub
Sub CreateGarbageFile(sAbsFilename, oFS)
Dim bSngByteBlock
Dim sBlock
Dim oFile, oDrive
bSngByteBlock = false
Set oDrive = oFS.GetDrive(oFS.GetDriveName(sAbsFilename))
Set oFile = oFS.CreateTextFile(sAbsFilename, false, false)
sBlock = String(lStartBlockSize, 0)
On Error Resume Next
Do While oDrive.FreeSpace > 0
If oDrive.FreeSpace < lStartBlockSize Then
If bSngByteBlock = false Then
WScript.Echo "INFO: Falling back to single byte block"
bSngByteBlock = true
sBlock = String(1, 0)
End If
End If
oFile.Write sBlock
If Err.Number <> 0 Then
WScript.Echo "WARNING: Error " & Chr(34) & Err.Description & Chr(34) & " ("_
& Err.Number & ") occured while writing garbage file"
Exit Do
End If
Loop
On Error GoTo 0
oFile.Close
End Sub
Sub ShowStartMsg()
WScript.Echo "Overwrite Script 1.0 (2004-09-05)"
WScript.Echo "Copyright (C) 2004 Dennis Dietrich"
WScript.Echo "http://www.myblog.de/scotty"
WScript.Echo ""
WScript.Echo "WARNING: The script is experimental. Use it at your own risk!"
WScript.Echo "To cancel the execution of this script press CTRL + C"
WScript.Echo ""
End Sub
Sub ShowMsg(sMsg, bShowHelpHint, bExit)
WScript.Echo sMsg
If bShowHelpHint = True Then
WScript.Echo ""
WScript.Echo "Use " & Chr(34) & "CScript Overwrite.vbs /?" & Chr(34) & " to get help."
End If
If bExit = True Then
WScript.Quit
End If
End Sub
Sub ShowHelp(bExit)
WScript.Echo "Cleans free disk space from recoverable data by overwriting it with random"
WScript.Echo "information. For a higher level of security execute this script at least three"
WScript.Echo "times. Only NTFS partitions are supported."
WScript.Echo ""
WScript.Echo "CScript Overwrite.vbs [path] [filename]"
If bExit = True Then
WScript.Quit
End IF
End Sub`
(灵感来自 http://www.codeproject.com/KB/vbscript/overwrite_script.aspx)
仅供参考:
随着 vmware 对其知识库进行现代化改造,下载 link 不再有效。
经过一番搜索,我找到了这个 link https://kb.vmware.com/sfc/servlet.shepherd/version/download/068f4000009EgK0AAK
附带的 zip
案例中包含的内容
https://kb.vmware.com/s/article/1023856?lang=en_US&queryTerm=1023856
我的 Ubuntu 中的二进制文件也因缺少库而失败,但正在下载
http://archive.ubuntu.com/ubuntu/pool/universe/o/openssl098/libssl0.9.8_0.9.8o-7ubuntu3.1_i386.deb 安装它很有帮助。
基本上这个答案应该只是 rubo77 对 的评论 - 但我的声誉太低所以你去吧。
VirtualBox 能够压缩(减小大小).vdi
个图像,但不能压缩 .vmdk
个磁盘图像。但是我们可以压缩 .vmdk
个文件,如果我们:
- 分离
- 转换为
.vdi
- 紧凑
- 转换回
.vmdk
- 再次连接到原来的虚拟机
所以我尝试用这个脚本缩小我的 VirtualBox 图像:
#/bin/bash
VM_PATH=~/VirtualBox\ VMs
cd "$VM_PATH"
VM="$(ls ffnord-example_gc-gw0_* -d -1|head -n 1)"
cd "$VM"
VM_VDMK_NAME="$(ls *.vmdk -1|head -n 1)"
VM_NAME="$VM_PATH/$VM/$VM_VDMK_NAME"
echo reducing size of "$VM_NAME"
ls -lah "$VM_NAME"
set -x
vboxmanage showvminfo "${VM}"
vboxmanage storageattach "${VM}" --storagectl SATA --port 0 --device 0 --type hdd --medium none
vboxmanage clonehd --format vdi "${VM_NAME}" /tmp/VM-disk.vdi
vboxmanage closemedium disk "${VM_NAME}" --delete
vboxmanage modifyhd /tmp/VM-disk.vdi --compact
vboxmanage clonehd --format vmdk /tmp/VM-disk.vdi "${VM_NAME}"
vboxmanage closemedium disk /tmp/VM-disk.vdi --delete
vboxmanage storageattach "${VM}" --storagectl SATA --port 0 --device 0 --type hdd --medium 4/VMs/VM-disk1.vmdk
我改编了 this script from crysol 但似乎这不适用于 Ubuntu?第一个 vboxmanage storageattach
立即以错误开始:
VBoxManage: error: Could not find a controller named 'SATA'
如果我尝试 "SATA Controller"
:
vboxmanage storageattach "${VM}" --storagectl "SATA Controller" --port 0 --device 0 --type hdd --medium none
我收到这个错误:
VBoxManage: error: No storage device attached to device slot 0 on port 0 of controller 'SATA Controller'
VBoxManage: error: Details: code VBOX_E_OBJECT_NOT_FOUND (0x80bb0001), component SessionMachine, interface IMachine, callee nsISupports
VBoxManage: error: Context: "DetachDevice(Bstr(pszCtl).raw(), port, device)" at line 381 of file VBoxManageStorageController.cpp
如果我注释掉那些 vboxmanage storageattach
行,脚本工作正常,但生成的 VM 大小与以前相同,并且不再启动。
我找到了 solution:
首先在 VM 中用零填充所有空闲 space:
cat /dev/zero > zero.fill;sync;sleep 1;sync;rm -f zero.fill
在您的主机中,从 VMware Knowledge Base:
安装 vmware-vdiskmanagercd /tmp/
wget http://kb.vmware.com/selfservice/viewAttachment.do?attachID=1023856-vdiskmanager-linux.7.0.1.zip&documentID=1023856
unp 1023856-vdiskmanager-linux-7.0.1.zip
mv 1023856-vmware-vdiskmanager-linux.7.0.1 /usr/bin/vmware-vdiskmanager
chmod +x /usr/bin/vmware-vdiskmanager
请注意,您有足够的可用磁盘-space在开始之前,您需要在此过程中将 MV 增长到两倍大小。
然后压缩:
/usr/bin/vmware-vdiskmanager -k ~/VirtualBox\ VMs/<virtual disk.vmdk>
我无法让 rubo77s 解决方案高于 vmware-vdiskmanager 解决方案,我相信它依赖于 vmware 工作站或 vmware 播放器,我没有,我确实找到了可执行文件,但它给了我错误。
我用他的零命令解决了这个问题
cat /dev/zero > zero.fill;sync;sleep 1;sync;rm -f zero.fill
然后使用 virtualboxes 导出到 .ova 工具。
这将导致 ova stripping/compressing 归零 space。 然后你可以重新导入它。
我不需要安装 VMWare 也不需要转换回 VMDK,所以我使用了
主机内部:
sudo yum clean all
sudo dd if=/dev/zero of=/EMPTY bs=1M
sudo rm -f /EMPTY
cat /dev/null > ~/.bash_history && history -c && exit
那么客户机关闭后:
$ vboxmanage clonehd --format vdi centos-7-1-1.x86_64.vmdk newdisk.vdi
$ ls -lh
-rwx------+ 1 Chloe None 39G Mar 26 14:52 centos-7-1-1.x86_64.vmdk
-rwx------+ 1 Chloe None 22G Mar 26 15:01 newdisk.vdi
它也允许稍后压缩
$ vboxmanage modifyhd newdisk.vdi --compact
在 VirtualBox GUI 中,我 selected 'Choose Virtual Hard Disk File' 到 select 新文件。
我得到了这个 oooold 脚本,它允许您清除分区 Windows 内所有不必要的数据。它是用 VBscript 编写的:
`REM This script is published under the BSD Licence
REM http://www.opensource.org/licenses/bsd-license.php
Option Explicit
Const sDefaultDir = "C:\"
Const sDefaultFilename = "overwrite.garbage"
Const lStartBlockSize = 32768
Call Main
Sub Main()
Dim sPath, sFilename
Dim oArgs, oFS, oDrive, oRegExp, oMatches
ShowStartMsg
Set oArgs = WScript.Arguments
Set oFS = CreateObject("Scripting.FileSystemObject")
If oArgs.Count = 1 Then
If oArgs(0) = "/?" Then
ShowHelp true
End If
End If
If oArgs.Count > 2 Then
ShowMsg "ERROR: Invalid command line parameters (too many parameters specified)", true, true
End If
If oArgs.Count > 0 Then
sPath = oFS.GetAbsolutePathName(oArgs(0))
Else
sPath = ""
End If
If oFS.FolderExists(sPath) Then
WScript.Echo "Checking folder " & Chr(34) & sPath & Chr(34) & ": OK"
If Right(sPath, 1) <> "\" Then
sPath = sPath & "\"
End If
Else
WScript.Echo "Checking folder " & Chr(34) & sPath & Chr(34) & ": FAILED"
sPath = sDefaultDir
WScript.Echo "INFO: Using default folder " & Chr(34) & sPath & Chr(34)
End If
If oArgs.Count = 2 Then
sFilename = oArgs(1)
If sFilename = "" Then
ShowMsg "ERROR: Filename must not be empty", true, true
End If
Else
sFilename = sDefaultFilename
WScript.Echo "INFO: Using default filename " & Chr(34) & sFilename & Chr(34)
End If
Set oRegExp = new RegExp
oRegExp.Pattern = "[\\/\:\*\?\" & Chr(34) & "\<\>\|]"
Set oMatches = oRegExp.Execute(sFilename)
If oMatches.Count = 0 Then
WScript.Echo "Validating filename: OK"
Else
WScript.Echo "Validating filename: FAILED"
ShowMsg "ERROR: Filename must not contain the following characters:"_
& " \ / : * ? " & Chr(34) & " < > |", true, true
End If
If oFS.FileExists(sPath & sFilename) = False Then
WScript.Echo "Ensuring that file " & Chr(34) & sFilename & Chr(34) &_
" does not exist: OK"
Else
WScript.Echo "Ensuring that file " & Chr(34) & sFilename & Chr(34) &_
" does not exist: FAILED"
ShowMsg "ERROR: File " & Chr(34) & sPath & sFilename & Chr(34) & " already exists", true, true
End If
Set oDrive = oFS.GetDrive(oFS.GetDriveName(sPath))
If UCase(oDrive.FileSystem) = "NTFS" Then
WScript.Echo "Checking for NTFS: OK"
Else
WScript.Echo "Checking for NTFS: FAILED"
ShowMsg "ERROR: " & oDrive.FileSystem & " file system not supported", true, true
End If
Select Case oDrive.DriveType
Case 1, 2
WScript.Echo "Checking drive type: OK"
Case Else
WScript.Echo "Checking drive type: FAILED"
Select Case oDrive.DriveType
Case 3
ShowMsg "ERROR: Network drives are not supported", true, true
Case 4
ShowMsg "ERROR: CD-ROM drives are not supported", true, true
Case 5
ShowMsg "ERROR: RAM Disk drives are not supported", true, true
Case Else
ShowMsg "ERROR: Unkown drives are not supported", true, true
End Select
End Select
If oDrive.FreeSpace > 0 Then
WScript.Echo "Checking for free space: OK"
Else
WScript.Echo "Checking for free space: FAILED"
WScript.Echo "INFO: No free space available (no action required)"
ShowMsg "INFO: Exiting Overwrite Script...", false, true
End If
WScript.Echo "Creating garbage file " & Chr(34) & sPath & sFilename & Chr(34) & "..."
CreateGarbageFile sPath & sFilename, oFS
WScript.Echo "Garbage file successfully created!"
WScript.Echo "INFO: " & oDrive.AvailableSpace & " byte(s) remained which could not be overwritten"
WScript.Echo "Deleting garbage file..."
oFS.DeleteFile sPath & sFilename
WScript.Echo "Garbage file successfully deleted!"
WScript.Echo "Exiting Overwrite Script..."
WScript.Quit
End Sub
Sub CreateGarbageFile(sAbsFilename, oFS)
Dim bSngByteBlock
Dim sBlock
Dim oFile, oDrive
bSngByteBlock = false
Set oDrive = oFS.GetDrive(oFS.GetDriveName(sAbsFilename))
Set oFile = oFS.CreateTextFile(sAbsFilename, false, false)
sBlock = String(lStartBlockSize, 0)
On Error Resume Next
Do While oDrive.FreeSpace > 0
If oDrive.FreeSpace < lStartBlockSize Then
If bSngByteBlock = false Then
WScript.Echo "INFO: Falling back to single byte block"
bSngByteBlock = true
sBlock = String(1, 0)
End If
End If
oFile.Write sBlock
If Err.Number <> 0 Then
WScript.Echo "WARNING: Error " & Chr(34) & Err.Description & Chr(34) & " ("_
& Err.Number & ") occured while writing garbage file"
Exit Do
End If
Loop
On Error GoTo 0
oFile.Close
End Sub
Sub ShowStartMsg()
WScript.Echo "Overwrite Script 1.0 (2004-09-05)"
WScript.Echo "Copyright (C) 2004 Dennis Dietrich"
WScript.Echo "http://www.myblog.de/scotty"
WScript.Echo ""
WScript.Echo "WARNING: The script is experimental. Use it at your own risk!"
WScript.Echo "To cancel the execution of this script press CTRL + C"
WScript.Echo ""
End Sub
Sub ShowMsg(sMsg, bShowHelpHint, bExit)
WScript.Echo sMsg
If bShowHelpHint = True Then
WScript.Echo ""
WScript.Echo "Use " & Chr(34) & "CScript Overwrite.vbs /?" & Chr(34) & " to get help."
End If
If bExit = True Then
WScript.Quit
End If
End Sub
Sub ShowHelp(bExit)
WScript.Echo "Cleans free disk space from recoverable data by overwriting it with random"
WScript.Echo "information. For a higher level of security execute this script at least three"
WScript.Echo "times. Only NTFS partitions are supported."
WScript.Echo ""
WScript.Echo "CScript Overwrite.vbs [path] [filename]"
If bExit = True Then
WScript.Quit
End IF
End Sub`
(灵感来自 http://www.codeproject.com/KB/vbscript/overwrite_script.aspx)
仅供参考: 随着 vmware 对其知识库进行现代化改造,下载 link 不再有效。
经过一番搜索,我找到了这个 link https://kb.vmware.com/sfc/servlet.shepherd/version/download/068f4000009EgK0AAK
附带的 zip案例中包含的内容 https://kb.vmware.com/s/article/1023856?lang=en_US&queryTerm=1023856
我的 Ubuntu 中的二进制文件也因缺少库而失败,但正在下载 http://archive.ubuntu.com/ubuntu/pool/universe/o/openssl098/libssl0.9.8_0.9.8o-7ubuntu3.1_i386.deb 安装它很有帮助。
基本上这个答案应该只是 rubo77 对