Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

The Solnix handbook

The Solnix Operating System is a supported distribution of illumos built entirely with the Nix package manager and the NixOS module system — the illumos analog of NixOS (Linux) and nixbsd (FreeBSD/OpenBSD).

The Solnix OS targets four CPU architectures — x86_64, aarch64, RISC-V, and SPARC (the x86_64-solaris, aarch64-solaris, riscv64-solaris, and sparcv9-solaris systems) — and is designed for both server and desktop use. It is optimized for virtualized hosting on all the major cloud platforms (AWS/EC2, Microsoft Azure, Google Cloud, and the rest), while remaining a first-class OS on bare metal.

Describe an illumos machine declaratively in Nix; get a bootable, atomically upgradeable, rollback-capable system backed by ZFS boot environments.

Status: early / preview. The first bootable image has landed — an unstable-edition x86_64 ISO + raw disk image (v2026.08.07), preview-grade (Download). The positioning above describes the target the Solnix OS is designed for, not everything that runs today. x86_64 is the primary target; aarch64, RISC-V, and SPARC are in bring-up (see CPU architecture support). Solnix now installs and runs on real hardware — a full disk install on a Lenovo ThinkPad X1 Extreme with the NixOS workflow intact (ZFS boot environments, solnix-rebuild, generations, sudo), and working wifi (Intel AC 9560: WPA2/CCMP, encrypted traffic). That install is headless today: graphics are still in active bring-up. The COSMIC desktop has been shown to compile for illumos (Rust, Wayland, GTK4, Mesa/Vulkan), which proved the toolchain stack is viable, but a GPU-driven display on real hardware is not yet working — it is gated on a kernel console-handover and up-to-date GPU drivers (see the news for the honest, dated status). This handbook documents the design and the working infrastructure (binary cache, package search) as they come online. It does not over-claim: sections marked planned are not yet real, and “works” means works on hardware, not merely compiles.

Why

illumos-gate is fully buildable from source today, ships ZFS + zones + bhyve + LX-branded zones, and already has a native atomic-upgrade story (beadm boot environments). Nix’s immutable store + generation model maps cleanly onto that. Solnix marries the two.

How, in one breath

Reuse NixOS’s evaluator and module system verbatim; add an *-illumos platform and a fine-grained pkgs.solnix.* world to a nixpkgs fork; drive services through SMF (not systemd) via an smf.services.* module; bake /nix/store paths into ELF RUNPATH with the Solaris link-editor (no GNU tooling); map each Nix generation onto a ZFS boot environment. This is nixbsd’s playbook, retargeted to illumos.

Where to go next

For Linux (and NixOS) users

You know Linux. Maybe you know NixOS. Solnix is neither — it is illumos managed with Nix. Most of your instincts transfer, but the substrate is different: a different kernel, a different init, a different filesystem, a different firewall, a different way to run containers. This page is the map. Each row points at the deeper handbook page.

If you know Nix already, the Nix half transfers almost unchanged (same language, store, module system) — see Learning Nix. What changes is everything the packages target. If you also came from Solaris/IPS packaging, read Learning Nix for the pkg → Nix mapping.

The one-screen map

You know (Linux / NixOS)On Solnix (illumos)Where
systemd (systemctl, unit files, journalctl)SMF (svcs, svcadm, svccfg, XML manifests)SMF services
systemctl status / journalctl -usvcs -x + /var/svc/log/<fmri>.logSMF · Debugging
iptables / nftablesipfilter (ipf, ipnat)Networking
bridges / veth / tc / netnsCrossbow: dladm, ipadm, flowadmNetworking (Crossbow)
cgroups + namespaces / Docker / LXCZones (native), LX zones for Linux binsZones · LX zones
ext4 / xfs / btrfs + LVM / mdadmZFS (pool + datasets, checksums, snapshots)ZFS storage
/proc + strace / perf / ftrace / eBPFDTrace (+ truss, pargs, pfiles, procfs)DTrace · Debugging
apt / dnf / pacmanNix — pkgs.solnix.*, declarative configLearning Nix
NixOS generations (Linux)Nix generations → ZFS boot environmentsBoot environments
GRUBloader (x86, FreeBSD-derived) / OpenBoot (SPARC)Boot environments
glibcillumos libc (pkgs.solnix.libc, not glibc)How Solnix is built
ldd / patchelf / RPATH (GNU)elfdump + Solaris link-editor writing RUNPATHHow Solnix is built
sudopfexec (RBAC/privilege-backed)see RBAC below
gdb / core dumpsMDB (mdb), coreadm, crash dumpsDebugging
hardware errors in dmesgFMA (fmadm faulty, fmdump)illumos features

The differences that actually bite

A few of these are more than a command swap — they change how you think:

Init is SMF, and SMF is always running. You do not write systemd units; you describe smf.services.* and Solnix renders SMF manifests. When something is broken, the reflex is not journalctl — it is svcs -x, which walks the dependency graph and tells you which service is stuck and where its log is. A service that keeps crashing lands in maintenance (not a restart loop) until you svcadm clear it. See SMF services.

Containers are zones — and Linux binaries need an LX zone. A native zone is an isolated illumos environment on the shared kernel (stronger isolation than a container, near-native speed). But a native zone runs illumos userland. To run Linux binaries you use an LX-branded zone, which presents the Linux syscall ABI on the illumos kernel — no VM. On Solnix, native zone tooling is early and LX is a roadmap item; see Zones and LX zones.

The filesystem is ZFS, all the way down — including your OS upgrades. There is no separate LVM/mdadm layer; ZFS is pool + volume manager + filesystem in one, with checksums and cheap snapshots. Crucially, your system generations live in ZFS too: each Nix generation is a boot environment (a bootable ZFS clone of root), so upgrade is atomic and rollback is instant — the same idea as NixOS generations, but the bootloader points at a whole bootable root dataset. See ZFS storage and Boot environments.

Observability is DTrace, not eBPF/strace/perf. DTrace predates them and does the whole job — kernel and userland, safe on production — from one language. Your strace foo becomes truss foo for quick work, and dtrace -n '...' for anything real. There is a /proc, but you inspect it with pargs, pfiles, pstack rather than reading files by hand. See DTrace.

pfexec, not sudo — and it’s backed by real privileges. illumos has fine-grained RBAC (roles) and process privileges — the kernel splits “root” into dozens of distinct privileges a process can hold or drop individually, and roles grant only the profiles a user needs. pfexec runs a command with the profiles your user is authorized for. This is least-privilege built into the OS, finer-grained than Linux capabilities and older. This handbook uses pfexec for privileged commands throughout.

The linker is Solaris ld, and there is no patchelf. Nix’s model bakes absolute /nix/store paths into binaries. On Linux nixpkgs that uses GNU ld and patchelf; on Solnix the Solaris link-editor writes ELF RUNPATH and you inspect it with elfdump. Same outcome, native tooling. This matters if you package software that has GNU-linker assumptions baked in. See How Solnix is built.

What Solnix is not

To keep expectations straight (the full story is in the history):

  • Not Linux — different kernel, libc, and init.
  • Not NixOS — same Nix, different target OS.
  • Not Oracle Solaris — the open illumos branch, not Oracle’s closed product.

Where to go from here

For BSD users

You come from FreeBSD, OpenBSD, NetBSD, or DragonFly BSD. Of everyone arriving at Solnix, you have the shortest trip. illumos is a System-V Unix cousin, but it shares the BSD values you already hold — one coherent base system (not a kernel plus a thousand packages), conservative engineering, and real documentation — and you literally share code: ZFS, bhyve, and the FreeBSD-derived boot loader all live on both sides of the fence. Most of what changes is init, isolation, and packaging. This page is the map; each row points at the deeper handbook chapter.

Solnix is illumos managed with Nix. If you have used pkg + ports, the mental shift is from an imperative ports tree to a declarative, reproducible build of the whole system — see Learning Nix.

The one-screen map

You know (FreeBSD / OpenBSD / NetBSD)On Solnix (illumos)Where
rc.d / service / rcctlSMF — dependency-aware, self-restarting; svcs, svcadm, svccfgSMF services
service foo status / rc debuggingsvcs -x + /var/svc/log/<fmri>.logSMF · Debugging
jails (FreeBSD) / vmmZones — the original OS container (2005); LX zones for the Linux ABIZones · LX zones
bhyve / FreeBSD loaderbhyve (ported from FreeBSD) + the same FreeBSD-derived loader on x86Boot environments
pf (packet filter)ipfilter (ipf / ipnat) — the pre-pf IPF, still first-class hereNetworking
ifconfig / vlan / bridge / netgraphCrossbow: dladm, ipadm, flowadm (VNICs, vswitches, flows in-kernel)Networking (Crossbow)
ZFS (FreeBSD)ZFS — same lineage; illumos is a primary home of OpenZFS workZFS storage
UFS/FFS + gpartZFS pool + datasets (no separate volume manager)ZFS storage
pkg / ports / pkg_add / make installNix — pkgs.solnix.*; the base system is Nix-described tooLearning Nix
ktrace / dtrace (FreeBSD/NetBSD) / trussDTrace — the original, deepest implementation (illumos is its home) + trussDTrace
doas / sudopfexec — RBAC roles + fine-grained kernel privilegessee RBAC below
gdb / kgdb / core dumpsMDB (mdb), coreadm, crash dumpsDebugging
base = one coherent source treesame philosophy — illumos is a unified kernel+userland gateHow Solnix is built

What actually feels different

You will be at home faster than a Linux refugee, but three things are genuinely new:

SMF is a real service manager, not shell rc. FreeBSD’s rc.d and OpenBSD’s rc are ordered shell scripts; SMF is a dependency-graph supervisor with a queryable repository, automatic restart, and a fault boundary. You describe smf.services.* in Nix and Solnix renders the manifests. When something breaks the reflex is svcs -x (it names the stuck dependency and its log), and a flapping service lands in maintenance rather than looping. See SMF services.

Zones predate jails’ modern form — and LX runs Linux without a VM. If you love jails, you will love zones: the same “lightweight, kernel-shared isolation” idea, shipped in 2005, with resource controls and branded-zone flexibility. A native zone runs illumos userland; to run Linux binaries you use an LX-branded zone, which presents the Linux syscall ABI on the illumos kernel — no emulation VM. On Solnix, zone tooling is early; see Zones and LX zones.

Packaging is Nix, and it describes the whole system. Ports/pkg are excellent, but they are imperative and per-package. Nix builds a reproducible closure for the entire machine — kernel, userland, services, your config — and each change is an atomic, rollback-able boot environment. It is the base-system coherence you value from BSD, made declarative. See Learning Nix.

pfexec, not doas/sudo — backed by real privileges. illumos splits “root” into dozens of fine-grained kernel privileges, and RBAC roles grant users only the profiles they need. pfexec runs a command with your authorized profiles. It is least-privilege built into the kernel, finer-grained than anything in the BSD base. This handbook uses pfexec throughout.

The things you already share (so they’re easy)

  • ZFS is the same filesystem you know; zpool/zfs commands transfer, and illumos is where much OpenZFS work originates. See ZFS storage.
  • DTrace on FreeBSD/NetBSD is a port of this; here you get the reference implementation, deepest and most complete. See DTrace.
  • bhyve and the x86 loader came from FreeBSD; the lineage is literally shared.
  • ipfilter is the IPF that predates pf — if you ever used IPF, it is still first-class here.

What Solnix is not

To keep expectations straight (full story in the history):

  • Not a BSD — it is illumos (the open OpenSolaris continuation), a System-V Unix, not a Berkeley one. The values rhyme; the kernel lineage does not.
  • Not Linux — different kernel, libc, and init.
  • Not Oracle Solaris — the open illumos branch, not Oracle’s closed product.

Where to go from here

For macOS users

macOS is a Unix \u2014 certified UNIX, in fact \u2014 so your terminal muscle memory (the shell, ssh, pipes, man) transfers directly. What changes is everything under the hood: a different kernel, a different service manager, a different filesystem, a different package story, and \u2014 bluntly \u2014 Solnix is a server/developer OS without the polished desktop you have today (graphics are in active bring-up; see the status). If you live in Terminal and like how coherent macOS feels, you will recognize the philosophy. This page maps what you know onto Solnix; each row points at the deeper chapter.

Solnix is illumos managed with Nix.

The one-screen map

You know (macOS / Darwin)On Solnix (illumos)Where
launchd (launchctl, .plist)SMF \u2014 the same "dependency-aware supervisor with a repository" idea; svcs, svcadmSMF services
launchctl list / Console.app logssvcs -x + /var/svc/log/<fmri>.logSMF \u00b7 Debugging
Homebrew / MacPorts (brew install)Nix \u2014 pkgs.solnix.*, declarative + reproducible, whole-systemLearning Nix
APFS + Disk Utility, snapshotsZFS \u2014 pool + datasets, checksums, snapshots, clones (APFS’s snapshot idea, deeper)ZFS storage
Time MachineZFS snapshots + zfs send/recv (manual today; the primitives are stronger)ZFS storage
Docker Desktop (a Linux VM)Zones (native, no VM) + LX zones for Linux binariesZones \u00b7 LX zones
dtrace / InstrumentsDTrace \u2014 the original; Instruments is built on DTrace. Same tool, native.DTrace
lldb / crash reportsMDB (mdb), coreadm, crash dumpsDebugging
sudopfexec \u2014 RBAC roles + fine-grained kernel privilegessee RBAC below
pf firewall (pfctl)ipfilter (ipf / ipnat)Networking
networksetup / ifconfigCrossbow: dladm, ipadm, flowadmNetworking (Crossbow)
System Integrity Protection / sealed system volumeZFS boot environments \u2014 atomic OS updates, instant rollback (via Nix generations)Boot environments
dyld, .dylib, install_name_toolELF + Solaris link-editor (RUNPATH), elfdumpHow Solnix is built

What actually feels different

You know DTrace already \u2014 this is its home. Apple shipped DTrace and built Instruments on it; on Solnix you get the reference implementation, unsandboxed and complete. Your sudo dtrace -n '...' becomes pfexec dtrace -n '...'. See DTrace.

launchd \u2192 SMF is a near-one-to-one mental move. Both replace shell init with a dependency-aware supervisor backed by a declarative description and a queryable state. You stop writing .plist files and start describing smf.services.* in Nix; launchctl list becomes svcs, and a broken service is diagnosed with svcs -x instead of digging through Console. See SMF services.

Homebrew \u2192 Nix is a bigger leap than it looks. brew is imperative and per-package; Nix builds a reproducible closure for the entire machine and makes every change an atomic, rollback-able boot environment. No more "works on my Mac" drift \u2014 the config is the system. See Learning Nix.

Containers are zones, and there is no hidden Linux VM. Docker Desktop on macOS runs a Linux VM behind the scenes; illumos zones are native kernel-shared isolation with no VM, and LX-branded zones present the Linux ABI directly on the illumos kernel. On Solnix this tooling is early; see Zones and LX zones.

pfexec, not sudo \u2014 and the firewall is ipf, not pfctl. Confusingly, macOS’s pf and illumos’s ipf are different firewalls (macOS adopted BSD pf; illumos kept the older IPF that pf succeeded). Privilege is RBAC + fine-grained kernel privileges via pfexec. See Networking.

The honest part

macOS gives you a world-class desktop. Solnix does not, yet \u2014 it installs and runs headless on real hardware with wifi, and a graphical desktop (COSMIC) is in active bring-up but not working on hardware today (see the news for dated status). If you are here for a Unix server or a reproducible development OS with the best filesystem and tracing in the business, Solnix is for you now. If you need a daily-driver GUI laptop, it is not there yet \u2014 we would rather tell you straight.

What Solnix is not

  • Not macOS/Darwin \u2014 different kernel (illumos, not XNU/Mach) and no Cocoa.
  • Not Linux \u2014 different kernel, libc, and init.
  • Not a finished desktop \u2014 see the status note above and the roadmap.

Where to go from here

  • New to Nix (coming from Homebrew)? Learning Nix.
  • Want the filesystem/tracing depth you’ll actually enjoy? ZFS \u00b7 DTrace.
  • Want the backstory? the history.

For Windows users

This is the longest trip of anyone’s \u2014 and we’ll be honest about that up front. Solnix is a Unix server/developer operating system; it does not have a Windows- like desktop, Explorer, the registry, or .exe compatibility, and its graphical environment is still in bring-up (see the status). If you have used WSL (Windows Subsystem for Linux), PowerShell, or Hyper-V, you already have the footholds that make this approachable. This page maps Windows concepts onto their Solnix equivalents; each row points at the deeper chapter.

Solnix is illumos \u2014 a Unix \u2014 managed with Nix. The single biggest adjustment: the system is described declaratively in text and rebuilt atomically, rather than configured by clicking and by in-place installers.

