hyper2kvm

VMDK and Disk Image Validation

Comprehensive validation tools for ensuring disk image integrity before migration


Overview

Hyper2KVM provides built-in validation capabilities to check disk image integrity at multiple levels before attempting migration. This helps catch corruption, format issues, and filesystem problems early in the migration process.

Validation Levels

Level Speed Requires Root Description
Basic Fast No qemu-img metadata + structure check
Deep Medium Yes Basic + partition table inspection via NBD
Full Slow Yes Deep + read-only filesystem checks (fsck -n)

Quick Start

Command-Line Validation

# Basic validation (fast, no root required)
python scripts/validate_vmdk.py /path/to/disk.vmdk

# Deep validation with partition table check
sudo python scripts/validate_vmdk.py --deep /path/to/disk.vmdk

# Full validation with filesystem integrity checks
sudo python scripts/validate_vmdk.py --full /path/to/disk.vmdk

Python API

from hyper2kvm.core.vmcraft.nbd import NBDDeviceManager
import logging

logger = logging.getLogger(__name__)
nbd = NBDDeviceManager(logger, readonly=True)

# Basic validation (fast)
metadata = nbd._validate_image('/path/to/disk.vmdk')
print(f"Format: {metadata['format']}")
print(f"Size: {metadata['virtual-size'] / (1024**3):.2f} GiB")

# Deep validation (requires sudo)
report = nbd.validate_filesystems(
    '/path/to/disk.vmdk',
    check_partitions=True,
    run_fsck=False
)
print(f"Partitions: {len(report['partitions'])}")

# Full validation with fsck (requires sudo, slower)
report = nbd.validate_filesystems(
    '/path/to/disk.vmdk',
    check_partitions=True,
    run_fsck=True
)
for fsck in report['fsck_results']:
    print(f"{fsck['partition']}: {fsck['status']}")

# Comprehensive disk inspection with LVM (requires sudo)
report = nbd.inspect_disk(
    '/path/to/disk.vmdk',
    check_lvm=True,
    activate_lvm=True,
    run_fsck=False
)
print(f"LVM PVs: {len(report['lvm']['physical_volumes'])}")
print(f"LVM VGs: {len(report['lvm']['volume_groups'])}")
print(f"LVM LVs: {len(report['lvm']['logical_volumes'])}")
print(f"Filesystems: {len(report['filesystems'])}")

Validation and Inspection Methods

1. Basic Validation (_validate_image())

Fast structural validation using qemu-img

metadata = nbd._validate_image(image_path)

What it checks:

Advantages:

Returns:

Raises:


2. Deep Filesystem Validation (validate_filesystems())

Comprehensive validation with partition table inspection

report = nbd.validate_filesystems(
    image_path,
    format='vmdk',           # Optional format hint
    check_partitions=True,   # Inspect partition table
    run_fsck=False          # Skip filesystem checks
)

What it checks:

Advantages:

Requirements:

Returns:

Raises:


3. Comprehensive Disk Inspection (inspect_disk())

Complete disk structure analysis including LVM

report = nbd.inspect_disk(
    image_path,
    format='vmdk',           # Optional format hint
    check_lvm=True,          # Detect LVM structures
    activate_lvm=True,       # Activate VGs to see LVs
    run_fsck=False          # Skip fsck for faster inspection
)

What it checks:

Advantages:

Requirements:

Returns:

Use cases:


Use Cases

Pre-Migration Validation

Validate images before starting migration:

from hyper2kvm.core.vmcraft.nbd import NBDDeviceManager
import logging

logger = logging.getLogger(__name__)
nbd = NBDDeviceManager(logger, readonly=True)

def validate_before_migration(image_path):
    """Validate image before migration."""
    print(f"Validating: {image_path}")

    # Step 1: Quick structure check
    try:
        metadata = nbd._validate_image(image_path)
        print(f"✓ Format: {metadata['format']}")
    except RuntimeError as e:
        print(f"✗ Invalid image: {e}")
        return False

    # Step 2: Partition table check (if root)
    try:
        report = nbd.validate_filesystems(
            image_path,
            check_partitions=True,
            run_fsck=False
        )
        print(f"✓ Partitions: {len(report['partitions'])}")
    except RuntimeError as e:
        print(f"⚠ Partition check failed: {e}")

    print("✓ Image is ready for migration")
    return True

Batch Validation

Validate multiple images before batch migration:

#!/bin/bash
# Validate all VMDKs in a directory

