Thank you for visiting!
My little window on internet allowing me to share several of my passions
Categories:
- VoidLinux
- OpenBSD
- FreeBSD
- VoidLinux
- ZFS
- Tunnel
- fapws
- Nvim
- Firewall
- got
- PEKwm
- Zsh
- VM
- High Availability
- vdcron
- My Sysupgrade
- Nas
- VPN
- DragonflyBSD
- Alpine Linux
- Openbox
- Desktop
- Security
- yabitrot
- nmctl
- Tint2
- Project Management
- Hifi
- Alarm
Most Popular Articles:
Last Articles:
A proposition of Boot Environment for VoidLinux running on ZFS
Posted on 2026-09-24 21:22:00 from Vincent in VoidLinux
If you run FreeBSD on ZFS, you probably can't imagine upgrading without
bectl anymore. Take a boot environment, run freebsd-update or pkg upgrade,
and if something goes wrong, reboot into the previous state. No backup to
restore, no rescue USB stick.
vbe: bectl-style boot environments on Void Linux
As you saw in one of my previous post, I also run a Void Linux laptop with root on ZFS, and I missed that workflow
there. So I wrote vbe, a small POSIX sh script that brings the core
bectl concepts to Void Linux, using
ZFSBootMenu as the boot loader.
How it works
The idea is the same as on FreeBSD. A boot environment (BE) is a ZFS dataset
directly under a parent dataset, typically <pool>/ROOT:
vpool/ROOT/void <- the system currently running
vpool/ROOT/pre-upgrade <- a boot environment created before an upgrade
Creating a BE means taking a snapshot of the running root and cloning it.
Thanks to copy-on-write, this is instant and costs almost no space at first.
On the boot side, ZFSBootMenu plays the role of the FreeBSD loader. It finds
every dataset with mountpoint=/ in the pool, lets you pick one at boot, and
uses the pool's bootfs property as the default, just like FreeBSD.
Usage
The commands mirror bectl:
vbe list [-H] # list boot environments
vbe create <name> # snapshot + clone the running BE
vbe activate <name> # make <name> the default BE (pool bootfs)
vbe destroy [-y] <name> # destroy a BE and the snapshot created for it
Example output of vbe list:
BE Active Mountpoint Space Created
pre-upgrade - - 8.2M 2026-09-20 18:42
void NR / 6.1G 2025-11-03 10:15
The Active column has the same meaning as with bectl: N = active now,
R = active on reboot.
A typical upgrade
doas vbe create pre-upgrade
doas xbps-install -Su
If everything works, remove the safety copy later:
doas vbe destroy pre-upgrade
If the upgrade broke something, reboot, choose pre-upgrade in ZFSBootMenu,
then make it permanent:
doas vbe activate pre-upgrade
doas zfs promote vpool/ROOT/pre-upgrade # reverse the clone dependency
doas vbe destroy void # remove the broken BE
The zfs promote step is needed because pre-upgrade is a clone of a
snapshot of void. Promoting it makes void the dependent one, so it can be
destroyed.
Assumptions
vbe deliberately keeps the same simple layout that bectl expects:
- root on ZFS, booted through ZFSBootMenu;
/bootlives inside the BE, so kernel and initramfs roll back together
with the system;- a BE has no child datasets: keep
/home, logs and other data outside of
ROOT, so that a rollback never touches your personal files; - kernel arguments are stored in the
org.zfsbootmenu:commandlineproperty
on<pool>/ROOT, so every BE inherits them. vbe checks this before
creating a BE and suggests the right command if it is missing.
Should I mention that, despite I'm on voidlinus, I'm using ksh, doas, openntpd, got, ... ?
After using OpenBSD since 2009 and FreeBSD since 2024, I have some bias and habits ;)
Differences from bectl
vbe is intentionally small. Compared to bectl:
- there is no
mount,renameorjailcommand; - there is no one-shot activation (
bectl activate -t); to boot a BE once,
simply pick it in ZFSBootMenu; - properties set locally on the running BE are not copied to the new one;
set shared properties (compression, acltype, xattr...) on the parent
dataset or the pool instead; - a BE is always created from the running system (no
-eoption).
It also refuses the dangerous cases: destroying the running BE, the default
BE (bootfs), or a BE that is currently mounted.
Installation
vbe is a single shell script with no dependencies beyond the ZFS tools and a
standard Void base system
You can get it from my repository: repo.vincentdelft.be/vbd
got clone ssh://anon@repo.vincentdelft.be/vbe
got checkout vbe.git
cd vbe
doas install -m 755 vbe /usr/local/bin/vbe
License: is BSD-2 clauses
Feedback
This is a small personal tool, but I'd be glad to hear from anyone who tries
it.
For sure, patches are welcome ;)
!!! Be careful that this is a early beta code !!!