Whitepaper técnico — PodHeitor CloudStack para Bacula

Backup VM-level com CBT block-level (QEMU dirty bitmaps), replicação contínua DR, cross-restore para Proxmox/Hyper-V/VMware e conversão de formato em streaming — capacidades que o plugin CloudStack do Bacula Enterprise não cobre.

Documento técnico complementar à página do plugin PodHeitor CloudStack.

1. O problema: o plugin CloudStack do Bacula Enterprise é API-only

O Bacula Enterprise CloudStack plugin opera estritamente sobre a API do CloudStack: cria snapshot de volume, faz download via API, restaura via API. Isso tem três limites duros:

  • Sem CBT real. O incremental do BEE é diff de snapshot a nível de API — granularidade de volume, não de bloco. Para uma VM de 200 GB com 500 MB modificados, o BEE ainda transfere a diferença de snapshot completa do CloudStack, não os blocos sujos.
  • Sem replicação contínua. O BEE não tem modo DR push. Se você quer replicação para site secundário, precisa de uma segunda solução (CloudStack Snapshot Schedule + cópia manual).
  • Sem cross-restore. O backup CloudStack do BEE só restaura para CloudStack. Migrar para Proxmox/Hyper-V/VMware exige conversão manual com qemu-img + reconstrução de config.

O PodHeitor CloudStack Plugin elimina os três gargalos com acesso direto KVM/libvirt via NBD, dirty bitmap nativo do QEMU, e pipeline de conversão em streaming.

2. Modelo arquitetural — 100% Rust cdylib

A v2.0.0+ é arquitetura 100% Rust. O FD-side .so é um cdylib puro (build a partir de ../PodHeitor Rust cdylib/crates/plugin-cloudstack/) que dlopen-a no bacula-fd. Nenhum source AGPLv3 do Bacula é vinculado estaticamente. O shim C++ legado foi removido — todas as responsabilidades (identidade do plugin, validação de parâmetros, driver PTCOMM, virtual-file buffering, restore replay) estão reimplementadas no framework Rust metaplugin-rs.

┌──────────────────────────────────────────────────────────┐
│  Bacula File Daemon (FD)                                 │
│  ┌────────────────────────────┐                          │
│  │  podheitor-cloudstack-fd.so│──PTCOMM──▶┌────────────┐ │
│  │  (Rust cdylib)             │◀─────────│  Rust      │ │
│  │                            │          │  Backend   │ │
│  └────────────────────────────┘          └─────┬──────┘ │
│                                                │        │
│  ┌──────────────────────────────────────────────┴─────┐ │
│  │   CloudStack API (HMAC-SHA1) + SSH/NBD data plane  │ │
│  └────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────┘

O backend (~12.000 LOC Rust) é spawnado como subprocesso por job — preservando o boundary PTCOMM de crash-isolation. O cdylib é mínimo: identidade de plugin + driver PTCOMM + virtual-file buffering. Toda lógica de backup, restore, replicação e conversão vive no backend.

3. Three-Layer Change Detection (CBT)

O incremental real do PodHeitor não é diff de snapshot — é uma pipeline de três camadas que cobre os caminhos felizes e patológicos:

Camada Mecanismo Função
L1 QEMU QMP dirty bitmap Apenas blocos modificados desde o último backup entram no pipeline
L2 xxHash64 block hash Elimina falsos-positivos de bitmap resets sujos (hard reboot do KVM, host crash)
L3 SIMD zero-block detection Elimina regiões esparsas/zeradas — benefício de thin provisioning

Resultado típico: redução de janela de backup > 90% vs Full em incrementais sucessivos.

4. Modos de operação

Mode Propósito
(unset) Backup Bacula normal (Full ou Incremental)
bitmap_push DR contínuo — envia deltas de dirty-bitmap para dr_host
seed Sync full inicial antes de mudar para bitmap_push
receiver Daemon DR-side — aceita bitmap pushes recebidos
daemon Sender de replicação long-running (out-of-band dos jobs Bacula)
failover_pre / failover_exec Promove réplica DR a primary
failback_pre / failback_exec Re-sync primary após failover e swap back
reprotect Re-estabelece replicação na direção reversa
replication_status Query de saúde sender/receiver

5. Cross-restore — conversão em streaming

O plugin restaura uma VM CloudStack em hipervisor diferente do origem. Detectado pelo parâmetro cross_restore:

Target Conversão de disco Adaptação de guest
proxmox qcow2 → qcow2 (passthrough) ou raw Geração de qm config; ajuste de driver virtio
hyperv qcow2 → vhdx (streaming via qemu-img) VMCX XML; integração services
vmware qcow2 → vmdk (streaming) VMX file; VMware Tools handoff

