Updating Slackware -current...

I have been running the development version of Slackware for some years now and to do this I had previously been using an ad hoc collection of scripts and one-liners that have accreted over time. When I managed to brick my system just recently, after an ill considered glibc update, I decided that the time had come for me to be a little more systematic in updating Slackware -current.

I have published my successful method on this page so that perhaps others may benefit from my efforts or perhaps even make some suggestions to improve the steps I give below.

7 steps...

With a little massaging I have managed to get my standard update down to a pretty solid 7 steps. These steps have kept me safely updating for some time and in researching these steps I have also come to know Slackware a little better.

1. Update Slackware tree...

For a long time I used an excellent script written by Eric Hameleers to keep an offline Slackware -current tree updated for subsequent installation to my system. However I eventually decided to use my own very simple rsync one-liner with the usual goal for me, Gentle Reader, of keeping everything as simple as possible! This one-liner is as follows:

rsync -avz --delete --bwlimit=10000 --stats --progress \
      rsync.osuosl.org::slackware/slackware64-current/ \
    /home/andrew/ssd2/Slackware/slackware64-current/

The only element of this that is at all unusual is the use of the option --bwlimit=10000 which I started using a while back when there was some rsync oddity on Slackware -current, I will remove it one day. Now, before actually installing from this updated tree there are a few safety options to consider which I will give as steps 2 to 4 inclusive:

2. Have a re-installation strategy...

To keep myself completely covered in the event of my system becoming unbootable I actually use two strategies, both of which create a bootable installation iso:

  1. Installation iso: The first strategy is to create an installation iso from the Slackware -current tree. I have borrowed the syntax from PV with a few very minor changes to suit my own needs:
    cd /home/andrew/ssd2/Slackware/slackware64-current/ && \
    xorriso -as mkisofs \
            -iso-level 3 \
            -full-iso9660-filenames \
            -R -J -A "Slackware Install" \
            -hide-rr-moved \
            -v -d -N \
            -eltorito-boot isolinux/isolinux.bin \
            -eltorito-catalog isolinux/boot.cat \
            -no-emul-boot -boot-load-size 4 -boot-info-table \
            -isohybrid-mbr /usr/share/syslinux/isohdpfx.bin \
            -eltorito-alt-boot \
            -e isolinux/efiboot.img \
            -no-emul-boot -isohybrid-gpt-basdat \
            -m 'extra' -m 'pasture' -m 'patches' -m 'source' -m 'testing' \
            -volid "SlackDVD" \
            -output /tmp/slackware64-current.iso \
            .
    
    This is then dd'd onto a USB stick with the correct path using syntax as simple as I can make it, and then it is ready to go:
    dd if=/tmp/slackware64-current.iso of=/dev/sdc bs=512 status=progress
    
  2. Liveslak: Courtesy of Eric Hameleers there is a very nice 'live' iso for Slackware that works beautifully from a USB stick and this is a very, very useful USB stick to have prepared for any installation disaster. After downloading the latest iso from Eric I update my current USB stick with:
    ./iso2usb.sh --refresh -i slackware64-live-current.iso -o /dev/sdc 
    
    I will not give great details of installation and usage of this live, 'persistent', USB installation here as Eric has published such documentation on his blog. Suffice it to say that both installation USB and Slackware Live USB should both the tested before committing to a major upgrade!

3. Have a 'safe' kernel in place...

On my own system I always compile my own kernel, just behind the cutting edge of the -current kernel, and use this as my daily working kernel. This has kept me out of trouble several times when the latest -current offering does not agree with either the NVidia drivers or the VirtualBox installation. I have borrowed the technique largely from an older post by Eric Hameleers, but the syntax is pretty universal in the Linux world. The example below compiles 6.1.6:

cd /home/andrew/ssd2/kernels/ && \
wget https://mirrors.edge.kernel.org/pub/linux/kernel/v6.x/linux-6.12.20.tar.xz && \
tar -C /usr/src -xvf linux-6.12.20.tar.xz && \
cd /usr/src && rm linux && ln -s linux-6.12.20 linux && \
cd /usr/src/linux && \
zcat /proc/config.gz > /usr/src/linux/.config && \
make oldconfig && make menuconfig

I usually append -ads to the kernel name for easy identification / blame and after a trawl through the many, many options I install:

