SYSTEMD.OFFLINE-UPDATES(7)

๐Ÿ’– systemd.offline-updates โ€” the manual page, but make it make sense ๐Ÿ’–

okay bestie, so this is systemd.offline-updates(7) โ€” it's the page that explains how to do "offline" system updates with systemd. pull up a chair, grab a strawberry ๐Ÿ“, and let's get into it.


โœจ NAME โœจ

systemd.offline-updates โ€” Implementation of offline updates in systemd


๐Ÿฆ‹ IMPLEMENTING OFFLINE SYSTEM UPDATES ๐Ÿฆ‹

So this page is literally telling you how to implement "offline" system updates with systemd. And when we say "offline" OS updates, we mean package installations and updates that get run while the system is booted into a special system update mode. Why? Because otherwise you get conflict drama between libraries and services that are currently running and the ones on disk. messy. ๐Ÿ™ˆ This whole document was inspired by this GNOME design whiteboard[1].

Here's the logic, step by step, no cap:

  1. The package manager gets the system updates ready by downloading all the (.rpm or .deb or whatever) packages to update off-line into a special directory /var/lib/system-update โ€” or another directory of the package/upgrade manager's choice, live your truth.
  2. When the user OK'ed the update, the symlink /system-update or /etc/system-update gets created, pointing to /var/lib/system-update (or wherever that directory with the upgrade files lives) and then the system is rebooted. And why is this symlink sitting in the root directory? Because we need to check for it very early at boot โ€” at a time where /var/ is not available yet. it's giving "root dir or it didn't happen". ๐Ÿ’…
  3. Very early in the new boot, systemd-system-update-generator(8) checks whether /system-update or /etc/system-update exists. If it does, it (temporarily and for this boot only) redirects โ€” i.e. symlinks โ€” default.target to system-update.target, a special target that pulls in the base system (i.e. sysinit.target, so that all file systems are mounted but little else) plus the system update units. iconic behaviour honestly.
  4. The system now continues to boot into default.target, and therefore into system-update.target. That target pulls in all system update units. Only one service should perform an update (peep the next point), and all the other ones should exit cleanly with a "success" return code and without doing anything at all. Update services should be ordered after sysinit.target so that the update starts after all file systems have been mounted. order matters, bestie. ๐Ÿซถ
  5. First step as an update service: check if the /system-update or /etc/system-update symlink points to the location used by that update service. If it doesn't exist, or it points to a different location, the service must exit without error. It is possible for multiple update services to be installed, and for multiple update services to be launched in parallel, and only the one that corresponds to the tool that created the symlink before reboot should perform any actions. Also, for the record: it is unsafe to run multiple updates in parallel. ๐Ÿ’€
  6. The update service should now do its job. If applicable and possible, it should create a file system snapshot, then install all packages. After completion โ€” regardless whether the update succeeded or failed โ€” the machine must be rebooted, for example by calling systemctl reboot. And on failure, the script should revert to the old file system snapshot (without the symlink).
  7. The update scripts should exit only after the update is finished. It is expected that the service which performs the update will cause the machine to reboot after it is done. And if system-update.target is successfully reached โ€” i.e. all update services have run โ€” and the /system-update or /etc/system-update symlink still exists, it will be removed and the machine rebooted as a safety measure. the cleanup era we love to see. โœจ
  8. After a reboot, now that the /system-update and /etc/system-update symlink is gone, the generator will not redirect default.target anymore, and the system now boots into the default target again. back to regularly scheduled programming, periodt.

๐Ÿ‘‘ RECOMMENDATIONS ๐Ÿ‘‘

  1. To make things a bit more robust, we recommend hooking the update script into system-update.target via a .wants/ symlink in the distribution package, rather than depending on systemctl enable in the postinst scriptlets of your package. More specifically: for your update script, create a .service file, without [Install] section, and then add a symlink like /usr/lib/systemd/system/system-update.target.wants/foobar.service โ†’ ../foobar.service to your package.
  2. Make sure to remove the /system-update and /etc/system-update symlinks as early as possible in the update script to avoid reboot loops in case the update fails. seriously. reboot loops are not the vibe. ๐Ÿ˜ญ
  3. Use FailureAction=reboot in the service file for your update script to ensure that a reboot is automatically triggered if the update fails. FailureAction= makes sure that the specified unit is activated if your script exits uncleanly (by non-zero error code, or signal/coredump). If your script succeeds, you should trigger the reboot in your own code, for example by invoking logind's Reboot() call or calling systemctl reboot. See org.freedesktop.login1(5) for details about the logind D-Bus API.
  4. The update service should declare DefaultDependencies=no, Requires=sysinit.target, After=sysinit.target, After=system-update-pre.target, Before=system-update.target and explicitly pull in any other services it requires. just lay it all out, bestie.
  5. It may be desirable to always run an auxiliary unit when booting into offline-updates mode, which itself does not install updates. To do this, create a .service file with Wants=system-update-pre.target and Before=system-update-pre.target and add a symlink to that file under /usr/lib/systemd/system-update.target.wants .

๐ŸŒธ SEE ALSO ๐ŸŒธ

systemd(1), systemd.generator(7), systemd-system-update-generator(8), dnf.plugin.system-upgrade(8)


๐Ÿ“ NOTES ๐Ÿ“

  1. GNOME design whiteboard https://wiki.gnome.org/Design/OS/SoftwareUpdates

and that's the whole page, bestie!! you ate. ๐ŸŽ€

this was systemd 262.1, from the SYSTEMD.OFFLINE-UPDATES(7) manual โ€” go forth and update offline, safely, with your symlinks removed early. mwah. ๐Ÿ’–๐Ÿฆ‹โœจ

๐Ÿ“ฆ 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