for vmdk in /vms/*.vmdk; do
    echo "Validating: $vmdk"
    python scripts/validate_vmdk.py "$vmdk" || echo "Failed: $vmdk"
done

CI/CD Integration

Integrate validation into CI/CD pipelines:

# .github/workflows/validate-images.yml
name: Validate VM Images

on: [push]

jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2

      - name: Install dependencies
        run: |
          sudo apt-get update
          sudo apt-get install -y qemu-utils

      - name: Validate images
        run: |
          for img in test-images/*.vmdk; do
            python scripts/validate_vmdk.py "$img"
          done

Command-Line Tool

scripts/validate_vmdk.py

Standalone validation script with multiple modes.

Basic Validation

python scripts/validate_vmdk.py /path/to/disk.vmdk

Output:

======================================================================
Basic Validation: disk.vmdk
======================================================================

✓ Image Structure: VALID

Image Metadata:
  Format: vmdk
  Virtual Size: 100.00 GiB
  Actual Size: 25.50 GiB

======================================================================
Basic validation completed successfully
======================================================================

Deep Validation

sudo python scripts/validate_vmdk.py --deep /path/to/disk.vmdk

Output:

======================================================================
Deep Validation: disk.vmdk
======================================================================

✓ Deep Validation: PASSED

Image: /path/to/disk.vmdk
Format: vmdk
Virtual Size: 100.00 GiB
Actual Size: 25.50 GiB

Partition Table:
NAME    FSTYPE SIZE  LABEL UUID                                 MOUNTPOINT
nbd0           100G
├─nbd0p1 ext4   96G   root  a1b2c3d4-...
└─nbd0p2 swap   4G          e5f6g7h8-...

Found 2 partitions:
  - nbd0p1: nbd0p1 ext4 96G root a1b2c3d4-...
  - nbd0p2: nbd0p2 swap 4G e5f6g7h8-...

======================================================================
Deep validation completed successfully
======================================================================

Full Validation

sudo python scripts/validate_vmdk.py --full /path/to/disk.vmdk

Output:

[... deep validation output ...]

Filesystem Checks:
  ✓ /dev/nbd0p1: clean
  ✓ /dev/nbd0p2: clean

======================================================================
Full validation completed successfully
======================================================================

Options

usage: validate_vmdk.py [-h] [--deep] [--full] [-v] [--json] image

Validate VMDK and disk images for integrity

positional arguments:
  image          Path to disk image (VMDK, QCOW2, VHD, etc.)

optional arguments:
  -h, --help     show this help message and exit
  --deep         Enable deep validation (partition table check via NBD)
  --full         Enable full validation (includes read-only fsck)
  -v, --verbose  Verbose output (debug logging)
  --json         Output results as JSON (for --deep/--full only)

Examples

Example Scripts

1. examples/vmdk_validation_example.py

Demonstrates all validation methods:

# Basic validation
python examples/vmdk_validation_example.py /path/to/disk.vmdk

# Deep/full validation (requires sudo)
sudo python examples/vmdk_validation_example.py /path/to/disk.vmdk

What it demonstrates:


Technical Details

How Validation Works

Basic Validation Flow

  1. Run qemu-img check to detect corruption
  2. Run qemu-img info --output=json for metadata
  3. Parse results and log warnings
  4. Return metadata dictionary

Deep Validation Flow

  1. Perform basic validation first
  2. Find free NBD device
  3. Connect image via qemu-nbd --read-only
  4. Run partprobe to scan partitions
  5. Run lsblk -f to inspect partition table
  6. Optionally run fsck -n (read-only) on each partition
  7. Disconnect NBD device
  8. Return validation report

Error Handling

The validation methods handle various error conditions:

Performance

Validation Level Time (typical) Disk Access
Basic 1-2 seconds Metadata only
Deep 5-10 seconds Partition scan
Full 30-300 seconds Full read scan

Note: Full validation time depends on disk size and filesystem complexity.


Best Practices

When to Use Each Level

Use Basic Validation:

Use Deep Validation:

Use Full Validation:

Recommendations

  1. Always validate before batch migrations
  2. Use basic validation in automated workflows
  3. Use deep validation for production VMs
  4. Use full validation only when troubleshooting
  5. Version control validation scripts for repeatability

Troubleshooting

Common Issues

Permission Denied

Error: Permission denied

Solution: Deep and full validation require sudo:

sudo python scripts/validate_vmdk.py --deep disk.vmdk

NBD Module Not Loaded

Error: Failed to load NBD module

Solution: Load NBD module manually:

sudo modprobe nbd max_part=16

qemu-img Not Found

Error: qemu-img: command not found

Solution: Install qemu-img:

# Fedora/RHEL/CentOS
sudo dnf install qemu-img

# Ubuntu/Debian
sudo apt-get install qemu-utils

Invalid VMDK Descriptor

Error: invalid VMDK image descriptor

Common causes:

Solution: Use the descriptor file (without -flat suffix)


See Also


Last Updated: January 2026 Status: Production Ready Requirements: qemu-img (basic), qemu-nbd + NBD kernel module (deep/full)