有没有办法调整虚拟机磁盘的大小?比如将磁盘大小从 32GB 增加到 64GB。我在 Ubuntu 服务器 11.10 64 位上运行 KVM/Qemu。谢谢。
答案1
在基于 Debian 的发行版上,你应该使用virt-resize
。这现在几乎可以处理引擎盖下的所有事情。假设你的图像名为Windows 7(为什么不呢?)首先确保您的虚拟机已关闭:
安装工具:
# apt-get install libguestfs-tools
获取虚拟机磁盘的位置:
# virsh dumpxml Win7 | xpath -e /domain/devices/disk/source
Found 2 nodes in stdin:
-- NODE --
<source file="/var/lib/libvirt/images/Win7.img" />
-- NODE --
<source file="/var/lib/libvirt/images/Win7.iso" />
您可能需要适应/var/lib/libvirt/images/Win7.img
以下几点:
# virt-filesystems --long --parts --blkdevs -h -a /var/lib/libvirt/images/Win7.img
Name Type MBR Size Parent
/dev/sda1 partition 07 100M /dev/sda
/dev/sda2 partition 07 32G /dev/sda
/dev/sda device - 32G -
创建你的 64G 磁盘:
# truncate -s 64G /var/lib/libvirt/images/outdisk
您需要扩展 /dev/sda2(不是启动分区):
# virt-resize --expand /dev/sda2 /var/lib/libvirt/images/Win7.img /var/lib/libvirt/images/outdisk
Examining /var/lib/libvirt/images/Win7.img ...
100% [progress bar] --:--
**********
Summary of changes:
/dev/sda1: This partition will be left alone.
/dev/sda2: This partition will be resized from 32G to 64G. The
filesystem ntfs on /dev/sda2 will be expanded using the
'ntfsresize' method.
**********
Setting up initial partition table on outdisk ...
Copying /dev/sda1 ...
Copying /dev/sda2 ...
100% [progress bar] 00:00
100% [progress bar] 00:00
Expanding /dev/sda2 using the 'ntfsresize' method ...
Resize operation completed with no errors. Before deleting the old
disk, carefully check that the resized disk boots and works correctly.
为了以防万一,请进行备份(mv
如果您不想要备份,请使用):
# cp /var/lib/libvirt/images/Win7.img /var/lib/libvirt/images/Win7.img.old
# mv /var/lib/libvirt/images/outdisk /var/lib/libvirt/images/Win7.img
现在启动!
更多信息:人virt-resize
答案2
我建议在执行任何操作之前,先完整复制一份磁盘映像,然后当所有磁盘映像损坏时,您可以将其复制回来重新开始。
您需要做三件事:
1) 使磁盘映像更大。在您的主机中:
qemu-img resize foo.qcow2 +32G
现在您的客户可以看到更大的磁盘,但仍然有旧的分区和文件系统。
2) 使磁盘映像内的分区更大。为此,您需要在客户机中启动 LiveCD,因为您无法弄乱已安装的分区。这相当复杂,可能是最危险的部分。这里要复制的内容很多,所以我现在只提供链接。您要执行如下操作:
http://www.howtoforge.com/linux_resizing_ext3_partitions_p2
或者 2b) 如果您只是想要更多存储空间,创建新分区会更简单(也更安全)。使用 fdisk 或 cfdisk,或任何您觉得合适的工具 - 您现在应该会在客户磁盘上看到一大堆未分配的空间。
3) 最后,如果您调整了现有分区的大小,请将新更大分区内的文件系统变得更大(这实际上在上面链接的指南中)。在您的客户端中:
resize2fs /dev/sda1
答案3
我认为 Caesium 的答案很好,我只是想写下一些其他命令来实现同样的事情。
假设你有一个包含磁盘映像的文件disk.img
,即它有一个分区表和一个或多个分区,并且你想让最后一个分区更大。你需要做的是
1) 使整个文件变大,比如说 4GiB。一种快速的方法是使用dd
dd if=/dev/zero of=disk.img bs=1c seek=4G count=0
2)使用 fdisk 增大分区(我希望可以在 parted 或一些更好的工具中执行此操作...有人可以吗?)
fdisk disk.img
键入p
打印分区表并查找分区的起始扇区,例如分区 2 从扇区 106496 起始。
您要做的就是从分区表中删除该分区,然后创建一个从完全相同的扇区开始但结束于较晚扇区的新分区。然后该分区将包含有效的文件系统。
输入d
并提供要删除的分区编号。(吞咽!)
输入n
并给出所需的分区号,然后输入起始扇区。您必须使用与之前相同的起始扇区。最后输入结束扇区,或者让 fdisk 选择您可以使用的最高扇区。
键入w
将更改写回磁盘映像文件,然后退出 fdisk。
3) 现在您需要调整文件系统的大小。为此,您需要知道文件系统在磁盘映像内的偏移量(= 文件系统的位置)。如果您知道扇区大小(通常为 512),则可以根据扇区号计算此值,或者您可以使用parted
parted disk.img u b p
(parted
可以将命令作为命令行参数,因此这意味着“单位字节”和“打印”,因此它打印分区表并使用字节作为大小 uint。)
这将打印出分区的开始和结束。假设您的分区从 54525952 开始,然后使用 创建一个回送块设备losetup
。
losetup -f --show -o 54525952 disk.img
losetup
例如,告诉您它选择了哪个开发人员/dev/loop0
。现在您可以使用resize2fs
:
resize2fs /dev/loop0
最后删除循环设备
losetup -d /dev/loop0
答案4
#include <stdio.h>
static unsigned long auxfilesize(FILE* fp) {
unsigned long len=0;
int c=0;
while ( (c = fgetc(fp)) != -1 ) {
len++;
}
return len;
}
static unsigned long aux_copyNBytesFromTo(FILE* from, FILE* to,
unsigned long fromSize,
unsigned long bytes) {
unsigned long iter = 0;
while ( iter++ < fromSize ) {
int c = fgetc(from);
fputc(c, to);
}
iter-=1;
if ( fromSize < bytes ) {
while ( iter++ < bytes ) {
fputc(0, to);
}
}
return iter;
}
int main(int argc, char **argv) {
FILE *from = fopen(argv[1], "rb");
FILE *to = fopen(argv[2], "wb" );
unsigned long l = auxfilesize(from);
rewind(from);
aux_copyNBytesFromTo(from, to, l, (l + l/2)) ;
fclose(from);
fclose(to);
}
这个简单的程序在虚拟映像的末尾添加了 N 个字节。我使用 Windows XP 的 Paragon 分区映像来合并新创建的映像。在这里运行正常。