General Question About Updates

Yes, via TTY, you should have the output of the update process left visible even if the updater crashes. I have had the pamac GUI crash bad on me once, and I had to do something with grub’s CLI to fix afterwards. I was pretty new at the time and prolly just messed something after the crash. Can’t remember anymore.

Anyway, I changed my update- and install practices to sudo pacman -Syu after that.

There are a few reasons that isn’t true.

Updating binaries that are currently in use only appears to work. Most of the time you can get away with it. This works because when a file is replaced on a UNIX system, processes that already have it open continue using the old inode. In effect, you temporarily have two versions of the file on disk: the new one linked in the filesystem, and the old one still referenced by open file descriptors. The old copy remains until all handles to it are closed. Even ext2 from 1993 operates this way.

For simple cases (or minor updates), you can update while something is running and then restart the affected service. That often works fine. If you update a shared library without breaking ABI compatibility (things like function names), processes using the old version will keep using it until restarted, and newly started processes will use the new one. As long as the library hasn’t changed in an incompatible way, things will behave perfectly fine.

That’s a simplification. The real picture is more complex.

The safest approach is not to overwrite components that are actively in use.

You’re playing with fire otherwise, especially when updating an entire desktop environment.

A commonly recommended approach here is to stop the display manager:

sudo systemctl stop gdm lightdm sddm plasmalogin

Which avoids most problems..

However, if you truly want to update from a TTY, the cleaner method is to switch the system out of graphical.target and into multi-user.target. This stops the display manager and related graphical dependencies in a controlled way.

And this works for any DE!

When you only stop the login manager, there’s still a lot running under graphical.target, so I try to minimise that.

I enter the TTY by running:

sudo systemctl isolate multi-user

(.target is implied for the isolate command.)

I used to only update in rescue.target, or single user mode. But I hate killing off all my terminal sessions! But it really is the safest way.

Once truly in the TTY, then I run the updates, and reboot.

But if you want to return to the *GUI,* you can just run:

sudo systemctl isolate graphical

Old-school SysV users will remember init <runlevel>. This is the systemd equivalent, just with dependency awareness instead of fixed runlevels.


You can see the difference on this fairly vanilla Plasma install:

systemctl list-dependencies rescue.target

stdout
rescue.target
○ ├─rescue.service
● └─sysinit.target
●   ├─dev-hugepages.mount
●   ├─dev-mqueue.mount
●   ├─kmod-static-nodes.service
○   ├─ldconfig.service
●   ├─lvm2-lvmpolld.socket
●   ├─lvm2-monitor.service
●   ├─plymouth-read-write.service
●   ├─plymouth-start.service
●   ├─proc-sys-fs-binfmt_misc.automount
●   ├─sys-fs-fuse-connections.mount
●   ├─sys-kernel-config.mount
●   ├─sys-kernel-debug.mount
●   ├─sys-kernel-tracing.mount
○   ├─systemd-ask-password-console.path
○   ├─systemd-binfmt.service
○   ├─systemd-boot-random-seed.service
○   ├─systemd-firstboot.service
○   ├─systemd-hibernate-clear.service
○   ├─systemd-hwdb-update.service
○   ├─systemd-journal-catalog-update.service
●   ├─systemd-journal-flush.service
●   ├─systemd-journald.service
○   ├─systemd-machine-id-commit.service
●   ├─systemd-modules-load.service
○   ├─systemd-pcrmachine.service
○   ├─systemd-pcrnvdone.service
○   ├─systemd-pcrphase-sysinit.service
○   ├─systemd-pcrphase.service
○   ├─systemd-pcrproduct.service
●   ├─systemd-random-seed.service
○   ├─systemd-repart.service
●   ├─systemd-sysctl.service
○   ├─systemd-sysusers.service
●   ├─systemd-timesyncd.service
●   ├─systemd-tmpfiles-setup-dev-early.service
●   ├─systemd-tmpfiles-setup-dev.service
●   ├─systemd-tmpfiles-setup.service
○   ├─systemd-tpm2-setup-early.service
○   ├─systemd-tpm2-setup.service
●   ├─systemd-udev-trigger.service
●   ├─systemd-udevd.service
○   ├─systemd-update-done.service
●   ├─systemd-update-utmp.service
●   ├─cryptsetup.target
●   ├─imports.target
●   ├─integritysetup.target
●   ├─local-fs.target
●   │ ├─-.mount
●   │ ├─\x2esnapshots.mount
●   │ ├─boot-efi.mount
●   │ ├─home-.snapshots.mount
●   │ ├─home.mount
●   │ ├─systemd-remount-fs.service
●   │ ├─tmp.mount
●   ├─kmod-static-nodes.service
○   ├─ldconfig.service
●   ├─lvm2-lvmpolld.socket
●   ├─lvm2-monitor.service
●   ├─plymouth-read-write.service
●   ├─plymouth-start.service
●   ├─proc-sys-fs-binfmt_misc.automount
●   ├─sys-fs-fuse-connections.mount
●   ├─sys-kernel-config.mount
●   ├─sys-kernel-debug.mount
●   ├─sys-kernel-tracing.mount
○   ├─systemd-ask-password-console.path
○   ├─systemd-binfmt.service
○   ├─systemd-boot-random-seed.service
○   ├─systemd-firstboot.service
○   ├─systemd-hibernate-clear.service
○   ├─systemd-hwdb-update.service
○   ├─systemd-journal-catalog-update.service
●   ├─systemd-journal-flush.service
●   ├─systemd-journald.service
○   ├─systemd-machine-id-commit.service
●   ├─systemd-modules-load.service
○   ├─systemd-pcrmachine.service
○   ├─systemd-pcrnvdone.service
○   ├─systemd-pcrphase-sysinit.service
○   ├─systemd-pcrphase.service
○   ├─systemd-pcrproduct.service
●   ├─systemd-random-seed.service
○   ├─systemd-repart.service
●   ├─systemd-sysctl.service
○   ├─systemd-sysusers.service
●   ├─systemd-timesyncd.service
●   ├─systemd-tmpfiles-setup-dev-early.service
●   ├─systemd-tmpfiles-setup-dev.service
●   ├─systemd-tmpfiles-setup.service
○   ├─systemd-tpm2-setup-early.service
○   ├─systemd-tpm2-setup.service
●   ├─systemd-udev-trigger.service
●   ├─systemd-udevd.service
○   ├─systemd-update-done.service
●   ├─systemd-update-utmp.service
●   ├─cryptsetup.target
●   ├─imports.target
●   ├─integritysetup.target
●   ├─local-fs.target
●   │ ├─-.mount
●   │ ├─\x2esnapshots.mount
●   │ ├─boot-efi.mount
●   │ ├─home-.snapshots.mount
●   │ ├─home.mount
●   │ ├─systemd-remount-fs.service
●   │ ├─tmp.mount
●   │ ├─var-cache.mount
●   │ └─var-log.mount
●   ├─swap.target
●   │ └─dev-disk-by\x2duuid-a9ddc99c\x2d63fa\x2d454f\x2d9692\x2da5d3bb0e961a.swap
●   └─veritysetup.target

systemctl list-dependencies graphical.target

stdout
graphical.target
● ├─plasmalogin.service
● └─multi-user.target
●   ├─cronie.service
●   ├─dbus-broker.service
●   ├─ModemManager.service
●   ├─NetworkManager.service
●   ├─plymouth-quit-wait.service
●   ├─plymouth-quit.service
●   ├─sshd.service
●   ├─systemd-ask-password-wall.path
●   ├─systemd-logind.service
●   ├─systemd-user-sessions.service
●   ├─basic.target
●   │ ├─-.mount
○   │ ├─beesd@enp1s0.service
●   │ ├─tmp.mount
●   │ ├─paths.target
●   │ ├─slices.target
●   │ │ ├─-.slice
●   │ │ └─system.slice
●   │ ├─sockets.target
●   │ │ ├─dbus.socket
●   │ │ ├─dirmngr@etc-pacman.d-gnupg.socket
●   │ │ ├─dm-event.socket
●   │ │ ├─gpg-agent-browser@etc-pacman.d-gnupg.socket
●   │ │ ├─gpg-agent-extra@etc-pacman.d-gnupg.socket
●   │ │ ├─gpg-agent-ssh@etc-pacman.d-gnupg.socket
●   │ │ ├─gpg-agent@etc-pacman.d-gnupg.socket
●   │ │ ├─keyboxd@etc-pacman.d-gnupg.socket
●   │ │ ├─polkit-agent-helper.socket
●   │ │ ├─sshd-unix-local.socket
●   │ │ ├─systemd-ask-password.socket
●   │ │ ├─systemd-bootctl.socket
●   │ │ ├─systemd-coredump.socket
●   │ │ ├─systemd-creds.socket
●   │ │ ├─systemd-factory-reset.socket
●   │ │ ├─systemd-hostnamed.socket
●   │ │ ├─systemd-importd.socket
●   │ │ ├─systemd-journald-dev-log.socket
●   │ │ ├─systemd-journald.socket
●   │ │ ├─systemd-logind-varlink.socket
●   │ │ ├─systemd-machined.socket
●   │ │ ├─systemd-mute-console.socket
○   │ │ ├─systemd-pcrextend.socket
○   │ │ ├─systemd-pcrlock.socket
●   │ │ ├─systemd-repart.socket
●   │ │ ├─systemd-sysext.socket
●   │ │ ├─systemd-udevd-control.socket
●   │ │ ├─systemd-udevd-kernel.socket
●   │ │ ├─systemd-udevd-varlink.socket
●   │ │ └─systemd-userdbd.socket
●   │ ├─sysinit.target
●   │ │ ├─dev-hugepages.mount
●   │ │ ├─dev-mqueue.mount
●   │ │ ├─kmod-static-nodes.service
○   │ │ ├─ldconfig.service
●   │ │ ├─lvm2-lvmpolld.socket
●   │ │ ├─lvm2-monitor.service
●   │ │ ├─plymouth-read-write.service
●   │ │ ├─plymouth-start.service
●   │ │ ├─proc-sys-fs-binfmt_misc.automount
●   │ │ ├─sys-fs-fuse-connections.mount
●   │ │ ├─sys-kernel-config.mount
●   │ │ ├─sys-kernel-debug.mount
●   │ │ ├─sys-kernel-tracing.mount
○   │ │ ├─systemd-ask-password-console.path
○   │ │ ├─systemd-binfmt.service
○   │ │ ├─systemd-boot-random-seed.service
○   │ │ ├─systemd-firstboot.service
○   │ │ ├─systemd-hibernate-clear.service
○   │ │ ├─systemd-hwdb-update.service
○   │ │ ├─systemd-journal-catalog-update.service
●   │ │ ├─systemd-journal-flush.service
●   │ │ ├─systemd-journald.service
○   │ │ ├─systemd-machine-id-commit.service
●   │ │ ├─systemd-modules-load.service
○   │ │ ├─systemd-pcrmachine.service
○   │ │ ├─systemd-pcrnvdone.service
○   │ │ ├─systemd-pcrphase-sysinit.service
○   │ │ ├─systemd-pcrphase.service
○   │ │ ├─systemd-pcrproduct.service
●   │ │ ├─systemd-random-seed.service
○   │ │ ├─systemd-repart.service
●   │ │ ├─systemd-sysctl.service
○   │ │ ├─systemd-sysusers.service
●   │ │ ├─systemd-timesyncd.service
●   │ │ ├─systemd-tmpfiles-setup-dev-early.service
●   │ │ ├─systemd-tmpfiles-setup-dev.service
●   │ │ ├─systemd-tmpfiles-setup.service
○   │ │ ├─systemd-tpm2-setup-early.service
○   │ │ ├─systemd-tpm2-setup.service
●   │ │ ├─systemd-udev-trigger.service
●   │ │ ├─systemd-udevd.service
○   │ │ ├─systemd-update-done.service
●   │ │ ├─systemd-update-utmp.service
●   │ │ ├─cryptsetup.target
●   │ │ ├─imports.target
●   │ │ ├─integritysetup.target
●   │ │ ├─local-fs.target
●   │ │ │ ├─-.mount
●   │ │ │ ├─\x2esnapshots.mount
●   │ │ │ ├─boot-efi.mount
●   │ │ │ ├─home-.snapshots.mount
●   │ │ │ ├─home.mount
●   │ │ │ ├─systemd-remount-fs.service
●   │ │ │ ├─tmp.mount
●   │ │ │ ├─var-cache.mount
●   │ │ │ └─var-log.mount
●   │ │ ├─swap.target
●   │ │ │ └─dev-disk-by\x2duuid-a9ddc99c\x2d63fa\x2d454f\x2d9692\x2da5d3bb0e961a.…
●   │ │ └─veritysetup.target
●   │ └─timers.target
●   │   ├─archlinux-keyring-wkd-sync.timer
○   │ │ ├─systemd-hibernate-clear.service
○   │ │ ├─systemd-hwdb-update.service
○   │ │ ├─systemd-journal-catalog-update.service
●   │ │ ├─systemd-journal-flush.service
●   │ │ ├─systemd-journald.service
○   │ │ ├─systemd-machine-id-commit.service
●   │ │ ├─systemd-modules-load.service
○   │ │ ├─systemd-pcrmachine.service
○   │ │ ├─systemd-pcrnvdone.service
○   │ │ ├─systemd-pcrphase-sysinit.service
○   │ │ ├─systemd-pcrphase.service
○   │ │ ├─systemd-pcrproduct.service
●   │ │ ├─systemd-random-seed.service
○   │ │ ├─systemd-repart.service
●   │ │ ├─systemd-sysctl.service
○   │ │ ├─systemd-sysusers.service
●   │ │ ├─systemd-timesyncd.service
●   │ │ ├─systemd-tmpfiles-setup-dev-early.service
●   │ │ ├─systemd-tmpfiles-setup-dev.service
●   │ │ ├─systemd-tmpfiles-setup.service
○   │ │ ├─systemd-tpm2-setup-early.service
○   │ │ ├─systemd-tpm2-setup.service
●   │ │ ├─systemd-udev-trigger.service
●   │ │ ├─systemd-udevd.service
○   │ │ ├─systemd-update-done.service
●   │ │ ├─systemd-update-utmp.service
●   │ │ ├─cryptsetup.target
●   │ │ ├─imports.target
●   │ │ ├─integritysetup.target
●   │ │ ├─local-fs.target
●   │ │ │ ├─-.mount
●   │ │ │ ├─\x2esnapshots.mount
●   │ │ │ ├─boot-efi.mount
●   │ │ │ ├─home-.snapshots.mount
●   │ │ │ ├─home.mount
●   │ │ │ ├─systemd-remount-fs.service
●   │ │ │ ├─tmp.mount
●   │ │ │ ├─var-cache.mount
●   │ │ │ └─var-log.mount
●   │ │ ├─swap.target
●   │ │ │ └─dev-disk-by\x2duuid-a9ddc99c\x2d63fa\x2d454f\x2d9692\x2da5d3bb0e961a.…
●   │ │ └─veritysetup.target
●   │ └─timers.target
●   │   ├─archlinux-keyring-wkd-sync.timer
●   │   ├─fstrim.timer
●   │   ├─logrotate.timer
●   │   ├─man-db.timer
●   │   ├─pamac-cleancache.timer
●   │   ├─pamac-mirrorlist.timer
●   │   ├─shadow.timer
●   │   ├─snapper-cleanup.timer
●   │   ├─snapper-timeline.timer
●   │   └─systemd-tmpfiles-clean.timer
●   ├─getty.target
○   │ └─getty@tty1.service
●   └─remote-fs.target
○     └─var-lib-machines.mount

Too Long Didn’t Click:

systemctl list-dependencies rescue.target --no-pager | wc
     62     133    2310
systemctl list-dependencies graphical.target --no-pager | wc
    127     464    5395

Unless the thing that crashes is a major component of GNOME, Plasma, XFCE, etc. – it’s quite possible for such a crash to take your TTY with it.

When I say that logging out and entering a TTY from outside of the GUI is safer when performing a sync, I am in no way referring to a specific application (like pamac-manager, for example) randomly crashing, but when major components are updated as part of the sync (the forthcoming Plasma 6.6 comes to mind) then there is a potential risk if those components are in use.

In a case such as that it might also be prudent to kill SDDM from the same TTY (before the sync) as it still remains active in the background. @Aragorn composed an in-depth article on the topic once, many moons ago, if I’m not mistaken.

Not exactly, because your sddm session is also your login session, even if you are logged in as yourself again from a different tty. It’s all about the tree of PIDs, with its root being your login session. So if you kill that, then you also kill pamac.

You mean this one? :backhand_index_pointing_down:

@linux-aarhus has also posted something like that in the Contributions > Tutorials section.

So THIS is how it works?! Thanks!

Really appreciate your whole comment. Got me more interested in getting to know systemctl more.