An appliance (read: homepod, alexa, etc.) is not a stripped down computer. It’s a fully functional computer with spyware on it out-of-the-box.

Cory Doctorow, The coming war on general computation.

I wanted to have pi-hole on my local network but didn’t want Fedora/Debian based distros for my Raspberry Pi (I don’t wanna reinstall the distro whenever a version is expired) so I went with Slackware using the sarpi project: Slackware ARM on a Raspberry Pi.

Slackware ARM on a Raspberry Pi

The installation process doesn’t differ much from slackware64. Following the install documentation from sarpi is pretty straight forward. I downloaded a mirror with the software sets and put them in an USB to spare the network configuration during installation.

I opted for an ext2 FS for the root partition, which I discovered to have issues given the RPi doesn’t have a hardware clock (RTC): whenever a power failure occurs, the FS is corrupted and e2fsck needs to be run to fix the illegal inodes. After some digging, supposedly ext4 works somewhat better because of the journaling, though I imagine the lack of RTC still causes issues to the timestamps. What I ended up doing is modifying both the single-user init script AND the rc.local script.

By default, /etc/rc.d/rc.S will dump the root partition if necessary, but when the ext2 partition gets corrupted, the -a flag for fsck is not enough, as lack of care when fixing the inodes may lead to data loss. Alas, I’d rather setup a backup job than to connect to a terminal every time the darn RPi reboots, so I made a small change:

242c242
<     /sbin/fsck $FORCEFSCK -C -a /
---
>     /sbin/fsck $FORCEFSCK -C -y /

As for setting the time, I added this to /etc/rc.d/rc.local:

RETVAL=0
ntpdate 0.pool.ntp.org
RETVAL=$?

# If we couldn't get the date via NTP servers, set it to a recent,
# post-installation date at least
if [ $RETVAL -ne 0 ]; then
    date -s "Sat Sep 26 15:30:00 2021"
fi

Pi Hole

Prerequisites

Changes to install script

The basic-install script required some minor changes to work with slackware, but since rpm is part of base, I leveraged a lot on that. Though I did write rc scripts both for lighttpd & pihole-FTL.

These are the changes for /etc/.pihole/automated install/basic-install.sh, or <repo>/automated install/basic-install.sh if it’s the first time you run the script:

392c392
<     else
---
>     elif is_command yum; then
393a394,395
>     else
>         PKG_MANAGER="slackpkg"
1575c1577
<     else
---
>     elif is_command service ; then
1577a1580,1588
>     else
>         local rc_file="/etc/rc.d/rc.$1"
>
>         if [ -f $rc_file ]; then
>             bash $rc_file restart
>         else
>             printf "  %b %s..." "${CROSS}" "restart_service: $rc_file not found, skipping..."
>         fi
1591c1602
<     else
---
>     elif is_command update-rc.d ; then
1593a1605,1612
>     else
>         local rc_file="/etc/rc.d/rc.$1"
>
>         if [ -f $rc_file ]; then
>             chmod +x $rc_file
>         else
>             printf "  %b could not enable service: $rc_file not found, skipping..." "${CROSS}"
>         fi

Additionally, I added rc scripts for lighttpd & pihole-FTL, and checks to start them at boot time in /etc/rc.d/rc.local:

/etc/rc.d/rc.lighttpd (click for details)
#!/bin/sh

LIGHTTPD=/usr/sbin/lighttpd
PIDFILE=/var/run/lighttpd/lighttpd.pid
LIGHTTPD_OPTIONS="-f /etc/lighttpd/lighttpd.conf"

is_pidof() {
  local STATE=$(ps -p $1 -o cmd= | grep "$2" > /dev/null ; echo $?)
  return $STATE
}

lighttpd_start() {
  echo "Starting lighttpd: $LIGHTTPD"
  if [ -r $PIDFILE ] && is_pidof $(cat $PIDFILE) lighttpd ; then
    echo "Already running!"
    return
  fi
  mkdir -p $(dirname $PIDFILE)
  chown -R lighttpd:lighttpd $(dirname $PIDFILE)
  $LIGHTTPD $LIGHTTPD_OPTIONS
}

