7 Steps to safely updating Slackware -current...

I have been running the development version of Slackware for some years now and to do this successfully I have previously been using an ad hoc collection of scripts and one-liners that have accreted over time. When I actually bricked 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, particularly as I prefer to do this manually rather than by using automated tools. I have published my 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. Let me know what you think by using the email link at the base of this page...

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 come to know Slackware a little better. I have been using Slackware for some years now but I learn a little more every day!

1. Update Slackware tree...

Now I confess that 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! So my very basic rsync 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. Because I am a little lazy I have left it in place even after the issue was resolved. Now, before installing from this updated tree there are a few safety options to consider. These I now 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. The first strategy is to simply create an installation iso from the Slackware -current tree. To do this I have borrowed syntax suggested by PV in the Slackware documentation, with a few very minor changes to suit my own needs:

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 small USB stick, the stick only needs to be 4GB as the Slackware tree has been pared down somewhat with the use of the -m 'xxx' option. It should perhaps not even need to be mentioned, Gentle Reader, that great care must be taken with the output device as dd is not kind with mistakes in this area. The syntax once again is very simple:

dd if=slackware64-current.iso of=/dev/sdc bs=512 status=progress

Times have moved along from such a simple strategy and there is now a second strategy, which I utilise along with this simple iso created from the Slackware tree. 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. On my system the syntax to update the USB stick with the latest Slackware Live is as follows:

./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 the NVidia drivers or VirtualBox installation. For some time as well I have needed to patch the kernel to get around a particularly annoying issue with my Kindle Oasis and Calibre. I 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 5.10.27:

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

Now that I no longer need to patch the kernel for my Oasis the only other changes I really make to the config is firstly under 'File Systems' build in ext4 and secondly add a 'stamp' to the kernel under General setup > Local version - append to kernel release (-ads). But nowthat I am retired I will be digging a little deeper into this 'safety' kernel but for the moment I simply build and install the kernel as follows:

make -j 32 bzImage modules && \
make -j 32 modules_install && \
cp -v arch/x86/boot/bzImage /boot/vmlinuz-5.10.27-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#5.10.18-ads#5.10.27-ads#g' /etc/lilo.conf && lilo

And then, after crossing your fingers, reboot the system and test the kernel, secure in the knosledge 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 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={'ssd2','.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 and it is the first thing I do before upgrading Slackware -current. If you are a little puzzled about /mnt/ssd2 I can tell you that this is an internal SSD that I added to my build for 'heavy' storage (large media files, installation isos, source code etc). And I confess that it took me a few tries before I managed to get the --exclude= syntax correct...

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. 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. As a sidenote I should mention that I do not upgrade a running kernel and I suspect, Gentle Reader, that neither should you! A new initrd must be generated and Lilo must be set correctly. The example below shows the strategy for upgrading Linux kernel 5.10.28 with kernel 5.10.29:

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

Incremental kernel updates usually pose no particular problem but it is good practice to not only have a safe, default kernel in place but also to hold off updates for a period when a major kernel upgrade arrives in Slackware -current.

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 suggested script of our BDFL:

#!/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...