make -j 32 bzImage modules && \
make -j 32 modules_install && \
cp -v arch/x86/boot/bzImage /boot/vmlinuz-6.12.20-ads

Not the most sophisticated build I know but it is a bit of fun, keeps my system safe and leaves the door open to further exploration on a rainy weekend! A quick adjustment to Lilo:

sed -i_bak 's#6.10.6-ads#6.12.20-ads#g' /etc/lilo.conf && lilo

Now installing in this manner will leave the kernel immune from the usual removal utility of Slackware so I have created a small script to easily remove the kernel and its installation when it is no longer required:

#!/bin/sh
#---------------------------------------------------#
# Remove self-compiled kernels which are installed  #
# without the standard installpkg/removepkg tools.  #
#---------------------------------------------------#

VERSION=6.12.20

# Make sure we are root (Stolen from SBopkg):
if [[ $(id -u) != 0 ]]; then
  echo "This removal script must be run as root. Exiting." >&2
  exit 1
fi

# Remove the installed kernel:
rm -v /boot/vmlinuz-$VERSION-ads

# Remove the kernel source:
rm -rfv /usr/src/linux-$VERSION

# Remove the installed modules:
rm -rfv /lib/modules/$VERSION-ads

And then, after crossing your fingers, reboot the system and test the new kernel, secure in the knowledge that the 'stock' Slackware -current kernels are still in place.

4. Backup files...

Before starting the actual installation from the Slackware -current tree vital files should be backed up. There are many, many ways to do this but my own very basic technique has been keeping me safe for a while. I bought an external USB 4TB spinning drive back when such things were absurdly expensive and created the world's simplest script to backup my most important files:

#!/bin/sh

rsync -avz --exclude={'.cache','.local/share/Trash'} \
          /home/andrew \
          /mnt/ssd2 \
          /usr/share/games/ut2004 \
          /etc \
          /run/media/andrew/Backup/backup.$(date "+%d.%m.%Y")

You can see, Gentle Reader, that I like simple things as there is nothing particularly ornate in this little script! Nevertheless it has got me out of trouble many times in the past.

5a. Update the system...

Read the ChangeLog!! Probably the most important thing to do before even considering to update the system from the new tree. I look for any updated shared libraries, major Xorg updates, big kernel changes and a few other possible problem areas. When these issues have been resolved the simplest way to update the system from the updated Slackware -current tree is as follows:

cd /mnt/ssd2/Slackware/slackware64-current/slackware64 && \
for dir in a ap d e f k kde l n t tcl x xap xfce y ; do
   ( cd $dir ; upgradepkg --install-new *.t?z )
done

It is also possible to modify the upgradepkg line given above with the following if you wish to keep a few applications and their installed versions out of the upgrade process:

upgradepkg --install-new $(ls *.t?z | grep -vE '(MPlayer|slrn|ffmpeg)')

Now I bricked my system with a bad glibc upgrade when using this technique, through my own ignorance and impatience. The libraries have now had a name change to make this less possible but still if there are any major glibc upgrades I still run the upgrade as follows:

upgradepkg /mnt/ssd2/Slackware/slackware64-current/slackware64/a/aaa_glibc-solibs-*.txz
upgradepkg /mnt/ssd2/Slackware/slackware64-current/slackware64/a/pkgtools-*.txz
upgradepkg /mnt/ssd2/Slackware/slackware64-current/slackware64/a/tar-*.txz
upgradepkg /mnt/ssd2/Slackware/slackware64-current/slackware64/a/xz-*.txz
upgradepkg /mnt/ssd2/Slackware/slackware64-current/slackware64/a/findutils-*.txz

And then upgrade the rest of the tree in the usual way. It was this fiasco with updating glibc that made me write this page and so I managed to learn a huge amount from my error! Best way to learn is often from your own mistakes...

5b. Update Multilib...

For some time I had moved away from having the ability to compile and run purely 32bit applications on my 64bit system. However more recently I had the need to return this ability to my system using Eric's work. The following downloads, installs or updates the whole thing:

