vidma - Virtual Disks Manipulator (tool for resizing VDI)

Discussions related to using VirtualBox on Linux hosts.
przemoc
Posts: 32
Joined: 4. Sep 2008, 16:02
Primary OS: MS Windows other
VBox Version: PUEL
Guest OSses: Linux, Windows, DragonFlyBSD, FreeBSD, NetBSD, OpenBSD
Location: Poland

Re: vidma - Virtual Disks Manipulator (tool for resizing VD

Post by przemoc »

Creating 1 GB fixed VDI in VBoxManage and resizing it in vidma (Windows, v0.0.4)
  1. Create new 1GB disk image using VBoxManage.

    Code: Select all

    G:\>"C:\Program Files\Oracle\VirtualBox\VBoxManage.exe" createhd --filename test.vdi --size 1024 --variant fixed
    0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
    Disk image created. UUID: 791edcda-59a6-45b3-b020-892212800c3b
  2. Get information about this image.

    Code: Select all

    G:\>vidma test.vdi
    Recognized file format:
            Virtual Disk Image (vdi)
    
    pre.file_info                    = <<< Oracle VM VirtualBox Disk Image >>>
    
    pre.signature                    = beda107f 3201962111
    version                          = 00010001 65537
    header.size                      = 00000190 400
    header.type                      = 00000002 2 (fixed)
    header.flags                     = 00000000 0
    header.offset.bam                = 00001000 4096
    header.offset.data               = 00002000 8192
    header.pchs.cylinders            = 00000000 0
    header.pchs.heads                = 00000000 0
    header.pchs.sectors              = 00000000 0
    header.pchs.sector_size          = 00000200 512
    header.dummy                     = 00000000 0
    header.disk.size                 = 0000000040000000 1073741824
    header.disk.blk_size             = 00100000 1048576
    header.disk.blk_extra_data       = 00000000 0
    header.disk.blk_count            = 00000400 1024
    header.disk.blk_count_alloc      = 00000400 1024
    header.uuid.create               = 791edcda-59a6-45b3-b020-892212800c3b
    header.uuid.modify               = 9f71b37c-a646-4c7f-abac-ad7acb42351d
    header.uuid.linkage              = 00000000-0000-0000-0000-000000000000
    header.uuid.parent_modify        = 00000000-0000-0000-0000-000000000000
    header.lchs.cylinders            = 00000000 0
    header.lchs.heads                = 00000000 0
    header.lchs.sectors              = 00000000 0
    header.lchs.sector_size          = 00000200 512
  3. Check image size.

    Code: Select all

    G:\>for %I in (test.vdi) do @echo %~zI
    1073750016
  4. Extend image to 2GB in-place. (Moving blocks is required here.)

    Code: Select all

    G:\>vidma test.vdi 2048
    Recognized file format:
            Virtual Disk Image (vdi)
    
    Requested disk resize
    from                  1024 block(s)
    to                    2048 block(s)
    (each block has    1048576 bytes + 0 extra bytes)
    
    Disk size will change
    from            1073741824 bytes (           1024 MB)
    to              2147483648 bytes (           2048 MB)
    
    Image size will change
    from            1073750016 bytes (           1024 MB)
    to              2148532224 bytes (           2049 MB)
    
    Required free space on the volume
                    1074782208 bytes (           1024 MB)
    Available free space on the volume
                    2783248384 bytes (           2654 MB)
    
    Resize operation will be performed in-place.
    WARNING All allocated blocks require moving.
            In case of fail DATA LOSS is highly POSSIBLE!
            Think twice before continuing!
    
    Are you sure you want to continue? (y/N) y
    
    Operation: Resize
    [1/4] Moving blocks: 1024/1024 Done
    [1/4] Syncing
    [1/4] Data moved (1024 blocks by 1040384 bytes in 17468 ms = ~61 B/us)
    [2/4] Updating block allocation map: Done
    [2/4] Syncing
    [3/4] Updating file size: Done
    [3/4] Syncing
    [4/4] Updating header: Done
    [4/4] Syncing
    Operation finished
    
    header.offset.data               = 00100000 1048576
    header.disk.size                 = 0000000080000000 2147483648
    header.disk.blk_count            = 00000800 2048
    header.disk.blk_count_alloc      = 00000800 2048
    header.lchs.cylinders            = 00000000 0
    header.lchs.heads                = 00000000 0
    header.lchs.sectors              = 00000000 0
  5. Check again image size.

    Code: Select all

    G:\>for %I in (test.vdi) do @echo %~zI
    2148532224
  6. Resize image to 250GB in-place. (It would be fast, because blocks wouldn't be moved now thanks to previous resize done using vidma; I don't have enough space, though.)

    Code: Select all

    G:\>vidma test.vdi 256000
    Recognized file format:
            Virtual Disk Image (vdi)
    
    Requested disk resize
    from                  2048 block(s)
    to                  256000 block(s)
    (each block has    1048576 bytes + 0 extra bytes)
    
    Disk size will change
    from            2147483648 bytes (           2048 MB)
    to            268435456000 bytes (         256000 MB)
    
    Image size will change
    from            2148532224 bytes (           2049 MB)
    to            268436504576 bytes (         256001 MB)
    
    Required free space on the volume
                  266287972352 bytes (         253952 MB)
    Available free space on the volume
                    1708523520 bytes (           1629 MB)
    which seems not enough to perform the resize operation!
    
    Resize operation will be performed in-place.
    CAUTION Only disk metadata will be modified.
            In case of fail data loss is highly unlikely,
            but image METADATA CAN BE CORRUPTED!
    
    Are you sure you want to continue? (y/N) n
    Resize aborted.
  7. Shrink image back to 1GB in-place.

    Code: Select all

    G:\>vidma test.vdi 1024
    Recognized file format:
            Virtual Disk Image (vdi)
    
    Requested disk resize
    from                  2048 block(s)
    to                    1024 block(s)
    (each block has    1048576 bytes + 0 extra bytes)
    
    Disk size will change
    from            2147483648 bytes (           2048 MB)
    to              1073741824 bytes (           1024 MB)
    
    Image size will change
    from            2148532224 bytes (           2049 MB)
    to              1074790400 bytes (           1025 MB)
    
    Required free space on the volume
                             0 bytes (              0 MB)
    Available free space on the volume
                    1708523520 bytes (           1629 MB)
    
    Resize operation will be performed in-place.
    CAUTION Only disk metadata will be modified.
            In case of fail data loss is highly unlikely,
            but image METADATA CAN BE CORRUPTED!
    WARNING Shrinking disk in-place means
            IRRETRIEVABLY LOSING DATA KEPT BEYOND NEW SIZE!
    
    Are you sure you want to continue? (y/N) y
    
    Operation: Resize
    [1/4] No need to move blocks: Done
    [2/4] Updating block allocation map: Done
    [2/4] Syncing
    [3/4] Updating file size: Done
    [3/4] Syncing
    [4/4] Updating header: Done
    [4/4] Syncing
    Operation finished
    
    header.offset.data               = 00100000 1048576
    header.disk.size                 = 0000000040000000 1073741824
    header.disk.blk_count            = 00000400 1024
    header.disk.blk_count_alloc      = 00000400 1024
    header.lchs.cylinders            = 00000000 0
    header.lchs.heads                = 00000000 0
    header.lchs.sectors              = 00000000 0
  8. Get information about the image now.

    Code: Select all

    G:\>vidma test.vdi
    Recognized file format:
            Virtual Disk Image (vdi)
    
    pre.file_info                    = <<< Oracle VM VirtualBox Disk Image >>>
    
    pre.signature                    = beda107f 3201962111
    version                          = 00010001 65537
    header.size                      = 00000190 400
    header.type                      = 00000002 2 (fixed)
    header.flags                     = 00000000 0
    header.offset.bam                = 00001000 4096
    header.offset.data               = 00100000 1048576
    header.pchs.cylinders            = 00000000 0
    header.pchs.heads                = 00000000 0
    header.pchs.sectors              = 00000000 0
    header.pchs.sector_size          = 00000200 512
    header.dummy                     = 00000000 0
    header.disk.size                 = 0000000040000000 1073741824
    header.disk.blk_size             = 00100000 1048576
    header.disk.blk_extra_data       = 00000000 0
    header.disk.blk_count            = 00000400 1024
    header.disk.blk_count_alloc      = 00000400 1024
    header.uuid.create               = 791edcda-59a6-45b3-b020-892212800c3b
    header.uuid.modify               = 9f71b37c-a646-4c7f-abac-ad7acb42351d
    header.uuid.linkage              = 00000000-0000-0000-0000-000000000000
    header.uuid.parent_modify        = 00000000-0000-0000-0000-000000000000
    header.lchs.cylinders            = 00000000 0
    header.lchs.heads                = 00000000 0
    header.lchs.sectors              = 00000000 0
    header.lchs.sector_size          = 00000200 512
  9. Create image copy resized to 2GB. (UUID won't change.)

    Code: Select all

    G:\>vidma test.vdi 2048 copy.vdi
    Recognized file format:
            Virtual Disk Image (vdi)
    
    Requested disk resize
    from                  1024 block(s)
    to                    2048 block(s)
    (each block has    1048576 bytes + 0 extra bytes)
    
    Disk size will change
    from            1073741824 bytes (           1024 MB)
    to              2147483648 bytes (           2048 MB)
    
    Image size will change
    from            1074790400 bytes (           1025 MB)
    to              2148532224 bytes (           2049 MB)
    
    Required free space on the volume
                    2148532224 bytes (           2049 MB)
    Available free space on the volume
                    2782265344 bytes (           2653 MB)
    
    Resize operation in fact will create resized copy of the image.
    NOTE    UUID of the new image will be the same as old one.
    NOTE    Input file is safe and won't be modified.
    
    Are you sure you want to continue? (y/N) y
    
    Operation: Resize
    [1/4] Copying blocks: 1024/1024 Done
    [1/4] Syncing
    [1/4] Data copied (1024 blocks in 18203 ms = ~58 B/us)
    [2/4] Updating block allocation map: Done
    [2/4] Syncing
    [3/4] Updating file size: Done
    [3/4] Syncing
    [4/4] Updating header: Done
    [4/4] Syncing
    Operation finished
    
    header.offset.data               = 00100000 1048576
    header.disk.size                 = 0000000080000000 2147483648
    header.disk.blk_count            = 00000800 2048
    header.disk.blk_count_alloc      = 00000800 2048
    header.lchs.cylinders            = 00000000 0
    header.lchs.heads                = 00000000 0
    header.lchs.sectors              = 00000000 0
Desktop: NUC11PHKi7C [Core i7-1165G7 @ 2.80GHz, DDR4-3200 32GB RAM, GeForce RTX 2060, M.2 NVMe SSD 2TB] | 32UN880-B
Laptop: ThinkPad T430 (2344-56G) [Core i7 3520M @ 2.9GHz, DDR3-1600 8GB RAM, NVS 5400M, SATA3 SSD 512GB]
przemoc
Posts: 32
Joined: 4. Sep 2008, 16:02
Primary OS: MS Windows other
VBox Version: PUEL
Guest OSses: Linux, Windows, DragonFlyBSD, FreeBSD, NetBSD, OpenBSD
Location: Poland

Re: vidma - Virtual Disks Manipulator (tool for resizing VD

Post by przemoc »

It's a follow up to Reduce VDI size - accidentaly made 80 TB! topic regarding shrinking dynamic VDI using vidma. Latest version (v0.0.4) is used in below listings.

---

Shrinking dynamic VDI can be done in a safe way and that's how vidma does it - only metadata are changed (actual data on your virtual disk stay untouched), so if you decide to shrink it in-place (i.e. without creating new file), then it can be done in an instant. It doesn't mean such shrinkage cannot be done wrongly (like shrinking it below your last partition if the filesystem on that partition has nothing stored at the end of it), but even if it is done wrongly, you can easily fix that by resizing your VDI back to the old size - then it's guaranteed that only metadata will be changed.

In short: vidma doesn't allow you to shink dynamic VDI below the point of last allocated blocks in it.

Example: Let's try to shrink 80GB dynamic VDI with last sector already modified. vidma won't allow it.

Code: Select all

$ vidma mydisk.vdi 40960
Recognized file format:
        Virtual Disk Image (vdi)

Requested disk resize
from                 81920 block(s)
to                   40960 block(s)
(each block has    1048576 bytes + 0 extra bytes)
But minimal possible block count equals
                     81920 block(s)
Resize aborted.
---

vidma allows you to do changes in the images in-place. It can be potentially unsafe if data blocks are moved (which can happen only when you enlarge the image) and this is when you should make a backup if you want to be 100% sure that nothing will be lost during some accident. If you provide an output file that is different than input file, then nothing is changed in the input file, because it's no longer an in-place operation, thus you don't have to backup the image in the first place (you're writing to the other one, i.e. output file).

In short: vidma informs you about what has to be done to do the resize you are requesting (and whether it is possible) and shows how potentially risky such operation is. It won't start resizing until you explicitly confirm it.

Example: You mistakenly resized your dynamic VDI to 80 TB instead of 80 GB. Let's fix it in vidma.

Code: Select all

$ vidma mydisk.vdi 81920
Recognized file format:
        Virtual Disk Image (vdi)

Requested disk resize
from              83886080 block(s)
to                   81920 block(s)
(each block has    1048576 bytes + 0 extra bytes)

Disk size will change
from        87960930222080 bytes (       83886080 MB)
to             85899345920 bytes (          81920 MB)

Image size will change
from            1410334720 bytes (           1345 MB)
to              1410334720 bytes (           1345 MB)

Required free space on the volume
                         0 bytes (              0 MB)
Available free space on the volume
               78296571904 bytes (          74669 MB)

Resize operation will be performed in-place.
CAUTION Only disk metadata will be modified.
        In case of fail data loss is highly unlikely,
        but image METADATA CAN BE CORRUPTED!
WARNING Shrinking disk in-place means
        IRRETRIEVABLY LOSING DATA KEPT BEYOND NEW SIZE!

Are you sure you want to continue? (y/N) y

Operation: Resize
[1/4] No need to move blocks: Done
[2/4] Updating block allocation map: Done
[2/4] Syncing
[3/4] Updating file size: Done
[3/4] Syncing
[4/4] Updating header: Done
[4/4] Syncing
Operation finished

header.offset.data               = 14100000 336592896
header.disk.size                 = 0000001400000000 85899345920
header.disk.blk_count            = 00014000 81920
header.disk.blk_count_alloc      = 00000400 1024
header.lchs.cylinders            = 00000000 0
header.lchs.heads                = 00000000 0
header.lchs.sectors              = 00000000 0
It took only a few seconds.
Desktop: NUC11PHKi7C [Core i7-1165G7 @ 2.80GHz, DDR4-3200 32GB RAM, GeForce RTX 2060, M.2 NVMe SSD 2TB] | 32UN880-B
Laptop: ThinkPad T430 (2344-56G) [Core i7 3520M @ 2.9GHz, DDR3-1600 8GB RAM, NVS 5400M, SATA3 SSD 512GB]
Post Reply