SYSTEMD.V(7)
๐
SYSTEMD.V(7) โ the systemd.v situation
okay so bestie, pull up a chair, because this page is about versioned resource directories and it's lowkey iconic once it clicks. This is the systemd.v manual, and yes we're getting into it.
โจ NAME โจ
systemd.v โ a directory full of versioned resources, aka the glow-up folder
๐ธ DESCRIPTION ๐ธ
So here's the vibe: in a bunch of different places, systemd components will let you hand them paths whose trailing components end in the ".v/" suffix, and that suffix means "this points at a directory". When that happens, the component doesn't just shrug โ it goes looking inside that directory for suitable files, does a version comparison, and opens the newest one it finds (newest by version, obviously). This whole thing has been available since version v256.
Specifically, bestie, there are two expressions supported:
- When you're looking for files with a suffix
.SUFFIX, and a path...PATH/NAME.SUFFIX.v/is specified, then every file matching...PATH/NAME.SUFFIX.v/NAME_*.SUFFIXgets enumerated, filtered, sorted, and the newest file gets used. The primary sorting key is the variable part โ that's the bit indicated by the wildcard"*". - When a path
...PATH.v/NAME___.SUFFIXis specified (meaning: the penultimate component of the path ends in".v"and the final component contains a triple underscore), then every file matching...PATH.v/NAME_*.SUFFIXgets enumerated, filtered, sorted, and the newest file gets used โ again, by the variable part, again indicated by that wildcard"*".
To make this make sense, picture a directory /var/lib/machines/mymachine.raw.v/ that's populated with three files:
mymachine_7.5.13.rawmymachine_7.5.14.rawmymachine_7.6.0.raw
Now invoke a tool like systemd-nspawn(1) with a command line like this:
# systemd-nspawn --image=/var/lib/machines/mymachine.raw.v --boot
and it would automatically be resolved to the equivalent of:
# systemd-nspawn --image=/var/lib/machines/mymachine.raw.v/mymachine_7.6.0.raw --boot
A whole lot of systemd's functionality that expects a path to a disk image or an OS directory hierarchy supports this ".v/" versioned directory mechanism. For example: systemd-nspawn(1), systemd-dissect(1), or the RootDirectory=/RootImage= settings of service files (see systemd.exec(5)).
Wanna resolve".v/"paths straight from the command line, like for shell scripts? Use thesystemd-vpick(1)tool. That's literally what it's for. ๐ซถ
๐ฆ FILTERING AND SORTING ๐ฆ
The variable part of the filenames inside those ".v/" directories gets filtered and compared primarily with a version comparison, implementing the UAPI.10 Version Format Specification[1]. But bestie, there are extra rules on top, and they matter:
- If the variable part is suffixed by one or two integer values ("tries left" and "tries done") in the formats
+LEFTor+LEFT-DONE, then those indicate usage attempt counters. The idea: every single time before a file is attempted to be used, its "tries left" counter gets decreased and the "tries done" counter gets increased โ and yeah, that's done simply by renaming the file. When the file is successfully used (which for an OS image could mean: it successfully booted), the counters are removed from the file name, signaling that this file has been validated to work correctly. This mechanism mirrors the boot assessment counters defined by Automatic Boot Assessment[2]. Any filenames with no boot counters, or with a non-zero "tries left" counter, are sorted before filenames with a zero "tries left" counter. - Preceding those use counters (if they're specified at all), an optional CPU architecture identifier may be specified in the filename, separated from the version with an underscore. It's as defined in the architecture vocabulary of the
ConditionArchitecture=unit file setting, documented over insystemd.unit(5). Files whose name indicates an architecture that isn't supported locally get filtered out and are not considered for the version comparison. bye ๐ - The rest of the variable part is the version string. That's it, that's the whole thing.
Or, in other words, the files inside ".v/" directories should follow one of these naming structures:
NAME_VERSION.SUFFIXNAME_VERSION_ARCHITECTURE.SUFFIXNAME_VERSION+LEFT.SUFFIXNAME_VERSION+LEFT-DONE.SUFFIXNAME_VERSION_ARCHITECTURE+LEFT.SUFFIXNAME_VERSION_ARCHITECTURE+LEFT-DONE.SUFFIX
๐ EXAMPLE ๐
Okay here's a bigger one, extending the example from before. Picture the directory /var/lib/machines/mymachine.raw.v/, populated with the following files:
mymachine_7.5.13.rawmymachine_7.5.14_x86-64.rawmymachine_7.6.0_arm64.rawmymachine_7.7.0_x86-64+0-5.raw
Now run this on an x86-64 machine:
$ systemd-vpick --suffix=.raw /var/lib/machines/mymachine.raw.v/
This would resolve the specified path to /var/lib/machines/mymachine.raw.v/mymachine_7.5.14_x86-64.raw.
Explanation, because I know you're squinting at it: even though mymachine_7.7.0_x86-64+0-5.raw has the newest version, it is not preferred, because its tries left counter is zero. And even though mymachine_7.6.0_arm64.raw has the second newest version, it's also not considered here, because we're operating on an x86_64 system and that image is intended for arm64 CPUs. Finally, the mymachine_7.5.13.raw image isn't considered either, because it's older than mymachine_7.5.14_x86-64.raw. slay ๐
๐ SEE ALSO ๐
systemd(1), systemd-vpick(1), systemd-nspawn(1), systemd-dissect(1), systemd.exec(5), systemd-sysupdate(8)
๐ NOTES ๐
- UAPI.10 Version Format Specification https://uapi-group.org/specifications/specs/version_format_specification/
- Automatic Boot Assessment https://systemd.io/AUTOMATIC_BOOT_ASSESSMENT/
and that's the whole page bestie ๐ this was systemd 262.1 energy, SYSTEMD.V(7), no cap โ go forth and let your versioned directories sort themselves out, you've got this ๐โจ
๐ฆ where this page comes from
- arch rolling: systemd 262.1-1 ยท LGPL-2.1-or-later AND CC0-1.0 AND GPL-2.0-or-later AND MIT-0
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms