Whitepaper — PodHeitor Informix

Whitepaper — PodHeitor Informix

IBM Informix backup integrated with ON-Bar. Hot backup, individual dbspaces, logical log streaming, log-precise PITR, Continuous Log Restore (CLR) HA support.

  • Native ON-Bar — direct integration with the official Informix subsystem.
  • dbspace-level backup — backup and restore per dbspace, full granularity.
  • Logical log streaming — near-zero RPO.
  • Log-precise PITR — precise restore.
  • HDR and Enterprise Replication aware — back up from secondary, zero overhead on primary.

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.

Request a free 30-day trial →

🔴 COMMERCIAL DISCLAIMER

Bring your Bacula Enterprise, Veeam, Commvault or Netbackup contract or renewal proposal. We offer at least 50% discount with significantly more features.

Contact: heitor@opentechs.lat | +1 786 726-1749 | +55 61 98268-4220 (WhatsApp)


Table of Contents

  1. Executive Summary
  2. Business Case & TCO
  3. Architecture Overview
  4. Backup Engines Deep Dive
  5. Replication Capabilities
  6. Advanced Features
  7. Security & Compliance
  8. Observability
  9. Installation Guide
  10. Configuration Reference
  11. Restore Procedures & Use Cases
  12. Performance Reports
  13. Compatibility Matrix
  14. Sizing Guide
  15. Bacularis Integration
  16. Migration from TSM/ISP and ON-Bar PSM
  17. Troubleshooting
  18. Roadmap
  19. Validation Evidence (E2E Results)

1. Executive Summary

The PodHeitor Informix Backup, Replication and Conversion Plugin for Bacula is a commercial-grade, enterprise-ready plugin for HCL Informix Dynamic Server (IDS) 12.10 through 15.0, built natively for PodHeitor Backup+. Written entirely in Rust, it delivers near-zero runtime overhead, memory safety, and parallelism-first design — all in a single signed binary package that installs in minutes.

The Gap It Fills

Bacula Enterprise has no dedicated Informix plugin. The Enterprise database catalog ships DB2, MSSQL, MySQL, Oracle, PostgreSQL, Sybase and Amazon RDS — but not Informix. Organizations running IDS today are forced to choose between expensive IBM Spectrum Protect (TSM), manual bpipe+ontape shell scripts with no PITR or chain safety, or HCL’s PSM creating double-I/O staging on disk.

PodHeitor Informix is the first Bacula-native, XBSA-aware, Rust-based Informix plugin in the market.

Key Differentiators

Capability Hand-rolled scripts TSM/PSM + Bacula PodHeitor Informix
Cost Free, heavy maintenance Very expensive One-time license, no per-DB fees
Native XBSA No TSM only Yes — libpodheitor_xbsa.so
Parallelism None Limited N stripes × M dbspaces
PITR Manual Yes Automated continuous log shipping
Single-table restore None Manual archecker Built-in mode=table_level
Cross-version conversion Risky No mode=logical_dbexport first-class
HDR/RSS/SDS/ER bootstrap Manual hours Manual hours One bconsole command
Instant recovery No No IDS online in < 60 s via FUSE
Ransomware protection No No ARD hook (IDS 14.10+)
Observability None TSM dashboard Prometheus + OTLP
Bacula-native Partial (bpipe) Two-layer Direct XBSA + streaming

Validation Status

E2E Lab (2026-04-29):  PASS=22  FAIL=0  SKIP=0  TOTAL=22
Unit tests:            PASS=80  FAIL=0

All 22 end-to-end scenarios active and passing on a 4-VM lab (primary IDS, HDR secondary, RSS secondary, snapshot host) with IDS 15.0.1.0.3 Developer Edition and PodHeitor Backup.


2. Business Case & TCO

2.1 Cost Comparison (Annual, 10 TB Informix environment)

Solution License Infrastructure Operational Total
IBM Spectrum Protect ~$80,000/yr Separate TSM server DBA + TSM admin FTE ~$140,000/yr
Bacula Enterprise + manual scripts ~$30,000/yr None DBA FTE (scripts) ~$70,000/yr
Veeam Enterprise (DB module) ~$25,000/yr None Admin FTE ~$55,000/yr
PodHeitor Informix + PodHeitor Backup One-time fee Existing Bacula infra Minimal < $10,000 total

Contact heitor@opentechs.lat for pricing. We offer at least 50% discount on any competing renewal.

2.2 Risk Reduction

Risk Without PodHeitor With PodHeitor
Backup chain corruption Silent — detected at restore time Detected immediately via chain_health_check + archecker
Ransomware encryption before backup Backup captures encrypted data ARD hook aborts backup on anomaly
Point-in-time recovery gap Manual log archive management Continuous log shipping daemon, sub-minute RPO
HDR secondary bootstrap failure Hours of manual work + outage risk One-command automated bootstrap
Cross-version upgrade risk Manual dbexport/dbimport + downtime mode=logical_dbexport streaming, tested in E2E
Bare-metal DR (total server loss) Requires manual onconfig/sqlhosts reconstruction RestoreObject captures all metadata automatically

2.3 ROI Calculation Example

A mid-sized financial institution running Informix 14.10 on 5 servers, with daily backups and 4-hour RTO requirement:

  • TSM license + infrastructure: ~$60,000/yr
  • One recovery incident at 4h × 3 DBAs: ~$3,600 incident cost
  • PodHeitor migration: one-time cost + PodHeitor Backup (free)
  • Payback period: < 3 months

3. Architecture Overview

3.1 Component Diagram

┌─────────────────────────────────────────────────────────────────────┐
│  Bacula Director 15.0.3                                              │
│  Job scheduler, catalog, pool management                             │
└──────────────────────────────┬──────────────────────────────────────┘
                               │ TCP/TLS PTCOMM
                               ▼
┌─────────────────────────────────────────────────────────────────────┐
│  Bacula File Daemon (bacula-fd)                                      │
│                                                                      │
│  Loads: podheitor-informix-fd.so                                     │
│         ├── PLUGIN_PREFIX = "podheitor-informix:"                   │
│         ├── Namespace    = "@informix/"                              │
│         ├── 64 backup parameters + 33 restore parameters            │
│         └── PTCOMM binary protocol (streams D-packets to Director)  │
└──────────────────────────────┬──────────────────────────────────────┘
                               │ Unix socket / stdin-stdout PTCOMM
                               ▼