lighttpd_stop() {
  echo "Stopping lighttpd: $LIGHTTPD"
  if [ -r $PIDFILE ] && is_pidof $(cat $PIDFILE) lighttpd ; then
    kill $(cat $PIDFILE)
    rm -f $PIDFILE
  else
    echo "Not running!"
  fi
}

lighttpd_restart() {
  lighttpd_stop
  sleep 1
  lighttpd_start
}

lighttpd_reload() {
  kill -s HUP $(cat $PIDFILE)
}

case "$1" in
'start')
  lighttpd_start
  ;;
'stop')
  lighttpd_stop
  ;;
restart)
  lighttpd_restart
  ;;
reload)
  lighttpd_reload
  ;;
*)
  echo "usage $0 start|stop|restart"
esac
/etc/rc.d/rc.pihole-FTL (click for details)

NOTE: Did I add the pihole-FTL binary to /usr/bin...? I don't remember, if you don't have it there, cp it yourself!

#!/bin/sh

PIHOLE_FTL=/usr/bin/pihole-FTL
PIDFILE=/run/pihole-FTL.pid
PORTFILE=/run/pihole-FTL.port
piholeftl_OPTIONS=""
PIHOLE_USER=pihole

is_pidof() {
  local STATE=$(ps -p $1 -o cmd= | grep "$2" > /dev/null ; echo $?)
  return $STATE
}

piholeftl_start() {
  echo "Starting pihole-FTL: $PIHOLE_FTL"
  if [ -r $PIDFILE ] && is_pidof $(cat $PIDFILE) pihole-FTL ; then
    echo "Already running!"
    return
  fi
  mkdir -p $(dirname $PIDFILE)
  chown -R $PIHOLE_USER:$PIHOLE_USER $(dirname $PIDFILE)
  $PIHOLE_FTL $piholeftl_OPTIONS
}

piholeftl_stop() {
  echo -n "Stopping pihole-FTL..."
  if [ -r $PIDFILE ] && is_pidof $(cat $PIDFILE) pihole-FTL ; then
    kill $(cat $PIDFILE)
    rm -f $PIDFILE $PORTFILE
  else
    killall -q pihole-FTL
  fi
  echo
}

piholeftl_restart() {
  piholeftl_stop
  sleep 1
  piholeftl_start
}

piholeftl_reload() {
  kill -s HUP $(cat $PIDFILE)
}

case "$1" in
'start')
  piholeftl_start
  ;;
'stop')
  piholeftl_stop
  ;;
restart)
  piholeftl_restart
  ;;
reload)
  piholeftl_reload
  ;;
*)
  echo "usage $0 start|stop|restart"
esac
/etc/rc.d/rc.local (click for details)
if [ -x /etc/rc.d/rc.lighttpd ]; then
    /etc/rc.d/rc.lighttpd start
fi

if [ -x /etc/rc.d/rc.pihole-FTL ]; then
    /etc/rc.d/rc.pihole-FTL start
fi

MiniDLNA / ReadyMedia

Prerequisites

  • Install ffmpeg: for some reason, even though I had ffmpeg installed, a lot of libraries were missing, so I slackpkg installed them one by one (hint: test by running ffempeg --version).

Source

I tried installing the minidlna slackbuild but the ffmpeg inconsistencies caused the script to fail several times, so I opted to install a fork that supports transcoding (mirror), added a group/user & rc script:

#!/bin/sh
# /etc/rc.d/rc.minidlnad

MINIDLNA=/usr/local/sbin/minidlnad
PIDFILE=/var/run/minidlna/minidlna.pid
CONF=/etc/minidlna.conf
ARGS="-f $CONF"

test -f $MINIDLNA || exit 0

minidlnad_start() {
    echo -n "Starting minidlna: "
    $MINIDLNA $ARGS
    echo $?
}

minidlnad_stop() {
    echo -n "Stopping minidlna: "
    killall minidlnad
    echo $?
}

minidlnad_restart() {
    minidlnad_stop
    minidlnad_start
}

case "$1" in
'start')
    minidlnad_start
    ;;
'stop')
    minidlnad_stop
    ;;
'restart')
    minidlnad_restart
    ;;
*)
    echo "Usage: $0 start|stop|restart"
    exit 2
    ;;
esac

And of course, add a check to start during boot in /etc/rc.d/rc.local

Screenshot of VLC network sources on mobile.
The ever-grand VLC automagically ™ detecting the DLNA server.