cd /home/andrew/ssd2/Slackware/multilib && \
lftp -c 'open http://slackware.com/~alien/multilib/ ; mirror -c -e current' && \
cd current && \
upgradepkg --reinstall --install-new *.t?z && \
upgradepkg --install-new slackware64-compat32/*-compat32/*.t?z

As time moves on this will be less necessary but for the moment I do not begrudge an extra 5 minutes work with each update and as always I am very grateful for Eric's work!

5c. Sort out new kernels...

If a new stock kernel has been installed as part of this upgrade (rather than my own 'safety' kernel of course) it must be setup adequately. In the newer world of Slackware an initrd can now be automagically generated by /etc/default/geninitrd and it is time well spent to have a look at this script and carefully select or unselect some of the options. In previous days this would be done manually: the example below shows the older strategy for upgrading Linux kernel 6.12.20 with kernel 6.12.21. Whichever way the initrd is generated Lilo needs to be updated:

/usr/share/mkinitrd/mkinitrd_command_generator.sh -k 6.12.21 | bash
sed -i_bak 's#6.12.20#6.12.21#g' /etc/lilo.conf && lilo

You will note that I still use the old school method of installation: a 'legacy' BIOS setting and Lilo as a bootloader. Has worked for me for many, many years! I will change one day, perhaps when PV changes the defaults at his end...

6. Sort out the config files...

Slackware has a nice system of not updating config files automatically, thus not obliterating any carefully researched and crafted conf files! However some config files should really be updated and as my own system is a really simple one I will usually run the following script. This script has been pillaged and lightly modified from a script suggested by PV:

#!/bin/sh

cd /etc
find . -name "*.new" | while read configfile ; do
if [ ! "$configfile" = "./rc.d/rc.inet1.conf.new" \
-a ! "$configfile" = "./rc.d/rc.local.new" \
-a ! "$configfile" = "./rc.d/rc.modules.local.new" \
-a ! "$configfile" = "./group.new" \
-a ! "$configfile" = "./passwd.new" \
-a ! "$configfile" = "./shadow.new" ]; then
cp -a $(echo $configfile | rev | cut -f 2- -d . | rev) \
$(echo $configfile | rev | cut -f 2- -d . | rev).bak 2> /dev/null
mv --verbose $configfile $(echo $configfile | rev | cut -f 2- -d . | rev)
fi
done

# https://www.gnu.org/software/findutils/manual/html_node/find_html/Deleting-Files.html
# find /etc -mtime +90 -name "*.bak" -type f
# find /etc -mtime +90 -name "*.bak" -type f -delete

I have made a few very minor updates to the suggested script as well as adding a few one liners for selectively deleting some of the backup files left in place. Nevertheless I still spend a little time with a text editor trawling through the changes before running this script.

7. Remove old packages...

The ChangeLog will give a list of packages that have been removed from the tree and usually after a close look at these packages I will also delete them. These will be marked as 'Removed.' at the end of the line in the ChangeLog and I wrote the following rather clunky script to find these files and remove them:

#!/bin/sh
#---------------------------------------------------#
# Uninstall packages 'officially' removed from the  #
# Slackware -current tree...                        #
#---------------------------------------------------#

CHANGELOG=/home/andrew/ssd2/Slackware/slackware64-current/ChangeLog.txt

# 4 steps to parse the ChangeLog:
#   1. Use grep to find 'Removed.' at the end of lines
#   2. Use cut to remove the initial directory name and '/'
#   3. Use cut to trim away the end of the line, leaving the filename 
#   4. Use tr to remove the newline spacing

LIST=$(grep -a 'Removed.$' $CHANGELOG | cut -d '/' -f2 | cut -d ':' -f1 | tr '\n' ' ')

# And finally remove the parsed list of packages:
removepkg --terse "$LIST"

Although this works well enough I will return here and find something a little smoother in the coming weeks...

Appendix: Trim the SSDs...

I run 2 SSDs on this system and for my final step after updating I run the following to trim these drives. Since I usually update the Slackware -current tree every week or so this means that this little bit of housekeeping should be done on my system at a reasonable interval:

fstrim -av

And again, Gentle Reader, I will return to this little part of this page in the near future and make the use of fstrim a little more streamlined rather than using it as a clumsy one-liner to copy and paste into a Terminal window...

And in conclusion...

And so that is one man's way of safely updating Slackware -current. I am aware that there are some automated and semi-automated tools available to make this all a little easier but I choose to avoid these tools. No reason for you to avoid them though although I believe that these tools will take you a little further away from a 'hands-on' experience with Slackware.

If this approach has been at all helpful to you please let me know... In the meantime I am having a great time working with Slackware -current, what about you?