Storage Configuration
Configuring PureStorageDriver or MockStorageDriver in protector.conf
This page explains how to configure the storage backend for Trilio Site Recovery's protector-engine service. The [storage] section of protector.conf controls whether the engine communicates with physical Pure Storage FlashArray appliances or with the built-in Mock driver, which simulates FlashArray behavior using a local SQLite database. Correct storage configuration is a prerequisite for replication policy enforcement, consistency group management, and all DR operations including failover and failback.
Before configuring storage, ensure the following are in place:
- Two independent OpenStack clouds are deployed and reachable — a primary site and a secondary (DR) site, each with its own Nova, Cinder, Neutron, and Keystone endpoints.
- Trilio Site Recovery (
protector-apiandprotector-engine) is installed on both sites. See the Deployment Guide for installation steps. - Pure Storage FlashArray (for production use):
- Both arrays must have a replication connection established before configuring the driver (async replication link for async protection groups; ActiveCluster/Pod configuration for sync).
- API tokens with sufficient privileges must be available for both arrays.
- Management IPs of both arrays must be reachable from the hosts running
protector-engineon their respective sites.
- Cinder volume types with
replication_enabled='<is> True'andreplication_type='<in> async'(orsync) must exist on both sites. The storage driver respects these properties; volumes on non-replication-enabled types cannot be added to a Protection Group. - For Mock/testing environments: no physical arrays are required, but
/var/lib/protector/mock_storage/must be writable by theprotectorservice user.
The storage driver is part of protector-engine and requires no separate package installation. The configuration lives entirely in protector.conf. Follow the steps below to prepare the configuration file on each site.
Step 1 — Open protector.conf for editing
sudo -u protector vi /etc/protector/protector.conf
Step 2 — Add the [storage] section (Pure FlashArray)
For production deployments using Pure Storage FlashArray, append the following block:
[storage]
primary_array_url = https://flasharray-a.example.com
primary_array_api_token = T-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
secondary_array_url = https://flasharray-b.example.com
secondary_array_api_token = T-yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy
default_replication_interval = 300
default_rpo_minutes = 15
Repeat this step on the other site, substituting the appropriate array URLs and tokens for that site's perspective.
Step 3 — (Alternative) Enable the Mock driver for testing
If you are running an end-to-end DR test without physical FlashArray hardware, add the following to the [DEFAULT] section instead of — or in addition to — the [storage] block:
[DEFAULT]
use_mock_storage = True
When use_mock_storage = True, the engine ignores [storage] array credentials entirely and routes all storage operations to the SQLite-backed Mock driver.
Step 4 — Create the Mock storage directory (Mock driver only)
sudo mkdir -p /var/lib/protector/mock_storage
sudo chown -R protector:protector /var/lib/protector/mock_storage
Step 5 — Restart protector-engine to apply changes
sudo systemctl restart protector-engine
sudo systemctl status protector-engine
Verify the engine started cleanly before proceeding:
journalctl -u protector-engine -n 50 --no-pager
All storage configuration lives in two places in protector.conf: the [DEFAULT] section controls driver selection, and the [storage] section holds Pure FlashArray connection parameters.
[DEFAULT] section
| Option | Type | Default | Description |
|---|---|---|---|
use_mock_storage | Boolean | False | When True, the engine uses the Mock storage driver (SQLite-backed) instead of communicating with a real FlashArray. Set this for lab or CI environments where physical arrays are unavailable. |
[storage] section (Pure FlashArray driver)
These options are used when use_mock_storage is False (the default).
| Option | Type | Required | Description |
|---|---|---|---|
primary_array_url | String (HTTPS URL) | Yes | Management URL of the FlashArray associated with the primary OpenStack site. The engine on each site uses this to authenticate to the local array. |
primary_array_api_token | String | Yes | API token for the primary FlashArray. Treat this as a secret — consider using Barbican for encrypted storage in production. |
secondary_array_url | String (HTTPS URL) | Yes | Management URL of the FlashArray at the secondary (DR) site. The engine needs visibility to both arrays to orchestrate snapshot promotion during failover. |
secondary_array_api_token | String | Yes | API token for the secondary FlashArray. |
default_replication_interval | Integer (seconds) | No | Default interval between async replication snapshots. Used as the initial value when a replication policy is created without an explicit --replication-interval. Overridden per-Protection-Group by the policy. Example: 300 (5 minutes). |
default_rpo_minutes | Integer (minutes) | No | Default Recovery Point Objective in minutes. Used as the initial value for new replication policies. Overridden per-Protection-Group. Example: 15. |
Replication type: set at Protection Group creation, not here
The replication_type (sync or async) is not a driver-level configuration option. It is set per-Protection-Group at creation time via the CLI or API:
openstack protector protection-group create \
--replication-type async \
...
The engine maps this to the appropriate Pure Storage mechanism: async Protection Groups for async, and ActiveCluster Pods for sync. Both modes require the corresponding replication link to be pre-established on the arrays before the Protection Group is created.
Mock driver storage path
The Mock driver stores its SQLite database and simulated volume metadata in /var/lib/protector/mock_storage/. This path is not currently configurable via protector.conf. Ensure the directory exists and is owned by the protector service user.
Once storage is configured and protector-engine is running, the storage driver operates transparently behind Protection Group and replication policy operations. You do not interact with it directly — instead, you configure replication policies that reference the array credentials, and the engine uses the [storage] driver settings as defaults and connection context.
Creating a replication policy that references your FlashArray
The per-Protection-Group replication policy allows you to override the default interval and RPO and to supply the Pure Storage protection group name. The primary_fa_url and secondary_fa_url values in the policy must match the arrays you configured in [storage]:
openstack protector protection-group policy-create prod-web-app \
--primary-fa-url https://flasharray-a.example.com \
--primary-fa-token "T-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" \
--secondary-fa-url https://flasharray-b.example.com \
--secondary-fa-token "T-yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy" \
--pure-pg-name "pg-prod-web-app" \
--replication-interval 300 \
--rpo-minutes 15
Using the Mock driver for a full DR drill without physical arrays
With use_mock_storage = True, every storage operation — snapshot creation, volume promotion, consistency group replication — is simulated in SQLite. This lets you exercise the complete failover workflow, including test failovers and failback, in a lab environment. All metadata behavior (Protection Group state transitions, operation progress tracking, metadata sync blocking when the peer site is unreachable) is identical to production.
Verifying storage connectivity
After configuring the driver and restarting protector-engine, validate that the engine can reach both arrays by validating your registered sites:
openstack protector site validate site-a
openstack protector site validate site-b
A site validation failure that reports a storage-layer error typically indicates a misconfigured URL, invalid API token, or network routing issue between the engine host and the FlashArray management interface.
Example 1 — Minimal async production configuration
A two-site async deployment with a 5-minute replication interval and 15-minute RPO.
# /etc/protector/protector.conf (Site A)
[DEFAULT]
debug = False
log_dir = /var/log/protector
state_path = /var/lib/protector
[storage]
primary_array_url = https://fa-boston-01.example.com
primary_array_api_token = T-aaaabbbb-cccc-dddd-eeee-ffffffffffff
secondary_array_url = https://fa-seattle-01.example.com
secondary_array_api_token = T-11112222-3333-4444-5555-666677778888
default_replication_interval = 300
default_rpo_minutes = 15
The corresponding protector.conf on Site B uses the same values — primary and secondary are workload-relative labels, and both sites are configured symmetrically so that after a failover, Site B's engine can act as the new primary.
Expected engine log on successful startup:
INFO protector.engine.storage.pure [-] PureStorageDriver initialized: primary=fa-boston-01.example.com secondary=fa-seattle-01.example.com
Example 2 — Mock driver for end-to-end DR testing
Enable the Mock driver on both sites to run a complete DR drill without FlashArray hardware.
# /etc/protector/protector.conf (both sites)
[DEFAULT]
debug = True
log_dir = /var/log/protector
state_path = /var/lib/protector
use_mock_storage = True
Create the mock data directory before starting the engine:
sudo mkdir -p /var/lib/protector/mock_storage
sudo chown -R protector:protector /var/lib/protector/mock_storage
sudo systemctl restart protector-engine
Expected engine log on successful startup:
INFO protector.engine.storage.mock [-] MockStorageDriver initialized: data_dir=/var/lib/protector/mock_storage
WARNING protector.engine.storage.mock [-] Mock storage driver active — not suitable for production use
You can now create Protection Groups, add VMs, configure policies (array URLs are ignored), and execute test failovers as you would against real hardware.
Example 3 — Tighter RPO for a critical workload
Override the global defaults at the Protection Group policy level for a database cluster that requires a 5-minute RPO:
openstack protector protection-group policy-create db-cluster-pg \
--primary-fa-url https://fa-boston-01.example.com \
--primary-fa-token "T-aaaabbbb-cccc-dddd-eeee-ffffffffffff" \
--secondary-fa-url https://fa-seattle-01.example.com \
--secondary-fa-token "T-11112222-3333-4444-5555-666677778888" \
--pure-pg-name "pg-db-cluster" \
--replication-interval 120 \
--rpo-minutes 5
Expected output:
+----------------------+--------------------------------------+
| Field | Value |
+----------------------+--------------------------------------+
| protection_group_id | pg-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx|
| pure_pg_name | pg-db-cluster |
| replication_interval | 120 |
| rpo_minutes | 5 |
| status | active |
+----------------------+--------------------------------------+
Engine fails to start: [storage] options missing
Symptom: protector-engine exits immediately after restart with an error referencing missing configuration keys.
Likely cause: The [storage] section is absent from protector.conf and use_mock_storage is not set to True, so the Pure FlashArray driver attempts to initialize without required parameters.
Fix: Either add a complete [storage] block with valid primary_array_url, primary_array_api_token, secondary_array_url, and secondary_array_api_token values, or set use_mock_storage = True in [DEFAULT] for non-production environments. Restart the engine after editing.
Site validation fails with a storage connectivity error
Symptom: openstack protector site validate site-a returns an error indicating the engine cannot reach the FlashArray management interface.
Likely cause: One of the following: (1) primary_array_url or secondary_array_url is incorrect or uses HTTP instead of HTTPS; (2) the API token has expired or been revoked; (3) a firewall is blocking the engine host's access to the FlashArray management IP.
Fix:
- Confirm the URL is reachable from the engine host:
curl -sk https://flasharray-a.example.com/api/api_version - Verify the API token is valid by testing it directly against the FlashArray REST API.
- Check that no firewall rule blocks outbound HTTPS from the
protector-enginehost to the array management IPs. - Correct the values in
protector.confand restartprotector-engine.
Mock storage directory not writable
Symptom: With use_mock_storage = True, the engine starts but operations immediately fail with a permissions or file-not-found error referencing /var/lib/protector/mock_storage/.
Likely cause: The directory does not exist or is owned by root rather than the protector service user.
Fix:
sudo mkdir -p /var/lib/protector/mock_storage
sudo chown -R protector:protector /var/lib/protector/mock_storage
sudo systemctl restart protector-engine
Protection Group creation fails: volume type not replication-enabled
Symptom: Creating a Protection Group returns an error such as Volume type 'standard-ssd' does not support replication.
Likely cause: The Cinder volume type selected for the Protection Group is missing the replication_enabled='<is> True' extra spec, or the replication_type property does not match the Protection Group's replication type (async or sync).
Fix: Verify the volume type properties on both sites:
openstack volume type show replicated-ssd --fit-width
Ensure both replication_enabled='<is> True' and replication_type='<in> async' (or sync) are present. If missing, set them:
openstack volume type set replicated-ssd \
--property replication_enabled='<is> True' \
--property replication_type='<in> async'
Repeat on both sites, then retry Protection Group creation.
Replication interval changes in [storage] have no effect on existing policies
Symptom: You updated default_replication_interval in protector.conf and restarted the engine, but existing Protection Groups continue replicating at the old interval.
Likely cause: default_replication_interval and default_rpo_minutes are used only as defaults when a new replication policy is created without explicit overrides. They do not retroactively modify existing policies.
Fix: Update the replication policy for each affected Protection Group explicitly:
openstack protector protection-group policy-create <pg-name> \
--replication-interval <new-interval-seconds> \
--rpo-minutes <new-rpo>