如何调整虚拟机磁盘大小?

如何调整虚拟机磁盘大小?

有没有办法调整虚拟机磁盘的大小?比如将磁盘大小从 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 分区映像来合并新创建的映像。在这里运行正常。

相关内容