¿Cómo cambiar el tamaño del disco de la máquina virtual?


23

¿Hay alguna forma de cambiar el tamaño del disco de una máquina virtual? Digamos que aumenta el tamaño del disco de 32 GB a 64 GB. Estoy ejecutando KVM / Qemu en el servidor Ubuntu 11.10 de 64 bits. Gracias.

Respuestas:


27

En la distribución basada en Debian deberías usar virt-resizeen su lugar. Esto maneja casi todo debajo del capó ahora. Supongamos que su imagen se llama Win7 (¿por qué no?). Lo primero es asegurarse de que su VM esté apagada:

Instala la herramienta:

# apt-get install libguestfs-tools

Obtenga la ubicación de su disco VM:

# 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" />

Es posible que deba adaptarse /var/lib/libvirt/images/Win7.imga lo siguiente:

# 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   -

Crea tu disco 64G:

# truncate -s 64G /var/lib/libvirt/images/outdisk

Deberá expandir / dev / sda2 (no la partición de arranque):

# 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.

Haga una copia de seguridad por si acaso (o úsela mvsi no desea la copia de seguridad):

# 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

¡Ahora bota!

Para más información: man virt-resize


3
En lugar de hacer una copia de seguridad en el último paso (si la imagen es grande y no desea / no tiene el espacio adicional en el disco), simplemente puede hacer virsh edit virt_namey cambiar la ruta de la fuente del disco a la nueva. Luego, si no funciona, simplemente cámbielo e intente nuevamente. No tiene mucho sentido tener 3 imágenes cuando podrías hacerlo con 2.
Mike

1
O simplemente puede usar mv en lugar de cp para el primer comando. Además de ahorrar espacio en disco, también será dramáticamente más rápido de esta manera.
Kevin Keane

66
Una cosa importante a notar es que incluso si la imagen de origen tiene un tipo, la instancia de destino será rawtipo. si desea mantener, por ejemplo qcow2, el tipo, debe aplicar una conversión como:qemu-img convert -O qcow2 /var/lib/libvirt/images/outdisk /var/lib/libvirt/images/outdisk.qcow2
cierre de sesión

1
Y virt-resize incluso tiene una linda ruleta de progreso ncurses.
David McNeill

18

Recomiendo antes de hacer todo esto, tome una copia completa de la imagen del disco tal como está, luego, cuando todo se rompa, puede copiarla nuevamente para comenzar de nuevo.

Hay 3 cosas que debes hacer:

1) Amplíe la imagen del disco. En tu host:

qemu-img resize foo.qcow2 +32G

Ahora su invitado puede ver un disco más grande, pero aún tiene particiones y sistemas de archivos antiguos.

2) Amplíe la partición dentro de la imagen del disco. Para ello, debe iniciar un LiveCD en su invitado, ya que no podrá meterse con una partición montada. Esto es bastante complicado y probablemente la parte más peligrosa. Copiar aquí es bastante, así que solo voy a vincular por ahora. Quieres hacer algo como esto:

http://www.howtoforge.com/linux_resizing_ext3_partitions_p2

O 2b) crear una nueva partición sería más simple (y más seguro) si solo desea más espacio de almacenamiento. Use fdisk o cfdisk, o lo que sea que le resulte más cómodo; ahora debería ver un montón de espacio no asignado en su disco de invitado.

3) Finalmente, si ha cambiado el tamaño de su partición existente, haga que el sistema de archivos dentro de la nueva partición más grande sea más grande (de todos modos, esto está en la guía vinculada anteriormente). Dentro de su invitado:

resize2fs /dev/sda1

Gracias por la rápida respuesta. Parece una solución viable. Estaré fuera de la ciudad por unos días, pero una vez que regrese a la oficina la próxima semana, lo intentaré e informaré si funciona.
Tong Wang

1
Una pregunta más: si quiero reducir el tamaño del disco, ¿realizo los pasos en orden inverso? Me gusta: 1. reducir el sistema de archivos; 2. reducir la partición; 3. reducir la imagen del disco. ¿Correcto?
Tong Wang

Sí, resize2fs puede reducirse y crecer, pero obviamente necesitará suficiente espacio libre en el sistema de archivos. Al reducir la partición, me equivoco al dejar un poco más de lo necesario para que no corte accidentalmente el extremo del sistema de archivos :)
Cesium

Usted absolutamente PUEDE meterse con una partición montada
etherous

4

Creo que la respuesta de Caesium está bien, solo me gustaría escribir algunos otros comandos para lograr lo mismo.

Suponga que tiene un archivo disk.imgcon una imagen de disco, es decir, que tiene una tabla de particiones y una o más particiones, y diga que desea agrandar la última partición. Lo que tienes que hacer es

1) agrande todo el archivo, digamos 4GiB. Una forma rápida de hacerlo es usardd

dd if=/dev/zero of=disk.img bs=1c seek=4G count=0

2) agrandar la partición usando fdisk (desearía poder hacer esto en una herramienta separada o mejor ... ¿Alguien?)

fdisk disk.img

Escriba ppara imprimir la tabla de particiones y busque el sector de inicio de su partición, por ejemplo, la partición 2 comienza en el sector 106496.

Lo que hará es eliminar esa partición de la tabla de particiones y crear una nueva partición que comience exactamente en el mismo sector pero termine en una posterior. Entonces la partición contendrá un sistema de archivos válido.

Escriba dy proporcione el número de partición para eliminar. (¡Trago!)

Escriba ny proporcione el número de partición deseado, y luego el sector de inicio. DEBE utilizar el mismo sector de inicio que se utilizó anteriormente. Finalmente, proporcione el sector final o simplemente deje que fdisk elija el sector más alto que pueda usar.

Escriba wpara volver a escribir los cambios en el archivo de imagen del disco y salga de fdisk.

3) Ahora necesita cambiar el tamaño del sistema de archivos. Para esto, necesita el desplazamiento al (= la posición del) sistema de archivos dentro de la imagen del disco. Puede calcular esto a partir del número de sector si conoce el tamaño del sector (que generalmente es 512), o puede usarparted

parted disk.img u b p

( partedpuede tomar comandos como argumentos de línea de comandos, por lo que esto significa 'bytes de unidad' e 'imprimir', por lo que imprime la tabla de partición y usa bytes como tamaño uint).

Esto imprime la partición comienza y termina. Digamos que su partición comienza en 54525952, luego crea un dispositivo de bloqueo de bucle invertido con losetup.

losetup -f --show -o 54525952 disk.img 

losetupte dice qué desarrollador eligió, por ejemplo /dev/loop0. Ahora puedes usar resize2fs:

resize2fs /dev/loop0

y finalmente retire el dispositivo de bucle

losetup -d /dev/loop0


-1
#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);

}

Este sencillo programa agrega N bytes al final de la imagen virtual. Utilicé la imagen de partición Paragon para Windows XP para fusionar las imágenes recién creadas. Funciona bien aquí.


Función estática no utilizada 'auxfilesize', 'aux_copyNBytesFromTo'. ¿Por qué debería ayudar eso?
AB

¿No usado? No entiendo la pregunta. Ambos son usados.
Ilian Zapryanov

El resultado son bytes no asignados y un nuevo disco duro para el sistema operativo. Tienes que formatearlo. Si se pregunta por qué los foo-s son estáticos. Simplemente me salvó los prototipos y por qué no. Es un programa simple escrito en 2 minutos en mi tiempo libre :) Nada especial u óptimo.
Ilian Zapryanov

3
Podría haber utilizado herramientas existentes como ddo truncate...
rudimeier
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.