A conversão é streaming: nenhum arquivo intermediário é materializado. O pipeline é NBD read → qemu-img convert (stdin) → SSH/SMB push (stdout). Para uma VM de 100 GB indo CloudStack→Hyper-V, isso evita 100 GB de I/O temporário no FD host.

6. Data plane — três modos NBD

O parâmetro nbd_access_mode seleciona o caminho de leitura de bytes do hipervisor KVM:

Modo Funcionamento Quando usar
ssh_tunnel (default) SSH ao host KVM, abre túnel para porta NBD local, conecta cliente NBD via tunnel Default seguro — não exige abrir 10809 no firewall
direct Cliente NBD conecta direto a kvm-host:10809 Quando rede de backup é segregada e firewall permite
api_only Fallback API-only (download de snapshot via CloudStack) Quando SSH ao host KVM falha — log warning

Aritmética típica: direct entrega 3–5 GB/s em LAN 10 GbE; ssh_tunnel ~1.5–2.5 GB/s (limitado por overhead de criptografia); api_only raramente passa de 200 MB/s.

7. Replicação contínua DR (bitmap-push)

O modo bitmap_push transforma o plugin em um agente de replicação out-of-band: ciclos de cycle_interval segundos (default 300) leem o dirty bitmap atual, calculam delta vs último ciclo, e enviam para dr_host:dr_port sob transporte AES-256-GCM com PSK derivado.

  • PSK ≥ 32 caracteres obrigatório.
  • Retry com backoff exponencial: retry_count=3, retry_delay_ms=5000, jitter retry_jitter_ms=1000.
  • Resiliência: se o receiver cair, o sender mantém o bitmap acumulado; reconexão retoma do último ciclo confirmado.
  • Economia de banda: 95%+ vs cópia full (delta-only push).

O fluxo de failover automatiza a promoção: failover_pre drena pendências, failover_exec apresenta os disks da réplica para uma nova VM CloudStack no DR site. failback_pre/failback_exec + reprotect fecham o loop.

8. Performance

Métrica Valor típico
Throughput de Full backup 1.5–5 GB/s (depende de modo NBD, rede, disco)
Redução de janela Incremental 90%+ vs Full (dirty bitmap + hash dedup)
Economia de banda em replicação 95%+ (delta-only push)
Compressão zstd (level 3) 50–60%
Memória por disk backup concorrente ~17 MB (NBD buffers + zstd context + hash working set)
Hash lookup O(1) — array flat memory-mapped, OS page cache

9. Hash DB memory-mapped

O hash DB do PodHeitor é um array flat memory-mapped indexado por xxHash64. Diferentemente de DBs tradicionais (LMDB, RocksDB), não há latência SSD no caminho hot — o page cache do kernel mantém o working set residente. Resultado:

  • Lookup O(1) sem syscall (mmap-only).
  • SSD-latency-independent: rode em HDD se quiser.
  • Working set cresce com unique blocks, não com volume total.

10. Anti-patterns documentados

  • Não desabilite quiesce em workloads DB. Sem qemu-guest-agent freeze/thaw, snapshots de DB ficam crash-consistent — válidos mas não application-consistent. Para Postgres/MySQL/MSSQL, mantenha quiesce=true.
  • Não use verify_ssl=false em produção. Importe a CA do CloudStack management no trust store do FD host. verify_ssl=false existe para PoC/lab.
  • Não rode replicação bitmap_push sobre WAN sem cap. O ciclo default de 300s + delta pode saturar 100 Mbps em VMs write-heavy. Configure bandwidth_limit ou aumente cycle_interval.

11. License posture

O plugin distribui sob LicenseRef-PodHeitor-Proprietary. Não vincula estaticamente nenhum source AGPLv3 do Bacula. O binding é exclusivamente via extern "C" independente.

Pronto para avaliar?

Trial gratuito de 30 dias para workloads CloudStack qualificadas (KVM, validado em CloudStack 4.16/4.19/4.20). Garantimos no mínimo 50% de desconto vs Bacula Enterprise, Veeam, Commvault ou NetBackup, com mais funcionalidades inclusas — e cross-restore que nenhum dos três oferece.

Heitor Faria — Fundador, PodHeitor International
[email protected]
☎ +1 (789) 726-1749 · +55 (61) 98268-4220 (WhatsApp)
🔗 Página do plugin PodHeitor CloudStack

Disponível em: pt-brPortuguêsenEnglish (Inglês)esEspañol (Espanhol)

Deixe um comentário