Skip to content

Distribution Upgrade

Anagnostakis Ioannis edited this page Nov 12, 2026 · 6 revisions

Distribution Upgrade (upgrade-dist)

slacker upgrade-dist upgrades a whole system from one Slackware release to another - the big, one-way operation you run once, not a routine upgrade-all. It is the only command that deliberately steps outside the priority model (see below), because a release jump is exactly when "keep what you have" is the wrong default.

For the releases to come. slacker targets the development branch until Slackware 16.0 and is not built for 15.0, so upgrade-dist is meant for the release jumps from 16.0 onwards. The routes it allows today are still the 15.0 ones used during development and are replaced with the 16.0 routes when 16.0 is out.

Beta / handle with care. A distribution upgrade rewrites your mirror and repo configuration and replaces essentially every installed package. Always do a --dry-run first, and have backups. The network path (upgrade-dist current) has been run end-to-end on a test VM; the local source path (DISTRO_UPGRADE_MIRROR, below) is implemented but not yet tested - treat it as experimental.


What it does, in one picture

%%{init: {'theme':'base','themeVariables':{'primaryColor':'#161b22','primaryBorderColor':'#1f6feb','primaryTextColor':'#e6edf3','lineColor':'#6e7781','fontFamily':'monospace'}}}%%
flowchart TB
  A["upgrade-dist TARGET"]:::blue --> G{"x86 system and<br/>direction allowed?<br/>(whitelist gate)"}
  G -->|no| X["refused, nothing changed"]:::grey
  G -->|yes| C["typed point-of-no-return<br/>confirmation"]:::blue
  C --> K["escape-kit template +<br/>re-point mirror/repos +<br/>empty blacklist"]:::grey
  K --> U["update metadata<br/>for the target"]:::grey
  U --> P["upgrade EVERY package<br/>(priority/blacklist bypassed)<br/>core first, GnuPG chain last"]:::green
  P --> N["install-new + clean-system<br/>+ second pass + new-config"]:::green
  N --> R["kernel / initrd / bootloader<br/>reminder, then reboot"]:::blue
  classDef grey fill:#0d1117,stroke:#6e7781,color:#8b949e;
  classDef blue fill:#0d1117,stroke:#1f6feb,color:#e6edf3;
  classDef green fill:#0d1117,stroke:#2ea043,color:#e6edf3;
Loading

The target is where you are going

slacker upgrade-dist current     # move a stable release to the development branch
slacker upgrade-dist 17.0         # move to a newer stable (example)

TARGET is an explicit argument, never read from your mirror: current for the development branch, or a stable version like 17.0. The running release is read from /etc/os-release; the target comes from the argument, and upgrade-dist re-points the mirror and repos itself to match.

Allowed directions only (a fail-closed gate)

Before anything happens, the route is checked against a whitelist: a stable release to the development branch, or a stable release to a newer stable. Every other direction - already on the development branch, going backward, an unknown release - is refused with no changes made. The gate decides only the direction; the work it does is the same for every allowed route.

Not on Slackware ARM. upgrade-dist is supported on x86_64 and 32-bit x86 only. On aarch64 it refuses before reading or changing anything; there, keep the development branch up to date with upgrade-all.

Which binary runs where. Run the slacker package built for the release you are on (e.g. 16.0). An older-glibc binary keeps running on the newer system throughout the upgrade; afterwards, install the slacker package built for the new release.


The phases in detail

Once you confirm the typed point-of-no-return prompt, upgrade-dist runs the whole sequence for you:

  1. Escape kit. It first writes a template of your current package set, so you have a record of exactly what was installed before the upgrade began.

  2. Re-point the configuration. It rewrites the active mirrors line and every mirror/subtree repo to the target release; comments out any third-party repo whose versioned URL it cannot re-point (it tells you which); and backs up blacklist to blacklist.bak, then empties it (a frozen package must not block a release jump). A patches subtree follows the mirror automatically and stays active on the new release.

  3. Refresh metadata. One confirmation ("Connected to the target repositories. Proceed?", default yes), then it updates every repo silently.

  4. Upgrade everything - priority bypassed. For every installed package it takes the target distribution's build, ignoring source priority, the blacklist and frozen state on purpose - a release jump is precisely when those must not apply. Core packages (aaa_glibc-solibs, pkgtools, tar, xz, …) go first; the GnuPG verification chain (gnupg/gnupg2 and its libraries) goes last, so package signatures keep being verified throughout the run instead of breaking mid-stream.

  5. Fill and prune. It runs install-new (the target's newly-added packages), then clean-system (interactive - you review packages the new release no longer ships, including any now-disabled third-party ones), then a second pass to be certain nothing was missed.

  6. Configs and kernel. It reconciles *.new files (new-config), where a dist-upgrade additionally offers (A)ll new - install every incoming config and keep the previous one as .bak, the shape of the script in Patrick's upgrade HOWTO. The six protected files (/etc/passwd, /etc/shadow, /etc/group, /etc/rc.d/rc.inet1.conf, /etc/rc.d/rc.local, /etc/rc.d/rc.local_shutdown) are never replaced and are left for you to merge by hand: the five Patrick's script skips, plus rc.local_shutdown, slacker's own addition.

    Of the NEWCONFIG_* rules in slacker.conf (see Configuration), only NEWCONFIG_KEEP applies here: a file you keep is never replaced, not even by (A)ll new. Its incoming version is set aside as .new.kept, so you can compare it after the upgrade. NEWCONFIG_OVERWRITE and NEWCONFIG_REMOVE are not applied: like the blacklist, a release jump shows you every other file (slacker prints a note when such rules exist). With --yes there is no menu: kept files go to .new.kept, and for every other file your current one stays and its .new is removed. It then prints a final status and ends with a prominent kernel / initrd / bootloader reminder, following the upgrade HOWTO:

    • geninitrd first - it builds the initrd for the new kernel and updates grub.cfg;
    • then reinstall the bootloader you actually use: lilo (after checking /etc/lilo.conf points at a valid kernel), grub-install on UEFI, grub-install --target=i386-pc /dev/sdX on a legacy BIOS, or eliloconfig for ELILO;
    • booting from a USB stick? copy the new kernel onto it in place of the old.

    slacker prints these steps; it never runs them itself - the right bootloader and device are yours to know, and a wrong guess leaves an unbootable system after an otherwise finished upgrade. Reboot only after this, keeping the old kernel as a fallback.

Through a proxy

upgrade-dist re-points mirrors, repos and the blacklist, but never touches PROXY or NO_PROXY in slacker.conf, so a proxy set there carries the whole upgrade (see Configuration). With PROXY=env, keep the variables through sudo, or the downloads go direct.

Disk-safe by construction

Downloads happen in batches that are deleted as they install, so the upgrade never needs disk space for a whole release at once, and a disk-space preflight stops before touching the system if space is short. A core package that fails to verify aborts the run before anything is installed, so a broken download can never leave a half-upgraded core.


Relationship to the priority model and the release guard

  • Priority bypass. Everywhere else, slacker never migrates or downgrades an installed package across priorities (see Repositories and Priority). upgrade-dist is the single, deliberate exception: it takes the target distribution's version of every package regardless of where the installed copy came from. This is why it empties the blacklist and ignores frozen state.
  • Release-guard exemption. Normal install/upgrade refuse a package from a repo built for a different release than the running system (see Security). upgrade-dist is exempt - changing the release is its whole job - and it is the supported way to cross that boundary.

Upgrading from a local source (experimental)

For an offline or bandwidth-limited upgrade you can point upgrade-dist at a local copy of the target release instead of the network, via DISTRO_UPGRADE_MIRROR in /etc/slacker/distro-upgrade.conf:

# /etc/slacker/distro-upgrade.conf
# A local copy of the TARGET release tree, an NFS clone, or a mounted ISO.
DISTRO_UPGRADE_MIRROR=file:///mnt/iso/
# or a release tree with the version segment:
# DISTRO_UPGRADE_MIRROR=http://nas/slackware64-current/

When set, the upgrade re-points to this base instead of the mirror, and slacker validates it (its release segment matches the requested target, and its PACKAGES.TXT is reachable) before the point of no return.

Not yet tested. This local-source path is implemented and validated in code, but has not been run end-to-end on a real upgrade yet. Until it has, prefer the network path, and if you do try a local source, run --dry-run first and keep good backups.


Flags and a dry run

Flag Effect on upgrade-dist
--dry-run Shows the route, the mirror/repos URL transform, and the plan - and writes nothing. Always run this first.
--yes Runs non-interactively (skips the prompts, including the point-of-no-return). For automation only - know exactly what it will do. In the config phase it keeps your current files and removes their .new, except those under NEWCONFIG_KEEP, which go to .new.kept.
slacker --dry-run upgrade-dist current     # preview the whole thing, change nothing
sudo slacker upgrade-dist current          # the real upgrade (interactive)

After it finishes, follow the kernel reminder, reboot, and run slacker status on the new release to confirm everything is green.


See also

  • Repositories and Priority - the priority model upgrade-dist bypasses, and the subtree repos it re-points.
  • Security - verification, key pinning, and the release-match guard upgrade-dist is exempt from.
  • Configuration - distro-upgrade.conf, the NEWCONFIG_* rules, PROXY, and the rest of /etc/slacker.
  • Commands - the one-line reference for every action.

Clone this wiki locally