Technical whitepaper — PodHeitor Granular Restore for Bacula

SD-side Rust suite delivering three capabilities over a single core: file-level granular restore, block-level Instant Recovery (NBD/iSCSI/NFS-Datastore/SMB-VHDX), and cross-hypervisor V2V (Hyper-V↔Proxmox↔ESXi↔CloudStack↔Nutanix). Replaces Bacula Enterprise 18.2 Single Item Restore (SIR) with technical parity + cross-hypervisor differentiators SIR doesn’t cover.

Companion technical document to the PodHeitor Granular Restore plugin page.

1. The problem: Enterprise SIR is vSphere-centric

Reverse engineering of the bacula-enterprise-single-item-restore-18.2.3-26020419.el9.x86_64.rpm package showed:

  • SIR uses its own C++ parsers (vmbackend, bacula-fused) — not libguestfs.
  • Instant Recovery exists only for vSphere (NFS Datastore export via vsphere-ctl --ir-mode).
  • IR for Hyper-V doesn’t exist. IR for Proxmox/KVM/CloudStack/Nutanix doesn’t exist.
  • Cross-hypervisor V2V doesn’t exist — Hyper-V backups restore only on Hyper-V.
  • mount-vm JSON mode serializes a fragile proprietary format.
  • Local cache in working/mount-cache — staging is not zero.

For multi-hypervisor customers (typical of hosting providers and MSPs), these gaps are blocking. PHGR closes all four: Hyper-V IR, Proxmox/KVM IR, Nutanix/CloudStack IR, and cross-hypervisor V2V.

2. Architecture — cargo workspace, three binaries, one core

ADR-001: everything in a single cargo workspace with three binaries (phgrd, phird, phgr-cli) sharing a core crate (phgr-core). Not “everything in the same binary” — it’s “one codebase, multiple operational deliverables that can be installed independently”.

Crate Type Purpose
phgr-core lib Catalog, volume reader, delta/CBT, disk adapter, FS, exporters, V2V, sessions, audit
phgrd bin GR daemon (FUSE/SMB/NFS export)
phird bin IR daemon (NBD/iSCSI/NFS-Datastore + hypervisor drivers)
phgr-cli bin Interactive + scripted CLI (mount, ir, v2v, diff, verify)
phgr-api bin gRPC + REST gateway with OpenAPI
phgr-tests lib E2E test harness + lab fixtures

3. Granular Restore — file-level, no staging

The phgrd daemon mounts Bacula volumes as a FUSE filesystem, parses VHDX/VHD/VMDK/qcow2/raw/VDI, mounts NTFS/ext2/3/4/xfs/btrfs/ReFS/FAT/exFAT/ZFS partitions, and exposes files via:

  • FUSE local — mount at /mnt/phgr/<jobid>/<disk-N>/
  • SMB — dynamic share via Samba bacula.d/ include
  • NFS — dynamic export via /etc/exports.d/

The Bacula volume reader is pure Rust (ADR-005) — does not link libbacsd. In v1.0, fallback to orchestrated bextract when the Rust reader doesn’t cover an encoding. Footprint in /opt/bacula/working: ≤ 2 GB for a 200 GB VHDX (lazy reads + small LRU cache, vs SIR which fully caches).

4. Instant Recovery — VM boot in ≤ 60s

The phird daemon exposes the reconstructed image as a block target so a hypervisor boots the VM immediately. Four paths:

Hypervisor Block Path
Proxmox / KVM Direct NBD qm importdisk via nbd:// URL
VMware ESXi NFS Datastore Mount NFS export as datastore + register VM
Hyper-V iSCSI bridge Linux iSCSI Target → Hyper-V iSCSI initiator → New-VM with iSCSI VHDX
Nutanix / CloudStack iSCSI VG attach Temporary VG → attach VM → boot

Writes during IR land in a separate COW overlay (qcow2 backing file). Live migration to permanent storage runs in background (Storage vMotion / qm move-disk / equivalent) — user sees no transition. Observed RTO: ≤ 60s p95 wall-clock from operator clicking “Recover” to VM boot.

