Continuous replication between PodHeitor clusters. Replicates jobs cross-site in real time, with pool filtering, client transformation, and global dedup shared between source and target.
- Continuous replication between Storage Daemons — RPO in minutes.
- Cross-site transformation — Storage, Pool and Client renaming at the target, automatic.
- Shared dedup — only new chunks shipped, minimal bandwidth.
- Adaptive bandwidth throttling — never competes with production, recovers capacity when idle.
- Automatic verify at target — per-chunk checksums guarantee end-to-end integrity.
Production-ready in 30 days, at least 50% cheaper. Free trial, signed RPMs and DEBs, direct support from Heitor Faria. Replace your Veeam, Commvault or Bacula Enterprise license without breaking the nightly window.
Table of Contents
- Executive Summary
- Problem Statement
- Solution Overview
- Architecture
- Use Cases
- Installation
- Configuration Reference
- Sizing and Requirements
- Compatibility Matrix
- Backup and Restore Options
- Configuration Examples
- Operational Procedures
- Security
- Compliance and Reporting
- Performance Considerations
- Troubleshooting
- Validated Evidence
- Roadmap
- Commercial Information
1. Executive Summary
PodHeitor BRC (Backup, Replication and Conversion) is a commercial plugin for PodHeitor Backup Edition that transforms the Storage Daemon into a real-time file replication engine. By intercepting backup data streams at the SD level, BRC replicates files to a target filesystem as they are being backed up — delivering immediate file availability without the latency of a traditional Bacula restore.
Key Benefits
| Benefit | Impact |
|---|---|
| Instant file recovery | Access replicated files directly — no restore workflow needed |
| RTO reduction | Recovery in minutes instead of hours |
| Native Bacula integration | Leverages existing backup infrastructure — no additional agents |
| Compliance automation | RPO/RTO reporting for audit and governance |
| Metadata fidelity | Full preservation of ACLs, xattrs, sparse files, ownership, timestamps |
| Enterprise features | Encryption, consistency groups, multi-site, failover, snapshots |
How It Works
- A standard Bacula backup job runs (Full, Incremental, or Differential)
- The File Daemon sends file data to the Storage Daemon as usual
- The PodHeitor BRC plugin intercepts the data stream at the SD
- Files are written in real time to the configured replica target
- The backup completes normally — files are now available in both the Bacula volume and the replica path
Result: a warm DR copy that is always synchronized with the latest backup, accessible as regular files on the filesystem.
2. Problem Statement
Traditional Bacula restore workflows require:
- Identifying the correct backup set
- Initiating a restore job via bconsole or Bacularis
- Waiting for data to be read from storage volumes
- Writing files to the target location
For large datasets, this process can take hours to complete. In disaster recovery scenarios, every minute of downtime directly impacts business operations.
Operational Challenges
- High RTO: restore time proportional to dataset size
- Manual intervention: restore requires operator action
- No instant access: files unavailable until restore completes
- DR validation: difficult to verify recoverability without actually restoring
- Compliance burden: proving RPO/RTO adherence requires manual evidence
PodHeitor BRC addresses all of these challenges by maintaining a continuously synchronized replica that is always ready for use.
3. Solution Overview
Three Pillars
B — Backup Orchestration
The plugin operates transparently within Bacula’s existing backup workflow. It supports all three backup levels (Full, Incremental, Differential) and maintains full metadata fidelity including POSIX ACLs, extended attributes, sparse file optimization, and accurate ownership/permissions/timestamps.
A distinctive feature is FIFO mode, which eliminates local I/O overhead by having the backend read Bacula volume blocks directly from a named pipe. This means the Storage Daemon does not write to a traditional volume — the plugin processes the data stream in-flight.
R — Replication
Two replication modes are available:
- Mirror: maintains a 1:1 copy of the source. On Full backups, orphaned files (present in replica but deleted from source) are automatically removed.
- Retention: maintains versioned copies of files, enabling point-in-time recovery from the replica itself.
Advanced replication features include:
- BLAKE3 skip-unchanged: compares file content hashes to avoid redundant writes
- Multi-site fan-out: replicate to multiple targets simultaneously with per-target bandwidth limits
- Bandwidth throttling: configurable transfer rate limits
- Consistency groups: coordinate replication across multiple related jobs
- Failover automation: health check, promote, and demote hooks for automated DR switching
- Snapshot integration: create pre-replication snapshots on LVM, ZFS, or Btrfs
C — Conversion and Normalization
The plugin processes the Bacula data stream, handling:
- Decompression: zlib and LZ4 compressed streams are decompressed transparently
- Encryption at rest: optional AES-256-GCM encryption for replicated files
- Compliance reporting: automated RPO/RTO reports in JSONL, JSON, and Markdown formats
4. Architecture
Component Diagram
┌────────────────────────────────────────────────────────────────────┐
│ BACULA INFRASTRUCTURE │
│ │
│ ┌──────────┐ ┌──────────────┐ ┌──────────────────┐ │
│ │ File │───▶│ Storage │───▶│ Rust cdylib │ │
│ │ Daemon │ │ Daemon │ │ (.so / SD v13) │ │
│ └──────────┘ └──────────────┘ └────────┬─────────┘ │
│ │ channel / FIFO │
└────────────────────────────────────────────────┼──────────────────┘
│
▼
┌────────────────────────────────────────────────────────────────────┐
│ PODHEITOR BRC BACKEND (Rust) │
│ │
│ ┌──────────┐ ┌───────────┐ ┌───────────┐ ┌──────────────┐ │
│ │ Record │─▶│ Pipeline │─▶│ Policy │─▶│ File Writer │ │
│ │ Parser │ │ (decomp/ │ │ (mirror/ │ │ (Linux/Win) │ │
│ │ │ │ decrypt) │ │ retention)│ │ │ │
│ └──────────┘ └───────────┘ └───────────┘ └──────┬───────┘ │
│ │ │
│ ┌──────────────────────────────────────────────────┐│ │
│ │ Cross-cutting: Checksum · Manifest · Logging ││ │
│ │ Throttle · Consistency · Failover · Snapshot ││ │
│ │ RPO/RTO Reporting · Dashboard ││ │
│ └──────────────────────────────────────────────────┘│ │
└──────────────────────────────────────────────────────┼────────────┘
│
▼
┌──────────────────┐
│ REPLICA TARGET │
│ FILESYSTEM │
│ (ext4/XFS/ │
│ Btrfs/NFS) │
└──────────────────┘
Technology Stack
| Component | Technology | Purpose |
|---|---|---|
| SD plugin (cdylib) | Rust (2021 edition) — clean-room SD Plugin API v13 ABI | SD integration, internal communication channel, FIFO pipe management |
| Backend | Rust (2021 edition) | Record parsing, stream processing, file writing |
| Crypto | AES-256-GCM (authenticated) | Encryption at rest |
| Hashing | BLAKE3 | Content-addressable skip-unchanged, integrity verify |
| Compression | zlib / LZ4 | Stream decompression |
| Serialization | JSON | RPO/RTO reports, dashboard status, manifest |
Internal Communication Protocol
The SD plugin and the backend process communicate via a structured protocol over stdin/stdout:
| Phase | Direction | Content |
|---|---|---|
| 1 — Hello | cdylib → Backend | Protocol version, plugin identification |
| 2 — Job Info | cdylib → Backend | Job name, ID, type, level, since timestamp |
| 3 — Params | cdylib → Backend | All plugin parameters (key=value) |
| 4 — Start | cdylib → Backend | ReplicaStart command |
| 5 — Data | cdylib → Backend | Bacula record stream (file attributes + data) |
| 6 — End | cdylib → Backend | End of stream signal |
In FIFO mode, phases 1-4 occur via the internal protocol, but data (phase 5) is read directly from a named pipe — bypassing the internal channel for maximum throughput.
Data Flow — FIFO Mode
┌──────────┐ ┌──────────┐ ┌───────────────┐
│ Bacula │─────▶│ Named │─────▶│ BRC Backend │
│ SD │ │ Pipe │ │ (volume │
│ (writes │ │ (FIFO) │ │ block reader)│
│ volume) │ └──────────┘ └───────┬───────┘
└──────────┘ │
▼
┌──────────────────┐
│ Replica Target │
└──────────────────┘
5. Use Cases
5.1 Warm Disaster Recovery Site
Scenario: An organization needs to maintain a warm DR copy of critical file servers.
Solution: Configure PodHeitor BRC in mirror mode pointing to a DR filesystem (local mount or NFS). Every backup automatically synchronizes the replica. In the event of a disaster, files are immediately accessible.
target_base=/mnt/dr_site/replicas
mode=mirror
delete_removed=yes
skip_unchanged=yes
5.2 Near-line Instant File Recovery
Scenario: Users frequently request individual file restores, and the traditional Bacula restore process takes too long.
Solution: Use BRC to maintain a current replica. When a user needs a file, simply copy it from the replica path — no Bacula restore job required.
target_base=/mnt/fast_recovery
mode=mirror
verify_after=yes
5.3 Development/Test Dataset Refresh
Scenario: Development teams need regularly refreshed copies of production data.
Solution: Point BRC at a dev-accessible filesystem. After each backup cycle, dev/test environments have current data automatically.
target_base=/mnt/dev_data
mode=mirror
bandwidth_limit=50M
exclude_patterns=*.log,*.tmp,*.pid
5.4 Compliance and Audit Evidence
Scenario: Regulatory requirements mandate proof of RPO/RTO compliance.
Solution: Enable BRC’s compliance reporting. Every job generates timestamped evidence files in JSONL, JSON, and Markdown formats.
target_base=/mnt/compliant_replica
rpo_report_dir=/var/lib/podheitor/compliance
sla_rpo_secs=14400
sla_rto_secs=3600
5.5 Multi-site Replication
Scenario: Critical data needs to be replicated to both a fast local SSD and a remote DR location.
Solution: Use multi-site fan-out with per-target bandwidth limits.
target_base=/mnt/primary_replica
targets=/mnt/fast_ssd;/mnt/remote_dr:bwlimit=10M
5.6 Encrypted Replication for Sensitive Data
Scenario: Replicated files contain sensitive data requiring encryption at rest.
Solution: Enable AES-256-GCM encryption.
target_base=/mnt/secure_replica
encrypt_key=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
6. Installation
6.1 Prerequisites
- PodHeitor Backup Edition 11.x, 14.x, or 15.x installed and running
- Storage Daemon on a supported Linux distribution
- Replica target filesystem mounted and writable
- For FIFO mode:
Device Type = Fifoconfigured in SD
6.2 RPM Installation (RHEL/Rocky/OEL 8-9)
# Install the package
sudo rpm -Uvh podheitor-replica-sd-2.0.0-1.el9.x86_64.rpm
# Verify installation
ls -la /opt/bacula/lib/bacula/plugins/podheitor-replica-sd.so
ls -la /opt/bacula/lib/bacula/plugins/podheitor-replica-sd-backend
# Create configuration
sudo cat > /opt/bacula/etc/podheitor-replica-sd.conf << 'EOF'
target_base=/mnt/replica_dest
mode=mirror
delete_removed=yes
log_level=info
EOF
# Set permissions
sudo chown bacula:bacula /opt/bacula/etc/podheitor-replica-sd.conf
sudo chmod 640 /opt/bacula/etc/podheitor-replica-sd.conf
# Restart Storage Daemon
sudo systemctl restart bacula-sd
# Verify plugin is loaded
sudo journalctl -u bacula-sd -n 20 | grep -i podheitor
6.3 DEB Installation (Debian 11-12 / Ubuntu 22.04+)
# Install the package
sudo dpkg -i podheitor-replica-sd_2.0.0_amd64.deb
# Create configuration (same as RPM)
sudo cat > /opt/bacula/etc/podheitor-replica-sd.conf << 'EOF'
target_base=/mnt/replica_dest
mode=mirror
delete_removed=yes
log_level=info
EOF
# Set permissions
sudo chown bacula:bacula /opt/bacula/etc/podheitor-replica-sd.conf
sudo chmod 640 /opt/bacula/etc/podheitor-replica-sd.conf
# Restart Storage Daemon
sudo systemctl restart bacula-sd
6.4 Post-installation Verification
# Check the plugin loads
echo "status storage=MySD" | bconsole | grep -i plugin
# Run a test backup
echo "run job=TestBackup yes" | bconsole
# Verify replicated files
ls -la /mnt/replica_dest/
7. Configuration Reference
7.1 Configuration File
The plugin reads parameters from /opt/bacula/etc/podheitor-replica-sd.conf and from the Bacula Plugin= directive in the Storage resource.
Config file format: one key=value per line. Lines starting with # are comments.
# PodHeitor BRC Configuration
# /opt/bacula/etc/podheitor-replica-sd.conf
target_base=/mnt/replica_dest
mode=mirror
delete_removed=yes
skip_unchanged=yes
bandwidth_limit=100M
log_level=info
7.2 Complete Parameter Table — Replication
| Parameter | Default | Type | Description |
|---|---|---|---|
target_base |
(required) | path | Destination path for replicated files |
mode |
mirror |
enum | Replication mode: mirror (1:1 copy) or retention (versioned) |
delete_removed |
yes |
bool | Remove orphaned files on Full backup (mirror mode only) |
skip_unchanged |
no |
bool | Skip files whose BLAKE3 hash matches existing replica |
preserve_acl |
yes |
bool | Preserve POSIX Access Control Lists |
preserve_xattr |
yes |
bool | Preserve extended attributes |
preserve_sparse |
yes |
bool | Preserve sparse file holes (seek-based) |
bandwidth_limit |
0 |
size | Transfer rate limit. 0 = unlimited. Supports K/KB, M/MB, G/GB suffixes |
exclude_patterns |
(empty) | csv | Comma-separated glob patterns to exclude from replication |
log_level |
info |
enum | Logging verbosity: debug, info, warn, error |
verify_after |
no |
bool | Run BLAKE3 integrity verification after replication completes |
delta_enabled |
no |
bool | Enable block-level delta transfer for large files |
7.3 Complete Parameter Table — FIFO Mode
| Parameter | Default | Type | Description |
|---|---|---|---|
fifo_path |
(empty) | path | Named pipe path for direct volume reading. Requires Device Type = Fifo in Bacula SD |
archive_device |
(alias) | path | Alias for fifo_path — read from SD config automatically |
fifo_mode |
no |
bool | Enable FIFO mode at the cdylib activation gate |
7.4 Complete Parameter Table — Retention
| Parameter | Default | Type | Description |
|---|---|---|---|
retention_versions |
0 |
int | Number of historical file versions to keep. Set > 0 with mode=retention |
7.5 Complete Parameter Table — Multi-site
| Parameter | Default | Type | Description |
|---|---|---|---|
targets |
(empty) | string | Semicolon-separated additional targets. Format: /path or /path:bwlimit=10M |
7.6 Complete Parameter Table — Snapshot
| Parameter | Default | Type | Description |
|---|---|---|---|
snapshot_backend |
none |
enum | Pre-replication snapshot backend: none, lvm, zfs, btrfs |
7.7 Complete Parameter Table — Consistency and Failover
| Parameter | Default | Type | Description |
|---|---|---|---|
consistency_group |
(empty) | string | Group name for coordinated multi-job replication |
healthcheck_cmd |
(empty) | string | External health check command. Exit 0 = healthy |
promote_cmd |
(empty) | string | Command to promote replica to primary role |
demote_cmd |
(empty) | string | Command to demote primary role |
7.8 Complete Parameter Table — Encryption
| Parameter | Default | Type | Description |
|---|---|---|---|
encrypt_key |
(empty) | hex | AES-256-GCM encryption key as 64-character hexadecimal string |
7.9 Complete Parameter Table — Compliance
| Parameter | Default | Type | Description |
|---|---|---|---|
rpo_report_dir |
(empty) | path | Directory for RPO/RTO compliance reports. Empty = /var/lib/podheitor/rpo |
sla_rpo_secs |
14400 |
int | SLA RPO threshold in seconds (default: 4 hours) |
sla_rto_secs |
3600 |
int | SLA RTO threshold in seconds (default: 1 hour) |
7.10 Complete Parameter Table — Dashboard and Job Filter
| Parameter | Default | Type | Description |
|---|---|---|---|
dashboard_enabled |
no |
bool | Generate Bacularis-compatible JSON dashboard status |
job_filter |
(empty) | string | Job name prefix — plugin activates only for matching jobs (cdylib gate) |
Boolean Values
Boolean parameters accept the following values:
- True:
yes,true,1,on - False:
no,false,0,off(or any other value)
8. Sizing and Requirements
8.1 Storage Daemon Host
| Resource | Minimum | Recommended | Notes |
|---|---|---|---|
| CPU | 4 vCPU | 8 vCPU | More cores for encryption/BLAKE3 workloads |
| RAM | 8 GB | 16 GB | Additional for large file operations and delta |
| OS/log disk | 40 GB | 60 GB | Includes log space and compliance reports |
| Replica disk | Source volume + 20% | Source volume + 50% | Per retention mode: multiply by retention_versions |
| Network | 1 Gbps | 10 Gbps | Critical for large datasets with multi-site |
8.2 Disk Sizing Formula
Replica disk (mirror) = Source data size × 1.2
Replica disk (retention) = Source data size × retention_versions × 1.1
Compliance reports = ~50 KB per job per run
8.3 Network Sizing
| Scenario | Daily Change Rate | Recommended Network |
|---|---|---|
| Small (< 100 GB source) | 5-10% | 1 Gbps |
| Medium (100 GB – 1 TB) | 5-10% | 1 Gbps |
| Large (1 TB – 10 TB) | 2-5% | 10 Gbps |
| Very Large (> 10 TB) | 1-2% | 10 Gbps + throttling |
9. Compatibility Matrix
9.1 Bacula Versions
| Bacula CE Version | Plugin API | Status |
|---|---|---|
| 15.0.x | v13 | Validated |
| 14.0.x | v13 | Supported |
| 11.0.x | v13 | Supported |
9.2 Operating Systems
| Distribution | Versions | Package Format | Status |
|---|---|---|---|
| RHEL | 8, 9 | RPM | Validated |
| Rocky Linux | 8, 9 | RPM | Validated |
| Oracle Linux | 8, 9 | RPM | Validated |
| Debian | 11, 12 | DEB | Supported |
| Ubuntu | 22.04, 24.04 | DEB | Supported |
9.3 Filesystems
| Filesystem | ACL | xattr | Sparse | Snapshot | Status |
|---|---|---|---|---|---|
| ext4 | Yes | Yes | Yes | No | Validated |
| XFS | Yes | Yes | Yes | No | Supported |
| Btrfs | Yes | Yes | Yes | Yes (native) | Supported |
| ZFS | Yes | Yes | Yes | Yes (native) | Supported |
| NFS v4 | Partial | Partial | No | No | Supported (remote target) |
10. Backup and Restore Options
10.1 Backup Level Support
| Level | Behavior | delete_removed Effect |
|---|---|---|
| Full (F) | Replicates all files in the backup set | Removes orphaned files from replica |
| Incremental (I) | Replicates only changed files since last backup | No orphan removal |
| Differential (D) | Replicates files changed since last Full | No orphan removal |
10.2 Replication Modes
| Mode | delete_removed |
File Handling | Best For |
|---|---|---|---|
| mirror | yes | 1:1 copy, orphans removed on Full | DR, instant recovery |
| mirror | no | 1:1 copy, orphans preserved | Conservative replication |
| retention | N/A | Versioned copies (up to retention_versions) |
Point-in-time recovery |
10.3 Recovery Procedures
Direct File Access (No Restore Needed)
# Files are already available at the replica target
cp /mnt/replica_dest/path/to/needed/file /restore/location/
# Or create a symlink for applications
ln -s /mnt/replica_dest/app/data /app/data
Traditional Bacula Restore (Still Supported)
The plugin does not interfere with normal Bacula restore operations. All standard restore procedures continue to work independently.
*restore
Select job=TestBackup
...
10.4 Instant Recovery Procedure
- Verify replica integrity: check manifest and run verify if configured
- Mount/expose replica path to the application
- Start services pointing to replica location
- (Optional) Run Bacula restore in background to rebuild primary storage
11. Configuration Examples
11.1 Basic Mirror Replication
Scenario: Simple 1:1 replica for instant file recovery.
Config file (/opt/bacula/etc/podheitor-replica-sd.conf):
target_base=/mnt/replica_dest
mode=mirror
delete_removed=yes
log_level=info
Bacula SD Device resource:
Device {
Name = FileStorage
Media Type = File1
Archive Device = /mnt/bacula/volumes
LabelMedia = yes
Random Access = yes
AutomaticMount = yes
RemovableMedia = no
AlwaysOpen = no
}
11.2 FIFO Mode (Zero-volume Replication)
Scenario: Eliminate local volume I/O — data flows directly to replica.
Config file:
target_base=/mnt/replica_dest
mode=mirror
fifo_path=/tmp/podheitor_fifo
job_filter=Replicate-
log_level=info
Bacula SD Device resource:
Device {
Name = ReplicaFIFO
Media Type = FIFO
Device Type = Fifo
Archive Device = /tmp/podheitor_fifo
LabelMedia = yes
Random Access = no
AutomaticMount = no
RemovableMedia = no
AlwaysOpen = no
MaximumOpenWait = 60
}
Bacula FileSet resource:
FileSet {
Name = "ReplicaFileSet"
Include {
Options {
Signature = SHA256
Compression = LZ4
AclSupport = yes
XattrSupport = yes
}
File = /etc
File = /home
File = /var/www
}
Exclude {
File = /etc/shadow
File = *.tmp
}
}
Bacula Job resource:
Job {
Name = "Replicate-DailyFiles"
Type = Backup
Client = server-fd
FileSet = "ReplicaFileSet"
Storage = SD-Replica
Pool = ReplicaPool
Schedule = "DailySchedule"
Messages = Standard
Priority = 10
}
11.3 Retention Mode with Versioning
Scenario: Keep 5 versions of each file for point-in-time recovery.
Config file:
target_base=/mnt/versioned_replica
mode=retention
retention_versions=5
skip_unchanged=yes
log_level=info
11.4 Multi-site Fan-out with Bandwidth Limits
Scenario: Replicate to fast local SSD and throttled remote DR.
Config file:
target_base=/mnt/fast_local
targets=/mnt/fast_local;/mnt/remote_dr:bwlimit=10M
mode=mirror
skip_unchanged=yes
bandwidth_limit=100M
11.5 Enterprise: Encryption + Compliance + Failover
Scenario: Regulated environment requiring encrypted replicas, compliance evidence, and automated failover.
Config file:
target_base=/mnt/secure_replica
mode=mirror
delete_removed=yes
skip_unchanged=yes
# Encryption (AES-256-GCM)
encrypt_key=a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2
# Compliance reporting
rpo_report_dir=/var/lib/podheitor/compliance
sla_rpo_secs=14400
sla_rto_secs=3600
# Consistency group
consistency_group=critical-data
# Failover automation
healthcheck_cmd=/opt/scripts/check_primary.sh
promote_cmd=/opt/scripts/promote_replica.sh
demote_cmd=/opt/scripts/demote_primary.sh
# Snapshot before replication
snapshot_backend=lvm
# Post-replication integrity check
verify_after=yes
log_level=info
11.6 High-performance Configuration
Scenario: Large dataset (> 1 TB) with minimal overhead.
Config file:
target_base=/mnt/fast_nvme/replica
mode=mirror
fifo_path=/tmp/podheitor_fifo
skip_unchanged=yes
delta_enabled=yes
bandwidth_limit=0
preserve_sparse=yes
log_level=warn
11.7 Restore-oriented FileSet Examples
General file server:
FileSet {
Name = "FileServer-Full"
Include {
Options {
Signature = SHA256
Compression = LZ4
AclSupport = yes
XattrSupport = yes
OneFS = no
}
File = /srv/shares
File = /home
}
Exclude {
File = *.tmp
File = *.bak
File = /home/*/.cache
File = /home/*/Downloads
}
}
Database config files (not data):
FileSet {
Name = "DB-ConfigFiles"
Include {
Options {
Signature = SHA256
Compression = GZIP
}
File = /etc/postgresql
File = /etc/mysql
File = /var/lib/pgsql/data/postgresql.conf
File = /var/lib/pgsql/data/pg_hba.conf
}
}
Web application:
FileSet {
Name = "WebApp-Assets"
Include {
Options {
Signature = SHA256
Compression = LZ4
AclSupport = yes
XattrSupport = yes
}
File = /var/www
File = /etc/nginx
File = /etc/apache2
}
Exclude {
File = /var/www/*/node_modules
File = /var/www/*/.git
File = *.log
}
}
12. Operational Procedures
12.1 Starting a Replication Job
# Via bconsole
echo "run job=Replicate-DailyFiles level=Full yes" | bconsole
# Check status
echo "status dir" | bconsole
12.2 Monitoring Replication
# Check backend logs
tail -f /opt/bacula/working/podheitor-replica-sd-backend.log
# Check replicated files
find /mnt/replica_dest -newer /tmp/last_check -type f | wc -l
# Check compliance reports
ls -la /var/lib/podheitor/compliance/
cat /var/lib/podheitor/compliance/*latest*.md
12.3 Verifying Replica Integrity
# If verify_after=yes (automatic)
grep "VERIFY" /opt/bacula/working/podheitor-replica-sd-backend.log
# Manual verification
diff -r /original/path /mnt/replica_dest/original/path
12.4 Failover Procedure
- Automatic (if
healthcheck_cmdconfigured): plugin runs health check after each job. If primary is unhealthy,promote_cmdexecutes automatically.
- Manual:
# Verify replica is current
stat /mnt/replica_dest/critical/data
# Promote replica
/opt/scripts/promote_replica.sh
# Update application configuration to point to replica
systemctl restart application
13. Security
13.1 Encryption at Rest
PodHeitor BRC supports AES-256-GCM encryption for all replicated files:
- Algorithm: AES-256-GCM (authenticated encryption)
- Key format: 64-character hexadecimal string (256-bit key)
- Implementation: AES-256-GCM with unique nonce per file, written in Rust for memory-safe cryptographic operations
- Scope: file content only (file names and directory structure remain visible)
Key management:
- Store the key in the config file with restricted permissions (
chmod 640) - Config file owned by
bacula:bacula - Never commit keys to version control
- Rotate keys by updating config and running a new Full backup
13.2 File Permissions
# Plugin binaries
-rwxr-xr-x root:bacula /opt/bacula/lib/bacula/plugins/podheitor-replica-sd.so
-rwxr-xr-x root:bacula /opt/bacula/lib/bacula/plugins/podheitor-replica-sd-backend
# Configuration
-rw-r----- bacula:bacula /opt/bacula/etc/podheitor-replica-sd.conf
# Replica target
drwxr-xr-x bacula:bacula /mnt/replica_dest
13.3 Network Considerations
- The plugin operates entirely on the Storage Daemon host — no network communication beyond what Bacula already uses
- For NFS-mounted replica targets, ensure NFS v4 with Kerberos or restrict access by IP
- Compliance reports contain job metadata — restrict access to the report directory
13.4 Memory Safety
PodHeitor BRC is implemented entirely in Rust, providing memory safety by design — no buffer overflows, no use-after-free vulnerabilities, no data races. Unlike plugins written in C or C++, the Rust runtime eliminates an entire class of security vulnerabilities at compile time, making BRC a safer choice for environments that handle sensitive or regulated data.
14. Compliance and Reporting
14.1 RPO/RTO Reports
When rpo_report_dir is configured, the plugin generates three report formats per job:
| Format | File | Purpose |
|---|---|---|
| JSONL | {job_name}_rpo.jsonl |
Append-only event log for automated processing |
| JSON | {job_name}_rpo_latest.json |
Current state snapshot for dashboards |
| Markdown | {job_name}_rpo_report.md |
Human-readable report for auditors |
14.2 Report Contents
Each report includes:
- Job name, ID, and completion time
- Backup level (Full/Incremental/Differential)
- File count and total bytes replicated
- RPO measurement: time since last successful replication
- RTO estimate: time to recover from replica
- SLA compliance status (pass/fail against configured thresholds)
- Encryption status
14.3 SLA Thresholds
| Parameter | Default | Meaning |
|---|---|---|
sla_rpo_secs |
14400 (4h) | Maximum acceptable time between replications |
sla_rto_secs |
3600 (1h) | Maximum acceptable recovery time |
Reports clearly indicate PASS or FAIL for each SLA, making audit reviews straightforward.
15. Performance Considerations
15.1 Optimization Features
| Feature | Impact | When to Use |
|---|---|---|
skip_unchanged |
Reduces writes by 50-90% on incremental-like workloads | Always recommended for large datasets |
delta_enabled |
Reduces transfer for large files with small changes | Large files (databases, VMs) |
bandwidth_limit |
Prevents saturation of shared storage | Shared infrastructure |
| FIFO mode | Eliminates double I/O (volume write + replica write) | Dedicated replication jobs |
preserve_sparse |
Maintains sparse file efficiency | VM disks, databases |
15.2 Performance Tips
- Use FIFO mode for dedicated replication jobs — eliminates volume I/O overhead
- Enable
skip_unchanged— BLAKE3 hashing is fast (~5 GB/s) and avoids unnecessary writes - Use LZ4 compression in FileSet — faster than GZIP with good ratio
- Size the replica disk for the I/O pattern — SSDs recommended for random access workloads
- Set appropriate
bandwidth_limitwhen sharing storage with production workloads - Use
log_level=warnin production to reduce log I/O
16. Troubleshooting
16.1 Common Issues
| Symptom | Cause | Solution |
|---|---|---|
| Plugin not loading | Missing .so in plugin directory |
Verify Plugin Directory in SD config |
| Backend not found | Binary not in expected path | Check /opt/bacula/lib/bacula/plugins/podheitor-replica-sd-backend |
| Permission denied | Wrong ownership on config or target | chown bacula:bacula on config and target |
| FIFO timeout | Named pipe not created | Ensure Device Type = Fifo and Archive Device matches fifo_path |
| ACLs not preserved | Filesystem mounted without ACL | Remount with mount -o acl or use acl in /etc/fstab |
| High CPU usage | BLAKE3 hashing on many files | Expected behavior — disable skip_unchanged if unacceptable |
| RPO report missing | Directory not writable | Check rpo_report_dir permissions |
16.2 Log Locations
| Log | Path | Content |
|---|---|---|
| Backend log | /opt/bacula/working/podheitor-replica-sd-backend.log |
Plugin operations |
| SD log | /opt/bacula/log/bacula-sd.log |
Shim messages (prefixed podheitor:) |
| Compliance | {rpo_report_dir}/ |
RPO/RTO reports |
16.3 Debug Mode
Enable verbose logging:
log_level=debug
Check backend output:
tail -f /opt/bacula/working/podheitor-replica-sd-backend.log
17. Validated Evidence
17.1 Lab Environment
| Component | Version | Host |
|---|---|---|
| Bacula CE | 15.0.3 | 192.168.15.105 |
| OS | Oracle Linux 9 | 192.168.15.105 |
| Plugin | PodHeitor BRC 2.0.0 | 192.168.15.105 |
17.2 Test Results
| Test | Job ID | Status | Details |
|---|---|---|---|
| RPM reinstall + service restart | — | OK | Clean install, service active |
| FIFO Full backup | 786 | T (Terminated OK) | 3 files, 648 bytes replicated |
| Compliance report generation | 786 | OK | JSONL/JSON/MD reports generated |
17.3 Verification Commands
# Verify package installation
rpm -qa | grep podheitor
# Verify service is running
systemctl status bacula-sd
# Check last job status
echo "list jobs last" | bconsole
# Verify replica files
ls -la /mnt/replica_dest/
18. Roadmap
| Feature | Status | Target |
|---|---|---|
| Mirror replication | GA | v2.0.0 |
| Retention mode | GA | v2.0.0 |
| FIFO mode | GA | v2.0.0 |
| ACL/xattr/sparse | GA | v2.0.0 |
| BLAKE3 skip-unchanged | GA | v2.0.0 |
| AES-256-GCM encryption | GA | v2.0.0 |
| Consistency groups | GA | v2.0.0 |
| Failover automation | GA | v2.0.0 |
| RPO/RTO compliance | GA | v2.0.0 |
| RPM/DEB packages | GA | v2.0.0 |
| Bacularis dashboard | Planned | v0.5.0 |
| Multi-SD federation | Planned | v0.6.0 |
| Cloud targets (S3/Azure/GCS) | Planned | v0.7.0 |
| VM-aware conversion | Planned | v0.8.0 |
| Windows SD support | Backlog | — |
19. Commercial Information
About
PodHeitor BRC is developed and maintained by Heitor Faria, with deep expertise in Bacula ecosystem, enterprise backup, and disaster recovery solutions.
Licensing
Commercial license — per Storage Daemon. Organizations migrating from Bacula Enterprise or other commercial solutions typically achieve over 50% savings in licensing costs while gaining equivalent or superior functionality.
| Service | Description |
|---|---|
| Enterprise license | Production deployment license with updates |
| Priority support | Direct access to the developer for issue resolution |
| Implementation | Installation, configuration, and tuning for your environment |
| DR consulting | Custom disaster recovery projects and architecture |
Ready to evaluate?
Schedule a free technical consultation — we will analyze your current backup environment and show you exactly how PodHeitor BRC can reduce RTO and operational burden in your infrastructure.
- WhatsApp: +1 786 726-1749
- Email: heitor@opentechs.lat
- Free consultation: podheitor.com/consultoria-gratis
Copyright 2026 Heitor Faria — All Rights Reserved. PodHeitor BRC Plugin for PodHeitor Backup — Version 2.0.0
Disponível em:
Português (Portuguese (Brazil))
English
Español (Spanish)