┌─────────────────────────────────────────────────────────────────────┐
│  podheitor-informix-backend  (Rust static binary)                    │
│                                                                      │
│  ┌─── Engine Layer (mode=) ──────────────────────────────────────┐  │
│  │  xbsa          onbar_psm      ontape      logical_dbexport    │  │
│  │  (libxbsa.so)  (FIFO drain)   (STDIO)     (dbexport stream)   │  │
│  │  snapshot      replicate_hdr  replicate_rss  replicate_er     │  │
│  └──────────────────────────────────────────────────────────────┘  │
│  ┌─── XBSA Library (libpodheitor_xbsa.so) ──────────────────────┐  │
│  │  BSAInit / BSABeginTxn / BSACreateObject / BSASendData        │  │
│  │  BSAEndTxn / BSATerminate / BSAGetData / BSAQueryObject       │  │
│  └──────────────────────────────────────────────────────────────┘  │
│  ┌─── Logical-Log Shipper Daemon ────────────────────────────────┐  │
│  │  Polls sysmaster:syslogs every N seconds                       │  │
│  │  Ships closed logs via PTCOMM — sub-minute RPO                 │  │
│  └──────────────────────────────────────────────────────────────┘  │
│  ┌─── Observability ─────────────────────────────────────────────┐  │
│  │  Prometheus /metrics    OpenTelemetry OTLP traces              │  │
│  └──────────────────────────────────────────────────────────────┘  │
│  ┌─── Security ──────────────────────────────────────────────────┐  │
│  │  DBCRYPT capture/restore   ARD ransomware hook   Redaction    │  │
│  └──────────────────────────────────────────────────────────────┘  │
└──────────────────────────────┬──────────────────────────────────────┘
                               │ XBSA ABI / pipes / sockets / SQL
                               ▼
┌─────────────────────────────────────────────────────────────────────┐
│  HCL Informix Dynamic Server (12.10.FC12+ / 14.10 / 15.0)           │
│  + sysmaster (bar_action, bar_object, syslogs, sysshmvals)          │
│  + ON-Bar (onbar) + archecker + oncheck                             │
│  + HDR / RSS / SDS / ER replication topology                        │
│  + DBCRYPT keystore                                                  │
└─────────────────────────────────────────────────────────────────────┘

3.2 Data Flow — XBSA Mode (Preferred)

ON-Bar invoked by plugin
    │
    │ dlopen(libpodheitor_xbsa.so)
    ▼
libpodheitor_xbsa.so  ──Unix socket──►  podheitor-informix-backend
    │                                         │
    │ BSACreateObject(dbspace)                 │  compress (zstd/lz4)
    │ BSASendData(blocks)                      │  stripe N PTCOMM streams
    │                                         │  compute SHA-256
    │                                         │  write manifest sidecar
    ▼                                         ▼
  BSAEndTxn                           Bacula Storage Daemon
                                            (File, Tape, S3, Dedup)

3.3 Backup Volume Namespace

/@informix/<INSTANCE_UUID>/
├── __ph_manifest.json          # canonical job manifest (LSN, SHA256, dbspace list)
├── __ph_topology.json          # HDR/RSS/SDS/ER topology snapshot
├── __ph_dbcrypt.json           # encrypted keystore reference (no plaintext key)
├── __ph_layout.json            # dbspace → chunk path mapping
├── restoreobjects/
│   ├── onconfig
│   ├── sqlhosts
│   └── ixbar.<servernum>       # ON-Bar emergency boot file
├── dbspace/<name>/
│   ├── L0.<jobid>.s<N>.zst    # level-0 stripe N (ZSTD frame)
│   ├── L1.<jobid>.s<N>.zst
│   └── manifest.<jobid>.json  # per-dbspace LSN + SHA256
├── logs/
│   ├── log.<unique_id>.<lsn>.zst
│   └── continuous/<YYYY>/<MM>/<DD>/
└── logical/
    ├── dbexport.<db>.<jobid>.tar.zst
    └── schema.<db>.<jobid>.sql

4. Backup Engines Deep Dive

4.1 Mode xbsa — Native XBSA (Default on mode=auto)

The strategic differentiator. libpodheitor_xbsa.so implements the full IBM XBSA C ABI, built in Rust with native memory-safety. ON-Bar loads it via BAR_BSALIB_PATH, making Bacula a first-class Informix storage manager — no staging, no double-I/O, no FIFO juggling.

Advantages over all alternatives:

  • ON-Bar’s native parallelism (BAR_MAX_BACKUP) maps 1:1 to PTCOMM streams
  • Full access to ON-Bar’s catalog (sysmaster:bar_action, bar_object) for LSN capture
  • Supports archecker post-backup verification through standard ON-Bar book-keeping
  • Zero bytes ever written to the FD host’s local disk (working dir < 50 MB)

XBSA functions implemented: BSAInit, BSABeginTxn, BSACreateObject, BSASendData, BSAEndTxn, BSATerminate, BSAGetData, BSAQueryObject, BSAEndData, BSADeleteObject

4.2 Mode onbar_psm — PSM Fallback

ON-Bar writes to HCL Primary Storage Manager (PSM) targeted at a named pipe. Backend drains the pipe → PTCOMM. Used when organization policy forbids loading 3rd-party XBSA libraries.

4.3 Mode ontape — Legacy/Simple

ontape -s -t STDIO -L 0|1|2. Whole-server only; no dbspace granularity. For dev, small instances, or environments without ON-Bar configured. Validated in E2E T16.

4.4 Mode logical_dbexport — Cross-Version Conversion

dbexport <db> -ss -X -q streamed through an async tar-on-the-fly pipeline → PTCOMM. Output is a compressed tar containing schema SQL + per-table unload files. Restorable into any IDS version with dbimport. Primary use: major version migration (12.10 → 14.10 → 15.0). Validated in E2E T12.

4.5 Mode snapshot — LVM/ZFS Quiesce

  1. onmode -c checkpoint
  2. Put dbspaces into backup mode (BAR_BLOCK_BACKUP=1)
  3. LVM lvcreate --snapshot / ZFS zfs snapshot
  4. Release backup mode — quiesce window < 1 second
  5. Stream snapshot blocks via PTCOMM (content-defined chunking for dedup)
  6. Capture archived logical logs via onbar -b -l

Validated in E2E T13 using loop-backed LVM VG (ifxvg/ifxdata).

4.6 Backup Level Mapping

Bacula Level ON-Bar Level Plugin Behavior
Full onbar -b -L 0 Whole-server level 0 baseline. Manifest captures BAR_VERSION, INSTANCE_UUID, full dbspace list, LSN.
Differential onbar -b -L 1 Cumulative since L0. Auto-promotes to Full if chain_health_check detects broken chain.
Incremental onbar -b -L 2 OR logical-log only Default: level_incr=logical_log for sub-minute RPO. Ships only newly-closed log files.
VirtualFull (synthetic) Plugin merges L0+L1+L2 chain into new L0 stream consumed by Bacula consolidation.

5. Replication Capabilities

5.1 HDR (High-Availability Data Replication) Bootstrap

Problem: Setting up an HDR secondary today requires manual onmode -d primary, onmode -d secondary, custom network config, often hours of DBA work.

PodHeitor solution: Single restore job with mode=ag_seed ag_target_role=hdr_secondary:

  1. Restores latest backup chain to target with WITH NORECOVERY equivalent
  2. Adjusts DRAUTO/DRINTERVAL/DRTIMEOUT on target
  3. Executes onmode -d primary <target_servernum> on primary
  4. Executes onmode -d secondary <primary_servernum> on target
  5. Validates secondary reaches On-Line (Sec) state

Validated in E2E T10 and T14.

5.2 RSS (Remote Standalone Secondary) Bootstrap

Same flow with ag_target_role=rss. Uses onmode -d add RSS <name> on primary + onmode -d RSS <primary_name> on target. Validated in E2E T11.

5.3 SDS (Shared Disk Secondary) Attach

Validates shared-disk topology, attaches new SDS via onmode -d set SDS PRIMARY <primary_name>.

5.4 Enterprise Replication (ER) Topology Snapshot/Restore

__ph_topology.json captures the full ER mesh: servers, replicates, grids, subscriptions. On restore, cdr define server + cdr define replicate + cdr start replicate reconstitutes the topology. Critical for DR when the entire ER mesh must be rebuilt.

5.5 Backup from Secondary (Offload Primary)

Plugin = "podheitor-informix: prefer_secondary_for_backup=yes hdr_role_check=secondary"

Plugin detects the HDR pair, connects to the secondary, runs ON-Bar there. Primary CPU/I/O completely unaffected during backup window.


6. Advanced Features

6.1 Continuous Logical-Log Shipping (Sub-minute RPO)

When continuous_log=yes, the backend spawns a daemon thread that:

  • Polls sysmaster:syslogs every continuous_log_interval seconds (default: 60s, min: 5s)
  • Detects newly-closed logical log files (status U → B)
  • Ships each log atomically via a PTCOMM micro-job with SHA-256 integrity check
  • Detects and alerts on gaps in the log sequence

RPO achieved: < 1 minute in lab; < 5 seconds with continuous_log_interval=5.

Validated in E2E T09-F (base) + T09-I (continuous).

6.2 Point-in-Time Recovery (PITR)

podheitor-informix: mode=whole_server stop_at_time="2026-04-28 14:30:00"
                    point_in_time_tz=America/Sao_Paulo

Options:

  • stop_at_lsn=<N> — stop log replay at specific LSN
  • stop_at_time=<datetime> — stop at timestamp
  • stop_before_txn=<txnid> — stop before a specific transaction (for targeted rollback)

The plugin replays the backup chain L0 → L1 → L2 → logical logs up to the chosen point, then runs onmode -m to bring the instance online. Validated in E2E T05.

6.3 Instant Recovery (FUSE Mount)

podheitor-informix: mode=instant instant_fuse_mount=/var/lib/podheitor-informix/instant
  1. Restores chunk file headers and page 0 of each dbspace
  2. FUSE filesystem presents virtual chunk files backed by lazy-streamed Bacula data
  3. IDS boots via oninit -PHY against the FUSE-mounted chunks
  4. Instance is queryable in < 60 seconds
  5. Remaining blocks stream lazily in the background while IDS serves queries

Use case: immediate business continuity while full restore completes in background. Validated in E2E T17 using /dev/loop-control + /dev/fuse on VM 189.

6.4 Single-Table Extraction

podheitor-informix: mode=table_level table=app_db.dbo.orders
                    sandbox_docker_image=icr.io/informix/informix-developer-database:latest
                    single_item_export_dir=/tmp/restored
  1. Spins up an ephemeral Podman/Docker Developer Edition container
  2. Restores full backup chain into the sandbox
  3. Replays to the requested time point
  4. Runs dbexport/unload for the target table
  5. Copies output to single_item_export_dir
  6. Destroys the sandbox container

Result: Target table extracted in < 5 min from a 100 GB backup, zero production impact. Validated in E2E T07.

6.5 Chain Integrity Enforcement

By default (chain_health_check=yes), before every Differential or Incremental:

  1. Plugin queries sysmaster:bar_action for the preceding level-0 LSN
  2. Validates the manifest chain (SHA-256 of each sidecar)
  3. Compares against Bacula catalog job history

If the chain is broken (missing job, LSN gap, SHA mismatch), the job aborts before writing any data, preventing a false-confidence backup. Operators are notified with a clear error explaining the gap.

6.6 Virtual Full (Synthetic Full)

virtual_full=yes triggers a server-side chain merge: the plugin reads L0+L1+L2 streams from Bacula, merges them into a new L0 stream that Bacula ingests as a fresh Full backup. Eliminates long restore chains (no need to apply Diff+Incr at restore time) while avoiding another full backup from the IDS host.

6.7 Bare-Metal Disaster Recovery

Every backup automatically captures a RestoreObject containing:

  • onconfig (ONCONFIG file)
  • sqlhosts (connectivity definitions)
  • ixbar.<servernum> (ON-Bar emergency boot file)

When restoring to a fresh host with no prior IDS installation:

  1. Bacula restores the RestoreObject first
  2. Plugin reconstructs the IDS directory structure
  3. Runs standard oninit initialization
  4. Restores chunks and replays logs

Zero manual DBA intervention required. Validated in E2E T18.


7. Security & Compliance

7.1 Security Controls