The one-screen map

You know (Windows)On Solnix (illumos)Where
Services (services.msc, sc.exe, Set-Service)SMF \u2014 service manager with dependencies, auto-restart, a queryable repo; svcs, svcadmSMF services
Event Viewer / service logssvcs -x + per-service logs in /var/svc/log/SMF \u00b7 Debugging
winget / Chocolatey / MSI installersNix \u2014 pkgs.solnix.*, declarative + reproducible, whole-systemLearning Nix
the Registryplain-text config built by Nix (no central binary hive)Learning Nix
NTFS / Storage SpacesZFS \u2014 pool + volume manager + FS in one, with checksums + snapshotsZFS storage
Volume Shadow Copy / System RestoreZFS snapshots + boot environments (atomic OS rollback, done right)Boot environments
WSL (Linux binaries on Windows)LX-branded zones (Linux binaries on the illumos kernel, no VM)LX zones
Hyper-V / virtual machinesZones (native OS containers) + bhyve (full VMs)Zones
PowerShell (object pipeline)POSIX shells (bash, text pipeline) + DTrace for deep inspectionDTrace
Windows Defender Firewallipfilter (ipf / ipnat)Networking
network adapter settings GUICrossbow: dladm, ipadm, flowadmNetworking (Crossbow)
Run as administrator / UACpfexec + RBAC roles + fine-grained kernel privilegessee RBAC below
Task Manager / Performance Monitor / ETWprstat, svcs, and DTrace (ETW’s deeper cousin)DTrace
.dll + PATH / dependency walkerELF shared objects + Solaris link-editor RUNPATH, elfdumpHow Solnix is built

What actually feels different

Everything is text, and the system is rebuilt, not patched. On Windows you install and update software in place and configure it through GUIs and the registry. On Solnix you describe the machine in Nix, run a rebuild, and get a new, complete, atomically-activated system \u2014 with the previous one still bootable for instant rollback (a boot environment). There is no registry and no in-place installer drift; the text is the system. This is the central habit to learn. See Learning Nix.

Services are SMF \u2014 like services.msc, but dependency-aware and text-driven. Instead of sc.exe or the Services console, you describe smf.services.* and Solnix renders SMF manifests. svcs lists services, svcs -x diagnoses a broken one (it names the stuck dependency and its log), and a failing service lands in maintenance rather than silently retrying. See SMF services.

WSL \u2192 LX zones is the closest analogy you have. WSL runs Linux binaries on Windows; an LX-branded zone runs Linux binaries on the illumos kernel, no VM. And where you reached for Hyper-V, illumos gives you zones (lightweight native isolation) and bhyve (full VMs). On Solnix this tooling is early; see Zones and LX zones.

The command line is the primary interface. PowerShell’s object pipeline is powerful; the Unix world uses a text pipeline plus purpose-built tools \u2014 and for anything deep, DTrace (the tool ETW aspired to be) traces the whole system safely. Expect to live in a shell. See DTrace.

pfexec, not "Run as administrator." illumos splits “root” into dozens of fine-grained kernel privileges and grants users RBAC roles; pfexec runs a command with your authorized profiles. It is UAC’s idea \u2014 least privilege \u2014 but built into the kernel and far finer-grained.

The honest part

Windows is a desktop OS first. Solnix is not a desktop OS today \u2014 it installs and runs headless on real hardware (with wifi), and a graphical desktop is in active bring-up but not working on hardware yet (see the news). There is no .exe compatibility and no Windows API. Solnix is a strong choice if you want to learn Unix properly, run servers, or build reproducibly; it is not a Windows replacement for everyday desktop use. We would rather you know that now.

What Solnix is not

  • Not Windows \u2014 no registry, no Win32/.exe, no Explorer desktop.
  • Not Linux \u2014 though LX zones run Linux binaries; the kernel is illumos.
  • Not a finished desktop \u2014 see the status note above and the roadmap.

Where to go from here

Getting started

Early / preview. A first bootable Solnix image now exists — an unstable-edition x86_64 ISO + raw disk image (v2026.08.07), preview-grade: see Download. Also live: the binary cache (cache.solnix.io) and package search (search.solnix.io). Treat the image as a preview for testing in a VM, not a daily driver. The install steps below will firm up as the images stabilize.

New here entirely? Start with the introduction for what Solnix is and how it is put together, then come back.

Try it in your browser (no install)

The fastest look at Solnix needs nothing installed: https://solnix.io/tryit boots a real Solnix riscv64 kernel in a WebAssembly RISC-V emulator — OpenSBI → kernel → init → a live $ shell running the actual coreutils. Try ls, cat /etc/release, echo hi.

Two things to expect. It runs the kernel’s full self-test log before the prompt (fork/exec, copy-on-write faults, SMP + IPI wakeup, timer preemption, FP context switching), so the $ takes a minute or two to appear — that scrolling log is the boot, not a hang. And it is a demonstration image: its runtime linker prints a few [ld.so.1] proof lines before every command, and the minimal /bin/sh has no pipes or > redirection.

This is also the honest state of the RISC-V port: the kernel boots to a shell, but there is no riscv64 builder or binary cache yet (see CPU support).

Try the preview image

The first bootable image (v2026.08.07, unstable/preview — for a VM, not a daily driver) is on the download page. Quickest way to see it boot, in a VM:

# fetch + verify the ISO (checksum is on the download page / release manifest)
curl -LO https://cache.solnix.io/images/release-224-v2/solnix-x86_64-minimal.iso
sha256sum solnix-x86_64-minimal.iso        # compare to the published sum

# boot it in QEMU (BIOS or UEFI; the ISO is hybrid-bootable)
qemu-system-x86_64 -m 4096 -smp 2 -cdrom solnix-x86_64-minimal.iso

There is also a raw disk image (solnix-raw.img.gz) for writing to a disk or attaching directly. Expect rough edges — this is an early preview to kick the tires, report what breaks, and help the arches along, not a supported install.

Use the binary cache

If you build software that Solnix has already built, point nix at the cache and skip the recompilation:

# /etc/nix/nix.conf
substituters       = https://cache.solnix.io https://cache.nixos.org
trusted-public-keys = cache.solnix.io-1:8UNrVAOSOrI9PGHc8/pD2Yqp265ZeYb3OId+gv4+wm8= cache.nixos.org-1:6NCHdD59EeA7KA8wG4nSXk...

Prove the cache is real before you commit any config to it — ask it directly, no setup required:

$ nix store info --store https://cache.solnix.io
Store URL: https://cache.solnix.io
Public key: cache.solnix.io-1:8UNrVAOSOrI9PGHc8/pD2Yqp265ZeYb3OId+gv4+wm8=

Every store path is signed with the cache.solnix.io-1 key and Nix verifies the signature before use, so it does not matter where the bytes came from. See The binary cache for the full story, including the planned BitTorrent distribution and how seeding works.

Search for packages

Browse the package registry at search.solnix.io — BM25-ranked full-text search across the Solnix package set. It answers the question you actually have: is X packaged, and for which arch? See Package search.

Read the man pages

The man pages that ship with cached packages are browsable at solnix.io/docs — A–Z by package and section. Coverage is early (it grows as packages land), and every package in search links straight to its own man pages; for anything not yet indexed, the upstream illumos man pages are the reference.

Cross-compile from Linux

You do not need an illumos box to build for Solnix. From a Linux machine with Nix, add the cache above and build against the x86_64-solaris / aarch64-solaris platforms — prebuilt store paths come straight from the cache instead of being recompiled locally. This is how the non-primary architectures are populated today (see the news on cross-build artifacts). What does not cross-build from Linux is illumos-gate itself; see How Solnix is built for why, and CPU architecture support for per-arch status.

Contribute

The project lives at:

  • Infra + services: codeberg.org/gregburd/solnix-infra
  • Site + handbook: codeberg.org/gregburd/solnix-site
  • The distribution itself: the Solnix repo (illumos + Nix work)

Ports, packaging, and docs are all open. See Contributing.

Learning Nix

Solnix is built on Nix and the NixOS module system. This handbook documents what is specific to Solnix — the illumos target, the package set, boot environments, SMF, the binary cache. For Nix itself — the language, the CLI, flakes, the module system — the upstream documentation is excellent and we link to it rather than duplicate it.

If you administer illumos or Solaris today with IPS / pkg, the biggest adjustment is not the syntax — it is the shift from imperative to declarative. This page leads with that translation, then links out to the Nix fundamentals. (Coming from Linux/NixOS instead? See For Linux (and NixOS) users.)

For IPS / pkg users: the mental shift

IPS is imperative and stateful. You run pkg install, pkg update, pkg uninstall; each command mutates the live system image in place, and IPS tracks the resulting state in its own database. The image is the accumulation of every command you’ve ever run against it. To make that safe, IPS updates snap a new boot environment so you can fall back if an update goes wrong.

Nix is declarative and reproducible. You do not mutate a live image. You describe the desired system — the full set of packages and services — in a Nix configuration, and Nix builds that description into an immutable set of /nix/store paths, then activates it atomically. There is no accumulated state to drift; the configuration is the system. Two machines with the same configuration are the same system, byte for byte.

The payoff for a pkg user: the thing IPS does defensively — snapshot a boot environment around a risky update — is the normal, every-time mode in Solnix. Every configuration change produces a new Nix generation, and Solnix maps each generation onto its own ZFS boot environment. Rollback is not a recovery procedure; it is picking the previous BE at the loader. IPS bolts BEs onto updates; Solnix’s whole model is generations-as-BEs.

pkg → Nix, command by command

TaskIPS / pkg (imperative)Solnix / Nix (declarative)
Install a packagepkg install Xadd to environment.systemPackages in config → rebuild; or ad-hoc nix profile install nixpkgs#X
Remove a packagepkg uninstall Xremove it from the config → rebuild (it’s gone from the new generation); or nix profile remove X
List installedpkg listnix profile list, or just read the config; the store shows the closure
Search availablepkg search Xnix search nixpkgs X, or search.solnix.io for the Solnix set
Update the systempkg update (+ auto new BE)rebuild the config → new generation → new boot environment, activated atomically
Roll backbeadm activate <old-BE>beadm activate the previous generation’s BE, or pick it at the loader
Show/set repospkg publisher / set-publishersubstituters + trusted-public-keys in nix.conf → cache.solnix.io
Name a packageIPS FMRI pkg://.../X@versiona Nix attribute — pkgs.solnix.* (never pkgs.illumos.*)
Verify / fix an imagepkg verify / pkg fixrebuild the generation — the store path is the definition, so “fix” = re-realize

Note: the pkg column mutates one live image; the Nix column changes a description and produces a new, independently-bootable generation. You never edit the running system in place — you build a new one and switch to it.

FMRIs → attributes, publishers → substituters

