Como redimensionar o disco da máquina virtual?


23

Existe uma maneira de redimensionar o disco de uma máquina virtual? Digamos, aumentar o tamanho do disco de 32 GB para 64 GB. Estou executando o KVM / Qemu no servidor Ubuntu 11.10 64bit. Obrigado.

Respostas:


27

Na distribuição baseada no Debian você deve usar virt-resize. Isso lida com praticamente tudo sob o capô agora. Vamos supor que sua imagem se chama Win7 (por que não?). Primeira coisa: verifique se a sua VM está desligada:

Instale a ferramenta:

# apt-get install libguestfs-tools

Obtenha a localização do seu disco da 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" />

Pode ser necessário se adaptar /var/lib/libvirt/images/Win7.imgdo seguinte modo:

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

Crie seu disco 64G:

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

Você precisará expandir / dev / sda2 (não a partição de inicialização):

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

Faça um backup por precaução (ou use mvse você não quiser o backup):

# 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

Agora inicialize!

Para mais informações: man virt-resize


3
Em vez de fazer um backup na última etapa (se a imagem for grande e você não quiser / não tiver espaço em disco adicional), basta fazer virsh edit virt_nameo procedimento e alterar o caminho da fonte do disco para a nova. Então, se não funcionar, basta alterá-lo novamente e tente novamente. Não há muito sentido em ter 3 imagens quando você pode fazê-lo com 2. #
Mike #

1
Ou você pode simplesmente usar mv em vez de cp para o primeiro comando. Além de economizar espaço em disco, também será muito mais rápido dessa maneira.
Kevin Keane

6
Uma coisa importante a ser observada é que, mesmo que a imagem de origem tenha um tipo, a instância de destino será do rawtipo. se você deseja manter, por exemplo qcow2, o tipo, deve aplicar uma conversão como:qemu-img convert -O qcow2 /var/lib/libvirt/images/outdisk /var/lib/libvirt/images/outdisk.qcow2
logoff

1
E o virt-redimensionar tem até um bonito botão giratório de progresso.
David McNeill

18

Eu recomendo que, antes de fazer qualquer coisa, você faça uma cópia completa da imagem do disco como está e, quando tudo quebrar, você poderá copiá-la novamente para começar de novo.

Há três coisas que você precisa fazer:

1) Aumente a imagem do disco. No seu host:

qemu-img resize foo.qcow2 +32G

Agora seu convidado pode ver um disco maior, mas ainda possui partições e sistemas de arquivos antigos.

2) Faça a partição dentro da imagem do disco maior. Você precisa inicializar um LiveCD no seu convidado para isso, pois não poderá mexer com uma partição montada. Isso é bastante envolvido e provavelmente a parte mais perigosa. É muito para copiar aqui, então eu vou apenas ligar por enquanto. Você quer fazer algo assim:

http://www.howtoforge.com/linux_resizing_ext3_partitions_p2

OU 2b) criar uma nova partição seria mais simples (e mais seguro) se você quiser apenas mais espaço de armazenamento. Use fdisk ou cfdisk, ou o que você se sentir confortável - você deve ver um monte de espaço não alocado em seu disco convidado agora.

3) Finalmente, se você redimensionou sua partição existente, aumente o sistema de arquivos dentro da nova partição maior (na verdade, isso está no guia acima). Dentro do seu convidado:

resize2fs /dev/sda1

Obrigado pela resposta rápida. Parece uma solução viável. Estarei fora da cidade por alguns dias, mas quando voltar ao escritório na próxima semana, tentarei informar e informar se funcionar.
Tong Wang

1
Mais uma pergunta: se eu quiser diminuir o disco, eu executo as etapas em uma ordem inversa? Como: 1. encolher o sistema de arquivos; 2. encolher a partição; 3. reduza a imagem do disco. Direita?
Tong Wang

Sim, o resize2fs pode encolher e crescer, mas obviamente precisará de espaço livre suficiente no sistema de arquivos. Ao diminuir a partição, eu errava ao deixar um pouco mais do que o necessário, para que você não acidentalmente interrompa o sistema de arquivos :) #
687

Você absolutamente bagunça CAN com um montado partição
etherous

4

Eu acho que a resposta do Caesium é boa, eu gostaria de escrever alguns outros comandos para conseguir a mesma coisa.

Suponha que você tenha um arquivo disk.imgcom uma imagem de disco, ou seja, ele tenha uma tabela de partições e uma ou mais partições e diga que deseja aumentar a última partição. O que você precisa fazer é

1) aumentar o arquivo inteiro, digamos 4GiB. Uma maneira rápida de fazer isso é usardd

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

2) aumentar a partição usando o fdisk (eu gostaria de poder fazer isso em uma ferramenta dividida ou mais agradável ... Alguém?)

fdisk disk.img

Digite ppara imprimir a tabela de partições e procurar o setor inicial da sua partição, por exemplo, a partição 2 inicia no setor 106496.

O que você fará é excluir essa partição da tabela de partições e criar uma nova partição que inicie exatamente no mesmo setor, mas termine posteriormente. Em seguida, a partição conterá um sistema de arquivos válido.

Digite de forneça o número da partição a ser excluída. (Gole!)

Digite ne forneça o número da partição desejada e, em seguida, o setor de inicialização. Você DEVE usar o mesmo setor de inicialização usado anteriormente. Finalmente, dê ao setor final ou deixe o fdisk escolher o setor mais alto que você pode usar.

Digite wpara gravar as alterações novamente no arquivo de imagem de disco e saia do fdisk.

3) Agora você precisa redimensionar o sistema de arquivos. Para isso, é necessário o deslocamento para (= a posição do) sistema de arquivos dentro da imagem do disco. Você pode calcular isso a partir do número do setor, se souber o tamanho do setor (que geralmente é 512) ou usarparted

parted disk.img u b p

( partedpode assumir comandos como argumentos de linha de comando, portanto, significa 'unidade de bytes' e 'impressão', para que imprima a tabela de partição e use bytes como tamanho uint.)

Isso imprime a partição inicia e termina. Digamos que sua partição comece em 54525952 e faça um bloco de loopback com os dispositivos losetup.

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

losetupinforma qual desenvolvedor ele escolheu, por exemplo /dev/loop0. Agora você pode usar resize2fs:

resize2fs /dev/loop0

e finalmente remova o dispositivo de loop

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 programa simples adiciona N bytes ao final da imagem virtual. Usei a imagem da partição Paragon no Windows XP para mesclar as imagens recém-criadas. Funciona bem aqui.


Função estática não usada 'auxfilesize', 'aux_copyNBytesFromTo'. Por que isso deveria ajudar?
AB

Não utilizado? Eu não entendo a pergunta. Ambos são usados.
Ilian Zapryanov

O resultado são bytes não alocados e um novo disco rígido para o sistema operacional. Você precisa formatá-lo. Se você está perguntando por que os foo-s são estáticos. Apenas me salvou os protótipos e por que não. É um programa simples escrito em 2 minutos no meu tempo livre :) Nada de especial ou ideal.
Ilian Zapryanov

3
Você poderia ter usado ferramentas existentes como ddou truncate...
rudimeier
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.