Skip to main content

Installation

From a bare 2-node XCP-ng pool to replicated shared storage: seven steps, wizard included. There are no DRBD commands to learn and no config files to hand edit. One command installs, one command sets up, one command tears it all down.

Before you install

warning
  1. Lab pool only. The Tech Preview is a pre-release test build, distributed for a community torture test. Do not run it on production.
  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.
  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 and disables volatile write caches on drives that report one; 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.

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, partition, or md-RAID array on each host. The system disk and in-use devices are never offered by the wizard, but point it at the right device. (As a last resort on single-disk machines, the wizard can carve a partition from the system disk's unallocated free space, behind a stricter confirmation.) A ZFS zvol also works as a community-supported option: point setup at the stable /dev/zvol/<pool>/<dataset> path, and keep the dataset's sync property at standard (with sync=disabled, an acknowledged write is a lie and a power cut loses committed data).
  • A decent inter-host network. 1 Gbps works; 10 Gbps is recommended for write-heavy workloads (synchronous replication rides this link). Bonded NICs and/or stacked switches are recommended for reliability.
  • Fully update both hosts (yum update + reboot) before installing. A mixed-patch-level pool blocks HA configuration 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. TwinStor recovers from a global power cut automatically, but only if the machines actually power back on.
  • No permanently broken SRs in the pool. XCP-ng keeps a host disabled if any of its storage fails to plug at boot, and a disabled host blocks HA VM restarts. Forget or repair dead SRs first.
  • The runtime dependencies (DRBD 9 kernel module, drbd-utils, targetcli and friends) are bundled in the Tech Preview tarball and installed for you. No RPM chasing.

Pick your topology

The setup wizard asks you this. Both choices keep your data safe; the right one depends on a single property of your network, which maps directly onto the class of hardware you are deploying: can the path the two hosts replicate over fail independently of the gateway they use as tiebreaker, or do they fail together?

Match it to your network:

  • A single switch, one L2 segment (small office, edge, a lab box) → fate-shared. Replication and the gateway ride the same wire, so a host cannot lose its peer without also losing the gateway and knowing to step aside. The switch is a single point of failure, but its failure is a clean full-pool outage with intact data.
  • Redundant switches you run as one L2 (an MLAG pair or a stack carrying everything on one stretched segment) → fate-shared, now with no single point of failure. Losing one switch keeps the L2 up; only losing the whole L2 stops the pool, cleanly. For a site that has redundant switching but does not need a separate storage network, this is usually the simplest and lowest-surprise choice: you keep the by-construction safety and gain switch redundancy.
  • A dedicated storage network, separate from the client/gateway network (a storage plane on its own switches or fabric, common on VxRail, spine/leaf, or any build with a separate 25/40/100G storage VLAN) → arbitrated. Here the replication path and the gateway path fail independently, so the by-construction safety no longer holds and the direct link is required. Add a back-to-back cable between the two hosts as the primary replication path; your storage fabric becomes the automatic, alerted fallback.

The rule underneath all three: fate-shared is correct exactly when the peer and the gateway cannot fail apart, and arbitrated is for when they can. Spare NICs are not the trigger; a network that can partition storage away from the gateway is. And on every topology, the XHA heartbeat rides your management network, so keep that network redundant too (a bond, or the same MLAG pair): a management blip that a host mistakes for a peer failure is the usual cause of an avoidable HA fence.

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 fits the small-office and edge box with a single switch, and equally a redundant MLAG pair run as one segment, where you also lose the switch as a single point of failure. Its one trade-off on a genuinely single switch: that switch is a single point of failure. If it dies, both hosts self-fence into a clean full-pool outage, with no corruption.

GatewaytiebreakerSwitchclients + replication share the same wiresHost AHost B
Fate-shared · one switch carries everythingclients + replicationtiebreaker

One wire carries everything: the clients, the replication, and the gateway used as tiebreaker. That is the point: a host cannot lose its peer without losing everything else too, so it always knows to step aside.

Arbitrated (dedicated storage network)

When replication runs on its own network, separate from the clients and the gateway (a dedicated storage plane on its own switches or fabric), add a back-to-back direct link (a DAC or crossover cable) between the two hosts. In that topology the direct link is required for safety, not a luxury: it is exactly the case where the peer and the gateway can fail independently, so a host can no longer infer that a lost peer means it is the isolated one. Replication runs over both paths in active-backup mode with the direct link as the default active path, so a cable or NIC failure fails over to the storage fabric without interruption (and alerts loudly). This is the mode for enterprise builds with a separate storage plane. The wizard can configure the direct-link IP for you.

GatewaytiebreakerSwitch 1Switch 2Host AHost Bdirect cable · main replication path
Arbitrated · replication rides a dedicated cablereplicationclientstiebreaker

Each host is wired to both switches, so losing one switch takes out neither host. The direct cable carries the replication; the switched network carries the clients and stands by as the automatic replication fallback if the cable fails.

Choose the mode at install time: the second replication path cannot be added to a running cluster without a maintenance window.

Extra fence ping targets

The decision to keep serving during a partition is based on reaching the default gateway. You can add extra ping targets (a switch management IP, a second router) in /etc/twinstor/ping-targets, one IP per line: if any target answers, the node survives. Never put the direct-link IP in that file; an isolated node can still reach its peer over the cable while being invisible to every client.

Install the build on both hosts

For the Tech Preview there is no RPM yet; distribution is a tarball plus an install.sh. Get the current download link and its SHA-256 checksum from the TwinStor deploy page, then on each host (in dom0, as root):

root@twinstor-1 — install the build
# wget -O twinstor-test-<version>.tar.gz "<download URL>"
# verify before extracting (aborts if it does not match):
# echo "<published sha256>  twinstor-test-<version>.tar.gz" | sha256sum -c
# tar xzf twinstor-test-<version>.tar.gz && cd twinstor-test-<version> && ./install.sh

install.sh runs preflight checks, installs the bundled dependencies, places the twinstor binary and its systemd unit, verifies the DRBD kernel module loads, and prints the installed version. It configures nothing by itself: once it finishes, run twinstor setup.

Run the setup wizard on each node

No flags, just follow the prompts. Every answer has a sensible default:

root@twinstor-1 — twinstor setup
# twinstor setup

The wizard auto-detects the pool peer, asks which topology mode to use, lists the candidate disks with model, serial and size, and requires an explicit yes before wiping anything. Run it on the first node, then on the second: the second node inherits the cluster-wide choices the first node published, creates the shared SR, plugs it on both hosts, and enables HA (XHA).

On an already-installed node, twinstor setup instead shows the current settings and live status, with quit, uninstall, and reconfigure options.

For scripted deployments a non-interactive mode exists: twinstor setup --peer-ip <IP> --backing-device /dev/disk/by-id/<disk> on the first node prints the exact command to run on the peer. See twinstor --help for all flags.

If setup fails partway (a typo, a network hiccup), there is no automatic rollback, but setup is re-runnable: run it again with the same answers and it converges on the existing state, or run twinstor uninstall to clear the partial state and start clean. Before placing any workload, verify twinstor status reports ready on both nodes.

Firewall

Setup persistently adds two firewall rules on each host (marked with # TWINSTOR comments): 7789/tcp for replication and 3260/tcp for iSCSI.

Verify the cluster

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

root@twinstor-1 — twinstor status
# twinstor status

health:   healthy   serving, peer redundant

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

 readiness:   ready (local serving, peer redundant)

For the complete output and a field-by-field reading of every status line, see Administration.

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

Uninstall

twinstor uninstall removes TwinStor from a node and reverses everything in the correct order. By default it refuses to proceed while VMs still use the SR.

root@twinstor-1 — twinstor uninstall
# twinstor uninstall               # interactive confirmation
# twinstor uninstall --keep-data   # keep the backing device (do not wipe data)
# twinstor uninstall --force       # proceed even when the VM-safety check cannot confirm the SR is unused

Two things uninstall deliberately leaves in place: XCP-ng network objects (a back-to-back replication network and its dedicated-NIC IPs stay configured; remove them with xe pif-reconfigure-ip mode=None and xe network-destroy if you no longer want them), and any software-RAID array you built for the backing device (tear it down with mdadm --stop and --zero-superblock yourself).