Two IPS concepts map cleanly onto Nix:

  • An IPS FMRI (pkg://solaris/system/library@0.5.11,...) names a package and version in a publisher’s catalog. In Solnix a package is a Nix attribute — pkgs.solnix.libc, pkgs.solnix.sys, and so on (the fine-grained illumos world; see How Solnix is built). The version is pinned by the Nix expression / flake input, not resolved at install time.
  • An IPS publisher (a repository pkg fetches from) maps onto a Nix substituter: cache.solnix.io is the Solnix substituter, added with its trusted-public-keys in nix.conf. Where pkg publisher lists your repos, nix.conf’s substituters lists your caches — and every store path is signature-verified before use.

And the SMF story you already know carries straight over: on illumos an IPS update reconfigures services through SMF; on Solnix, services are declared with smf.services.* and re-imported on activation. See SMF services.

Start here (Nix fundamentals)

What is different in Solnix

Once you know Nix, these are the solnix-specific pieces to read here:

For illumos itself — the platform underneath Solnix — see the illumos features overview, For Linux (and NixOS) users if you’re bridging from Linux, and Further reading & resources.

Community (Nix-wide)

Solnix is a friendly neighbor in the wider Nix ecosystem:

Solnix’s own channels are on the Community page.

The binary cache

cache.solnix.io is a standard Nix binary cache — functionally like cache.nixos.org. Add it as a substituter and pull prebuilt, signed store paths for every architecture Solnix targets.

Setup

# /etc/nix/nix.conf
substituters       = https://cache.solnix.io https://cache.nixos.org
trusted-public-keys = cache.solnix.io-1:8UNrVAOSOrI9PGHc8/pD2Yqp265ZeYb3OId+gv4+wm8= cache.nixos.org-1:6NCHdD59EeA7KA8wG4nSXk...

Every store path is signed with the cache.solnix.io-1 key. Nix verifies the signature against your trusted-public-keys before using anything — so it does not matter where the bytes came from, only that they match a signature you trust.

How it is distributed

Cache objects will also be distributed over BitTorrent: each NAR is a torrent, seeded by the hub and by other Solnix users. This is not yet enabled — the narinfo served by cache.solnix.io always carries a plain HTTP URL: as the guaranteed fallback, so a stock nix works today over HTTP; the peer layer is an enhancement layered on top.

The property that matters: the more Solnix users, the faster and cheaper the cache — bandwidth scales with the community instead of with one origin’s egress bill.

Seeding (please read)

Once you have opted in, a machine using the Solnix cache seeds the public, signed cache artifacts it fetches to other Solnix users. This is deliberate and is how a multi-arch cache stays sustainable.

  • It is default on when you have opted in (solnix.cache.seed.enable = true), and gated by the privacy master switch — a machine whose config never touches it stays completely private and seeds nothing. See Peer-to-peer distribution and Privacy & telemetry.
  • It only ever shares public Nix store paths — never your private data.
  • Integrity is enforced by the cache signature regardless of source.

We state this plainly so no one is surprised to find their machine seeding.

Package search

search.solnix.io is full-text search over the Solnix package set — the illumos analog of search.nixos.org/packages. Use it to find whether a tool is packaged, which architectures it is built for, and how to install it.

Using it

  • Type a name or keyword; results rank the best match to the top and refine as you type.
  • Prefix matching: rtl finds rtld before you finish typing.
  • Typo-tolerant: opnssh still finds openssh.
  • Each result shows the architectures it is available for and, in the detail view, how to install it (declarative environment.systemPackages, nix profile, nix-env, or an ephemeral nix shell) plus links to its man pages and dependencies.

Everything found there is served by the binary cache — add the cache and the package installs without recompiling.

Following new packages

The registry publishes update feeds so you can track new and changed packages:

The announce@ mailing list rolls these up (once list subscription is open).

Programmatic access

There is a public REST + GraphQL API for the package data (search, package detail, dependency graph, man pages, systems). See the API reference at https://search.solnix.io/api/v1/openapi — this is tooling for building on top of Solnix, not something you need for everyday use.

illumos features

illumos is not a Linux distribution and not a kernel-only project — it is a complete Unix operating system descended from OpenSolaris, carrying a set of capabilities that were, in several cases, invented there. Solnix inherits all of them from the illumos gate. This page is a feature-by- feature overview: what each thing is, why it matters, and where Solnix stands on it today. Each has a fuller page linked from here.

On Solnix status, up front. These are illumos platform features; Solnix inherits them by being an illumos distribution. Where Solnix’s own tooling around a feature (a Nix module, a builder) is still planned, this page says so. The features themselves — ZFS, DTrace, SMF, zones, FMA — are real illumos features and work on any illumos host.

OpenZFS

What it is. A pooled-storage filesystem and volume manager in one. ZFS groups devices into a pool, carves datasets (filesystems) and volumes out of it on demand, and end-to-end checksums every block. It was developed at Sun in the early 2000s, open-sourced in 2005 as part of OpenSolaris, and illumos is a founding member of the OpenZFS community.

Why it matters. Cheap atomic snapshots and clones, send/receive for replication, on-demand scrubbing, and self-healing in redundant configurations — data integrity you cannot get from a traditional filesystem plus separate volume manager. Snapshots and clones are also the mechanism behind boot environments.

Solnix relevance. ZFS is the substrate for the whole Solnix upgrade model: each Nix generation is a ZFS boot environment, and cheap clones are what make atomic upgrade and instant rollback affordable. See ZFS storage.

DTrace

What it is. A safe, production-grade dynamic tracing framework spanning the whole system — kernel and userland, from one language (the D language). Thousands of instrumentation points (probes) sit dormant at zero cost until you enable them.

Why it matters. You can ask questions about a running production system — “which files is this process opening,” “what is the latency distribution of this syscall,” “which function is burning CPU” — without recompiling, restarting, or risking a crash. DTrace is designed to be safe to run on live systems.

Solnix relevance. For a Nix-built system, DTrace is the answer to “why is this store path’s binary behaving this way in production.” See DTrace.

Service Management Facility (SMF)

What it is. The init system and service supervisor. SMF tracks service dependencies, supervises and restarts processes, disables perpetually crashing services (moves them to maintenance), and keeps live configuration in a repository rather than only in flat files.

Why it matters. Dependency-aware startup, automatic restart with a fault boundary, and a single query (svcs -x) that tells you what is broken and why — the things you would otherwise assemble from several tools.

Solnix relevance. SMF is the direct replacement for systemd.services.*. Solnix renders SMF manifests from a declarative smf.services.* Nix module and converges the system to a milestone on activation. See SMF services.

Zones

What it is. OS-level virtualization: isolated illumos environments that share one kernel but have their own filesystem, process table, users, and network — a “virtual machine without the hypervisor overhead.” Zones predate Linux containers by years.

Why it matters. Strong isolation at near-native performance, plus branded zones — including LX-branded zones that run Linux binaries on the illumos kernel — and integration with ZFS (a zone on its own dataset) and resource controls.

Solnix relevance. Zones are a natural target for reproducible, Nix-built environments, but Solnix’s own zone tooling is early — see Zones for the honest status. Running Linux workloads on Solnix via the LX brand is a stated roadmap direction — see LX-branded zones.

Boot environments

What it is. Bootable ZFS clones of the root filesystem, managed with beadm. Each is an independent, bootable root; exactly one is the default boot target.

Why it matters. Upgrades become atomic (switch the boot target, do not mutate the live root) and rollback becomes instant (boot the previous environment). This is illumos’s native answer to safe system upgrades.

Solnix relevance. This is the mechanism Solnix maps Nix generations onto — the illumos analog of NixOS generations. See ZFS boot environments.

Fault Management Architecture (FMA)

What it is. A subsystem that collects hardware and software error telemetry, diagnoses it into faults, and takes automated action — retiring a bad CPU or memory page, or handing a service to SMF to restart. You interact with it via fmadm and fmdump.

Why it matters. Errors become diagnosed faults with a stable message ID you can look up, instead of cryptic log lines. The system can degrade gracefully (offline a failing component) rather than crash. FMA and SMF are wired together: a service fault and a hardware fault flow through the same machinery.

Solnix relevance. FMA is inherited from the gate; Solnix does not replace it. For a system where the software layer is immutable Nix store paths, FMA’s focus on hardware and service faults complements Nix’s focus on software correctness. fmadm faulty is part of the debugging toolkit.

Other platform pieces

illumos also carries, and Solnix inherits:

  • RBAC and process privileges — illumos splits the traditional all-or- nothing “root” into dozens of fine-grained privileges a process can hold or drop individually, and layers role-based access control (RBAC) on top: users assume roles granted only the profiles (bundles of authorizations) they need. pfexec runs a command with the profiles your user is authorized for — the least-privilege sudo-equivalent used throughout this handbook. This is finer-grained than Linux capabilities and predates them; it is why Solnix can hand a service exactly the privileges it needs and no more.
  • The modular debugger (MDB / mdb) — inspects running processes, core files, and kernel crash dumps, using CTF type data. Central to debugging.
  • Virtual networking — Crossbow (dladm) — the in-kernel network- virtualization stack: virtual NICs, virtual switches (etherstubs), VLANs, link aggregation, and flow/bandwidth controls, including per-zone networking. See Networking (Crossbow).
  • ipfilter — the host (and per-zone) firewall.
  • bhyve / KVM — hardware virtualization ported to illumos, for full VMs alongside zones.

Further reading

SMF services

On illumos the init system is the Service Management Facility (SMF) — not systemd, not SysV rc, not BSD rc.conf. If you come from NixOS you will reach for systemd.services.*; on Solnix the equivalent is smf.services.*. This page explains what SMF is, the concepts you need (FMRIs, states, milestones, manifests), the commands you use day to day (svcs, svcadm, svccfg), and how Solnix layers a declarative Nix module on top.

On illumos generally SMF has been the init and service supervisor since Solaris 10 (2005) and is mature and load-bearing. On Solnix the smf.services.* module that renders manifests from Nix is planned (roadmap T1.11/T1.12); SMF itself is inherited from the illumos userland and is real. Commands like svcs/svcadm/svccfg below are the genuine illumos commands.

SMF versus systemd, in one table

If you know systemd, this mapping gets you most of the way:

ConceptsystemdSMF
Service identitysshd.serviceFMRI svc:/network/ssh:default
Definitionunit file (.service)manifest (XML) + method script
List servicessystemctl list-unitssvcs -a
Start / stopsystemctl start/stopsvcadm enable/disable
Restartsystemctl restartsvcadm restart
Why did it fail?systemctl status / journalctlsvcs -x / service log
Boot targetstargets (multi-user.target)milestones (svc:/milestone/multi-user)
Config storeunit files on diskSQLite repository (svc.configd)
Reload configsystemctl daemon-reloadsvccfg import / manifest-import
Auto-restart on crashRestart=restarter policy + fault boundary

The biggest conceptual difference: SMF keeps live service configuration in a repository (a SQLite database owned by svc.configd), not only in flat files. Manifests seed the repository; running config can be changed with svccfg without editing the manifest. Solnix treats the manifest as the source of truth and re-imports on activation — the Nix way.

Ground truth: the concepts

FMRIs

Every service is named by a Fault Managed Resource Identifier (FMRI):

svc:/<category>/<name>:<instance>

For example svc:/network/ssh:default or svc:/system/console-login:default. You can usually abbreviate to the shortest unambiguous suffix, so svcs ssh works. A service can have multiple instances (:default, :vt2, …); each instance runs and is enabled/disabled independently.

Service states

An instance is always in exactly one state. svcs shows it in the STATE column:

StateMeaning
onlineRunning and healthy.
offlineEnabled but a dependency is not yet satisfied.
disabledAdministratively off (persists across reboot).
maintenanceFailed too many times / method error — needs a human.
degradedRunning but not fully functional.
uninitializedNot yet examined by its restarter.
legacy_runAn old rc-style script, tracked but not managed.

maintenance is the one you will care about most — it means SMF gave up restarting the service because it kept failing. See Debugging.

Milestones

Milestones are pseudo-services that group other services, like systemd targets:

  • svc:/milestone/single-user — single-user mode.
  • svc:/milestone/multi-user — normal multi-user, no network servers.
  • svc:/milestone/multi-user-server — multi-user plus network services.

The Solnix Phase-1 target is multi-user-server. You can boot to a milestone (boot -m milestone=single-user) or move the running system with svcadm milestone.

Manifests and method scripts

A manifest is an XML file describing a service — its FMRI, dependencies, start/stop methods, and default properties — conforming to service_bundle.dtd.1. Manifests live under:

/lib/svc/manifest/<category>/<name>.xml

The commands SMF runs to start/stop/refresh a service are method scripts, conventionally under /lib/svc/method/. A start method exits 0 on success; SMF watches the process and applies the restart policy if it dies.

At boot, svc:/system/manifest-import:default scans the manifest directories and imports anything new or changed into the repository. You can do it by hand:

pfexec svccfg import /lib/svc/manifest/network/ssh.xml

Note: Solnix uses pfexec (illumos’s sudo-equivalent, backed by RBAC profiles) for privileged commands throughout this handbook.

The repository

Live configuration lives in a SQLite database at /etc/svc/repository.db, owned by the svc.configd daemon. You never edit it directly — you go through svccfg. svc.startd is the master restarter that actually runs services and enforces dependencies.

Commands you use every day

svcs — list and inspect

svcs                     # all enabled instances and their state
svcs -a                  # include disabled instances
svcs ssh                 # one service
svcs -x                  # explain anything not running that should be
svcs -p svc:/network/ssh:default   # show the processes of a service
svcs -l svc:/network/ssh:default   # long form: deps, method, log location
svcs -d svc:/network/ssh:default   # dependencies
svcs -D svc:/network/ssh:default   # dependents

svcs -x is the single most useful command when something is wrong — it walks the dependency graph and tells you which service is blocking and where its log is.

svcadm — change state

pfexec svcadm enable  svc:/network/ssh:default    # start now + on boot
pfexec svcadm enable  -t svc:/network/ssh:default # start now, not persistent (-t = temporary)
pfexec svcadm disable svc:/network/ssh:default    # stop now + on boot
pfexec svcadm restart svc:/network/ssh:default    # restart
pfexec svcadm refresh svc:/network/ssh:default    # reread config (like SIGHUP)
pfexec svcadm clear   svc:/network/ssh:default    # clear maintenance, retry
pfexec svcadm milestone milestone/multi-user-server  # move the whole system

svcadm clear is how you retry a service that landed in maintenance after you have fixed the cause.

svccfg — edit configuration and manifests

pfexec svccfg import /path/to/service.xml         # import/update a manifest
pfexec svccfg export svc:/network/ssh:default     # dump current config as XML
svccfg -s svc:/network/ssh:default listprop       # list an instance's properties
pfexec svccfg -s svc:/network/ssh:default \
  setprop config/listen_port = integer: 2222      # change a property
pfexec svcadm refresh svc:/network/ssh:default    # make the change take effect

Logs

Each service instance has its own log — this is where a start-method’s stdout and stderr go:

/var/svc/log/<fmri-with-slashes-as-dashes>.log
# e.g. /var/svc/log/network-ssh:default.log

svcs -l <fmri> prints the exact logfile path. The workflow for a failed service is almost always:

svcs -x                                   # 1. what is broken and why
svcs -l svc:/network/ssh:default          # 2. find its log
tail /var/svc/log/network-ssh:default.log # 3. read the actual error

The system-wide boot/service log is /var/svc/log/svc.startd.log.

How Solnix manages services

The NixOS module system is reused verbatim, but the service layer is replaced. Where NixOS has systemd.services.<name>, Solnix has:

smf.services.<name> = {
  # declarative description: command, dependencies, environment, restart policy
};

The module renders the SMF XML manifest and the method script from that declaration into the system closure, and the activation step runs svccfg import followed by svcadm to bring the system to the target milestone (multi-user-server). This is the direct analog of nixbsd rendering rc.conf + /etc/rc.d entries and driving the FreeBSD rc system.

The key asymmetry with NixOS on Linux: SMF is already running when the activation script executes. Solnix is not the init system — svc.startd is. Solnix feeds the init system a manifest and asks it to converge. That keeps the module small and means a Solnix generation switch is “import the new manifests, converge to the milestone,” not “become PID 1.”

Further reading

ZFS storage

ZFS (OpenZFS) is the illumos filesystem and volume manager, and the substrate Solnix’s upgrade model is built on. If you come from NixOS you may have used ZFS as an optional root filesystem; on illumos it is the filesystem — the root pool, the swap, the dump device, and every boot environment live on it. This page covers the concepts (pools, datasets, snapshots, clones) and the zpool and zfs commands you need, then ties it back to boot environments.

On illumos generally ZFS is mature and load-bearing — illumos is a founding OpenZFS platform. On Solnix ZFS is inherited from the illumos gate; the commands below are the real illumos commands. What is planned on Solnix is the tooling that ties Nix generations to ZFS boot environments (see that page).

The model: pools and datasets

Traditional systems layer a filesystem on a partition on a disk. ZFS collapses that: you build a pool (a zpool) out of one or more devices with a chosen redundancy, and then create datasets inside the pool that draw from its shared free space on demand. There are two kinds of dataset:

  • Filesystems — mountable trees of files (most datasets).
  • Volumes (zvols) — block devices carved from the pool, used for swap, the crash-dump device, and zone/VM disks.

The root pool is conventionally named rpool. Boot environments live under rpool/ROOT/.

zpool — manage pools

zpool list                       # pools, size, health, capacity
zpool status                     # per-device health, errors, scrub progress
zpool status -v                  # verbose, lists any damaged files
pfexec zpool scrub rpool         # verify every block against its checksum
pfexec zpool create tank mirror c1t0d0 c1t1d0   # a mirrored pool

zpool status is your first stop for disk health. A scrub reads every block and checks it against its checksum; in a redundant pool it repairs bad blocks from the good copy automatically (“self-healing”). Scrub on a schedule.

Redundancy is chosen at pool creation — mirror, raidz, raidz2, raidz3 — and ZFS integrates the volume-manager job (which disks, what redundancy) with the filesystem, so it always knows which copy is good.

zfs — manage datasets

zfs list                         # datasets, used/avail/refer, mountpoint
zfs list -t snapshot             # snapshots
pfexec zfs create rpool/data     # a new filesystem dataset
pfexec zfs set compression=on rpool/data      # a property
zfs get all rpool/data           # every property of a dataset

Datasets have properties (compression, quota, mountpoint, recordsize, …) that are inherited down the tree unless overridden — a clean way to manage a hierarchy of filesystems from one place.

Snapshots

A snapshot is a read-only, point-in-time image of a dataset. It is copy-on-write, so it costs nothing at creation and grows only as the live dataset diverges from it.

pfexec zfs snapshot rpool/data@before-upgrade   # take a snapshot
zfs list -t snapshot rpool/data                 # list them
pfexec zfs rollback rpool/data@before-upgrade   # revert the dataset to it
pfexec zfs destroy rpool/data@before-upgrade    # remove a snapshot

You can browse a snapshot’s contents read-only under the dataset’s hidden .zfs/snapshot/<name>/ directory without rolling back — handy for recovering one file.

Clones

A clone is a writable dataset created from a snapshot; it shares the snapshot’s blocks copy-on-write and only consumes space as it is written to. Clones are the mechanism behind boot environments:

pfexec zfs clone rpool/data@snap rpool/data-copy

send / receive — replication and backup

A snapshot can be serialized to a byte stream and applied elsewhere — the same pool, another disk, or another machine over the network:

pfexec zfs send rpool/data@snap | pfexec zfs receive tank/data
# incremental, only the delta between two snapshots:
pfexec zfs send -i @snap1 rpool/data@snap2 | ssh host pfexec zfs receive tank/data

This is the foundation of ZFS backup and disaster recovery — full and incremental, verifiable end to end.

How this ties to boot environments

Everything on the ZFS boot environments page is these primitives applied to the root filesystem:

  • A boot environment is a dataset under rpool/ROOT/.
  • Creating a BE takes a snapshot of the current root and makes a clone of it — which is why it is instant and nearly free.
  • The clones share blocks, so twenty generations do not cost twenty full roots.
  • beadm is a convenience layer over exactly these zfs operations, aware of the boot loader.

So the same integrity guarantees (checksums, scrub, self-healing) and the same send/receive backup story that protect your data also protect your generations.

Further reading

ZFS boot environments

illumos ships a native atomic-upgrade story that predates and closely mirrors NixOS’s generations: boot environments (BEs), managed with beadm. A boot environment is a bootable clone of the root filesystem living on its own ZFS dataset. Solnix maps each Nix generation onto a boot environment, so the mental model you already have from NixOS transfers almost directly.

On illumos generally beadm and ZFS boot environments are mature and are how every illumos distribution does upgrades and rollback. On Solnix the generation-to-BE mapping in the activation path is planned (there is no bootable image yet — see Introduction); the beadm commands below are the real illumos commands and work on any illumos host.

The NixOS analogy (read this first)

If you run NixOS, you already understand boot environments — they are the same idea with a different mechanism:

NixOS on LinuxSolnix on illumos
Generation (a /nix/store system closure)Nix generation → one ZFS boot environment
nixos-rebuild switchbuild config → create + activate a new BE
GRUB submenu of past generationsboot loader menu of past BEs
Roll back = pick an older generationRoll back = beadm activate an older BE, or pick it at boot
nix-collect-garbage frees old generationsbeadm destroy removes old BEs
Copy-on-write nothing (store paths shared)ZFS clones share blocks (cheap)

The important difference: on Linux the bootloader points at a kernel + initrd + store path; on illumos the bootloader points at a whole bootable root dataset (the BE). ZFS makes that whole-root switch as cheap as NixOS’s per-path sharing, because a new BE is a clone, not a copy.

What a boot environment is

A BE is a ZFS dataset (under rpool/ROOT/ by convention) containing a complete, bootable root filesystem. Because ZFS clones are copy-on-write, creating a new BE from the running one:

  • costs almost no space initially (blocks are shared),
  • is near-instant,
  • leaves the current BE completely untouched and independently bootable.

You can have many BEs on one pool. Exactly one is active (the default boot target); you can also boot a non-active BE once without changing the default.

The beadm commands

List

beadm list
BE        Active Mountpoint Space Policy Created
solnix-1  N      /          8.1G  static 2026-01-10 09:14
solnix-2  NR     /          2.3G  static 2026-01-12 11:02

The Active column: N = active now (the running BE), R = active on reboot (the default boot target), NR = both. beadm list -a shows the datasets and snapshots that make up each BE.

Create

pfexec beadm create solnix-3               # clone the running BE
pfexec beadm create -e solnix-1 solnix-3   # clone from a specific BE

Creating a BE does not activate it — the running system is unaffected.

Activate

pfexec beadm activate solnix-3

Sets solnix-3 as the default boot target (R). It takes effect on the next reboot; the current system keeps running until then. This is the atomic switch: nothing on the live root is mutated.

Boot once without activating

At the boot loader menu you can select any BE for a single boot without making it the default — the illumos equivalent of picking an old NixOS generation from the GRUB submenu. If it works, beadm activate it; if not, reboot back to the default.

Destroy

pfexec beadm destroy solnix-1

Removes a BE and its datasets. You cannot destroy the currently running BE. This is the analog of garbage-collecting old NixOS generations.

Mount / unmount (inspect without booting)

pfexec beadm mount solnix-3 /mnt
# inspect /mnt ...
pfexec beadm unmount solnix-3

Useful for comparing two generations or repairing one from another.

Snapshots and BEs

A BE is built on ZFS snapshots and clones (see ZFS storage). Two things follow:

  • Creating a BE takes a snapshot of the source root and clones it. The snapshot is what makes the operation cheap and instant.
  • beadm create solnix-3@backup (name with @) creates a snapshot of a BE rather than a new BE — a point-in-time marker you can later turn into a BE.

Because it is all ZFS underneath, the same integrity, zfs send/receive, and scrub guarantees that protect your data protect your boot environments too.

Safe upgrade and rollback, end to end

The upgrade cycle Solnix targets, framed the NixOS way:

  1. Build a new system configuration → a new Nix generation.
  2. Create a boot environment for that generation (beadm create).
  3. Populate the new BE with the generation’s closure.
  4. Activate the new BE (beadm activate) — a boot-target change, not an in-place mutation.
  5. Reboot into the new generation. The previous BE remains bootable and untouched.
  6. Roll back if needed: boot the previous BE from the loader menu, or beadm activate it and reboot. No packages to reinstall, no state to unwind — you are back on the exact prior root.

The properties that make this worth it:

  • Atomic — the switch is a single pointer change; a power loss mid-upgrade leaves you on the old, intact BE.
  • Instant rollback — the previous root is right there, bootable.
  • Cheap — clones share blocks, so twenty generations do not cost twenty full roots.

Boot loader integration

illumos on x86 uses the loader (the FreeBSD-derived boot2/loader, replacing the older GRUB on modern distributions); SPARC uses OpenBoot. Either way, beadm activate updates the loader’s default and the menu lists the available BEs, so choosing an older generation at boot is a menu selection. This is the mechanism illumos already ships and trusts — Solnix reuses it rather than inventing a bootloader story.

Further reading

DTrace

DTrace is illumos’s dynamic tracing framework: a single tool that instruments the entire system — kernel and userland — safely enough to run on production. It was invented at Sun and is one of the reasons people run illumos at all. For a Solnix user, DTrace is the observability answer to “what is this Nix-built binary actually doing on this machine, right now, without a rebuild.”

On illumos generally DTrace is mature, safe, and load-bearing. On Solnix DTrace is inherited from the illumos gate; the one-liners below are real DTrace. Getting a full Solnix system to the point where you are tracing your own services is gated on the bootstrap (see Introduction) — but the framework itself is not Solnix’s to build.

What it is

DTrace exposes tens of thousands of instrumentation points (probes) across the kernel and userland. Every probe is dormant and costs nothing until you enable it. You write small scripts in the D language — a C-like language with awk-style pattern/action structure — that say “when this probe fires, in this context, do this.”

A probe is named by four parts:

provider:module:function:name

For example syscall::open:entry (the entry to the open syscall) or proc:::exec-success (a process successfully exec’d). Leaving a field blank matches all values, so syscall:::entry matches the entry of every syscall.

Providers

Providers are the sources of probes. The ones you reach for first:

ProviderWhat it traces
syscallEvery system call, entry and return.
procProcess lifecycle: exec, fork, exit, signals.
profileA timer — sample all CPUs at a fixed rate (profiling).
pidAny function or instruction in a specific userland process.
fbtFunction boundary tracing in the kernel (every kernel function).
ioBlock-device I/O — sizes, latency, which device.
schedScheduler events — on-cpu, off-cpu, run-queue.

The pid provider is how you trace your program’s functions with zero instrumentation compiled in — DTrace attaches to the live process.

A few one-liners

Which programs are being executed, system-wide:

pfexec dtrace -n 'proc:::exec-success { trace(curpsinfo->pr_psargs); }'

Count system calls by process name for a few seconds, then print a table:

pfexec dtrace -n 'syscall:::entry { @[execname] = count(); }'

Files being opened, and by whom:

pfexec dtrace -n 'syscall::open*:entry { printf("%s %s", execname, copyinstr(arg0)); }'

A latency distribution (a quantize power-of-two histogram) of read syscalls:

pfexec dtrace -n 'syscall::read:entry { self->t = timestamp; }
                  syscall::read:return /self->t/ { @ = quantize(timestamp - self->t); self->t = 0; }'

Sample kernel stacks at 997 Hz to see where CPU time goes:

pfexec dtrace -n 'profile-997 { @[stack()] = count(); }'

Aggregations (@) are DTrace’s headline feature: they sum/count/quantize in the kernel and only ship the summary to userland, so tracing a busy system stays cheap.

Safety — why you can run this in production

DTrace was designed from the start to be safe on live systems, and this is not a footnote — it is the reason it exists:

  • Probes are zero-cost when disabled and cheap when enabled.
  • The D language has no loops and no arbitrary memory writes — a DTrace script cannot hang or corrupt the kernel.
  • Accessing userland memory goes through safe copy-in (copyinstr, etc.) that faults gracefully instead of panicking.
  • There are tunable limits on buffers and drops so a misbehaving script degrades (drops records) rather than harming the system.

This is what lets you point DTrace at a production process and ask hard questions without a maintenance window.

Why it matters for Solnix

On a Nix system the software layer is immutable, reproducible store paths — great for building correctly, silent about runtime behavior on real hardware and real load. DTrace is the missing half: it tells you what a store-path binary does when it runs — which syscalls, which files, where the latency and CPU actually go — with no rebuild and no restart. It pairs naturally with MDB and core-file analysis for the post-mortem case.

Further reading

Zones

Zones are illumos’s OS-level virtualization: isolated environments that share one kernel but each have their own filesystem, process table, users, network stack, and resource limits. They predate Linux containers by years and are, in several ways, what containers grew up to imitate — with stronger isolation and first-class integration with ZFS, DTrace, and the fault management architecture.

On illumos generally zones are mature and heavily used (SmartOS runs essentially everything in zones). On Solnix zones are inherited from the illumos gate, but Solnix’s own declarative zone tooling is early / not yet built — only a preview image exists so far (see Introduction), let alone a solnix.zones.* module. This page describes the illumos feature and the intended Solnix relevance honestly, not a shipped capability.

What a zone is

A zone is a walled-off slice of one running illumos kernel. From inside, it looks like its own machine: its own root filesystem, its own processes and PIDs, its own users and hostname, its own network interfaces. From outside (the global zone), the operator sees and controls every zone. Because all zones share the single kernel, there is no hypervisor overhead — starting a zone is closer to starting a process than booting a VM.

  • Global zone — the base OS; it owns the hardware and administers all other zones.
  • Non-global zones — the isolated environments you create.

Branded zones

A zone’s brand determines the userland and syscall environment it presents:

  • Native (illumos/ipkg) zones — a normal illumos environment.
  • LX-branded zones — present the Linux system-call interface, so most Linux binaries run unmodified on the illumos kernel. This is how illumos distributions run Linux workloads without a VM. Solnix plans to pull LX support in from SmartOS — see LX-branded zones.

Isolation and integration

Zones are not just namespaces bolted on — they are wired into the rest of the platform:

  • ZFS — a zone typically lives on its own dataset, so snapshots, clones, and quotas apply per zone. See ZFS storage.
  • Virtual networking — Crossbow creates a virtual NIC (VNIC) per zone; the zone gets a real, isolated network stack. Put the VNICs on an etherstub for a private network between zones.
  • Resource controls — CPU, memory, and process caps are enforced per zone.
  • DTrace — from the global zone you can trace across zones; a zone can be granted limited DTrace on itself. See DTrace.
  • SMF — each zone runs its own SMF instance and service graph. See SMF services.

Brief usage (on any illumos host)

Zone administration is zonecfg (define) then zoneadm (install / boot / manage):

pfexec zonecfg -z web        # interactively define a zone named "web"
pfexec zoneadm -z web install
pfexec zoneadm -z web boot
zoneadm list -cv             # list all zones and their state
pfexec zlogin web            # get a shell inside the zone
pfexec zoneadm -z web halt   # stop it

Solnix relevance

Zones are an obvious fit for reproducible, Nix-built environments — a native zone whose entire userland is a set of /nix/store paths, created and torn down declaratively, would be the illumos analog of a NixOS container. That is a natural direction for Solnix but it is not built yet: the prerequisites are a working native Solnix system (the bootstrap, see How Solnix is built) and an SMF module, both of which come first. Treat zones today as “a powerful illumos feature Solnix will be able to exploit,” not “a Solnix feature.”

Further reading

LX-branded zones (Linux on illumos)

illumos zones come in brands — a brand decides which userland and system-call environment a zone presents. The most interesting brand for a mixed shop is the LX brand: an LX-branded zone presents the Linux system- call interface, so unmodified Linux binaries run directly on the illumos kernel — no virtual machine, no emulation of a whole CPU, no second kernel.

On illumos generally LX zones are a real, shipping feature — SmartOS runs Linux workloads this way in production. On Solnix LX support is a roadmap item, not yet built (see the Solnix plan below). This page describes the feature and the plan honestly; nothing here is a shipped Solnix capability.

What an LX-branded zone is

A native zone runs illumos userland on the illumos kernel. An LX zone runs a Linux userland (a Linux distribution’s files — Debian, Alpine, etc.) on the same illumos kernel. The trick is a brand: a thin translation layer that implements the Linux system-call ABI in terms of illumos kernel facilities. When a Linux binary in the zone calls, say, epoll_create or clone, the LX brand maps it to the illumos equivalent.

The result:

  • Linux ELF binaries run as-is — no recompilation, no patchelf, no VM.
  • Only one kernel runs (the illumos kernel), so there is no hypervisor overhead and no second OS to manage. It is a zone, with a zone’s near-native performance.
  • The zone still gets full illumos integration underneath — a ZFS dataset, a Crossbow VNIC, resource controls, and observability from the global zone with DTrace.

Compare the alternatives: a Linux VM (bhyve/KVM) runs a whole second kernel and pays for it; QEMU user-mode emulation is slow. The LX brand is neither — it is a syscall-translation shim, so Linux processes are just illumos processes wearing a Linux ABI.

How SmartOS pioneered the modern LX brand

An early lx brand existed in OpenSolaris but bit-rotted. The modern LX brand — the one that runs contemporary 64-bit Linux distributions — was built and is maintained by the SmartOS community (Joyent, now MNX). SmartOS’s whole model is “everything in a zone,” and LX zones let it run the vast catalog of Linux software (and Linux Docker images, via its Docker-to-zone layer) alongside native illumos zones on one kernel. That work lives in illumos-gate and the SmartOS platform, and is the reference implementation of LX today.

The Solnix plan (roadmap)

Solnix intends to pull LX-zone support in from SmartOS so that a Solnix machine can run Linux workloads alongside native illumos ones — without a VM. The intent, stated plainly:

  • Bring the SmartOS LX brand into Solnix so Linux binaries run in an LX zone on a Solnix host.
  • Let users run Linux Docker-style workloads / Linux-only binaries that have no illumos build, next to native Solnix (illumos + Nix) zones, on the same kernel.
  • Eventually wire this into Solnix’s declarative model — a Nix-described LX zone, the same way native zones are a natural target for a solnix.zones.* module (see Zones).

Why it matters

Not everything has an illumos build. An LX zone means you do not have to choose between “illumos-native” and “the Linux software I need” — you run the Linux thing in an LX zone and the illumos-native things in native zones, one kernel, one machine, full observability across all of it. For a Solnix user that is the difference between “illumos for the workloads that have illumos builds only” and “illumos as a general-purpose host that also runs your Linux workloads.”

Honest status

This is not in Solnix today. The prerequisites come first: a bootable native Solnix system (the bootstrap — see How Solnix is built) and the zone tooling generally (Zones is early). Pulling in the SmartOS LX brand is a stated direction, not a shipped feature. Treat LX-on-solnix as “planned, and here is why we plan it,” not “available now.”

Further reading

Networking (Crossbow)

illumos does not bolt virtual networking on as an afterthought — it ships an integrated network-virtualization stack in the kernel called Crossbow. Crossbow turns the network stack into something you carve up the way ZFS carves up storage: virtual NICs, virtual switches, and bandwidth/flow controls, all first-class and all administered with a small set of commands. It is the plumbing under per-zone networking.

On illumos generally Crossbow has been part of the platform since OpenSolaris (2009) and is mature and load-bearing — every zone’s network comes through it. On Solnix Crossbow is inherited from the illumos gate; the dladm/flowadm/ipadm commands below are the genuine illumos commands and work on any illumos host. What is not yet built on Solnix is a declarative solnix.networking.* Nix module that renders these from config — that is a roadmap item, like the SMF module. Today you configure networking imperatively with the commands below, the same as on any illumos system.

For the Linux admin: what Crossbow replaces

If you came from Linux, you assembled virtual networking from several independent tools. Crossbow unifies that same functionality — and it did so years earlier:

You’d reach for (Linux)On illumos (Crossbow)
ip link add … type veth / tapdladm create-vnic (a virtual NIC)
brctl / ip link add … type bridgedladm create-etherstub (a virtual switch)
ip link set … master br0VNICs created over an etherstub share it
network namespaces (ip netns)zones get their own VNICs
tc (traffic shaping / rate limits)dladm set-linkprop maxbw / flowadm
ip addr / ip routeipadm (IP addresses and interface config)
VLAN subinterfaces (ip link … type vlan)dladm create-vlan
bonding / LACPdladm create-aggr (link aggregation)

The mental model is close, but Crossbow is one coherent stack rather than a half-dozen loosely related tools, and the datalink/IP split (dladm for links, ipadm for IP) is cleaner than Linux’s overloaded ip.

The three command families

illumos splits network administration by layer:

  • dladm — the datalink layer (layer 2): physical NICs, VNICs, etherstubs, VLANs, aggregations, and per-link properties (MTU, MAC, bandwidth caps).
  • ipadm — the IP layer (layer 3): addresses, interface configuration, and tunables. (This replaced the old ifconfig.)
  • flowadm — flows: policy on classified traffic (by port, protocol, address), including bandwidth limits and priorities finer-grained than a whole-link cap.

List every datalink and its state:

dladm show-link
dladm show-phys          # physical NICs only
dladm show-vnic          # virtual NICs only

Create a VNIC over a physical NIC (this is the workhorse — every zone gets one):

pfexec dladm create-vnic -l net0 vnic0

Create an etherstub (a virtual switch with no physical uplink) and hang VNICs off it — this is how you build an isolated internal network between zones, with no external connectivity unless you add it:

pfexec dladm create-etherstub stub0
pfexec dladm create-vnic -l stub0 vnic_a
pfexec dladm create-vnic -l stub0 vnic_b
# vnic_a and vnic_b can now talk to each other, and nothing else

Set a bandwidth cap on a link (the simple, whole-link rate limit):

pfexec dladm set-linkprop -p maxbw=100M vnic0    # cap vnic0 at 100 Mbit/s
dladm show-linkprop -p maxbw vnic0               # check it

Other common link operations:

pfexec dladm create-vlan -l net0 -v 42 vlan42    # VLAN tag 42 on net0
pfexec dladm create-aggr -l net0 -l net1 aggr0   # LACP aggregation of two NICs
pfexec dladm set-linkprop -p mtu=9000 net0       # jumbo frames
pfexec dladm delete-vnic vnic0                   # tear a VNIC down

ipadm — IP configuration

Once a datalink exists (physical or virtual), ipadm gives it an IP:

ipadm show-if                                    # list IP interfaces
pfexec ipadm create-if vnic0                     # bring vnic0 up as an IP if
pfexec ipadm create-addr -T static \
  -a 192.0.2.10/24 vnic0/v4                       # static IPv4 address
pfexec ipadm create-addr -T dhcp vnic0/dhcp      # or DHCP
ipadm show-addr                                  # list all addresses
pfexec ipadm set-prop -p forwarding=on ipv4      # enable IP forwarding

flowadm — flows and finer bandwidth control

A flow classifies a subset of a link’s traffic and applies policy to it — more surgical than the whole-link maxbw:

# Cap only HTTPS traffic on vnic0 to 50 Mbit/s
pfexec flowadm add-flow -l vnic0 \
  -a transport=tcp,local_port=443 -p maxbw=50M https-flow
flowadm show-flow                                # list flows
flowadm show-flowprop https-flow                 # its properties
pfexec flowadm remove-flow https-flow            # remove it

Flows are how you say “throttle backups but not interactive traffic” or “give this service priority” without touching the rest of the link.

How Crossbow underpins zones

Crossbow is why zones get real, isolated network stacks rather than shared plumbing. The usual pattern:

  1. Create a VNIC per zone (dladm create-vnic -l net0 zoneA0).
  2. Assign that VNIC to the zone in its zonecfg (an anet/net resource).
  3. Inside the zone, that VNIC looks like a dedicated physical NIC — the zone has its own IP, routing, and firewall (ipfilter), fully isolated from the global zone and other zones.

Put the zones’ VNICs on an etherstub instead of the physical NIC and you have a private virtual network between zones with no external exposure — the illumos equivalent of a Docker bridge network or a set of namespaces on a veth bridge, but built into the OS and older than either.

Firewalling

Packet filtering is a separate subsystem, ipfilter (ipf/ipnat), configurable globally and per zone. It is the illumos analog of iptables/nftables. Crossbow shapes and switches; ipfilter filters and NATs.

Solnix status, honestly

  • The Crossbow stack itself is real and inherited from the gate — it works on any illumos host today.
  • Declarative Solnix networking is not built yet. There is no solnix.networking.* module rendering dladm/ipadm/flowadm state from Nix; that waits on a bootable Solnix system (see How Solnix is built) and follows the same pattern as the planned SMF module. Until then, configure networking with the commands above.

Further reading

How Solnix is built

Solnix reuses NixOS’s evaluator and module system verbatim, then retargets everything below it to illumos. This is nixbsd’s playbook applied to a different kernel and userland: keep the Nix language, the store, and the module system; replace the OS the packages target. This page describes the layers — the illumos gate, kernel versus userland, how Nix sits on top, and the two toolchains — for a reader who knows Nix/NixOS but is new to illumos.

The illumos gate

illumos is distributed as illumos-gate: a single source repository holding the kernel, the core libraries, the link-editor and runtime linker, and the base userland (libc, the C runtime, the ELF/CTF tools, svc.startd, and so on) — all built together as one coherent tree. Downstream distributions (OmniOS, OpenIndiana, SmartOS) take the gate and add packaging, installers, and extra software on top.

Solnix is one such downstream, but instead of a traditional package manager it uses Nix. The gate provides the kernel and the load-bearing userland pieces that must match the kernel’s ABI; Nix provides everything above that and the mechanism for building, distributing, and activating it.

Bootstrap constraint (stated honestly): illumos-gate does not cross-build from Linux. The bootstrap must start on an illumos host — a stage0 seed toolchain, extracted from a gate build, has to run natively on illumos before Nix can take over. See “Seed toolchain” below.

Kernel versus userland

Two boundaries matter on illumos and they shape how Nix layers on:

  • The kernel (unix, genunix, and modules) is inherited from the gate. It provides the system-call interface, ZFS, DTrace, zones, and the fault management architecture. Solnix does not rebuild the kernel with Nix in the general case; it is part of the platform the seed and the boot environment carry.
  • The userland splits into a load-bearing base — libc.so.1, the runtime linker ld.so.1, the C runtime objects, the link-editor ld, and the SMF machinery — which must be ABI-compatible with the kernel, and everything else, which is ordinary software Nix can build and place in /nix/store.

Solnix packages the load-bearing base as a fine-grained world so that even the lowest layers are Nix-managed store paths, then builds the rest the normal Nix way.

How Nix layers on illumos

Platform tuple

Add x86_64-solaris (GNU triple x86_64-unknown-solaris2.11) to a nixpkgs fork. nixpkgs already carries partial Solaris support — kernels.solaris, isSunOS, and an ld-solaris-wrapper — which is load-bearing for the bootstrap. The other targets follow the same pattern; see CPU architecture support.

pkgs.solnix.* — the fine-grained world

A dedicated package world holds the base illumos pieces as individual Nix derivations:

  • pkgs.solnix.libc — the Solaris libc.so.1 (not glibc).
  • pkgs.solnix.rtld — the runtime linker ld.so.1.
  • pkgs.solnix.ld — the Solaris link-editor.
  • pkgs.solnix.sys — the base tools and headers needed to reach multi-user.

These are the “world slices”: libc, rtld, ld, sys. Everything else in the Solnix package set builds against them. (Use pkgs.solnix.*, not pkgs.illumos.*.)

Seed toolchain (stage0)

Because the gate cannot cross-build from Linux, the bootstrap begins with a relocatable seed tarball extracted from an illumos-gate build: a compiler, a linker, libc, the C runtime objects (crt), headers, the runtime linker, and the ELF/CTF tools. It is unpacked into /nix/store and used to build a native Nix stdenv on the illumos host. Once that native stdenv exists, the seed is never referenced again — every later package is built by the Nix-native toolchain, and its outputs land in the binary cache so no one rebuilds them.

Nix’s whole model depends on baking absolute /nix/store paths into binaries so they find their exact dependencies. On Solnix this is done with the Solaris link-editor writing ELF RUNPATH, and inspected with elfdump — no GNU tooling. This is a real divergence from Linux nixpkgs, which leans on GNU ld and patchelf; on Solnix the native ld and elfdump do the equivalent work.

Init and generations

  • Init is SMF, not systemd. Solnix renders SMF manifests and drives svc.startd on activation. See SMF services.
  • Generations map onto ZFS boot environments — each Nix generation is a bootable BE, giving atomic upgrade and instant rollback. See ZFS boot environments.

The two toolchains

illumos-gate historically builds with a specific compiler, and modern illumos work supports both GCC and Clang. Solnix carries two toolchains:

  • GCC 14 (current pin) — the primary toolchain, matching the direction illumos-gate has moved for its main build.
  • Clang 21 (current pin) — the alternate toolchain, useful for code that expects Clang and for cross-checking correctness/diagnostics.

Carrying both is deliberate: it keeps Solnix honest about portability and gives package authors a fallback when one compiler chokes on illumos-specific code. The seed toolchain provides whichever compiler the stage0 gate build shipped; the Nix-native stdenv then rebuilds GCC 14 and Clang 21 (current pins) as ordinary packages.

Why this order matters

illumos-gate does not cross-build from Linux, so the bootstrap must start on an illumos host. Once a native Nix stdenv exists on illumos, the rest of the package set builds the usual Nix way — and those artifacts land in the binary cache so the community never rebuilds them. The architecture is, in one line: inherit the kernel and load-bearing userland from the gate, Nix-manage everything from libc up, activate through SMF and boot environments.

Further reading

CPU architecture support

The Solnix OS is a supported distribution of illumos aimed at four CPU targets — x86_64, aarch64, RISC-V, and SPARC — across both server and desktop use, and optimized for virtualized hosting on the major cloud platforms (AWS/EC2, Microsoft Azure, Google Cloud, and the rest). That is the design target; this page states current support honestly — the table reflects reality, not aspiration. Only x86_64 is a working primary target; the others are at various stages of bring-up, and desktop is a future core-team goal. This page gives the status of each CPU target, what “bring-up” means for it, and how cross-compilation fits in.

The four targets

ArchPlatform tupleStatusCachePhase
x86_64 (amd64)x86_64-solarisPrimary targetlive1
aarch64aarch64-solarisOut-of-tree illumos port exists; integrate itlive3
SPARC v9 (sun4v)sparcv9-solarisBit-rotting in-gate; revive with fork patcheslive4
RISC-Vriscv64-solarisKernel boots to a shell (try it in your browser); no builder/cache yetplanned5

amd64 first, always. No phase starts before the previous phase’s gate is green. This is the same honesty stance the binary cache takes: platforms without a builder yet appear as “no objects yet,” never as coverage that does not exist.

What each status means

x86_64 (amd64) — primary

The reference platform. illumos-gate builds natively on amd64, the seed toolchain is extracted here, and this is where the Nix-native stdenv comes up first. Everything in the roadmap is validated on amd64 before any other arch starts. If a Solnix feature works anywhere, it works here first.

aarch64 — integrate the existing port

There is an out-of-tree illumos aarch64 effort. The work is not “port illumos to ARM from scratch” but “integrate that port and bring a Nix-native stdenv up on it.” The cache line is live because it can serve Linux cross-build artifacts today (see cross-compilation below); illumos-native aarch64 objects light up when an aarch64 builder is running.

SPARC v9 (sun4v) — revive

SPARC support exists in illumos-gate but has bit-rotted from disuse. Bringing it back means fork patches to get the gate building again for sun4v, then the usual seed-and-bootstrap path. This is later in the roadmap (Phase 4) precisely because it is revival work, not integration.

RISC-V — planned

No illumos RISC-V port exists yet in a usable state; this is the furthest-out target (Phase 5). Listed so the intent is clear, marked planned so no one mistakes it for working.

Cross-compilation notes

There are two distinct build directions and they matter for how the cache is populated per arch:

  • Linux → target (cross). nixpkgs can cross-compile many packages from a Linux builder to a Solaris target tuple. This is what lets the cache line read live for arches whose native builder is not yet running: the cross-built artifacts are real, signed, and installable. It does not cover the load-bearing base or anything that needs a native illumos build — the gate does not cross-build from Linux (see How Solnix is built).
  • Native (illumos host). The seed toolchain and the load-bearing pkgs.solnix.* world must be built natively on an illumos host of that arch. This is the gated part: an arch is only fully supported once a native builder for it exists.

So “Cache: live” for a non-primary arch means “cross-build artifacts are available”; full native coverage arrives with a native builder, and the cache never advertises coverage it does not have.

Further reading

  • How Solnix is built — how the platform tuple, seed toolchain, and native stdenv fit together.
  • The binary cache — per-arch coverage and how artifacts are distributed.
  • Contributing — every arch needs a builder; this is the most direct way to help.

Peer-to-peer distribution

Solnix distributes both its binary cache and this website peer-to-peer, so the more people use Solnix, the faster and cheaper it gets for everyone — bandwidth scales with the community instead of with one origin’s egress bill.

Both forms of sharing are governed by the same privacy master switch as telemetry; see Privacy, telemetry & the community pulse.

Cache objects over BitTorrent

Each cache artifact (NAR) is distributed as a torrent, seeded by the hub and by other Solnix users. When you have opted in, your machine seeds the public, signed cache artifacts it has fetched to other Solnix users:

solnix.cache.seed.enable = true;   # default on when you have opted in
  • It only ever shares public Nix store paths — never your private data.
  • Integrity is enforced by the cache.solnix.io signature regardless of where the bytes came from, so a torrented NAR is exactly as trustworthy as one pulled over HTTP.

It complements the HTTP cache — it never replaces it

The narinfo served by cache.solnix.io always carries a plain HTTP URL: as the guaranteed fallback. A stock nix works today over HTTP; the peer layer is an enhancement layered on top. If no peer has what you need, Nix simply fetches it from cache.solnix.io as usual. See The binary cache.

The site over WebRTC

The Solnix website itself can be shared browser-to-browser over WebRTC, so visitors help serve the site to each other. There are two distinct audiences here, governed by two different mechanisms — don’t conflate them:

Website visitors (your browser)

When you open solnix.io in a browser, sharing is off by default. No WebRTC connection is made until you actively opt in through the consent prompt at the bottom of the page (“Help serve this site?”). The choice is stored in your browser (localStorage, key solnix.p2p.consent.v1) and is revocable in one click from the “P2P sharing” toggle in the footer, on any page.

WebRTC exposes your IP address to the peers you connect to, exactly as any direct peer-to-peer connection does. That is inherent to how a swarm works and is why it is opt-in. It is a different posture from the telemetry promise (“region only, IP dropped at the edge”): the site never collects or stores your IP, but it cannot hide it from your peers. If you don’t turn it on, your browser never peers with anyone. See Privacy.

Solnix machines (the OS)

A Solnix host can participate in serving the site’s static files too. That is governed by a Nix module option on the machine, not a browser prompt:

solnix.site.p2p.enable = true;   # default on once you've opted in (privacy.enable = false)

This is a browser/host enhancement layered on top; the site always loads normally from the origin over HTTP regardless of whether any peer sharing is on.

Opting out

Because both features are gated by the privacy master switch, a machine whose config never touches it does not seed and does not share — the default is fully private. To opt into the community pulse and then pare P2P back:

Note the inversion: solnix.privacy.enable = false turns sharing on — it opts you in, it does not disable privacy. See the warning in Privacy.

solnix.privacy.enable = false;      # opt in

solnix.cache.seed.enable = false;   # ...but don't seed the cache
solnix.site.p2p.enable   = false;   # ...and don't share the site

The effective rule is the same one telemetry uses: (not privacy.enable) && <feature>.enable. The master switch always wins. We state this plainly so no one is surprised to find their machine seeding.

Debugging

illumos has a deep, unusually coherent debugging toolkit — crash dumps, the modular debugger mdb, DTrace, core files with CTF type data, and the fault management architecture — and Solnix inherits all of it from the gate. This page walks the common cases: a service that will not start, a program that crashed, and a system that panicked or hung. It is adapted from the illumos user guide and framed for a Solnix user.

Honest status. Solnix is early — only a preview image exists so far (see Introduction), so end-to-end “debug your live Solnix box” is not yet an everyday thing. The commands below (svcs, mdb, savecore, pstack, coreadm, dumpadm, fmadm) are the real illumos commands and work on any illumos host. Where a step is solnix-specific and not built yet, it says so.

Note: commands that need privilege are shown with pfexec (illumos’s RBAC-backed sudo-equivalent). On some systems sudo is used instead.

A service failed to start

This is the most common everyday case and the fastest to diagnose. If something that should be running is not, ask SMF why:

svcs -x

svcs -x walks the service dependency graph and prints, for each broken service, the state, the likely cause, and the path to its log. Then read that log:

svcs -l svc:/network/ssh:default          # find the logfile: line
tail -50 /var/svc/log/network-ssh:default.log

If the service is in maintenance because it kept failing, fix the cause and retry:

pfexec svcadm clear svc:/network/ssh:default

See SMF services for the full state model and command set.

A program crashed (core files)

When a userland process crashes, illumos can save a core file — a snapshot of the process’s memory — that you inspect after the fact.

Check the core configuration first:

coreadm
     global core file pattern:
     global core file content: default
       init core file pattern: core
            global core dumps: disabled
       per-process core dumps: enabled

If per-process core dumps are enabled and the global pattern is empty, a crash writes a file named core in the process’s working directory. To set a predictable global location and pattern:

pfexec coreadm -g /var/cores/core.%f.%p -e global -e per-process
# %f = executable name, %p = pid; see coreadm(8) for all specifiers

Read the core file

The quick answer — the stack at the point of the crash:

pstack core

The deep answer — open it in the modular debugger:

mdb core
> ::status          # summary: signal, faulting instruction
> $C                # C stack backtrace
> ::stack           # same, another form
> ::regs            # registers at the fault
> $q                # quit

Because illumos binaries carry CTF type data, mdb can print structures with their real field names and types — you are not staring at raw hex. On Solnix the binary is a /nix/store path; mdb resolves its symbols and CTF the same way it does for any illumos binary, and the store path pins the exact build that produced the core.

The system panicked or hung (crash dumps)

When the kernel panics, illumos saves a crash dump of kernel memory to the dump device, then reboots. On the next boot you extract and analyze it.

Check the dump configuration:

pfexec dumpadm
      Dump content: kernel pages
       Dump device: /dev/zvol/dsk/rpool/dump (dedicated)
Savecore directory: /var/crash/<hostname>
  Savecore enabled: yes
   Save compressed: on

Extract the dump after the reboot:

pfexec mkdir -p /var/crash/`hostname`
pfexec savecore
cd /var/crash/`hostname`

savecore writes unix.<n> (the kernel) and vmcore.<n> (memory). Then pull the essential post-mortem information into one file with mdb:

echo '::panicinfo
::cpuinfo -v
::threadlist -v 10
::msgbuf
*panic_thread::findstack -v
::stacks' | mdb <n> > ~/crash.<n>

Keep crash.<n> (and, if you can, the dump itself) for a bug report. Note that a crash dump can contain confidential in-memory data — use judgment before sharing it publicly.

Forcing a dump from a hung system

If the system is wedged but responsive enough:

pfexec savecore -L      # live dump without rebooting
# or
pfexec reboot -d        # reboot and force a dump

For a truly frozen box, illumos supports dropping into the kernel debugger (kmdb) via the boot loader or an NMI; that is advanced and hardware-specific — see the illumos user guide linked below.

Hardware and diagnosed faults (FMA)

The fault management architecture turns error telemetry into diagnosed faults:

fmadm faulty           # currently diagnosed faults and affected components
fmdump                 # the fault log
fmdump -v              # verbose, with the fault event detail
fmstat                 # fault-manager module statistics

Each fault carries a stable message ID (like ZFS-8000-8A) you can look up. FMA covers hardware (CPU, memory, disks) and some software faults, and it hands service faults to SMF — so fmadm faulty and svcs -x together cover “what is wrong with this machine.”

Live tracing (DTrace)

For behavior on a running system — not a crash — reach for DTrace: which syscalls a process makes, where latency comes from, what is burning CPU, without a rebuild or restart. See DTrace.

Reporting a bug to Solnix

When you hit something you believe is a Solnix (not upstream illumos) problem, include:

  • what you did and what you expected versus what happened;
  • the Solnix generation / boot environment (beadm list) so the exact build is identifiable;
  • the relevant artifact: svcs -x output and the service log for a service failure; pstack/mdb output for a crash; the crash.<n> file for a panic; fmadm faulty for a hardware fault;
  • the store path(s) involved — a /nix/store path pins the exact build, which is the whole point of a reproducible system.

Send it to the development list — see Contributing for the current channels (hackers@solnix.io, planned). If the bug reproduces on stock illumos with no Nix involved, it likely belongs upstream at illumos.org.

Further reading

Contributing

Solnix is early (preview-image stage) and every arch needs builders. Contributions welcome.

Repos

RepoWhat
codeberg.org/gregburd/solnix-infraInfra + services (Nix, terranix, k8s)
codeberg.org/gregburd/solnix-siteThis site + handbook
Solnix (distribution)illumos + Nix bootstrap, pkgs.solnix.*, modules

Ways to help

  • Port an architecture. Each of aarch64, SPARC v9, and RISC-V needs work — and each needs a builder that can produce artifacts for the cache.
  • Package illumos software. Grow pkgs.solnix.*.
  • The seed toolchain. Help harden the stage0 extraction from illumos-gate.
  • Docs. Every page here has an edit link (top right).

Mailing lists

Development discussion happens on hackers@solnix.io; announcements and the weekly digest on announce@solnix.io. Subscribe on the community page. Confirmation links expire after 24 hours; opening one shows a confirmation form, and pressing its button completes signup. Each list email includes unsubscribe.

Confirmation proves address ownership, not posting trust. New senders are moderated. Automatic posting to hackers requires a confirmed subscription, explicit moderator vetting, no ban, and a passing sender-authentication check. Announcements always require moderation. Send plain text or .patch/.diff attachments: HTML, executable attachments and compressed archives are not accepted. Keep messages below 2 MiB and individual text parts below 512 KiB.

Pending posts and confirmed members awaiting posting-trust review appear in private daily moderator digests, only when there is work to resolve. Denial of posting trust leaves your subscription intact; a ban is separate. Announce posts still require individual moderation even after their author is vetted.

If a held post passes sender authentication, you receive an email explaining the hold and linking to a cancellation form. Opening the link changes nothing; confirm cancellation before the post is released. Release/rejection outcomes reply in the notification thread. A release means approved for delivery, not proof that every mailbox received it. Unauthenticated mail does not receive automatic notices to potentially forged addresses. Rejected SMTP submissions report their error directly to the sending mail system instead.

Published posts, including author addresses, are public and may be mirrored permanently. Subscriber membership is not published. Never send credentials, private keys or confidential material. Treat received patches as untrusted code.

Reading and searching without subscribing

  • Web: hackers archive and announce archive, with threaded discussion.
  • Search: use each archive’s search box. s:patch, f:author@example.org, and d:2026-01-01..2026-12-31 constrain subject, sender, and dates. See search syntax.
  • Export: search results offer mbox.gz for matching messages or whole threads.
  • Feeds: hackers Atom and announce Atom; searches also expose Atom feeds.
  • NNTP: lists.solnix.io:119, groups io.solnix.hackers and io.solnix.announce; public read-only news access, unencrypted. No personal password is needed.
  • Git: git clone https://lists.solnix.io/hackers/git/0.git hackers. Mirroring instructions describe keeping an offline copy. Public-inbox tools such as lei can search local imports.

IMAP and POP archive access

Both use implicit SSL/TLS and the lists.solnix.io certificate. Validate it; never supply personal mailbox credentials to these public readers.

SettingIMAPPOP3
Serverlists.solnix.iolists.solnix.io
Port1993 (not 993)995
UsernameanonymousYOUR-UUID@io.solnix.hackers or YOUR-UUID@io.solnix.announce
Passwordanonymousanonymous

IMAP: show all folders and choose io.solnix.hackers.0 or io.solnix.announce.0. History is split into 50,000-message folders (.0, .1, etc.); parent folders can appear empty. The server is read-only: no uploads, server-side flag changes, or archive deletions. Port 993 serves a different mail service on the shared IP; it does not serve these archives.

POP: generate a unique identifier once per client using uuidgen or python3 -c 'import uuid; print(uuid.uuid4())'. Keep it for later polls; it identifies your download cursor, and anyone who knows it can advance that cursor. Use separate accounts for the two lists. Without a suffix, POP presents the latest 1,000 messages; append .0, .1, etc. to the mailbox name for history.

POP deletions do not remove archive messages. The highest deleted message advances the cursor past earlier messages as well. The server advertises EXPIRE 0: retrieving messages may advance the cursor at QUIT even without explicit deletion. A client’s “leave messages on server” setting is therefore not a replay guarantee. Use a new UUID to redownload, or prefer IMAP/git when you want dependable historical browsing. These settings provide reading only, not an SMTP server or permission to post.

The GitGitGadget-style PR-to-patch bridge is planned, not deployed. Until then, send patches by email or use the Codeberg issue tracker.

How the community keeps costs sane

The binary cache is distributed peer-to-peer (over BitTorrent): using Solnix helps distribute it, so bandwidth scales with the community rather than with one origin. See The binary cache.

Community build federation

Solnix’s binary cache is built to be a community effort, not a single operator’s burden. Anyone running Solnix can help build packages, help deliver them, and (as trust is earned) help decide what gets cached — without ever being able to slip a compromised package to anyone else. This page explains how that works and how you can take part.

The one guarantee that makes it safe, stated up front:

No byte is ever served that solnix.io did not validate and sign, and no client ever imports a byte whose site signature it did not verify. Everything else — the community, BitTorrent, reputation — is optimization on top of that.

Who does what

  • solnix.io is the sole signer. It holds the cache signing key, validates every artifact (signature, hash, shape, closure) before serving it, and signs it with cache.solnix.io-1. The key never leaves its cluster.
  • Certified builders are enrolled identities that build the work queue and adjudicate community proposals. They never hold the signing key either — they submit unsigned build outputs and solnix.io signs them.
  • Community instances — you, running Solnix — can build packages and propose them over BitTorrent, and can seed packages to lighten the load. You earn a reputation over time.
  • Everyone pulling packages prefers BitTorrent and falls back to HTTPS.

There is no single point of failure in delivery (the swarm plus HTTPS). There is deliberately a single point of trust — one signer — because that is what keeps the cache safe.

The work queue is public

solnix.io publishes its build TODO list — which packages, which architectures (x86_64, aarch64, riscv64, UltraSPARC sparcv9), which man pages, which rebuilds — as a signed work-queue.json, available over both HTTPS (cache.solnix.io/work-queue.json) and BitTorrent. Because it is signed, you can verify it is the real queue. Certified builders claim items from it with a lease and build them; you can read it and build something yourself to propose.

Each item says what kind of work it is: a package at a target version (with the configuration its recipe specifies), a dependent that needs rebuilding because one of its dependencies changed, a package that is missing its man pages, or a rebuild after a validation failure.

Certified builders: daily, hands-off

A certified builder runs one command from cron, once a day:

solnix-builder run --systems x86_64-solaris,aarch64-solaris

That claims pending work for its architectures, builds each item in a sandbox, uploads the unsigned outputs to solnix.io’s staging, and lets the site validate and sign them. It is a plain script — no AI in the loop — because the queue entry plus the package recipe fully specify every build. Leases and heartbeats mean a long compile keeps its claim, and a builder that dies mid-build has its job automatically returned to the queue for someone else. Many builders can run on cron with no coordinator; the queue is the coordinator.

See the build team’s steering for the exact setup; the submit protocol is in the infra repo’s builder-onboarding.md.

Proposing a package (unauthenticated)

If you are running Solnix and you have built a package the cache wants, you can propose it even without being a certified builder:

  1. You build it and make a deterministic torrent of the result (fixed piece length, no timestamps, so honest builders of the same package produce the same torrent).
  2. You sign a small proposal record with your proposer key (a handle you generate once; it is not a signing key and grants no write access) and post it to solnix.io, then seed the bytes to the swarm.
  3. A certified builder picks up your proposal and independently rebuilds the same package. If their bytes match yours, your proposal is real: they submit it through the normal signed flow, solnix.io signs and serves it, and your reputation goes up. If the bytes do not match, the proposal is rejected and your reputation takes a hit — a mismatch is a loud signal, not an average.

Your proposal is only ever advisory. It can save a certified builder the trouble of discovering the work, but it can never put bytes into the cache that a certified builder didn’t independently reproduce and solnix.io didn’t sign. A bad proposal costs you reputation and some adjudication time; it cannot harm anyone.

Reputation

Every proposer key accrues a reputation score, stored on solnix.io and published (signed) so other peers can read it. The score moves on reproducibility, not popularity:

  • big increase when a certified builder independently reproduces your bytes;
  • small increase for a well-formed proposal that passes structural checks;
  • big decrease (and possible revocation) when your bytes don’t reproduce or you claim a hash you didn’t actually produce.

Because the only way to gain real reputation is to produce bytes that others independently reproduce, running a thousand fake identities buys nothing — you still can’t make a malicious package reproduce. Reputation is used to decide whose proposals get looked at first and which seeders peers prefer to pull from; it is never used in place of the mandatory signature check.

BitTorrent-first delivery

When your Solnix host needs a package, it:

  1. fetches the tiny signed narinfo from cache.solnix.io (over HTTPS),
  2. reads the torrent reference in it and pulls the actual package bytes from the swarm, preferring higher-reputation seeders, and
  3. falls back to HTTPS from solnix.io if the swarm is slow or has no seeders.

Either way, Nix verifies solnix.io’s signature before importing anything — so a hostile peer can only waste your bandwidth, never install a bad package. Pulling from the swarm lightens the load on solnix.io; seeding what you have helps your neighbours. Both are opt-in (seeding exposes your IP to peers, so it is off by default — see Peer-to-peer distribution and Privacy & telemetry).

Why this is secure and self-governing

  • Trust is reproducibility, not opinion. The only vote that counts is “I built it and got the same bytes.” That is Sybil-proof: fake identities can’t reproduce malicious bytes.
  • One signer, every time. Everything served is signed by solnix.io after its validation gate. Community and BitTorrent change discovery and delivery, never the trust root.
  • The client always checks the signature before importing, so a compromised delivery path is a bandwidth nuisance, nothing more.
  • Disagreement is an alarm. A single hash mismatch where others agree is investigated, not averaged away; suspect objects are quarantined for forensics, never silently dropped.
  • Keys are revocable, fast. Builder and proposer keys can be revoked and a re-quarantine sweep run; clients fetch the revocation list.
  • No personal data. Proposer keys are self-generated handles, attestations use key-ids or rotating nonces, and solnix.io never stores swarm IPs.

The aim is a cache that the whole community builds, delivers, and helps govern — fast, resilient, with no single point of failure in delivery — while remaining impossible for a bad actor to poison, because trust rests on independently reproducible bytes and a single, auditable signer.

The full technical design is in the infra repository: docs/design/community-build-federation.md and docs/design-p2p-trust-validation.md.

Privacy, telemetry & the community pulse

Participation should be private by default and deliberate. The reviewed server code now enforces a minimal usage-event contract for new writes. This is not a claim that the change is deployed or that historical data was cleaned.

If you opt into browser peer-to-peer sharing, peers can see your IP address. See P2P distribution for its controls and limitations.

What new telemetry writes retain

POST /telemetry accepts at most 4 KiB of strict flat EDN or JSON, with exactly three string fields: kind, attr, system. Kind must be in_use, installed or transferred; attribute and system must be an exact pair in the public package registry. The server stores those canonical values and its own timestamp and day. It does not retain submitted raw EDN/JSON (the legacy edn column gets constant empty text), region (NULL), identifiers or nonces. Unknown, duplicate, nested, missing and malformed fields are rejected, not silently persisted.

X-Region, X-Real-IP and X-Forwarded-For are ignored by this ingest. This is not evidence that connection IPs are absent from edge/network logs. Application request-parameter and query-bind logging is disabled on this write path; database and proxy logging configuration still needs review before deployment.

An anonymous global database quota admits at most 100 well-formed attempts per minute across API replicas, including unknown package pairs. There is no per-client identifier: one source can consume the quota or submit repeated events. This bounds writes, not Sybil attacks, people, machines or deduplicated daily use. Malformed requests are body-bounded but do not consume database quota; network request floods need separately managed ingress limits.

Invalid input returns 400, oversized bodies 413, global quota exhaustion 429, and actual database failures 503. Only a committed event receives 200. Legacy build herd_signal and raw-body internal writers fail closed; verified build evidence stays separate from usage events.

Historical raw EDN and caller-supplied regions may remain. No deletion, historical sanitization, retention job or production deployment is included. A separate 30-day retention proposal covers events, historical PII, backups and logs.

The solnix.privacy.enable master switch

The intended client contract below is private by default. The server review did not verify the client implementation or delivery behavior; these settings are not evidence that the current ingest is privacy-safe. Check your client implementation before relying on them. In this contract, true means fully private — no phone-home:

Note the inversion — this reads backwards. solnix.privacy.enable = true (the default) means NO data is sent. To join the community pulse you set it to false. Setting enable = false turns telemetry on, not off. We know this is a footgun; a positively-named solnix.telemetry.enable (default false) is planned to replace it.

solnix.privacy.enable = true;   # DEFAULT: fully private, phone-home OFF

A machine whose config never touches this stays completely private. Nothing is sent, nothing is shared.

To opt into the community pulse, set it to false. The individual features then default on, and you can pare any of them back:

solnix.privacy.enable = false;        # opt into the community pulse

# with privacy off, these default true — override any individually:
solnix.telemetry.enable          = true;   # group: all phone-home
solnix.telemetry.census.enable   = true;   #   platform / active-user census
solnix.telemetry.packages.enable = true;   #   transferred / installed / in-use
solnix.cache.seed.enable         = true;   # P2P: seed built packages (BitTorrent)
solnix.site.p2p.enable           = true;   # P2P: browser WebRTC site sharing

The effective rule, in plain language: a feature is active only when the master switch is off and its group is on and the feature itself is on — (not privacy.enable) && telemetry.enable && <feature>.enable. The master switch always wins. Someone who never touches config is fully private; someone who opts in gets everything, then can turn off any piece.

See Peer-to-peer distribution for cache.seed and site.p2p.

Public aggregates and proposed safeguards

The metrics changes expose 30-day reported usage-event counts, not numbers of people or machines. Public count fields below five events are suppressed. Five events can all come from one source: this is not k-anonymity of five machines. Ranking still uses the existing weighted score, so count suppression is not a guarantee against inference from rank or inclusion.

Pulse reports rollup refresh time when known, not upstream inventory freshness. Unique-user totals are unmeasured. Small or missing regional buckets do not prove zero usage. Regional buckets can reflect historical, untrusted data only; new writes supply no region. Public metrics views expose aggregates, not raw bodies.

Edge-derived coarse regions, daily deduplication, and machine-based anonymity were design proposals, not implemented guarantees. No rotating nonce or new identifier is introduced by these fixes. Retention limits and any removal of previously retained raw bodies require separate approval.

Both EDN and JSON are supported, posted to https://search.solnix.io/telemetry, for example:

{:kind "in_use" :attr "hello" :system "x86_64-linux"}

The example pair must actually exist in the public registry. No client timestamp, region, census, nonce, personal field or store path is accepted.

Why report usage

Reported events can help identify packages receiving use or installation reports. They cannot establish community size or growth in distinct users. Participation should be deliberate and private by default; enforceable ingest safeguards must come before an unconditional privacy promise.

Where to see the results

  • Community pulse: reported package events, regional event aggregates and rollup refresh time, not an active-machine census.
  • Package search: popularity combines reported usage events and dependency information; it is not a count of users.

Further reading & resources

Solnix documents what is specific to Solnix; for illumos and Nix themselves, the canonical upstream material is excellent and we point at it rather than duplicate it. This is a curated reading list in the style of the SmartOS “illumos and SmartOS basics” page: the books, manuals, and sites worth knowing, grouped by topic, plus the solnix-specific resources.

Many of these describe Solaris/illumos as a general platform. The commands and concepts (SMF, ZFS, DTrace, zones, MDB, boot environments) apply directly to Solnix, which is an illumos distribution — Solnix changes how the system is built and activated (Nix), not how these subsystems work.

illumos itself

  • illumos.org — the project home: news, downloads, the distribution list.
  • illumos documentation — the docs this handbook’s structure and tone are modeled on (features, user guide, developer guide).
  • illumos manual pages — the authoritative reference for every command and subsystem below.
  • Solnix man pages — the man pages that ship with the packages actually in the binary cache, browsable A–Z by package and section (like manned.org, for Solnix). Coverage is early and grows as more packages land; for anything not yet here, the upstream illumos man pages are the reference. Every package in search also links straight to its man pages.
  • illumos-gate — the source tree Solnix inherits its kernel and load-bearing userland from. See How Solnix is built.
  • The illumos Developer’s Guide — building and contributing to the gate.

Basic system administration

Not yet documented (known gaps)

Accurate detail on these is thin in this handbook today; they are real illumos topics worth a page as Solnix matures. Listed here so they aren’t lost:

  • RBAC / privileges in depth — roles, profiles, authorizations, and the full privilege set. Briefly covered in illumos features (pfexec, least-privilege); a dedicated walkthrough is a gap. Reference: rbac(7), privileges(7), pfexec(1).
  • Kernel modules — modinfo, modload/modunload, add_drv, and how the gate’s kernel modules load. Not yet written up; relevant once Solnix builds kernel bits. Reference: modinfo(8).
  • FMA in depth — partly covered in illumos features and Debugging (fmadm faulty, fmdump); the diagnosis engine and event protocol are a gap.
  • pkgsrc — the package system SmartOS and some other illumos distributions use, and the thing Solnix replaces with Nix. Mentioned in the history; a comparison page is a gap.

Performance, profiling, and programming (DTrace)

Kernel and debugging

Nix and NixOS

solnix-specific

History: from SunOS to Solnix

Solnix did not appear from nowhere. It is the newest link in a chain that runs back more than forty years, through some of the most influential operating- system engineering ever done. Knowing the lineage makes the rest of this handbook click into place — why the commands look the way they do, why ZFS and DTrace and zones all live in one coherent system, and what Solnix is (and isn’t).

The thread that connects all of it is a single idea that keeps recurring in this story: that systems software is most valuable when it is shared — read, criticized, improved, and carried forward by more hands than any one company can hire. That idea is older than Sun, older than BSD; it runs back to the research labs where Unix was born and to a university that decided the right thing to do with great code was to give it away. Solnix is a late inheritor of that conviction, and this chapter traces how the conviction (and the code) travelled from AT&T’s Unix room to a laptop running solnix-rebuild today.

SunOS — the BSD years, and the AT&T / Berkeley roots (1970s–1980s)

To start with SunOS is to start one generation too late. The real root is AT&T Unix, written at Bell Labs beginning in 1969 by Ken Thompson and Dennis Ritchie (with Rudd Canaday, Brian Kernighan, Doug McIlroy, and Joe Ossanna shaping its tools and philosophy). Unix was small, composable, and — crucially for everything that followed — written mostly in C, so it could move between machines. Because a 1956 antitrust consent decree barred AT&T from selling software, Bell Labs licensed Unix, source included, to universities for a nominal fee. That accident of regulation is why Unix spread through academia instead of staying a Bell Labs secret.

That early culture of shared source did not last on its own — it had to be fought for, and the fight produced the ideas and licenses that Solnix depends on today. In 1983 Richard Stallman announced the GNU Project (“GNU’s Not Unix”) to build a complete, free Unix-compatible system after watching proprietary licensing lock away code that had once been shared; in 1985 he founded the Free Software Foundation (FSF) and later wrote the GNU General Public License (GPL), whose copyleft — you may use and modify, but derivatives must stay free — became the legal engine of the free-software movement. GNU’s tools (GCC, Emacs, bash, coreutils, and the rest) are the userland most Unix-like systems, Linux included, were built from, and they are the GNU/BSD tools a Solnix user still finds on PATH. When Linus Torvalds released the Linux kernel in 1991 under the GPL, it was GNU’s userland and GNU’s license that made it a usable, legally durable system — the “GNU/Linux” pairing Stallman asks us to name in full. Solnix sits on the other branch of that same story (the illumos kernel rather than Linux), but it inherits the movement’s central premise: that the source should travel with the software. The licensing arguments that shaped OpenSolaris’s CDDL two decades later (below) are a direct continuation of the debate Stallman started here.

The university that did the most with it was the University of California, Berkeley. Starting in the mid-1970s, Berkeley’s Computer Systems Research Group (CSRG) turned its AT&T license into the Berkeley Software Distribution (BSD) — at first add-on tools, then a near-complete reworking of the system. Bill Joy, then a Berkeley graduate student, was the central figure: he wrote the vi editor and the C shell (csh), assembled the early BSD releases, and — most consequentially — led the integration of TCP/IP networking and the sockets API into 4.1c/4.2BSD under a DARPA contract, giving Unix the network stack that would carry the Internet. Marshall Kirk McKusick designed the Berkeley Fast File System (FFS) and later shepherded CSRG and the BSD lineage for decades; Sam Leffler, Keith Bostic, Mike Karels, and Özalp Babaoğlu (author of early Unix virtual-memory work) were among the others whose names recur in the BSD changelogs. Berkeley also pushed Unix toward virtual memory, reliable signals, and the long demand-paged-VM tradition that Sun’s engineers would later rebuild.

In 1982 Bill Joy left Berkeley to co-found Sun Microsystems, and he brought the BSD sensibility with him. Sun’s first workstations ran SunOS, a Unix built directly on 4.xBSD: bsd-style tooling, the Fast File System, sockets and TCP/IP, vi and csh — tuned for Sun’s Motorola- and later SPARC-based hardware, and extended by Sun with NFS (the Network File System, which Sun published as an open protocol) and the first serious workstation virtual-memory and VFS architecture. Through the 1980s SunOS was a BSD system in all but name, and it set the house style — networked, graphical, developer-friendly — that Solaris, illumos, and Solnix still carry. This is the true root of the family tree: Solnix is, at bottom, a descendant of AT&T Unix as reimagined at Berkeley and commercialized at Sun.

SunOS 5 / Solaris — the SVR4 rewrite (1992)

In 1992 Sun made a decisive break — and it was a wrenching one, because it meant setting aside the pure-BSD system its own users loved. Sun partnered with AT&T itself to co-develop System V Release 4 (SVR4), explicitly intended as the unification of the industry’s two great Unix branches: AT&T’s commercial System V and Berkeley’s BSD. SVR4 folded in the best of both — BSD’s sockets, FFS (as UFS), job control, and csh; System V’s STREAMS, the Service Access Facility, shared memory and the SysV IPC suite, and the /usr and packaging conventions — into one standard. Sun shipped its implementation as SunOS 5, marketed as Solaris 2. (This is the source of the enduring confusion: “SunOS” became the kernel/version string uname reports — SunOS 5.x — while “Solaris” was the product brand. illumos still answers SunOS to uname today, and so does Solnix.)

The migration was painful and famous: longtime SunOS 4 (BSD) users had to relearn packaging, init, and device naming, and Sun maintained a BSD-compatibility layer for years to ease the transition. But the SVR4 bet is why the modern system looks the way it does. This heritage is why illumos — and therefore Solnix — uses SVR4 conventions: the /usr layout, the SVR4 packaging model that later evolved into IPS, the STREAMS-derived networking and device frameworks, the service and driver interfaces, and much of the userland shape a Linux admin finds slightly unfamiliar. Solaris was, from 1992 on, a System V system with deep Berkeley blood — exactly the hybrid Solnix inherits.

The Solaris innovations (late 1990s–2000s)

Over the next fifteen years Solaris stopped merely unifying other people’s ideas and became a laboratory that generated its own — a run of operating-system research, shipped in a production OS, that the rest of the industry spent the following decade imitating. Sun’s willingness to fund deep kernel work (and to hire and keep the engineers who could do it) made Solaris the place where several now-ubiquitous ideas were first made real at scale. The ones Solnix inherits directly:

  • ZFS — a pooled-storage filesystem and volume manager with end-to-end checksums, copy-on-write transactions, cheap snapshots, clones, and built-in RAID. It erased the decades-old split between “filesystem” and “volume manager” and made silent data corruption detectable. See ZFS storage.
  • DTrace — safe, production-grade dynamic tracing of the whole system, kernel and userland, from one scripting language, with zero overhead when not enabled. It changed how a generation of engineers debugs live systems. See DTrace.
  • SMF — the Service Management Facility: a dependency-aware init system and service supervisor with a fault boundary, automatic restart, and a queryable repository — years before Linux’s init debate settled on anything comparable. See SMF services.
  • Zones — OS-level virtualization (lightweight, near-zero-overhead containers with their own process table, network, and filesystem view) years before Linux containers existed. See Zones.
  • Crossbow — network virtualization in the kernel: virtual NICs, virtual switches, flows, and bandwidth controls, so a single host could carve up its networking the way Zones carved up the OS. See Networking (Crossbow).
  • FMA — the Fault Management Architecture: hardware and software errors diagnosed into faults with stable message IDs, so a failing DIMM or disk produces an actionable, documented event instead of a cryptic panic. See illumos features.

Any one of these would have been a notable system in its own right; most research groups would build a career on a single one. Solaris shipped all of them, integrated and supported, in one coherent OS — which is exactly the platform Solnix builds on, and exactly why a project this small can offer capabilities this large: we did not have to invent them, only to package them.

Stewardship: packaging and release discipline at Sun’s peak

The technology was only half of what made Solaris formidable; the other half was stewardship — the unglamorous discipline of versioning, packaging, and predictable releases, done well for over a decade. Solaris’s pkg/SVR4 packaging (and later the network-based IPS, the Image Packaging System built for OpenSolaris) was genuinely ahead of its time: packages with real dependency metadata, cryptographic verification, a system-wide notion of a coherent, versioned “this is a supported configuration,” and — with ZFS — the ability to snapshot the whole system before an update and roll back cleanly if it went wrong. (If that sounds familiar, it should: it is the same instinct Solnix now serves with Nix generations and ZFS boot environments.) Around it Sun ran a model of release stewardship that enterprises could set their watches by — a clear Solaris 2.x → 7 → 8 → 9 → 10 cadence, long support lifecycles, binary compatibility guarantees so strict that applications built for an early Solaris release would still run years later, and a single, accountable owner answering for the whole stack.

That single-owner model is the “one throat to choke” that enterprise buyers prize: one vendor to certify the hardware, ship the patches, honor the support contract, and take the blame. It is a real strength — as long as that owner is healthy, competent, and interested in leading. Sun, at its peak, was all three, and Solaris was arguably the best-stewarded commercial Unix in the industry. But the model has a single point of failure that is not technical at all: the owner’s will. When Sun faltered and was acquired, the same concentration that had made Solaris dependable became the thing that could switch it off — which is exactly what the next sections describe.

OpenSolaris — the open-sourcing (2005)

In 2005 Sun did something almost no commercial Unix vendor had been willing to do: it released the source of a shipping, flagship, revenue-bearing operating system. Under the newly-written CDDL (Common Development and Distribution License), the OpenSolaris project put the kernel, ZFS, DTrace, SMF, Zones, FMA, and most of the core userland into public, buildable source. For the first time anyone could read how production ZFS actually worked, build the kernel from source, send fixes, and ship a derivative. It was a genuine inflection point — the moment the technology stopped being Sun’s alone and became the commons that Solnix now draws from.

The release was also a deliberate community-building act, not just a code drop. Sun stood up mailing lists and discussion forums, opened its bug database, published the build tools and the “OS/Net” (ON) consolidation gate, created the OpenSolaris Governing Board, and actively courted outside developers and downstream distributions. Within a couple of years a real ecosystem had formed: multiple distributions, a port to other hardware, and a steady inflow of external contributors. The CDDL (file-level copyleft, deliberately not GPL-compatible) was itself a considered choice — it let Solaris code be shared openly while remaining practical for a company with patents and a commercial product to protect. That same license is why illumos is open today, and why the whole lineage below 2005 is auditable source rather than legend.

Sun was choosing a license at a moment when open licensing had matured well beyond the original GPL. The Creative Commons had been founded in 2001 by Lawrence Lessig, Hal Abelson, and Eric Eldred (growing out of Lessig’s free-culture work and his Eldred v. Ashcroft copyright challenge), and by 2005 its share-with-conditions model had made the very idea of a spectrum of public licenses mainstream — not just for software but for writing, images, and data. (This handbook and the Solnix docs are themselves offered in that spirit.) The CDDL was Sun’s own point on that spectrum: based on Mozilla’s MPL, file-scoped, patent-aware. The broader lesson of the era — that “open” is a set of carefully chosen terms, not a single switch — is one Solnix takes seriously in how it signs, licenses, and attributes everything it ships.

The world OpenSolaris was born into — and where it was headed

To understand why OpenSolaris mattered, place it in 2005. Linux (kernel 2.6) was ascendant and improving fast, but it was still catching up on serious storage and observability: there was no production answer to ZFS (btrfs would not begin until 2007 and stayed experimental for years), no DTrace (SystemTap was young and fragile, and strace/gdb were no substitute for whole-system tracing), and kernel-native containers were years away (LXC landed around 2008, Docker in 2013, both clearly in the lineage of ideas Zones had already shipped). The BSDs were healthy and genuinely open — FreeBSD 5/6, NetBSD, OpenBSD, and the young DragonFly BSD — technically respected and in some areas ahead, but without ZFS or DTrace at the time; tellingly, FreeBSD would soon import both directly from OpenSolaris. Proprietary Unix was in visible retreat: SGI’s IRIX, DEC/HP’s Tru64, and HP-UX were winding down, IBM’s AIX was holding on in enterprise shops, and the broader “Unix wars” had largely burned out. Apple’s Mac OS X had just begun its Intel transition on a Mach/BSD foundation. Microsoft’s Windows Server 2003 owned the corporate datacenter by unit count.

Against that backdrop OpenSolaris was genuinely unique: the only open-source system that shipped ZFS, DTrace, SMF, Zones, Crossbow, and FMA together, in one integrated, production-grade, enterprise-supported OS. Nothing else, open or closed, combined that specific set.

Its intended future was correspondingly ambitious. Sun positioned OpenSolaris as the open foundation of a thriving, Linux-style ecosystem. The flagship effort was Project Indiana, led by Ian Murdock — the founder of Debian, hired by Sun exactly for his distribution-building credibility — which shipped as OpenSolaris 2008.05: a friendly, single-CD, live-installable desktop-and-server distribution with a modern, network-based package manager (IPS, the Image Packaging System) and a GNOME desktop, deliberately approachable to Linux users. The plan was for the open codebase and the commercial Solaris to advance together, with the outside community as a first-class participant rather than an afterthought — Sun even shipped the commercial Solaris 10 and 11 express builds from the same open gate. ZFS and DTrace were already spreading to other operating systems, and OpenSolaris was meant to be the hub of that diffusion: the reference implementation everyone else learned from. That trajectory was cut short in 2010 — but, as the rest of this chapter shows, the fork preserved both the technology and a surprising amount of the original intent.

The family tree since open source

Everything below the 2005 open-sourcing is one tree. The last open OpenSolaris drop became the illumos gate, and every living illumos system — including Solnix — descends from it. Oracle Solaris is the one closed branch off to the side.

The illumos / Solaris family tree since open source (2005) A branching diagram: SunOS (BSD) leads to Solaris (SVR4), then OpenSolaris in 2005. In 2010 Oracle closes Solaris on one branch; the community forks the last open drop into illumos, which branches into OpenIndiana, OmniOS, SmartOS, Tribblix, and Solnix. SunOS (BSD)early 1980s Solaris / SunOS 5SVR4, 1992 OpenSolaris (CDDL)open-sourced 2005 Oracle Solaris 11+closed again, 2010 illumos gatecommunity fork, 2010 OpenIndiana OmniOS SmartOS Tribblix SolnixNix on illumos
Green = open; red = closed (Oracle Solaris); gold = Solnix. Every open branch shares the 2010 illumos gate as its upstream.

Text version of the same tree (for screen readers / plain text):

SunOS (BSD, early 1980s)
  └─ Solaris / SunOS 5 (SVR4, 1992)
       └─ OpenSolaris (CDDL, open-sourced 2005)
            ├─ Oracle Solaris 11+ ............ CLOSED again (2010)
            └─ illumos gate ................. community fork of the last
                 │                             open drop (2010), still open
                 ├─ OpenIndiana   (desktop/server; the direct successor)
                 ├─ OmniOS        (minimal, stable server)
                 ├─ SmartOS       (hypervisor; zones + LX-branded zones)
                 ├─ Tribblix      (retro, lightweight package manager)
                 └─ solnix        (Nix / NixOS module system on illumos)  ← this OS

Oracle closes Solaris (2010)

Oracle completed its acquisition of Sun Microsystems in early 2010, and the change in posture was swift. In August 2010 an internal memo leaked that laid out the new direction plainly: Solaris development would continue, but behind closed doors, with source released only after a binary shipped (if at all), under a restrictive license. The OpenSolaris Governing Board, seeing it had no partner left to govern with, dissolved itself. The regular open source drops simply stopped; the public onnv gate went quiet. Oracle shipped Solaris 11 in 2011 as a wholly proprietary product.

For the community that had spent five years building on the open code, this was an existential moment. Thousands of person-years of engineering — ZFS, DTrace, Zones, the whole integrated system — had been public and buildable, and overnight the upstream was gone. Many of the key Sun engineers also left in the wake of the acquisition, scattering to companies that would soon become central to the open story (notably Joyent, Nexenta, and Delphix). The question was no longer “how do we contribute upstream?” but “is there an upstream at all?” The answer had to be built from the last open bytes Sun had released.

The community forks: illumos (2010)

Rather than let the open codebase die, the community forked the last open OpenSolaris drop into a new project: illumos, announced by Garrett D’Amore (then at Nexenta) in August 2010 and quickly joined by many of the ex-Sun engineers. The name nods to illumination (and keeps the “-os” of the heritage), and to the ON (“OS/Net”) consolidation it descends from — the core kernel-plus-network userland gate that had always been the heart of Solaris.

The fork was not a simple copy. A handful of components in the OpenSolaris tree had never actually been open-sourced — Sun had shipped them as closed binaries inside the otherwise-open system (parts of the C library’s crypto, some drivers, assorted utilities). To make a fully free gate that could build without any Oracle-owned bits, the illumos project had to replace those closed pieces with new open implementations — painstaking, unglamorous work that was the difference between “mostly open” and “actually buildable by anyone.” The result became what this handbook calls the illumos gate: a fully open, community-maintained continuation of the OpenSolaris kernel and core userland, with no proprietary dependencies, that has been developed continuously ever since. See How Solnix is built.

Two things are worth stating plainly, because they are a common source of confusion. First, illumos is not Solaris and is not owned by Oracle — it is the open, living branch that forked before Oracle closed the gates; Oracle’s Solaris 11+ is the separate, closed branch. Second, the fork preserved not just code but continuity: the same engineers, conventions, uname string, and engineering culture carried straight across, so illumos is better understood as OpenSolaris-continued than as a from-scratch reimplementation. Solnix sits at the far end of that unbroken line.

With thanks — the people who made Solaris open

Solnix exists because, twenty years ago, a group of people fought to put this technology in the open and then kept it alive when its original owner walked away. Credit in a project like this is not a formality — it is the honest accounting of a debt. We wrote almost none of what makes this system remarkable; we are standing on the shoulders of the people named below (and many we have missed). It is right to name them.

Making OpenSolaris happen (2004–2005). Opening a shipping, commercial Unix was not inevitable — it took engineers, lawyers, program managers, and executives inside Sun who believed the code belonged to the community, and who were willing to do the slow, political, unglamorous work of actually getting it released. Among many:

  • Jonathan Schwartz and Scott McNealy — the Sun executives (CEO and chairman/CEO) who publicly committed Sun to open-sourcing Solaris and defended the decision internally when it would have been easier not to.
  • Danese Cooper, Sun’s “open-source diva” and a central figure in Sun’s open-source strategy, and the legal/licensing team who navigated the minefield of releasing patent-encumbered enterprise code — producing the CDDL so the source could ship cleanly and defensibly.
  • Claire Giordano, who helped lead and shape the OpenSolaris community effort — the programs, the launch, and the connective tissue between Sun and the outside developers — the kind of community-and-communications work that determines whether an “open” project is open in practice or only on paper.
  • Stephen Hahn and Bart Smaalders, who designed and built IPS (the Image Packaging System) for the OpenSolaris distribution — the modern, network-based package manager Project Indiana needed.
  • The ZFS team — Jeff Bonwick and Matt Ahrens foremost (with Bill Moore and others) — whose filesystem became the single most influential thing OpenSolaris gave the world, and who argued for and supported its open release.
  • The DTrace authors — Bryan Cantrill, Mike Shapiro, and Adam Leventhal — who built safe production tracing, evangelized it relentlessly, and then helped carry the community forward after the acquisition.
  • Mike Shapiro again, and the engineers behind SMF and FMA; the Zones team led by Andrew Tucker (with the later resource-management and branded-zones work); and the broad OS/Net (ON) consolidation engineering organization whose collective work quite literally is the gate.
  • Ian Murdock — founder of Debian — who led Project Indiana, the effort to turn OpenSolaris into an approachable, Linux-friendly distribution. (Murdock died in 2015; the distribution model he pushed for lives on in every illumos distro, this one included.)

Sun engineers across the longer arc. Beyond the 2005 launch, Solaris and its open descendants carry the fingerprints of many more Sun (and ex-Sun) engineers, before and after the open-sourcing:

  • Bill Joy — Sun co-founder, and before that the Berkeley student who gave Unix vi, csh, and its TCP/IP networking (see the BSD section above); the single clearest human link between Berkeley Unix and Sun.
  • Andy Bechtolsheim and Vinod Khosla — Sun’s other co-founders, whose hardware and company made the software possible.
  • James Gosling — of Java fame, but a deep Sun systems figure whose presence shaped the engineering culture that produced this work.
  • Rich McDougall and Jim Mauro — whose Solaris Internals books documented the kernel so thoroughly that outsiders could actually learn it.
  • Casper Dik, Alan Hargreaves, and the many kernel and performance engineers whose names fill the SunSolve archives and the ON changelogs.
  • Dan Price, Jerry Jelinek, and the Zones/branded-zones engineers whose work later made LX-branded zones (Linux binaries on the illumos kernel) possible — see LX-branded zones.

Keeping it alive (2010 and after). When Oracle closed the gates, OpenSolaris would have become a dead archive without the people who forked it and then sustained it for over a decade:

  • Garrett D’Amore, who launched illumos, replaced the last closed-source components Oracle had never opened, and did the founding organizational work so a fully-free gate could exist, build, and attract contributors.
  • The companies that gave ex-Sun engineers a home and funded continued illumos work — Nexenta (ZFS storage), Joyent (cloud + SmartOS, under the renewed leadership of Bryan Cantrill), and Delphix (where Matt Ahrens continued core ZFS/OpenZFS work).
  • The distributions that carried the gate into production and still do: OpenIndiana, OmniOS (and the community OmniOSce after Oracle-era sponsorship changed), SmartOS (Joyent, now MNX), and Tribblix (Peter Tribble, a one-person labor of love).
  • The OpenZFS community, which reunited the ZFS forks across illumos, FreeBSD, Linux, and macOS into one shared codebase — arguably the clearest proof that the open release worked.
  • Everyone who, for fifteen years since, has kept the gate compiling, the drivers current, the man pages honest, and the knowledge documented. Solnix is downstream of all of it.

If you worked on any of this and we’ve under-credited you — or worse, missed you — that’s our error, not a slight. Tell us (see Contributing) and we’ll fix it. The honest summary bears repeating: we wrote almost none of what makes this system remarkable. We packaged it with Nix, and we are grateful to stand on it.

What OpenSolaris gave the world — its influence elsewhere

The truest measure of OpenSolaris is not the distributions that descend from its gate, but how much of it other systems took, mimicked, re-implemented, or were plainly inspired by. For a project whose commercial owner abandoned it, the diffusion is remarkable — several of its ideas are now simply how computing is done, often on systems whose users have never heard the name “Solaris.”

ZFS — adopted almost everywhere, mostly as literal code.

  • FreeBSD imported ZFS directly from OpenSolaris (2007) and made it a first-class, officially-supported filesystem — the CDDL source dropped straight in. For years FreeBSD was the most prominent production home of ZFS outside Solaris.
  • Linux gained ZFS via ZFS on Linux (an out-of-tree module, kept separate precisely because CDDL and GPL don’t mix) — widely used despite the licensing awkwardness, and the backbone of appliances like TrueNAS (formerly FreeNAS) and countless storage boxes.
  • macOS had an official Apple ZFS port in progress (later cancelled), kept alive by the community as OpenZFS on OS X.
  • All of these eventually converged into OpenZFS, a single shared codebase spanning illumos, FreeBSD, Linux, and macOS — the OpenSolaris filesystem, now the de-facto open standard for serious storage, maintained in common by the very ecosystems it spread to.
  • Even systems that did not adopt ZFS were pushed by it: btrfs on Linux and Microsoft’s ReFS are both clear responses to the pooled-storage, checksummed, copy-on-write model ZFS proved.

DTrace — reimplemented and chased for fifteen years.

  • FreeBSD and NetBSD ported DTrace directly from the OpenSolaris source.
  • macOS shipped DTrace (Apple built Instruments partly on top of it), as did (briefly) QNX and others.
  • Oracle ported DTrace to Oracle Linux — ironically re-opening the technology it had closed in Solaris.
  • On mainline Linux, DTrace’s influence is written all over the modern observability stack: SystemTap chased it first, and today eBPF — with tools like bpftrace whose language is deliberately DTrace-like — is in large part the Linux world finally building what DTrace demonstrated was possible. Engineers who learned tracing on DTrace built much of it.

Zones — the container idea, shipped first.

  • OpenSolaris Zones (2004) were production OS-level virtualization years before Linux had anything equivalent. The lineage of ideas runs through LXC (2008) to Docker (2013) and the entire container industry. The implementations are independent, but Zones demonstrated — at scale, in production — that lightweight per-application OS virtualization was the right model, and Joyent ran a public cloud on Zones for years to prove it.

SMF, FMA, and the rest.

  • SMF’s dependency-aware, self-healing, repository-backed service model prefigured much of what the Linux world argued about and eventually got with systemd — a convergent answer to the same problem SMF had already shipped.
  • FMA’s structured, message-ID’d fault diagnosis influenced how later systems think about turning raw errors into actionable, documented events.
  • Crossbow’s in-kernel network virtualization (VNICs, virtual switches, flows) anticipated the virtual-networking primitives that cloud and container networking now take for granted.

Taken together: a storage layer that became the open standard, a tracing model the whole industry rebuilt, and a virtualization idea that seeded an entire industry. OpenSolaris may have “lost” commercially, but as a set of ideas it won comprehensively — and Solnix gets to run the originals, integrated, rather than the imitations.

The illumos distribution ecosystem

Just as Linux is a single kernel that dozens of distributions package in their own way, illumos is one gate that several distributions build on — each taking the identical kernel-and-core-userland and differing mostly in packaging, defaults, release cadence, and intended use. Knowing the siblings helps place Solnix among them:

  • OpenIndiana — the most direct OpenSolaris successor and the general-purpose desktop/server distribution. It inherited Project Indiana’s IPS packaging and GNOME desktop and is the closest thing to “what OpenSolaris 2008.05 would have become.” If you want the traditional Solaris experience, open, this is it.
  • OmniOS (and the community-run OmniOSce) — a deliberately minimal, rock-stable server distribution with a conservative release model and long support windows. Built for people who want illumos as boring, dependable infrastructure — storage servers, hypervisors, appliances.
  • SmartOS (Joyent, now MNX) — a hypervisor-focused distribution that boots from RAM/USB and runs everything in zones. It pioneered the modern LX-branded zone — running unmodified Linux binaries on the illumos kernel via a Linux syscall-emulation layer (see LX-branded zones) — and powered a public cloud, proving illumos at serious scale.
  • Tribblix — a retro-flavored, intentionally lightweight distribution with its own minimal package manager (zap), largely the work of one person, Peter Tribble, and a reminder that an illumos distro can be small and personal.

Each takes the same gate and makes different trade-offs. Solnix is the newest sibling, and it makes the most unusual trade-off of all — described next.

Models of stewardship — and why Solnix chose a new one

Step back and the whole chapter is really a story about how software is governed, told through one codebase changing hands. It is worth naming the models explicitly, because Solnix is a deliberate choice among them.

The single-commercial-owner model (Sun’s Solaris) gives you coherence, accountability, and “one throat to choke” — and it works beautifully until the owner loses interest or capacity, at which point the same concentration becomes a kill switch. Oracle proved the downside in a single year.

Linux is the great natural experiment in the alternative, and its history is a survey of stewardship models tried, transformed, and sometimes abandoned. One kernel, many distributions, governed every which way: a benevolent-dictator kernel (Torvalds) over a foundation-funded commons (the Linux Foundation); a volunteer social contract (Debian, governed by its constitution and elected leader); a community edition feeding a commercial product (Fedora → RHEL; openSUSE → SLE); a purely commercial distribution that later had its community rug pulled (CentOS, redirected to Stream — a vivid repeat of the Solaris-under-Oracle lesson); and community forks born from exactly that betrayal (Rocky Linux, AlmaLinux). Some of these models thrived; some curdled the moment a commercial sponsor’s incentives shifted. The pattern is clear: governance, not technology, is what usually decides whether an operating system stays trustworthy over decades.

illumos chose the community-fork model out of necessity in 2010 — and kept the technology alive, which is no small thing. But honesty requires naming where that left it: OpenSolaris/illumos today is highly fragmented and lightly used. It is several small distributions sharing a gate, maintained heroically by a dedicated few, and it is no longer widely taken seriously as a choice for production servers or for the desktop. The engineering is still world-class; the adoption, reach, and momentum are not.

Solnix is a deliberate attempt to change that — by pairing the best technology in this story with a different model for everything around it. The bet is specific: take the genuinely remarkable OpenSolaris/illumos assets — ZFS, DTrace, SMF, Zones, Crossbow, FMA, the whole integrated kernel — and wrap them in the Nix model for building, distributing, and certifying software: reproducible packages, a signed binary cache, a trust model where what you install is provably what was reviewed, and atomic, rollback-able system generations. On top of that, a new community governance model (see Community build federation and Contributing): not one commercial throat to choke, and not an ad-hoc volunteer scramble either, but reproducibility-as-trust — many independent builders able to verify each other’s work, with a single transparent signing authority rather than a single corporate owner.

The Solnix team believes this is the best road forward for the assets in OpenSolaris/illumos: keep the irreplaceable kernel engineering, replace the fragile stewardship and dated packaging around it, modernize the rough edges, and — critically — bring device-driver support up to date, the single biggest thing standing between illumos and real desktop and server use today. The goal is unabashed: to make Solnix a genuinely good choice for a desktop or a server again, and to see adoption increase steadily as those rough edges are smoothed — for the benefit of everyone who ever depended on this lineage. The technology earned a second life; Solnix is an attempt to give it one.

And finally: Solnix

Solnix — the Solnix Operating System — is the newest illumos distribution, and it differs in one specific way: instead of a traditional package manager (IPS, or SmartOS’s pkgsrc), it uses Nix and the NixOS module system to build and manage the whole system declaratively. It is designed as a first-class OS across four CPU targets — x86_64, aarch64, RISC-V, and SPARC — for both server and desktop use, and optimized for virtualized hosting on the major cloud platforms. Each configuration change produces a new, atomically-activated system backed by a ZFS boot environment; rollback is instant.

To be precise about what Solnix is and isn’t:

  • Solnix is illumos — the same kernel, ZFS, DTrace, SMF, zones, Crossbow, and FMA described above — packaged and managed with Nix.
  • Solnix is not Linux. It does not use the Linux kernel, glibc, or systemd.
  • Solnix is not NixOS. It reuses NixOS’s evaluator and module system, but targets the illumos kernel and userland, not Linux.
  • Solnix is not Oracle Solaris. It descends from the open illumos branch, not Oracle’s closed product.

Status. Solnix is early — a first preview image just landed (see Introduction). The history above is real and settled; Solnix’s own place in it is just beginning.

Further reading