5. Cross-hypervisor V2V

phgr-cli v2v converts disk format and emits native config for the target hypervisor:

Source → Target Disk conversion Config emitted
Hyper-V → Proxmox vhdx → qcow2 qm create + qm set
VMware → Proxmox vmdk → qcow2 qm create
Proxmox → Hyper-V qcow2 → vhdx VMCX XML
VMware → Hyper-V vmdk → vhdx VMCX XML
Hyper-V → VMware vhdx → vmdk VMX
Proxmox → VMware qcow2 → vmdk VMX

Conversion uses streaming qemu-img convert. Virtio drivers are injected via virt-customize when the target requires them (Linux guest moving from Hyper-V to KVM).

6. Diffs vs Bacula Enterprise SIR

Capability Enterprise SIR 18.2 PHGR v1.x
GR Hyper-V/VMware/Xen/KVM Yes Yes — parity
GR Proxmox / CloudStack / Nutanix Namespace exists, real support sparse Yes — differentiator
IR vSphere Yes Yes — parity
IR Hyper-V No Yes — iSCSI bridge
IR Proxmox / KVM No Yes — direct NBD
IR Nutanix / CloudStack No Yes — iSCSI VG
Cross-hypervisor V2V No Yes
Zero-staging Local cache ≥ 2 GB FUSE direct, ≤ 2 GB / 200 GB VHDX
Parallelism C++ sync Rust async + tokio + io_uring when available
API Proprietary format gRPC + REST with OpenAPI
Diff between two jobs No Yes — audit, DR remote saving
Optional auto-malware scan No clamav/yara opt-in

7. Signed audit log (compliance)

Every restore session emits an HMAC-chained trail: each entry includes a hash of the previous one, ensuring tampering is detectable. Covers LGPD / GDPR / PCI requirements for forensic evidence of who accessed which data.

8. Throughput targets

Metric Target
Granular restore on fast volume (NVMe) ≥ 250 MB/s
Concurrent sessions without > 30% degradation ≥ 4
IR start (p95 wall-clock) ≤ 60s
Footprint in /opt/bacula/working ≤ 2 GB for 200 GB VHDX
FS families supported 8 (NTFS, ext2/3/4, xfs, btrfs, ReFS, FAT, exFAT, ZFS)

9. Documented anti-patterns

  • Don’t run phird for IR without a configured COW overlay. Writes during IR go to the base image and corrupt the point-in-time backup.
  • Don’t expose phgrd SMB shares publicly. The Samba bacula.d/ include is for LAN — no TLS, no hardened Kerberos. Use SMB over VPN.
  • Don’t trust the Enterprise SIR namespace to identify source. Backups named @HYPERV-WINAPI, @vsphere etc are hints, but the PHGR parser validates by disk-format magic number, not by path.
  • Don’t forget ZFS dataset cleanup when the working dir is ZFS. Sessions use clones; cleanup is automatic via SessionGuard Drop, but force-killing the daemon leaves orphan clones.

10. License posture

PHGR is AGPLv3 with commercial dual-licensing available. Unlike FD plugins (which must avoid transitive AGPL because they run inside bacula-fd), PHGR is a standalone SD-side suite — does not link against Bacula source at any point. Volume reading uses the documented format in pure Rust, no libbacsd.

Ready to evaluate?

Free 30-day trial for multi-hypervisor customers needing Instant Recovery on Hyper-V/Proxmox/KVM/Nutanix/CloudStack or cross-hypervisor V2V. We guarantee at least 50% discount vs Bacula Enterprise SIR or Veeam Instant VM Recovery, with cross-hypervisor IR and V2V that neither offers.

Heitor Faria — Founder, PodHeitor International
[email protected]
☎ +1 (789) 726-1749 · +55 (61) 98268-4220 (WhatsApp)
🔗 PodHeitor Granular Restore plugin page

Disponível em: pt-brPortuguês (Portuguese (Brazil))enEnglishesEspañol (Spanish)

Leave a Reply