TWINSTOR
Tech Preview · v0.5.0 · July 2026

TWINSTOR Deployment Guide

From a bare 2-node XCP-ng pool to replicated shared storage — and then to a proper torture test. Pre-release test build: run it on a lab pool, not production. And keep backups.

Read this first

Four things to keep in mind before you install

1

Lab pool only

This is a pre-release test build, distributed for a community torture test. Do not run it on production. If it survives your abuse, then maybe, just maybe, it becomes a product.

2

Keep your backups

Two replicas protect against hardware failure, not against fat fingers, ransomware or "oops I deleted the wrong VM". Backups are mandatory defense in depth, with TWINSTOR or without it — keep backing up with XO or whatever you use.

3

Safe by default

Auto-healing only fires when TWINSTOR is certain it cannot corrupt data. When in doubt, it prefers a clean outage over a risky recovery: a full-pool stop with intact data beats a split-brain every single time.

4

Honest about cheap disks

TWINSTOR uses direct, synchronous writes (DRBD protocol C) and disables volatile write caches on drives that report one, re-applied on every boot; enterprise drives with power-loss protection are left at full performance. But no software can make a lying drive durable — if your disks are bargain-bin, know that risk. Pull the power and see what survives: that is exactly what this test is for.

Deployment

Seven steps, wizard included

No DRBD commands to learn, no config files to hand edit. One command installs, one command sets up, one command tears it all down.

1

Meet the prerequisites

  • 2× XCP-ng hosts in a pool. Multipath is enabled for you by twinstor setup; you do not need to turn it on yourself.
  • A free local disk or partition with spare space on each host. The system disk and in-use devices are never offered, but point it at the right one.
  • Fully update both hosts (yum update + reboot) before installing. A mixed-patch-level pool blocks HA config changes.
  • In the BIOS of both hosts, set "Restore on AC Power Loss" to Power On so the pool comes back by itself after an outage.

The runtime dependencies (DRBD 9 kernel module, drbd-utils, targetcli and friends) are bundled in the test tarball and installed for you — no RPM chasing.

2

Pick your topology

The setup wizard asks you this. Two choices; both keep your data safe.

Fate-shared (default)

One switch, one L2 segment, gateway on it. The safety property holds by construction: you cannot lose the peer without also losing the gateway. This is the cheap small-office / edge box. Single trade-off: the switch is a single point of failure — if it dies, both hosts self-fence into a clean full-pool outage, no corruption.

Arbitrated (redundant network)

For multi-switch setups, add a back-to-back direct link (DAC or crossover) between the hosts. DRBD replicates over the switched network with the direct link as a hot standby (active-backup), so losing a path fails over with no split-brain. The wizard can configure the direct-link IP for you.

3

Install the test build on both hosts

There is no RPM yet — for this test phase, distribution is a tarball plus an install.sh. Fetch it straight onto both hosts and run the installer on each:

# on each host (dom0), as root
wget -O twinstor-test-0.5.0.tar.gz "https://nextcloud.vates.tech/public.php/dav/files/H2kNDT2jTBAozCr"

# verify before extracting (aborts if it does not match):
echo "124171c2c73fde13c21c76b0012bfbdb8cd212277c6ce960d294ed94eeae838f  twinstor-test-0.5.0.tar.gz" | sha256sum -c

tar xzf twinstor-test-0.5.0.tar.gz && cd twinstor-test-0.5.0 && ./install.sh

install.sh runs preflight checks, installs the bundled dependency RPMs from deps/, places the static binary (/usr/local/bin/twinstor, ~4 MB) and the systemd unit, verifies the DRBD kernel module loads, and prints the installed version. It does not configure anything: once it finishes, run twinstor setup (next step). An RPM is planned for the real release.

4

Run the setup wizard on each node

No flags, just follow the prompts — every answer has a sensible default:

twinstor setup

It auto-detects the peer, asks which topology mode to use (step 2), lists the candidate disks with model / serial / size, defaults every answer, and requires an explicit yes before wiping anything. Run it on the first node, then on the second. The second node creates the shared SR, plugs the PBDs on both hosts, and enables XHA.

The wizard is the way in: run it on both nodes and TWINSTOR configures DRBD, the iSCSI target, multipath and XHA for you — no flags to memorize, no config files to hand-edit. Use it on both nodes for a consistent setup.

5

Verify the cluster

A healthy twinstor status shows both nodes Primary / UpToDate / Connected:

twinstor status

health:  ● healthy  — serving, peer redundant

     version:     0.5.0
     daemon:      running
     resource:    twinstor-data
     host:        twinstor-1 (this node), peer twinstor-2
     pool master: twinstor-1 (this node)
     pool HA:     enabled

   drbd
       role:       Primary
       disk:       UpToDate
       connection: Connected
       peer role:  Primary
       peer disk:  UpToDate

   readiness:   ready (local serving, peer redundant)
   iscsi:       active
   multipath:   ok
       twinstor-data dm-3 LIO-ORG,twinstor
       |-+- prio=50 status=active   (local path)
       `-+- prio=10 status=enabled  (remote path)
   tiebreaker:  192.168.1.1 (gateway)

That is it: you now have a shared SR. Create VMs on it, live-migrate them in every direction, and they will auto-restart on the survivor if a host dies.

6

Now, break it

Resilience is the whole reason TWINSTOR exists. The default posture: keep serving through failures, recover automatically once it is safe. Here is what should survive with nobody touching anything:

  • A dead local data disk does not take the VMs down. DRBD detaches it and the local iSCSI target keeps serving by transparently forwarding I/O to the peer's still-good copy. The VMs see no path change — just slightly higher latency. The moment the disk comes back (or is replaced), it resyncs and returns to full redundancy on its own. A failed disk is a "fix it whenever" event, not a 2am outage.
  • A dead node restarts its VMs on the survivor. XHA fences the lost host and XAPI restarts its VMs on the peer, which is already serving — they come straight back on the local path.
  • The daemon crashing changes nothing for I/O. systemd restarts twinstor, while DRBD and the iSCSI target persist in the kernel. Storage never blinks.
  • Brief network blips are absorbed. A flap shorter than the disconnect threshold stays Connected: no resync, no drama.
  • Reads stay local, failover is automatic. Multipath prefers each host's local iSCSI path, and fails over to the peer's path if the local target itself disappears.

What to throw at it

We are calling for functional, realistic failures — the kind that genuinely happen in a ROBO / edge / small-office context. Using a firewall to selectively block only some traffic so that auto-heal becomes impossible is not a functional break: no real deployment does that to itself. That is poking the model with tweezers, not testing reality. Very welcome, please do these:

  • Yank network cables (one node, both nodes, mid-write).
  • Yank power cables, including a global power cut to both hosts at once (the classic "race to become master on boot" scenario).
  • Switch port flapping and switch reboots.
  • Full switch power loss (single switch is a known trade-off in fate-shared mode, see step 2).
  • Upgrades: host RPU (Rolling Pool Update), and re-running install.sh to stage a new TWINSTOR build over a running one.
  • Plain host reboots, graceful and ungraceful.
  • VM live migration in every direction, repeatedly, during all of the above.
  • Disk pull / disk failure / disk re-insertion.
  • Anything else that can plausibly happen to two hosts sitting in a closet at a remote site.

If you can corrupt data, lose an acknowledged write, or wedge the cluster into a state it cannot recover from using one of the above — that is gold, and exactly what we need to hear about.

7

Report what you find

When something breaks (please make it break):

  1. Run twinstor support-bundle on both nodes.
  2. Note what you did — the exact sequence: "pulled power on A during a migration, then rebooted the switch", etc.
  3. Tell us what you expected vs what happened (data loss? wedged state? VMs not restarting?).

Post it on the TWINSTOR thread with the two bundles attached, and include your twinstor --version in any report.

Reference

Command cheat sheet

# Which build am I running (please include this in any report)
twinstor --version

# Show DRBD, iSCSI, multipath and sync status
twinstor status

# Same, machine-readable (for monitoring)
twinstor status --json

# Collect logs + redacted config + state snapshot for a bug report.
# Run on BOTH nodes and attach both files.
twinstor support-bundle

# Remove TWINSTOR from this node (reverses everything in order)
twinstor uninstall
twinstor uninstall --keep-data   # keep the backing LV
Bonus

Keep your application's own HA in control

Because both hosts share the same SR, your VMs can live anywhere and move freely — so you can pair TWINSTOR with XO's Load Balancer anti-affinity. While the cluster is healthy, the load balancer keeps your VMs balanced and, crucially, keeps the members of your own application-level HA (replicated databases, a clustered app, a pair of front-ends) on separate hosts. Even if you lose one host, you never lose both copies at once: your app's redundancy stays in your control, on top of the storage redundancy TWINSTOR already gives you.

What comes next

Prove the foundation first

This phase validates the core architecture: the 2-node dual-primary, the self-healing, the safety model. If it holds up, there is a lot to build on top — some of it already prototyped in our lab, like encryption at rest (a LUKS layer under DRBD), deliberately kept out of this build. One thing at a time.

And yes, this will be open sourced — that is not in question. The repo is currently the messy result of a month of intense experimentation; it gets a cleanup pass once the community has hammered the design and surfaced its real weaknesses. Harden first, then ship a clean repo.