Surface Control Default
Plugin configuration passfile path verified to chmod 600; backend aborts if looser Enforced
Connection strings in logs Secret regex redaction in all PTCOMM logger output redact_sysuser_passwords=yes
DBCRYPT keystore Only encrypted blob (hash pointer) stored in __ph_dbcrypt.json; plaintext key NEVER logged or stored dbcrypt_capture=yes
XBSA library load path Verified against /opt/podheitor-informix/lib/; LD_PRELOAD rejected Enforced
Working directory /var/run/podheitor-informix mode 0700 owned by informix Enforced
Sandbox container Ephemeral, --read-only root + tmpfs; deleted after extraction Enforced
FUSE mount Read-only; mounted as informix:informix mode 0700 Enforced
ON-Bar exit codes Non-zero triggers job fail chain_health_check=yes
Correlation IDs All PTCOMM messages structured-logged with Bacula JobId Always

7.2 DBCRYPT Support

Informix’s DBCRYPT feature encrypts data at rest at the storage engine level. PodHeitor:

  • Captures the keystore metadata (not the key) in __ph_dbcrypt.json
  • Records the key label/alias for restore-side hook invocation
  • On restore, invokes the DBCRYPT passphrase hook before oninit
  • Result: encrypted-at-rest databases back up and restore with no manual key management

Validated in E2E T15.

7.3 ARD Ransomware Hook

When ransomware_hook=yes, the plugin runs onstat -g ARD before the backup and checks for:

  • Entropy anomalies in recently written logical log blocks
  • Sudden increase in UPDATE/DELETE rates (Active Ransomware Detection, IDS 14.10+)

If an anomaly is detected, the backup aborts with a clear warning, preventing the ransomware-encrypted state from overwriting a clean backup.

7.4 File Permission Hardening Checklist

# Verify correct permissions after install
ls -la /opt/bacula/plugins/podheitor-informix-fd.so    # -rwxr-xr-x root root
ls -la /opt/bacula/plugins/podheitor-informix-backend   # -rwxr-x--- root informix
ls -la /opt/podheitor-informix/lib/libpodheitor_xbsa.so # -rwxr-x--- root informix
ls -la /opt/bacula/etc/podheitor-informix.conf          # -rw------- informix informix
ls -la /var/run/podheitor-informix/                     # drwx------ informix informix

8. Observability

8.1 Prometheus Metrics

When metrics_endpoint=localhost:9100 is set, the plugin exposes a standard Prometheus /metrics endpoint.

Metric Type Description
podheitor_ifx_job_bytes_total Counter Total bytes transferred this job
podheitor_ifx_job_throughput_bytes_sec Gauge Current transfer rate
podheitor_ifx_dbspace_progress_pct Gauge Per-dbspace completion percentage
podheitor_ifx_logship_lag_seconds Gauge Log shipping lag (continuous_log mode)
podheitor_ifx_onbar_exit_code Gauge Last ON-Bar invocation exit code
podheitor_ifx_archecker_pass Gauge 1=pass, 0=fail (last archecker run)
podheitor_ifx_queue_depth Gauge PTCOMM write-ahead queue depth
podheitor_ifx_active_stripes Gauge Current number of active PTCOMM streams
podheitor_ifx_xbsa_buffer_pool_used Gauge XBSA buffer pool utilization (bytes)

Example Grafana query for throughput:

rate(podheitor_ifx_job_bytes_total[1m])

Example Grafana query for log shipping lag alert:

podheitor_ifx_logship_lag_seconds > 300

8.2 OpenTelemetry OTLP Traces

When otel_endpoint=http://collector:4317 is set, the plugin emits structured spans to an OTLP-compatible collector (Jaeger, Tempo, Honeycomb, etc.).

Span hierarchy:

backup.job (job_id=NNNNN, instance=ifxprod)
  ├── engine.xbsa.init
  ├── dbspace.rootdbs.backup (level=0)
  │     ├── stripe.0.compress
  │     └── stripe.0.ptcomm_write
  ├── dbspace.app_data.backup (level=0)
  ├── manifest.write
  ├── archecker.verify
  └── topology.snapshot

9. Installation Guide

9.1 Prerequisites

Bacula File Daemon host (co-located with IDS):

  • OS: OL9/RHEL 8/9/Rocky 8/9/AlmaLinux 8/9, Ubuntu 20.04/22.04/24.04, Debian 11/12, SLES 15
  • PodHeitor Backup FD 15.0.3+
  • HCL Informix 12.10.FC12+ / 14.10.FCx / 15.0.x installed
  • informix user/group with standard IDS privileges
  • For mode=snapshot: LVM or ZFS on dbspace devices, losetup+lvcreate available
  • For mode=instant: /dev/fuse + /dev/loop-control accessible
  • For mode=table_level: Podman or Docker installed

Bacula Director:

  • Director 15.0.x with the FileSet and Job definitions (see §10)

9.2 Install on EL8/EL9 (RPM)

# Download the RPM from releases/
rpm -ivh podheitor-informix-plugin-0.1.0-1.el9.x86_64.rpm

# Verify installation
ls /opt/bacula/plugins/podheitor-informix-fd.so
ls /opt/bacula/plugins/podheitor-informix-backend
ls /opt/podheitor-informix/lib/libpodheitor_xbsa.so
ls /opt/bacula/etc/podheitor-informix.conf.sample

9.3 Install on Ubuntu 22.04 / Debian 12 (DEB)

# Download the DEB from releases/
dpkg -i podheitor-informix-plugin_0.1.0-1_amd64.deb

# Verify
dpkg -L podheitor-informix-plugin

9.4 Configure the Plugin

# Copy and edit the sample config
cp /opt/bacula/etc/podheitor-informix.conf.sample 
   /opt/bacula/etc/podheitor-informix.conf
chmod 600 /opt/bacula/etc/podheitor-informix.conf
chown informix:informix /opt/bacula/etc/podheitor-informix.conf

vi /opt/bacula/etc/podheitor-informix.conf

Minimum required settings:

[connection]
informixdir    = "/opt/ibm/informix"
informixserver = "ifxprod"
onconfig       = "onconfig.std"

[engine]
mode           = "auto"   # xbsa if onbar available, else ontape
compress       = "zstd"
compress_level = 3

9.5 Configure BAR Environment

# /etc/sysconfig/podheitor-informix  (read by onbar and backend)
cat > /etc/sysconfig/podheitor-informix << 'EOF'
INFORMIXDIR=/opt/ibm/informix
INFORMIXSERVER=ifxprod
ONCONFIG=onconfig.std
INFORMIXSQLHOSTS=/opt/ibm/informix/etc/sqlhosts
PATH=/opt/ibm/informix/bin:$PATH
BAR_BSALIB_PATH=/opt/podheitor-informix/lib/libpodheitor_xbsa.so
BAR_MAX_BACKUP=4
BAR_XFER_BUF_SIZE=1048576
BAR_NB_XPORT_COUNT=10
EOF
chmod 640 /etc/sysconfig/podheitor-informix
chown root:informix /etc/sysconfig/podheitor-informix

9.6 Preflight Check

/opt/bacula/plugins/podheitor-informix-backend --dry-run 
  /opt/bacula/etc/podheitor-informix.conf

Expected output:

[INFO] PodHeitor Informix v0.1.0 — preflight check
[INFO] IDS version: 15.0.1.0.3
[INFO] ON-Bar available: yes
[INFO] archecker available: yes
[INFO] XBSA library: /opt/podheitor-informix/lib/libpodheitor_xbsa.so [OK]
[INFO] BAR_BSALIB_PATH configured: yes
[INFO] Working dir: /var/run/podheitor-informix [created, mode 0700]
[INFO] Connectivity: ifxprod@localhost:9088 [OK]
[INFO] DRY-RUN COMPLETE — all checks passed

9.7 Restart bacula-fd

systemctl restart bacula-fd
journalctl -u bacula-fd -n 50 | grep -i podheitor
# Expected: "Loaded plugin: podheitor-informix v0.1.0"

10. Configuration Reference

10.1 Backup Options

# Parameter Default Type Description
Connection
1 informixdir $INFORMIXDIR path IDS install directory
2 informixserver $INFORMIXSERVER string Server name (sqlhosts entry)
3 onconfig $ONCONFIG file onconfig file override
4 sqlhosts $INFORMIXSQLHOSTS file sqlhosts file override
5 user informix string Run-as OS user
6 passfile path Credential file (chmod 600)
7 kerberos_keytab path Kerberos keytab for Trusted Context
Engine
8 mode auto enum `auto xbsa onbar_psm ontape logical_dbexport snapshot replicate_hdr replicate_rss replicate_sds replicate_er`
Scope
9 dbspace * glob Which dbspaces to back up
10 include_dbspace glob (multi) Explicit include list
11 exclude_dbspace tempdb* glob (multi) Exclusion list
12 database glob Logical-mode DB filter
13 whole_system yes bool Whole-server vs per-dbspace
14 include_blobspace yes bool Traditional blobspaces
15 include_sbspace yes bool Smart-blob sbspaces
16 include_external_dbspace no bool External (read-only) dbspaces
17 include_temp_dbspace no bool Temp dbspaces
Levels
18 level_full 0 int Map Bacula Full → ON-Bar level 0
19 level_diff 1 int Map Bacula Differential → level 1
20 level_incr logical_log enum `2 logical_log`
21 force_full_after 7 int Auto-promote to Full after N incrementals
22 chain_health_check yes bool Verify chain before Diff/Incr
23 simulate_full no bool Force level 0 regardless of Bacula request
24 copy_only no bool Side-channel backup (doesn’t disturb chain)
Performance
25 bar_max_backup # CPU cores int Sets BAR_MAX_BACKUP (parallel ON-Bar streams)
26 stripes 1 int N-way striping per stream (1–32)
27 parallel_dbspaces # CPU cores int Concurrent dbspace backups
28 bar_xfer_buf_size 1048576 bytes Sets BAR_XFER_BUF_SIZE
29 bar_nb_xport_count 10 int Sets BAR_NB_XPORT_COUNT
30 xbsa_buffer_count 8 int XBSA shared buffer pool depth
31 xbsa_block_size 65536 bytes XBSA block size
32 compress zstd enum `none zstd lz4`
33 compress_level 3 int ZSTD compression level (1–22)
34 lob_chunked_streaming yes bool Content-defined chunking for sbspace LOBs
35 max_rate_kbps 0 int Per-job bandwidth throttle (0=unlimited)
36 cpu_quota 0 pct cgroup CPU quota for backend process
Log Shipping
37 continuous_log no bool Background log shipping daemon
38 continuous_log_interval 60 seconds Polling interval (min 5)
39 continuous_log_archive_only yes bool Stop after BAR_RETRY failures
40 salvage_logs no bool onbar -l -s salvage after crash
Integrity
41 oncheck_pre_backup no enum `no ce cI cD`
42 oncheck_post_backup no enum `no ce cI cD`
43 archecker_verify yes bool Run archecker after backup
44 manifest_sha256 yes bool Per-stream SHA256 in manifest
45 verify_lsn_chain yes bool Cross-check sysmaster:bar_action LSNs
Replication
46 topology_snapshot yes bool Snapshot HDR/RSS/SDS/ER topology
47 er_subscribe_snapshot yes bool Capture ER replicates + grids
48 hdr_role_check any enum `primary secondary any`
49 prefer_secondary_for_backup no bool Back up from HDR secondary
Security
50 dbcrypt_capture yes bool Capture DBCRYPT keystore metadata
51 redact_sysuser_passwords yes bool Filter sysmaster:sysuser from exports
52 audit_export no bool Include audit trail
53 ransomware_hook no bool Abort on ARD anomaly detection
Observability
54 metrics_endpoint host:port Prometheus /metrics endpoint
55 otel_endpoint URI OTLP traces collector
56 progress_report_interval 30 seconds Job-log progress cadence
Operational
57 dry_run no bool Preflight only (no write)
58 abort_on_chain_break yes bool Refuse Diff/Incr if chain broken
59 working_dir /var/run/podheitor-informix path FIFO + sentinel dir
60 config_file /opt/bacula/etc/podheitor-informix.conf path External config TOML
61 cluster_id string Multi-cluster namespace separator
62 bar_ixbar_path $INFORMIXDIR/etc/ixbar.<servernum> path ON-Bar emergency-boot file
63 restore_object yes bool Store onconfig+sqlhosts+ixbar as RestoreObject
64 virtual_full no bool Synthetic full from L0+L1+L2 chain

10.2 Restore Options

# Parameter Default Description
1 mode auto `auto whole_server in_place new_instance single_dbspace table_level instant ag_seed logical_import`
2 informixdir $INFORMIXDIR Target IDS install directory
3 informixserver (source name) New IDS server name
4 onconfig $ONCONFIG Target onconfig file
5 dbspace_relocation_map JSON file for logical→physical chunk path remapping
6 target_root_dbspace Override rootdbs chunk path
7 target_dbspace Single-dbspace mode target
8 dbspace * Which dbspaces to restore
9 database * Logical-mode DB filter
10 table (multi) mode=table_level target tables
11 column_filter Optional column-level filter (table_level)
12 recovery yes WITH RECOVERY (yes) vs NORECOVERY (for HDR seed)
13 stop_at_lsn Stop log replay at LSN
14 stop_at_time Stop log replay at timestamp
15 stop_before_txn Stop before specific transaction
16 point_in_time_tz UTC Timezone for stop_at_time
17 physical_only no Restore physical only (skip logical log replay)
18 drop_existing no `no yes only_if_match`
19 tail_log_before yes Salvage current logical logs before destructive restore
20 verify_post archecker `no oncheck archecker both`
21 dry_run no Preflight (validate manifest + paths, no write)
22 parallel_streams (backup value) Concurrent restore streams
23 stripes (backup value) Match backup stripes
24 parallel_dbspaces # CPU cores Concurrent dbspace restores
25 instant_fuse_mount /var/lib/podheitor-informix/instant FUSE mount for instant recovery
26 sandbox_docker_image icr.io/informix/informix-developer-database:latest Sandbox image for table_level
27 single_item_export_dir /var/lib/podheitor-informix/extracted Output for table_level
28 ag_target_role `hdr_secondary rss sds`
29 ag_primary_host Primary to attach to after seed
30 dbcrypt_keystore Override DBCRYPT keystore location
31 dbcrypt_passphrase_file Passphrase for sealed keystore
32 progress_report_interval 30 Progress cadence
33 regexwhere Bacula standard regex relocation

10.3 FileSet Examples

Basic whole-server backup (XBSA, defaults):

FileSet {
  Name = "Informix-Full"
  Include {
    Options { Signature = SHA256 }
    Plugin = "podheitor-informix:"
  }
}

Specific dbspaces, striped, with verification:

FileSet {
  Name = "Informix-AppData"
  Include {
    Plugin = "podheitor-informix: include_dbspace=app_data include_dbspace=app_index
              exclude_dbspace=tempdb* archecker_verify=yes compress=zstd
              stripes=4 parallel_dbspaces=2"
  }
}

Continuous log shipping (sub-minute RPO):

FileSet {
  Name = "Informix-LogShip"
  Include {
    Plugin = "podheitor-informix: continuous_log=yes continuous_log_interval=30"
  }
}

Cross-version migration:

FileSet {
  Name = "Informix-Export"
  Include {
    Plugin = "podheitor-informix: mode=logical_dbexport database=app_db"
  }
}

Snapshot mode (LVM):

FileSet {
  Name = "Informix-Snapshot"
  Include {
    Plugin = "podheitor-informix: mode=snapshot snapshot_vg=ifxvg snapshot_lv=ifxdata snapshot_size=1G"
  }
}

VLDB high-performance backup (8 stripes, 4 parallel dbspaces):

FileSet {
  Name = "Informix-VLDB"
  Include {
    Plugin = "podheitor-informix: stripes=8 parallel_dbspaces=4 bar_max_backup=8
              bar_xfer_buf_size=4194304 compress=zstd compress_level=3"
  }
}

Backup from HDR secondary (offload primary):

FileSet {
  Name = "Informix-HDR-Secondary"
  Include {
    Plugin = "podheitor-informix: prefer_secondary_for_backup=yes hdr_role_check=secondary"
  }
}

10.4 Job Definitions

Job {
  Name     = "informix-prod-full"
  JobDefs  = "DefaultJob"
  Type     = Backup
  Level    = Full
  FileSet  = "Informix-Full"
  Schedule = "WeeklyFull"
  Client   = "ifx-prod-fd"
  Storage  = "DiskStorage"
  Pool     = "Informix-Full"
}

Job {
  Name     = "informix-prod-diff"
  JobDefs  = "DefaultJob"
  Type     = Backup
  Level    = Differential
  FileSet  = "Informix-Full"
  Schedule = "DailyDiff"
  Client   = "ifx-prod-fd"
  Storage  = "DiskStorage"
  Pool     = "Informix-Diff"
}

Job {
  Name        = "informix-prod-logship"
  JobDefs     = "DefaultJob"
  Type        = Backup
  Level       = Incremental
  FileSet     = "Informix-LogShip"
  Schedule    = "Every5Min"
  Client      = "ifx-prod-fd"
  Storage     = "DiskStorage"
  Pool        = "Informix-Logs"
  Max Run Time = 10 minutes
}

11. Restore Procedures & Use Cases

11.1 Whole-Server Restore (In-Place)

bconsole> restore client=ifx-prod-fd
[browse and mark]
bconsole> mod
Plugin Options: podheitor-informix: mode=in_place drop_existing=only_if_match
                tail_log_before=yes verify_post=both
bconsole> yes

11.2 Restore to New Instance (Disaster Recovery)

bconsole> restore client=ifx-prod-fd where=/
Plugin Options: podheitor-informix: mode=new_instance informixserver=ifxprod-dr
                dbspace_relocation_map=/etc/podheitor-informix/dr-relocation.json
                verify_post=archecker

11.3 Point-in-Time Recovery

Plugin Options: podheitor-informix: mode=whole_server
                stop_at_time="2026-04-28 14:30:00"
                point_in_time_tz=America/Sao_Paulo
                verify_post=both

11.4 Instant Recovery

Plugin Options: podheitor-informix: mode=instant
                instant_fuse_mount=/var/lib/podheitor-informix/instant

Expected timeline:

  • 0–15s: restores chunk headers + page 0
  • 15–60s: IDS boots against FUSE mount
  • 60s+: instance online, lazy-streaming continues

11.5 Single-Table Extraction

Plugin Options: podheitor-informix: mode=table_level
                table=app_db.dbo.orders
                stop_at_time="2026-04-28 12:00:00"
                sandbox_docker_image=icr.io/informix/informix-developer-database:latest
                single_item_export_dir=/tmp/orders-restored

11.6 HDR Secondary Bootstrap

Plugin Options: podheitor-informix: mode=ag_seed
                ag_target_role=hdr_secondary
                ag_primary_host=ifx-prod:9088
                recovery=no

11.7 Cross-Version Migration (12.10 → 15.0)

Step 1 — backup source (12.10):

Plugin = "podheitor-informix: mode=logical_dbexport database=app_db"

Step 2 — restore to 15.0 target:

Plugin Options: podheitor-informix: mode=logical_import informixdir=/opt/ibm/informix
                informixserver=ifxprod-new database=app_db

12. Performance Reports

12.1 Throughput Benchmarks (Lab — OL9, IDS 15.0.1, 1 Gbps network)

DB Size Mode stripes parallel_dbspaces Throughput Wall Time
10 GB xbsa (zstd-3) 2 1 250 MB/s 42 s
10 GB ontape (zstd-3) 1 n/a 85 MB/s 2 min
50 GB xbsa (zstd-3) 4 2 420 MB/s 2 min
100 GB xbsa (zstd-3) 4 4 440 MB/s 4 min
100 GB snapshot (zstd-3) 4 4 520 MB/s 3.5 min

12.2 Compression Ratio Comparison

Data Type zstd-3 zstd-9 lz4 none
OLTP (mixed) 2.8× 3.5× 2.2×
Text/documents 6.2× 8.0× 4.5×
IDS system dbspaces 3.1× 4.0× 2.4×
Binary BLOBs 1.05× 1.05× 1.02×

Recommendation: compress=zstd compress_level=3 for most environments. Use lz4 for CPU-constrained hosts; zstd compress_level=9 for backup storage cost reduction.

12.3 RPO / RTO Targets

Configuration RPO RTO
Daily Full only 24 h 1–4 h
Weekly Full + daily Diff 24 h 30 min–2 h
Weekly Full + daily Diff + 5-min log ship < 5 min 1–3 h
Continuous log shipping (default) < 1 min 1–3 h
Continuous log shipping (interval=5) < 5 s 1–3 h
HDR secondary + nightly backup seconds < 5 min (failover)
Instant recovery (FUSE) as backup < 60 s
Snapshot + log shipping < 30 s 30 min–2 h

12.4 Memory Footprint

Default configuration: xbsa_buffer_count=8 × xbsa_block_size=64KiB × stripes=1 × parallel_dbspaces=# cores

stripes parallel_dbspaces Memory ceiling
1 1 0.5 MB
4 4 8 MB
8 8 32 MB
32 16 256 MB

FD host disk footprint: < 50 MB (FIFOs + sentinels + manifest only). No staging files ever written.


13. Compatibility Matrix

13.1 IDS Version × Feature Matrix

Feature IDS 12.10.FC12 IDS 14.10 IDS 15.0
mode=xbsa
mode=ontape
mode=onbar_psm
mode=logical_dbexport
mode=snapshot
Continuous log shipping
PITR (stop_at_lsn)
HDR bootstrap
RSS bootstrap
ARD ransomware hook ❌ (< 14.10)
DBCRYPT capture
Virtual Full
Instant recovery (FUSE)

13.2 OS × Package Availability

OS RPM (el9) DEB Notes
Oracle Linux 9 Primary GA target
RHEL 9 / Rocky 9 / AlmaLinux 9 GA
RHEL 8 / Rocky 8 GA (el9 RPM compatible)
Ubuntu 22.04 LTS GA
Ubuntu 20.04 LTS GA
Debian 12 GA
Debian 11 GA
SLES 15 Via el9 RPM
AIX 7.2/7.3 Roadmap v0.2.0
Windows Server 2019/2022 Roadmap v0.3.0
Linux ARM64 Roadmap v0.3.0

13.3 Bacula Compatibility

PodHeitor Backup Support
15.0.3 ✅ Primary GA target
15.0.x
14.x ✅ (PTCOMM compatible)
< 14 ⚠️ Not tested

14. Sizing Guide

14.1 Minimum Requirements

Component Minimum Notes
FD host RAM 1 GB XBSA buffer pool at defaults ≈ 0.5 MB
FD host CPU 2 cores Compression + 1 parallel stream
FD host disk 50 MB Working dir (FIFOs + manifest only)
FD host OS disk No staging; never writes data to local disk
Network FD→SD 100 Mbps Minimum functional

14.2 Recommended Production Sizing

IDS Environment FD RAM FD CPU Network stripes parallel_dbspaces
Small (< 100 GB, single dbspace) 4 GB 4 cores 1 Gbps 2 1
Medium (100 GB–1 TB, 4–8 dbspaces) 8 GB 8 cores 10 Gbps 4 4
Large (1–10 TB, 10+ dbspaces) 16 GB 16 cores 25 Gbps 8 8
VLDB (> 10 TB, many dbspaces) 32 GB 32 cores 25+ Gbps 16–32 16+

14.3 Bacula Storage Daemon Sizing

Daily change rate Storage pool SD disk I/O Notes
< 50 GB/day 4 TB disk SAS/SATA Standard pools
50–500 GB/day 20 TB disk SSD recommended Enable zstd compression on SD too
> 500 GB/day NAS/SAN or tape High throughput Consider Bacula Dedup SD plugin

15. Bacularis Integration

Bacularis provides a web UI on top of PodHeitor Backup. The PodHeitor Informix plugin ships a bacularis/plugin-descriptor.json that:

  • Adds “Informix” as a client resource type in the Bacularis backup wizard
  • Renders all 64 backup parameters as form fields with validation
  • Shows the restore browser with IDS-aware namespace (/@informix/) tree view
  • Displays E2E validation results inline

To enable the descriptor:

cp /opt/bacula/plugins/bacularis/plugin-descriptor.json 
   /var/www/bacularis/protected/Common/Modules/PluginConfig/podheitor-informix.json
systemctl restart bacularis

16. Migration from TSM/ISP and ON-Bar PSM

16.1 Migrating from IBM Spectrum Protect (TSM/ISP)

See MIGRATION_FROM_TSM.md for the full procedure. Summary:

  1. Install PodHeitor Backup + PodHeitor on the IDS host
  2. Run parallel backups (TSM + PodHeitor) for one full backup cycle to validate
  3. Confirm chain integrity via archecker + manifest
  4. Set BAR_BSALIB_PATH to point to PodHeitor library (replaces TSM library)
  5. Decommission TSM client

Key difference: TSM’s BAR_BSALIB_PATH points to its own library. PodHeitor’s library is a drop-in replacement — ON-Bar doesn’t know the difference.

16.2 Migrating from ON-Bar PSM Scripts

See MIGRATION_FROM_PSM.md. Summary:

  1. Identify your current BAR_MAX_BACKUP, BAR_XFER_BUF_SIZE, backup windows
  2. Create equivalent PodHeitor FileSet with mode=onbar_psm as a transition step
  3. Validate one full backup cycle
  4. Switch to mode=xbsa (default) for direct streaming
  5. Remove PSM scripts and staging disk allocation

Storage savings from removing staging: PSM writes to disk (.bak files) before Bacula picks them up. PodHeitor streams directly, eliminating 1× backup set of disk space.


17. Troubleshooting

17.1 Plugin Not Loaded

bacula-fd: error: plugin "podheitor-informix" not found

Cause: .so not in Bacula plugin directory. Fix: Verify /opt/bacula/plugins/podheitor-informix-fd.so exists; check bacula-fd.conf has Plugin Directory = /opt/bacula/plugins.

17.2 XBSA Library Load Failure

[ERROR] BAR_BSALIB_PATH not set or library not found

Cause: BAR_BSALIB_PATH not set in /etc/sysconfig/podheitor-informix. Fix:

echo "BAR_BSALIB_PATH=/opt/podheitor-informix/lib/libpodheitor_xbsa.so" 
  >> /etc/sysconfig/podheitor-informix
systemctl restart bacula-fd

17.3 ON-Bar Exits Non-Zero

[ERROR] onbar exit code 45 — see /tmp/onbar_<jobid>.log

Cause: ON-Bar error. Check the log file. Fix: Typically: wrong INFORMIXSERVER, IDS not running, or sysmaster.bar_action locked.

cat /tmp/onbar_<jobid>.log
onstat -g ses   # check active IDS sessions

17.4 Chain Health Check Failure

[ABORT] Chain broken: L0 JobId=1234 not found in catalog (or SHA mismatch)

Cause: Differential/Incremental job aborted because the preceding Full or Diff is missing. Fix: Run a new Full backup. If the Full exists and SHA is wrong, the backup volume may be corrupt — investigate SD device.

17.5 Continuous Log Shipping Gap

[WARN] Log gap detected: expected log unique_id=150, got 152

Cause: Log file 151 was never closed (IDS bug) or was already overwritten. Fix:

onbar -l -s   # salvage logs from disk
# OR set salvage_logs=yes in config

17.6 Diagnostic Commands

# Check IDS status
onstat -

# Check ON-Bar backup history
onstat -g bac

# Check logical log status
onstat -l

# Run archecker manually on last backup
archecker -b -v -f /@informix/<UUID>/__ph_manifest.json

# Check plugin runtime
journalctl -u bacula-fd -n 200 | grep -i podheitor

# Dry-run preflight
/opt/bacula/plugins/podheitor-informix-backend --dry-run 
  /opt/bacula/etc/podheitor-informix.conf

18. Roadmap

Version Target Key Features
v0.1.0 GA 2026-04-29 Full Linux x86_64 support, all 22 E2E scenarios PASS
v0.2.0 2026 Q3 AIX 7.x support (ppc64), NetApp ONTAP snapshot provider, OneDB 2.x compatibility
v0.3.0 2026 Q4 Windows Server FD, Linux ARM64, ER multi-mesh restore
v0.4.0 2027 Q1 Bacularis UI plugin form descriptor, Kubernetes sidecar FD
v0.5.0 2027 Q2 Cross-version logical apply replication (12.10 → 14.10 live streaming)
v1.0.0 2027 Q3 Full platform support (Linux + AIX + Windows + ARM64) + Bacularis UI

19. Validation Evidence (E2E Results)

19.1 Lab Environment

Component Details
Bacula Director 192.168.15.105, Community 15.0.3, OL9
IDS Primary (VM 186) 192.168.15.130, ifxprod, IDS 15.0.1.0.3 Developer Edition in Docker
IDS HDR Secondary (VM 187) 192.168.15.131, ifxhdr, IDS 15.0.1.0.3
IDS RSS Secondary (VM 188) 192.168.15.132, ifxrss, IDS 15.0.1.0.3
IDS Snapshot Host (VM 189) 192.168.15.133, ifxsnap, OL9 bare-metal + loop-backed LVM VG (ifxvg) + FUSE3

19.2 E2E Results — 2026-04-29 (JobIds 6358–6379)

ID Scenario JobId Level Result
T01 Whole-server Full backup 6358 Full ✅ PASS
T02-F Full+Diff+Incr chain — Full 6359 Full ✅ PASS
T02-D Full+Diff+Incr chain — Differential 6360 Differential ✅ PASS
T02-I Full+Diff+Incr chain — Incremental 6361 Incremental ✅ PASS
T03 Restore in-place (restore_object=yes) 6362 Full ✅ PASS
T04 Restore to new instance 6363 Full ✅ PASS
T05-F PITR chain — Full baseline 6364 Full ✅ PASS
T05-I PITR chain — Incremental (log-ship) 6365 Incremental ✅ PASS
T06 Single-dbspace (rootdbs only) 6366 Full ✅ PASS
T07 Table-level backup & extract 6367 Full ✅ PASS
T08 4-stripe parallel backup 6368 Full ✅ PASS
T09-F Continuous log shipping — base 6369 Full ✅ PASS
T09-I Continuous log shipping — Incremental 6370 Incremental ✅ PASS
T10 HDR secondary bootstrap 6371 Full ✅ PASS
T11 RSS secondary bootstrap 6372 Full ✅ PASS
T12 Logical export (mode=logical_dbexport) 6373 Full ✅ PASS
T13 LVM snapshot (snapshot_vg=ifxvg) 6374 Full ✅ PASS
T14 HDR seeding via Bacula transport 6375 Full ✅ PASS
T15 DBCRYPT metadata sidecar 6376 Full ✅ PASS
T16 ontape explicit fallback 6377 Full ✅ PASS
T17 Instant recovery (loopdev+FUSE) 6378 Full ✅ PASS
T18 Bare-metal RestoreObject DR 6379 Full ✅ PASS

PASS=22 / FAIL=0 / SKIP=0 / TOTAL=22 — 100% clean sweep


Contact & Licensing

Licensing

PodHeitor Informix is proprietary software distributed by subscription. For commercial terms, technical demo, or a free 30-minute assessment, reach the team via the channels below.

Ready to evaluate?


PodHeitor Informix Backup, Replication and Conversion Plugin for Bacula — v0.1.0 GA © 2026 Heitor Faria. All rights reserved.

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

Leave a Reply