hyper2kvm

VMDK Conversion Directory Configuration

Overview

hyper2kvm converts sparse VMDK files to QCOW2 format during migration for reliability and performance. This guide explains how to configure the temporary conversion directory for optimal disk space management.

Default Behavior

Before (hardcoded):

After (configurable):

Configuration Methods

1. CLI Argument (Highest Priority)

# Specify conversion directory via CLI
h2kvmctl --conversion-dir /path/to/conversions --config migration.yaml

# Example: Use large disk for conversions
h2kvmctl --conversion-dir /mnt/large-disk/vmcraft-temp --config centos.yaml

2. YAML Configuration File

# migration.yaml
cmd: local
vmdk: /path/to/vm.vmdk
output_dir: /path/to/output

# Conversion directory configuration
conversion_dir: ~/large-disk/vmcraft-conversions

# Other settings...
fstab_mode: stabilize-all
libvirt_import: true

3. Environment Variable

# Set via environment (future enhancement)
export HYPER2KVM_CONVERSION_DIR=/mnt/large-disk/conversions
h2kvmctl --config migration.yaml

Use Cases

Single-User Workstation

Scenario: Developer migrating VMs on local workstation

# Use default per-user cache directory
h2kvmctl --config migration.yaml

# Conversion files stored in: ~/.cache/hyper2kvm/conversions

Benefits:

Multi-User Server

Scenario: Shared server with multiple users running migrations

# User 1
h2kvmctl --conversion-dir ~/conversions --config user1-vm.yaml

# User 2
h2kvmctl --conversion-dir ~/conversions --config user2-vm.yaml

Benefits:

Dedicated Service User

Scenario: Automated migration service running as dedicated user

# Create dedicated user
sudo useradd -r -m -d /var/lib/hyper2kvm -s /bin/bash hyper2kvm
sudo mkdir -p /var/lib/hyper2kvm/conversions
sudo chown hyper2kvm:hyper2kvm /var/lib/hyper2kvm/conversions

# Add to required groups
sudo usermod -a -G kvm,qemu,disk,libvirt hyper2kvm

# Configure sudoers for NBD operations
sudo tee /etc/sudoers.d/hyper2kvm << 'EOF'
hyper2kvm ALL=(ALL) NOPASSWD: /usr/bin/qemu-nbd
hyper2kvm ALL=(ALL) NOPASSWD: /usr/sbin/modprobe
hyper2kvm ALL=(ALL) NOPASSWD: /usr/bin/qemu-img
hyper2kvm ALL=(ALL) NOPASSWD: /usr/bin/mount
hyper2kvm ALL=(ALL) NOPASSWD: /usr/bin/umount
hyper2kvm ALL=(ALL) NOPASSWD: /usr/sbin/vgchange
hyper2kvm ALL=(ALL) NOPASSWD: /usr/sbin/lvscan
hyper2kvm ALL=(ALL) NOPASSWD: /usr/sbin/blkid
EOF

# Run migration as service user
sudo -u hyper2kvm h2kvmctl --conversion-dir /var/lib/hyper2kvm/conversions --config migration.yaml

Benefits:

Large Disk for Conversions

Scenario: Home directory has limited space, need to use different disk

# Mount large disk
sudo mkdir -p /mnt/large-disk
sudo mount /dev/sdb1 /mnt/large-disk

# Create conversion directory
mkdir -p /mnt/large-disk/hyper2kvm-conversions

# Run migration
h2kvmctl --conversion-dir /mnt/large-disk/hyper2kvm-conversions --config migration.yaml

Benefits:

Container/Kubernetes Deployment

Scenario: Running hyper2kvm in container with volume mounts

# Kubernetes Pod
apiVersion: v1
kind: Pod
metadata:
  name: hyper2kvm-migration
spec:
  containers:
  - name: hyper2kvm
    image: hyper2kvm:latest
    volumeMounts:
    - name: conversions
      mountPath: /var/conversions
    - name: vmdk-source
      mountPath: /vmdk
    - name: output
      mountPath: /output
    command:
    - h2kvmctl
    - --conversion-dir
    - /var/conversions
    - --config
    - /config/migration.yaml
  volumes:
  - name: conversions
    emptyDir:
      sizeLimit: 100Gi
  - name: vmdk-source
    persistentVolumeClaim:
      claimName: vmdk-pvc
  - name: output
    persistentVolumeClaim:
      claimName: output-pvc

Benefits:

Disk Space Considerations

Sparse VMDK Conversion

Scenario: VM with 500GB virtual size, 2GB actual usage

# Sparse conversion (LVM not detected)
# Disk space needed: ~2GB (actual usage)
h2kvmctl --conversion-dir ~/conversions --config vm.yaml

Process:

  1. VMDK → RAW: ~2GB (sparse)
  2. RAW → QCOW2: ~2GB (sparse-aware)
  3. Total: ~4GB during conversion, ~2GB final

Non-Sparse Conversion (LVM/RAID/LUKS)

Scenario: VM with 500GB virtual size, contains LVM

# LVM detected → sparse disabled (prevent corruption)
# Disk space needed: ~500GB (full virtual size)
h2kvmctl --conversion-dir /mnt/large-disk/conversions --config vm.yaml

Warning: hyper2kvm automatically disables sparse conversion for:

Best Practice: Always use a conversion directory with enough space for the full virtual size.

Checking Available Space

# Check home directory space
df -h ~

# Check conversion directory space
df -h ~/.cache/hyper2kvm/conversions

# Check large disk space
df -h /mnt/large-disk

Cleanup and Maintenance

Manual Cleanup

# Remove all conversion temporary files
rm -rf ~/.cache/hyper2kvm/conversions/*

# Remove specific conversion
rm -rf ~/.cache/hyper2kvm/conversions/vm-name.*

Automatic Cleanup

Conversion files are automatically cleaned up:

Systemd Timer for Cleanup

# /etc/systemd/system/hyper2kvm-cleanup.timer
[Unit]
Description=Cleanup hyper2kvm conversion directory daily

[Timer]
OnCalendar=daily
Persistent=true

[Install]
WantedBy=timers.target
# /etc/systemd/system/hyper2kvm-cleanup.service
[Unit]
Description=Cleanup old hyper2kvm conversions

[Service]
Type=oneshot
ExecStart=/usr/bin/find /var/lib/hyper2kvm/conversions -type f -mtime +1 -delete
User=hyper2kvm
Group=hyper2kvm

Enable:

sudo systemctl enable --now hyper2kvm-cleanup.timer

Troubleshooting

Permission Denied

Error: Permission denied: /var/tmp/vmcraft-conversions

Solution:

# Use user-specific directory
h2kvmctl --conversion-dir ~/conversions --config migration.yaml

No Space Left on Device

Error: qemu-img: error while writing at byte X: No space left on device

Solution:

# Check available space
df -h ~/.cache/hyper2kvm/conversions

# Use larger disk
h2kvmctl --conversion-dir /mnt/large-disk/conversions --config migration.yaml

# Or clean up old conversions
rm -rf ~/.cache/hyper2kvm/conversions/*

Conversion Directory Not Created

Error: Conversion fails with “directory does not exist”

Solution: Directory is created automatically, but ensure parent directory is writable:

# Ensure parent exists and is writable
mkdir -p ~/custom-conversions
h2kvmctl --conversion-dir ~/custom-conversions --config migration.yaml

Security Considerations

Directory Permissions

Default behavior:

# Created with mode 0700 (owner read/write/execute only)
ls -ld ~/.cache/hyper2kvm/conversions
# drwx------ user user ~/.cache/hyper2kvm/conversions

Custom directory:

# Ensure proper permissions
mkdir -p /var/lib/hyper2kvm/conversions
chmod 700 /var/lib/hyper2kvm/conversions
chown hyper2kvm:hyper2kvm /var/lib/hyper2kvm/conversions

Sensitive Data

Warning: Conversion files are unencrypted temporary copies of VM disks.

Best practices:

SELinux/AppArmor

SELinux context (RHEL/CentOS/Fedora):

# Set proper context for conversion directory
sudo semanage fcontext -a -t virt_image_t "/var/lib/hyper2kvm/conversions(/.*)?"
sudo restorecon -Rv /var/lib/hyper2kvm/conversions

AppArmor profile (Ubuntu/Debian):

# Add to /etc/apparmor.d/local/usr.bin.qemu-system-x86_64
/var/lib/hyper2kvm/conversions/** rw,

Performance Tips

I/O Performance

Best practices:

Example: Optimal Setup

# Fast SSD for conversions (temporary)
h2kvmctl --conversion-dir /mnt/ssd/conversions \
         --config migration.yaml

# Large HDD for final output (permanent)
# (configured in migration.yaml as output_dir)

Migration Path

From Hardcoded /var/tmp

No action required - defaults changed automatically to ~/.cache/hyper2kvm/conversions

Existing Scripts

Option 1: Use default

# Old (still works)
hyper2kvm --config migration.yaml

# New (same behavior)
h2kvmctl --config migration.yaml
# Uses ~/.cache/hyper2kvm/conversions

Option 2: Explicit configuration

# Preserve old behavior
h2kvmctl --conversion-dir /var/tmp/vmcraft-conversions --config migration.yaml

Summary

Scenario Recommended Configuration
Developer workstation Default (~/.cache/hyper2kvm/conversions)
Multi-user server Per-user (~/conversions)
Dedicated service /var/lib/hyper2kvm/conversions
Limited disk space External disk (/mnt/large-disk/conversions)
Container deployment Volume mount (/var/conversions)
CI/CD pipeline Workspace directory ($WORKSPACE/conversions)

Key Points: