Rolling Back a Bad openSUSE Update: What Snapper Actually Reverts
Snapper's pre/post snapshots make a bad openSUSE update reversible — but only for the root subvolume. How undochange and rollback differ, and what they leave behind.
16 Aug 2025, 21:14 UTC

A package update breaks a driver, a service, or the display manager. On openSUSE, the default Btrfs layout gives you two different undo tools — snapper undochange and snapper rollback — and they are not interchangeable. Picking the wrong one, or assuming either restores everything, is where a recoverable update turns into an afternoon of repair work.
The useful mental model: Snapper makes a single package transaction cheaply reversible, but the snapshot boundary is the root subvolume only. Knowing what sits outside that boundary is what makes the decision safe.
What the snapshot boundary actually contains
Default openSUSE partitioning on Leap 15.x and Tumbleweed creates a Btrfs root with several subvolumes carved out of it: /home, /var/log, /var/cache, /var/tmp, /tmp, /srv, /opt, /usr/local, and the GRUB directories. Snapshots are taken of the top-level subvolume, so those carved-out paths are not captured.
The practical consequence: a rollback returns /usr, /etc, /lib, and the package database, but leaves your home directory, logs, and caches exactly as they are now. Snapper's own storage lives in /.snapshots, itself a separate subvolume, and snapshots are read-only.
Two kinds of snapshots matter here. The snapper-zypp-plugin hooks into libzypp's commit phase, so every package install, update, or removal produces a numbered pre/post pair — triggered identically by zypper and by YaST Software. Separately, hourly timeline snapshots accumulate on a schedule.
undochange and rollback are different operations
snapper undochange | snapper rollback | |
|---|---|---|
| Scope | Applies the file differences between two snapshots to the running system | Makes a snapshot the new default root subvolume |
| Reboot | Not required | Required to take effect |
| Best for | Reversing one package transaction in place | A system that will not boot, or a change you want fully discarded |
| Main risk | Running services keep stale file handles; reverting a kernel while it is running | Discards everything after the snapshot, including unrelated later changes |
Worked example: reversing one zypper transaction
Run these as root or with sudo. The placeholders <pre> and <post> are snapshot numbers from the listing.
Find the pair. Run
sudo snapper listand look for apre/postpair whose Description names the zypper command and the packages involved. ThePre #column on the post snapshot points back at its matching pre snapshot.Inspect before changing anything. Run
sudo snapper status <pre>..<post>. Each line names a file and its change type. This is the step people skip: if you hand-edited a config file after the update, that edit is inside the diff andundochangewill revert it too.Apply the reversal with
sudo snapper undochange <pre>..<post>.Verify. Confirm the package version with
rpm -q <package-name>and cross-check the transaction againstzypper historyor/var/log/zypp/history. Restart any service whose binaries changed — a running process keeps the file it started with, so the rollback is not visible to it until restart.
One risk worth stating plainly: reverting a kernel package while the system is running leaves the running kernel and the on-disk kernel out of sync until you reboot. openSUSE keeps multiple kernel versions installed by default, so a reboot usually lands on a kernel that still exists, but third-party modules such as NVIDIA or VirtualBox builds may need rebuilding against the restored kernel.
Trade-offs you accept by relying on this
- /home is not reverted. Application configuration in your home directory that a newer version migrated stays migrated, which can mismatch the older binaries you just restored.
- Logs survive. Because
/var/logis outside the snapshot, the evidence of the failure is still there after a rollback. Good for a post-mortem, but it means the restored system is not a clean point-in-time image. - Space is finite. Snapshots share unchanged extents and store changed blocks. Frequent updates on a small root partition can fill it, and Btrfs handles a full filesystem poorly.
- The boot menu grows. The GRUB read-only snapshot submenu is limited by default, but old snapshots still need periodic deletion.
- Btrfs only. None of this exists on an ext4 or XFS root, and it cannot be retrofitted without repartitioning or reinstalling.
A practical retention check
Read the cleanup settings with sudo cat /etc/snapper/configs/root. The keys that control growth are TIMELINE_LIMIT_HOURLY, TIMELINE_LIMIT_DAILY, NUMBER_LIMIT, NUMBER_LIMIT_IMPORTANT, and EMPTY_PRE_POST_CLEANUP. The zypp plugin's own behavior is configured in /etc/snapper/zypp.conf.
Then correlate count with consumption using sudo btrfs filesystem usage / alongside sudo snapper list. If usage climbs and the list is long, tighten the timeline limits first: timeline snapshots are usually the bulk of the count, while pre/post pairs are the ones you actually want to keep for a rollback.
The decision rule
If the system boots and you want to reverse one transaction, use snapper undochange on that specific pre/post pair. If it does not boot, or you want the whole root back at a known point, boot the read-only snapshot from the GRUB submenu and run snapper rollback, then reboot. Either way, check snapper status first, and remember that /home, /var/log, and /var/cache are not part of the deal.
Command syntax here reflects the default layout on current Leap 15.x and Tumbleweed releases; confirm flags with snapper --help and the openSUSE documentation for your specific version before relying on them in a recovery situation.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.