Nov 13

A. 扩大相对简单:
1. 先在 VMWARE 虚拟机属性中扩展磁盘到目标容量;
2. 下载 gparted LiveCDISO
3. 虚拟机光驱加载 ISO,启动时进 BIOS 设置光驱启动,然后进入 gparted 的 Linux 图形界面拖放一下即可。
4. 具体参考可 VMware虚拟机中调整Linux分区大小——使用GParted

B. 缩小较为复杂:(全文参考/复制自 减小 VMware 虚拟机的硬盘容量

以初始分配了 40GB 硬盘空间的虚拟机 Windows XP 为例,重新调整的目标为 10GB。

一、清理删除当前虚拟机下的所有快照,如果这些快照很重要不能删,那接下来的操作对你就没意义了。

二、确认虚拟机硬盘是拆分成多个文件的动态分配硬盘。本例子中,该虚拟机的所有文件放在 D:\Program files\Windows XP.vmwarevm 目录下。用 notepad2 打开虚拟机目录下和虚拟机同名的 *.vmdk 文件,如 『Windows XP.vmdk』。找到 # Extent description 部分,检查描述部分,一看就懂了。如图:

打开 vmdk 时几种可能的情况:

如果有多行描述,并且每行写了 SPARSE ,这就是我们需要的类型,拆分+动态分配磁盘。直接跳过后续转格式步骤,进入修改分区步骤即可。
如果有多行描述,但每行写的是 FLAT,则为拆分的预分配磁盘,需要转格式。
只有一行描述,写的是 FLAT,则是单一文件预分配磁盘,也需要转格式。
如果乱码或者提示打不开,则是单一文件动态分配磁盘,还是需要转格式。
VMWare 在新建虚拟机时会默认选择第一种类型,但玩家当初可能出于性能等考虑,选择了其它类型的虚拟硬盘。那么就需要使用 vmware 自带的一个命令行工具 vmware-vdiskmanager.exe转换成第一种类型。该工具在 vmware 安装目录下,默认为 “C:\Program Files (x86)\VMware\VMware Workstation\vmware-vdiskmanager.exe”。

转换方法:

该工具的命令行写法为:

工具名 参数1 源文件 参数2 参数3 目标名称
vmware-vdiskmanager -r(转格式) Windows XP.vmdk(例) -t(目的) 1(目的磁盘类型,1 为拆分+动态分配) newdisk.vmdk
该命令中, -r, -t 1两部分不需要变化, 目标名称 随意,之后会改名覆盖源文件。 源文件名 根据实际情况变化,而 工具名 通常要带上路径。

所以完整的命令大约是如下样子:

"C:\Program Files (x86)\VMware\VMware Workstation\vmware-vdiskmanager.exe" -r "d:\Program Files\Windows XP.vmwarevm\Windows XP.vmdk" -t 1 "d:\Program Files\Windows XP.vmwarevm\newdisk.vmdk"
1
"C:\Program Files (x86)\VMware\VMware Workstation\vmware-vdiskmanager.exe" -r "d:\Program Files\Windows XP.vmwarevm\Windows XP.vmdk" -t 1 "d:\Program Files\Windows XP.vmwarevm\newdisk.vmdk"

回车以后开始执行转换,看硬盘速度需要等一段时间。

转换完成以后,删除旧的 “Windows XP.vmdk” 和多个关联文件 “Windows XP-s0xx.vmdk”,然后把新的 newdisk.vmdk 重命名成 “Windows XP.vmdk” 以替换。其它 newdisk-s00x.vmdk 不用变。

三,打开虚拟机,进入系统。

在虚机机内,使用分区管理软件将硬盘分区缩小,并将空闲保留在右端,分区块保持在左端。我们的整体目标是从 40GB 缩到 10GB,则现在要多缩一点给后续操作留出余量。如图,暂时缩到 9GB。

Windows 7 以上系统,自带的磁盘管理就有『压缩卷』功能可以调整分区大小,WinXP 用的是 DiskGenius 免费版本。Linux 可参考上面扩大分区用的 gparted。 Win98 则需要寻找更古老的相应软件。
中途可能需要重启虚拟机,无妨,调整完关闭虚拟机即可。

四,加减乘除:

再次打开 Windows XP.vmdk 文件,定位到 # Extent description 部分。这次重点放在第二部分数字内容上,经计算,该数字为每个分块文件对应虚拟硬盘的簇数量,每簇 512 Byte,2 簇 = 1KB。我们的目标容量为 10GB,也就是:

10(GB)*1024(MB/GB)*1024(KB/MB)= 10485760 KB = 20971520 簇。

检查 # Extent description,前两个文件(前 N 个文件,这个 N 就是上面 10G 算出来的簇和 8323072 取模,也就是除法取整数)每个 8323072,则把第三行的数字改为:

20971520 – 8323072*2 = 4325376

并删掉后续各行及对应文件,我们就在 vmware 部分完成了虚拟机硬盘大小调整。

五,补足余量:

重开虚拟机。前次调整分区时,预留了 1GB 左右的余量。再次打开分区工具,把剩余未使用空间重新分配给各分区。

因为对计算机分区而言,由于存在分区表、启动扇区等原因,物理上的 10GB 硬盘空间在系统内表现是略小于 10GB 的,『内』『外』之间有差额,这对于虚拟机也一样成立。如果一开始就分区 10GB 而外部调整也等 10GB 的话,再次启动虚拟机就会报分区表错误,界时修改起来反而麻烦。现在这样按先预留余量,而后补足分区操作就没问题了。

六,清理死数据:

由于直接修改了描述文件,改小了簇数量,-s003.vmdk 里原本存于 4325376 之后的数据变成了永久的『死数据』。关闭虚拟机后,需要使用 vmware-vdiskmanager -r <源.vmdk> -t 1 <目标.vmdk> 再作一次转换。虽说是转换,但目的却是清理死数据。清理完以后直接单独替换新旧 -s003.vmdk 即可。(想想为什么?)

————————————————-

相关细节:

  • 虚拟机为 Linux 系统时原理一样。利用 GParted 等分区工具,首先缩小使用分区,并调整未分区块到尾端。关机编辑 vmdk 描述,开虚拟机调整补分区足余量,再关机清理死数据即可。
  • 预分配类型的虚拟硬盘必须先 vdiskmanager 转类型,不能直接操作。追求性能的话在编辑完再转回去。不过追求性能的话应该上 SSD,一力降十会。
  • 编辑 .vmx 和 .vmdk 文件不要用 Windows 自带的记事本。
  • 虚拟机备份直接复制整个目录即可。
  • 扩容不需要按本文操作,使用 vmware 自带功能即可。

————————————————-

如果 Linux 虚拟机在缩减后启动时出现 “Gave up waiting for suspend/resume device”并且启动时间很长:

Gave up waiting for suspend&resume device

原因:
调整分区大小或者移动分区的时候删除重建了 SWAP 分区,导致它的 UUID 变化。

解决办法:

使用 blkid 或者 lsblk -f 来确定 SWAP 分区的 UUID,并确保所有其他分区在 /etc/fstab 中具有正确的 UUID。

  1. 将正确的 SWAP 分区 UUID 写入 /etc/fstab
  2. 将正确的 SWAP 分区 UUID 写入 /etc/initramfs-tools/conf. d/resume
  3. 运行 sudo update-initramfs-u
  4. 运行 sudo reboot 重启,故障应该消失。

Nov 12

DNSQuerySniffer 查看系统 DNS 查询状况时发现每次查询都有重传 (DNS Retransmission) 现象(抓取方式选 WinPcap 时出现,选 Raw Sockets 不会)

折腾了好多天,卸载无数网络协议/驱动,最后发现卸载 VMware Bridge Protocol 现象消失,关掉开启的虚拟机也可以让现象消失。

这就不知道是 VMware 问题还是 WinPcap 问题了。。。 :?: :roll:

后续:

1. 上面已知 Bridge 模式会重传;
2. 试过 NAT 模式不会重传,但有无数 PTR 请求刷屏;
3. 用 Host-Only 模式,共享上网,目前一切OK。