aboutsummaryrefslogtreecommitdiffstats
path: root/upslak.sh
diff options
context:
space:
mode:
author Eric Hameleers <alien@slackware.com>2023-09-10 17:14:47 +0200
committer Eric Hameleers <alien@slackware.com>2023-09-10 17:14:47 +0200
commit672a9e4e7f160a65d1bdae49a65b734a2627a5f1 (patch)
tree3d57adf2cf43db2e55d0bf25cb4cb4a62a46b070 /upslak.sh
parentfad898a736db76ea3159b668a5979a8efc8ef80a (diff)
downloadliveslak-672a9e4e7f160a65d1bdae49a65b734a2627a5f1.tar.gz
liveslak-672a9e4e7f160a65d1bdae49a65b734a2627a5f1.tar.xz
Several enhancements to LUKS containers and their support scripts
To name the most important: - The filesystem inside the containers is no longer limited to ext4 and can now be btrfs, ext2, ext4, f2fs, jfs or xfs. The scripts 'iso2usb.sh' and 'isocomp.sh' now support this filesystem choice via a new '-F' switch. - The 'upslak.sh' script can now extend the size of your home and persistence container files, in case you run out of storage there. - The internal functions used in 'iso2usb.sh' 'isocomp.sh' and 'upslak.sh' are mostly unified now, and I intend to split all functions off into a separate file which makes maintenance as well as adding new functionaliy easier. - The 'upslak.sh' script will now create a 'kernelmodules' squashfs module and copies it to liveslak's 'addons' directory after updating the boot kernel on the USB stick and the kernel-modules inside the initrd image. This way, you no longer end up with a broken Live OS if you forgot to install a Slackware kernel-modules package inside the persistent Live OS prior to running 'upslak.sh' with the '-k' and '-m' parameters. In addition, the README.txt was updated with these enhancements so that the liveslak documentation is again completely up to date.
Diffstat (limited to 'upslak.sh')
-rw-r--r--upslak.sh526
1 files changed, 443 insertions, 83 deletions
diff --git a/upslak.sh b/upslak.sh
index 1b4633c..aa1c9ff 100644
--- a/upslak.sh
+++ b/upslak.sh
@@ -62,15 +62,28 @@ UPKERNEL=0
# Do not change usb wait time by default:
WAIT=-1
+# Not extending any container by default:
+EXTENSION=""
+
# ---------------------------------------------------------------------------
# END possible tasks to be executed by the script:
# ---------------------------------------------------------------------------
+# The extension for containerfiles accompanying an ISO is '.icc',
+# whereas the persistent USB stick created with iso2usb.sh uses '.img'.
+DEFEXT=".img"
+CNTEXT="${DEFEXT}"
+
+# Default filesystem for devices/containers:
+DEF_FS="ext4"
+FSYS="${DEF_FS}"
+
# Determine whether the USB stick has a supported kernel configuration
# i.e. one active and optionally one backup kernel plus mmodules:
SUPPORTED=1
# Values obtained from the init script on the USB:
+CORE2RAMMODS=""
DEF_KBD=""
DEF_LOCALE=""
DEF_TZ=""
@@ -81,7 +94,6 @@ LIVEUID=""
MARKER=""
MEDIALABEL=""
PERSISTENCE=""
-CORE2RAMMODS=""
SQ_EXT_AVAIL=""
VERSION=""
@@ -89,9 +101,15 @@ VERSION=""
KBACKUP=1
# Does the initrd contain an old kernel that we can restore?
-# The 'read_initrd' routing may set this to '0':
+# The 'read_initrddir' routine may set this to '0':
KRESTORE=1
+# By default we create an addon live module for the new kernel modules,
+# otherwise the Live OS will be broken after reboot.
+# User can skip this if they already installed the kernel-modules package
+# in the Live OS earlier:
+NOLIVEMODS=0
+
# Timeout when scanning for inserted USB device, 30 seconds by default,
# but this default can be changed from outside the script:
SCANWAIT=${SCANWAIT:-30}
@@ -109,8 +127,6 @@ MINFREE=${MINFREE:-10}
# Variables to store content from an initrd we are going to refresh:
OLDKERNELSIZE=""
-OLDKMODDIRSIZE=""
-OLDKVER=""
OLDWAIT=""
# Record the version of the new kernel:
@@ -121,10 +137,22 @@ IMGDIR=""
KERDIR=""
USBMNT=""
EFIMNT=""
+CNTDEV=""
+LODEV=""
+
+# Empty initialization:
+INCSIZE=""
+PARTFREE=""
+PARTSIZE=""
# These tools are required by the script, we will check for their existence:
REQTOOLS="cpio gdisk inotifywait lsblk strings xz"
+# Minimim free space (in MB) we want to have left in any partition
+# after we are done.
+# The default value can be changed from the environment:
+MINFREE=${MINFREE:-10}
+
# Compressor used on the initrd ("gzip" or "xz --check=crc32");
# Note that the kernel's XZ decompressor does not understand CRC64:
COMPR="xz --check=crc32"
@@ -133,7 +161,7 @@ COMPR="xz --check=crc32"
# List of kernel modules required for a live medium to boot properly;
# Lots of HID modules added to support keyboard input for LUKS password entry;
# Virtio modules added to experiment with liveslak in a VM.
-KMODS=${KMODS:-"squashfs:overlay:loop:efivarfs:xhci-pci:ohci-pci:ehci-pci:xhci-hcd:uhci-hcd:ehci-hcd:mmc-core:mmc-block:sdhci:sdhci-pci:sdhci-acpi:rtsx_pci:rtsx_pci_sdmmc:usb-storage:uas:hid:usbhid:i2c-hid:hid-generic:hid-apple:hid-cherry:hid-logitech:hid-logitech-dj:hid-logitech-hidpp:hid-lenovo:hid-microsoft:hid_multitouch:jbd:mbcache:ext3:ext4:isofs:fat:nls_cp437:nls_iso8859-1:msdos:vfat:exfat:ntfs:virtio_ring:virtio:virtio_blk:virtio_balloon:virtio_pci:virtio_pci_modern_dev:virtio_net"}
+KMODS=${KMODS:-"squashfs:overlay:loop:efivarfs:xhci-pci:ohci-pci:ehci-pci:xhci-hcd:uhci-hcd:ehci-hcd:mmc-core:mmc-block:sdhci:sdhci-pci:sdhci-acpi:rtsx_pci:rtsx_pci_sdmmc:usb-storage:uas:hid:usbhid:i2c-hid:hid-generic:hid-apple:hid-cherry:hid-logitech:hid-logitech-dj:hid-logitech-hidpp:hid-lenovo:hid-microsoft:hid_multitouch:jbd:mbcache:ext3:ext4:zstd_compress:lz4hc_compress:lz4_compress:btrfs:f2fs:jfs:xfs:isofs:fat:nls_cp437:nls_iso8859-1:msdos:vfat:exfat:ntfs:virtio_ring:virtio:virtio_blk:virtio_balloon:virtio_pci:virtio_pci_modern_dev:virtio_net"}
# Network kernel modules to include for NFS root support:
NETMODS="kernel/drivers/net kernel/drivers/virtio"
@@ -147,22 +175,32 @@ NETEXCL="appletalk arcnet bonding can dummy.ko hamradio hippi ifb.ko irda macvla
#
# Clean up in case of failure:
-cleanup() {
+function cleanup() {
# Clean up by unmounting our loopmounts, deleting tempfiles:
echo "--- Cleaning up the staging area..."
# During cleanup, do not abort due to non-zero exit code:
set +e
sync
+
+ if [ -n "$CNTDEV" ]; then
+ # In case of failure, only most recent LUKS mapped device is still open:
+ if mount | grep -q ${CNTDEV} ; then
+ umount -f ${CNTDEV}
+ cryptsetup luksClose $(basename ${CNTDEV})
+ losetup -d ${LODEV}
+ fi
+ fi
+
# No longer needed:
[ -n "${IMGDIR}" ] && ( rm -rf $IMGDIR )
[ -n "${KERDIR}" ] && ( rm -rf $KERDIR )
if [ -n "${USBMNT}" ]; then
if mount |grep -qw ${USBMNT} ; then umount ${USBMNT} ; fi
- rm -rf $USBMNT
+ rmdir $USBMNT
fi
if [ -n "${EFIMNT}" ]; then
if mount |grep -qw ${EFIMNT} ; then umount ${EFIMNT} ; fi
- rm -rf $EFIMNT
+ rmdir $EFIMNT
fi
set -e
} # End of cleanup()
@@ -170,7 +208,7 @@ cleanup() {
trap 'echo "*** $0 FAILED at line $LINENO ***"; cleanup; exit 1' ERR INT TERM
# Show the help text for this script:
-showhelp() {
+function showhelp() {
cat <<EOT
#
# Purpose: to update the content of a Slackware Live USB stick.
@@ -178,6 +216,7 @@ cat <<EOT
# $(basename $0) accepts the following parameters:
# -b|--nobackup Do not try to backup original kernel and modules.
# -d|--devices List removable devices on this computer.
+# -e|--examples Show some common usage examples.
# -h|--help This help.
# -i|--init <filename> Replacement init script.
# -k|--kernel <filename> The kernel file (or package).
@@ -190,27 +229,71 @@ cat <<EOT
# providing a devicename (using option '-o').
# -v|--verbose Show verbose messages.
# -w|--wait<number> Add <number> seconds wait time to initialize USB.
-#
-# Note that if you upgrade the kernel and modules using $(basename $0),
-# this will apply only to the USB boot kernel and its initrd!
-# Before running $(basename $0) to upgrade the kernel & modules,
-# you first need to upgrade the kernel-generic and kernel-modules packages
-# in the Live OS using installpkg/upgradepkg or slackpkg.
+# -x|--extend <fullpath> Full path (either in your filesystem or else
+# relative to the USB partition root)
+# to an existing (encrypted) container file,
+# whose size you want to extend.
+# Limitations:
+# - container needs to be LUKS encrypted.
+# - filename extension needs to be '${CNTEXT}'.
+# Supported filesystems inside container:
+# - $(resizefs).
+# -N|--nolivemods Don't create an addon live module containing
+# the new kernelmodules. Normally you *will* need
+# this addon module, *unless* you have already
+# installed these kernel-modules in the Live OS.
+# FYI: the kernel and module upgrade applies only
+# to the USB boot kernel and its initrd.
+# -X|--extendsize <size|perc> Extend size of existing container; value
+# is the requested extension of the container
+# in kB, MB, GB, or as percentage of free space
+# (integer numbers only).
+# Examples: '-X 125M', '-X 2G', '-X 20%'.
#
EOT
} # End of showhelp()
+function showexamples() {
+cat <<EOT
+#
+# Some common usage examples for $(basename $0)
+# ---------------------------------------------------------------------------
+#
+# Get a listing of all available removable devices on the computer:
+# ./$(basename $0) -d
+#
+# Updating kernel and modules, providing two packages as input and assuming
+# that the USB stick is known as /dev/sdX:
+# ./$(basename $0) -o /dev/sdX -m kernel-modules-4.19.0-x86_64-1.txz -k kernel-generic-4.19.0-x86_64-1.txz
+#
+# Restore the previous kernel and modules after a failed update,
+# and let the script scan your computer for the insertion of your USB stick:
+# ./$(basename $0) -s -r
+#
+# Replace the Live init script with the latest template taken from
+# the liveslak git repository:
+# wget https://git.liveslak.org/liveslak/plain/liveinit.tpl
+# ./$(basename $0) -o /dev/sdX -i liveinit.tpl
+#
+# Extend the size of the pre-existing LUKS container for your homedirectory
+# with 3 GB, and let the script scan for the insertion of your USB stick:
+# ./$(basename $0) -s -x /slhome.img -X 3G
+#
+EOT
+} # End of showexamples()
+
# Scan for insertion of a USB device:
-scan_devices() {
+function scan_devices() {
+ local MYSCANWAIT="${1}"
local BD
# Inotifywatch does not trigger on symlink creation,
# so we can not watch /sys/block/
- BD=$(inotifywait -q -t ${SCANWAIT} -e create /dev 2>/dev/null |cut -d' ' -f3)
+ BD=$(inotifywait -q -t ${MYSCANWAIT} -e create /dev 2>/dev/null |cut -d' ' -f3)
echo ${BD}
} # End of scan_devices()
# Show a list of removable devices detected on this computer:
-show_devices() {
+function show_devices() {
local MYDATA="${*}"
if [ -z "${MYDATA}" ]; then
MYDATA="$(ls --indicator-style=none /sys/block/ |grep -Ev '(ram|loop|dm-)')"
@@ -224,8 +307,110 @@ show_devices() {
echo "#"
} # End of show_devices()
+# Determine size of a mounted partition (in MB):
+function get_part_mb_size() {
+ local MYPART="${1}"
+ local MYSIZE
+ MYSIZE=$(df -P -BM ${MYPART} |tail -n -1 |tr -s '\t' ' ' |cut -d' ' -f2)
+ echo "${MYSIZE%M}"
+} # End of get_part_mb_size()
+
+# Determine free space of a mounted partition (in MB):
+function get_part_mb_free() {
+ local MYPART="${1}"
+ local MYSIZE
+ MYSIZE=$(df -P -BM ${MYPART} |tail -n -1 |tr -s '\t' ' ' |cut -d' ' -f4)
+ echo "${MYSIZE%M}"
+} # End of get_part_mb_free()
+
+# Determine requested container size in MB (allow for '%|k|K|m|M|g|G' suffix).
+# Note: sizes need to be integer values! Bash arithmetics don't work for floats.
+function cont_mb() {
+ # Uses global variables: PARTFREE
+ local MYSIZE="$1"
+ case "${MYSIZE: -1}" in
+ "%") MYSIZE="$(( $PARTFREE * ${MYSIZE%\%} / 100 ))" ;;
+ "k") MYSIZE="$(( ${MYSIZE%k} / 1024 ))" ;;
+ "K") MYSIZE="$(( ${MYSIZE%K} / 1024 ))" ;;
+ "m") MYSIZE="${MYSIZE%m}" ;;
+ "M") MYSIZE="${MYSIZE%M}" ;;
+ "g") MYSIZE="$(( ${MYSIZE%g} * 1024 ))" ;;
+ "G") MYSIZE="$(( ${MYSIZE%G} * 1024 ))" ;;
+ *) MYSIZE=-1 ;;
+ esac
+ echo "$MYSIZE"
+} # End of cont_mb()
+
+# Expand existing encrypted container file:
+function expand_container() {
+ # Uses external function: cleanup
+ # Uses global variables: CNTEXT, MINFREE
+ # Sets global variables: CNTDEV, LODEV, PARTFREE, PARTSIZE
+ local MYPART="$1" # disk partition
+ local MYINC="$2" # requested increase ('%|k|K|m|M|g|G' suffix)
+ local MYFILE="$3" # full path to ${CNTEXT} containerfile
+ local MYMAP="" # Name of the device-mapped file
+ local CNTIS="" # Stores size of the container
+
+ # Determine requested container increase in MB:
+ MYINC=$(cont_mb ${MYINC})
+
+ # Determine size of the target partition (in MB), and the free space:
+ PARTSIZE=$(get_part_mb_size ${MYPART})
+ PARTFREE=$(get_part_mb_free ${MYPART})
+
+ if [ $PARTFREE -lt $(( ${MYINC} + ${MINFREE} )) ]; then
+ echo "*** Free space on USB partition after file-resizing would be less than ${MINFREE} MB;"
+ echo "*** Not resizing the container file!"
+ cleanup
+ exit 1
+ fi
+
+ if ! file ${MYFILE} |grep -q 'LUKS' ; then
+ echo "*** No LUKS container: '${MYFILE}'"
+ cleanup
+ exit 1
+ else
+ echo "--- Expanding '$(basename ${MYFILE})' on '${MYPART}' with ${MYINC} MB..."
+ fi
+
+ # Append random bytes to the end of the container file:
+ dd if=/dev/urandom of=${MYFILE} bs=1M count=${MYINC} oflag=append conv=notrunc 2>/dev/null
+
+ # Setup a loopback device that we can use with or without cryptsetup:
+ LODEV=$(losetup -f)
+ losetup ${LODEV} ${MYFILE}
+
+ if cryptsetup isLuks ${LODEV} ; then
+ # Unlock LUKS encrypted container first:
+ MYMAP=$(basename ${MYFILE} ${CNTEXT})
+ CNTDEV=/dev/mapper/${MYMAP}
+ echo "--- Unlocking the LUKS container requires your passphrase..."
+ until cryptsetup luksOpen ${LODEV} ${MYMAP} ; do
+ echo ">>> Did you type an incorrect passphrases?"
+ read -p ">>> Press [ENTER] to try again or Ctrl-C to abort ..." REPLY
+ done
+ else
+ # Use the loopmounted block device for the un-encrypted container:
+ CNTDEV=${LODEV}
+ fi
+
+ # Run fsck so the filesystem is clean before we resize it:
+ fsck -fvy ${CNTDEV}
+ # Resize the filesystem to occupy the full new size:
+ resizefs ${CNTDEV}
+ # Just to be safe:
+ fsck -fvy ${CNTDEV}
+
+ # Don't forget to clean up after ourselves:
+ if cryptsetup isLuks ${LODEV} ; then
+ cryptsetup luksClose ${MYMAP}
+ fi
+ losetup -d ${LODEV} || true
+} # End of expand_container()
+
# Uncompress the initrd based on the compression algorithm used:
-uncompressfs () {
+function uncompressfs () {
if $(file "${1}" | grep -qi ": gzip"); then
gzip -cd "${1}"
elif $(file "${1}" | grep -qi ": XZ"); then
@@ -233,10 +418,76 @@ uncompressfs () {
fi
} # End of uncompressfs ()
+# Resize the filesystem on a block device:
+function resizefs() {
+ # Uses external function: cleanup
+ local MYDEV="${1}"
+ local MYFS
+ local TMPMNT
+
+ if [ -z "${MYDEV}" ]; then
+ # Without arguments given, reply with list of supported fs'es:
+ echo "btrfs,ext2,ext4,f2fs,jfs,xfs"
+ return
+ fi
+
+ # Determine the current filesystem for the block device:
+ MYFS=$(lsblk -n -o FSTYPE ${MYDEV})
+ if [ -z "${MYFS}" ]; then
+ echo "*** Failed to resize filesystem on device '${MYDEV}'!"
+ echo "*** No filesystem found."
+ cleanup
+ exit 1
+ fi
+
+ TMPMNT=$(mktemp -d -p ${TMP:=/tmp} -t alienres.XXXXXX)
+ if [ ! -d $TMPMNT ]; then
+ echo "*** Failed to create temporary mount for the filesystem resize!"
+ cleanup
+ exit 1
+ else
+ chmod 711 ${TMPMNT}
+ fi
+
+ # Mount the block device prior to the resize
+ # (btrfs, jfs and xfs do not support offline resize):
+ mount -o rw -t ${MYFS} ${MYDEV} ${TMPMNT}
+
+ # Resize the filesystem to occupy the full new device capacity:
+ case "${MYFS}" in
+ btrfs) btrfs filesystem resize max ${TMPMNT}
+ ;;
+ ext*) resize2fs ${MYDEV}
+ ;;
+ f2fs) resize.f2fs ${MYDEV}
+ ;;
+ jfs) mount -o remount,resize,rw ${TMPMNT}
+ ;;
+ xfs) xfs_growfs -d ${TMPMNT}
+ ;;
+ *) echo "*** Unsupported filesystem '${MYFS}'!"
+ cleanup
+ exit 1
+ ;;
+ esac
+
+ if [ ! $? ]; then
+ echo "*** Failed to resize '${MYFS}'filesystem on device '${MYDEV}'!"
+ cleanup
+ exit 1
+ else
+ # Un-mount the device again:
+ sync
+ umount ${TMPMNT}
+ rmdir ${TMPMNT}
+ fi
+} # End of resizefs()
+
+
# Collect the kernel modules we need for the liveslak initrd.
# When calling this function, the old module tree must already
# have been renamed to ${OLDKVER}.prev
-collect_kmods() {
+function collect_kmods() {
local IMGDIR="$1"
# Borrow (and mangle) code from Slackware's mkinitrd
@@ -369,9 +620,15 @@ collect_kmods() {
fi
} # End of collect_kmods ()
-# Read configuration data from old initrd:
-read_initrd() {
+# Read configuration data from old initrd,
+# after it has been extracted into a directory:
+function read_initrddir() {
local IMGDIR="$1"
+ local INITVARS="$2"
+ local OLDKVER
+ local OLDMODDIR
+ local OLDKMODDIRSIZE
+ local PREVMODDIR
cd ${IMGDIR}
@@ -379,7 +636,7 @@ read_initrd() {
OLDWAIT=$(cat ./wait-for-root)
# Read the values of liveslak template variables in the init script:
- for TEMPLATEVAR in DEF_KBD DEF_LOCALE DEF_TZ DISTRO LIVE_HOSTNAME LIVEMAIN LIVEUID MARKER MEDIALABEL PERSISTENCE CORE2RAMMODS SQ_EXT_AVAIL VERSION ; do
+ for TEMPLATEVAR in ${INITVARS} ; do
eval $(grep "^ *${TEMPLATEVAR}=" ./init |head -1)
done
@@ -411,23 +668,36 @@ read_initrd() {
fi
fi
fi
-} # End read_initrd()
-
-# Extract the initrd:
-extract_initrd() {
- local IMGFILE="$1"
+} # End read_initrddir()
+
+# Extract the initrd into a new directory and report the dirname back:
+function extract_initrd() {
+ local MYIMGFILE="$1"
+ local MYIMGDIR=$(mktemp -d -p ${TMP:=/tmp} -t alienimg.XXXXXX)
+ if [ ! -d $MYIMGDIR ]; then
+ echo "*** Failed to create temporary extraction directory for the initrd!"
+ cleanup
+ exit 1
+ else
+ chmod 711 $MYIMGDIR
+ fi
- cd ${IMGDIR}
- uncompressfs ${IMGFILE} \
- | cpio -i -d -m -H newc
+ cd ${MYIMGDIR}
+ uncompressfs ${MYIMGFILE} 2>/dev/null \
+ | cpio -i -d -m -H newc 2>/dev/null
+ echo "$MYIMGDIR"
} # End of extract_initrd()
# Modify the extracted initrd and re-pack it:
-update_initrd() {
- local IMGFILE="$1"
+function update_initrd() {
+ local MYIMGFILE="$1"
+ local MYIMGDIR="$2"
local NEED_RECOMP=0
+ local NEWMODDIR
+ local OLDMODDIR
+ local OLDKVER
- cd ${IMGDIR}
+ cd ${MYIMGDIR}
if [ ${WAIT} -ge 0 ]; then
if [ $WAIT != $OLDWAIT ]; then
echo "--- Updating 'waitforroot' time from '$OLDWAIT' to '$WAIT'"
@@ -438,24 +708,23 @@ update_initrd() {
if [ $UPKERNEL -eq 1 ]; then
OLDMODDIR=$(find ./lib/modules -type d -mindepth 1 -maxdepth 1 |grep -v .prev)
+ OLDKVER=$(strings $(find ${OLDMODDIR}/kernel/ -name "*.ko*" |head -1) |grep ^vermagic |cut -d= -f2 |cut -d' ' -f1)
rm -rf ./lib/modules/*.prev
if [ $KBACKUP -eq 1 ]; then
# We make one backup:
- if [ $VERBOSE -eq 1 ]; then
- echo "--- Making backup of kernel modules"
- fi
+ echo "--- Making backup of kernel modules (${OLDKVER}) in initrd"
mv -i ${OLDMODDIR} ${OLDMODDIR}.prev
else
- echo "--- No room for backing up old kernel modules"
+ echo "--- No room for backing up old kernel modules in initrd"
rm -rf ${OLDMODDIR}
fi
# Add modules for the new kernel:
- echo "--- Adding new kernel modules"
- collect_kmods ${IMGDIR}
+ echo "--- Adding new kernel modules (${KVER}) to initrd"
+ collect_kmods ${MYIMGDIR}
NEED_RECOMP=1
elif [ $RESTORE -eq 1 -a $KRESTORE -eq 1 ]; then
# Restore previous kernel module tree.
- # The 'read_initrd' routine will already have checked that we have
+ # The 'read_initrddir' routine will already have checked that we have
# one active and one .prev modules tree:
OLDMODDIR=$(find ./lib/modules -type d -mindepth 1 -maxdepth 1 |grep .prev || true)
NEWMODDIR=$(find ./lib/modules -type d -mindepth 1 -maxdepth 1 |grep -v .prev)
@@ -466,6 +735,11 @@ update_initrd() {
fi
if [ -n "${LIVEINIT}" ]; then
+ if ! file "${LIVEINIT}" |grep -q 'shell script' ; then
+ echo "*** Not a shell script: "${LIVEINIT}"!"
+ cleanup
+ exit 1
+ fi
echo "--- Replacing live init script"
cp ./init ./init.prev
if grep -q "@LIVEMAIN@" ${LIVEINIT} ; then
@@ -480,19 +754,21 @@ update_initrd() {
if [ ${NEED_RECOMP} -eq 1 ]; then
echo "--- Compressing the initrd image again"
- chmod 0755 ${IMGDIR}
- find . |cpio -o -H newc |$COMPR > ${IMGFILE}
+ chmod 0755 ${MYIMGDIR}
+ find . |cpio -o -H newc |$COMPR > ${MYIMGFILE}
fi
- cd - 1>/dev/null # End of 'cd ${IMGDIR}'
+ cd - 1>/dev/null # End of 'cd ${MYIMGDIR}'
} # End of update_initrd()
# Accept either a kernelimage or a packagename,
# and return the path to a kernelimage:
-getpath_kernelimg () {
+function getpath_kernelimg () {
local MYDATA="${*}"
- [ -z "${MYDATA}" ] && echo ""
- if [ -n "$(file "${MYDATA}" |grep -E 'x86 boot (executable|sector)')" ]; then
+ if [ -z "${MYDATA}" ]; then
+ echo ""
+ return
+ elif [ -n "$(file "${MYDATA}" |grep -E 'x86 boot (executable|sector)')" ]; then
# We have a kernel image:
echo "${MYDATA}"
else
@@ -505,38 +781,48 @@ getpath_kernelimg () {
# Accept either a directory containing module tree, or a packagename,
# and return the path to a module tree:
-getpath_kernelmods () {
+function getpath_kernelmods () {
local MYDATA="${*}"
- [ -z "${MYDATA}" ] && echo ""
+ local MYKVER
- if [ -d "${MYDATA}" ]; then
+ if [ -z "${MYDATA}" ]; then
+ echo ""
+ return
+ elif [ -d "${MYDATA}" ]; then
# We have directory, assume it contains the kernel modules:
- echo "${MYDATA}"
+ MYKVER=$(strings $(find ${MYDATA}/kernel/ -name "*.ko*" |head -1) |grep ^vermagic |cut -d= -f2 |cut -d' ' -f1)
+ if [ -z "${MYKVER}" ]; then
+ echo "*** Could not determine new kernel version from module directory!"
+ cleanup
+ exit 1
+ fi
+ mkdir -p ${KERDIR}/lib/modules/${MYKVER}
+ rsync -a ${MYDATA}/ ${KERDIR}/lib/modules/${MYKVER}/
else
# We assume a Slackware package:
# Extract the kernel modules from the package and return the path:
tar -C ${KERDIR} -xf ${MYDATA} lib/modules
- cd ${KERDIR}/lib/modules/*
- pwd
fi
+ cd ${KERDIR}/lib/modules/*
+ pwd
} # End of getpath_kernelmods
# Determine size of a mounted partition (in MB):
-get_part_mb_size() {
+function get_part_mb_size() {
local MYSIZE
MYSIZE=$(df -P -BM ${1} |tail -1 |tr -s '\t' ' ' |cut -d' ' -f2)
echo "${MYSIZE%M}"
} # End of get_part_mb_size
# Determine free space of a mounted partition (in MB):
-get_part_mb_free() {
+function get_part_mb_free() {
local MYSIZE
MYSIZE=$(df -P -BM ${1} |tail -1 |tr -s '\t' ' ' |cut -d' ' -f4)
echo "${MYSIZE%M}"
} # End of get_part_mb_free
-parse_template() {
- # Parse a liveslak template file and substitute the placeholders.
+# Parse a liveslak template file and substitute the placeholders.
+function parse_template() {
local INFILE="$1"
local OUTFILE="$2"
@@ -587,6 +873,10 @@ while [ ! -z "$1" ]; do
show_devices
exit
;;
+ -e|--examples)
+ showexamples
+ exit
+ ;;
-h|--help)
showhelp
exit
@@ -631,6 +921,18 @@ while [ ! -z "$1" ]; do
WAIT="$2"
shift 2
;;
+ -N|--nolivemods)
+ NOLIVEMODS=1
+ shift
+ ;;
+ -x|--extend)
+ EXTENSION="$2"
+ shift 2
+ ;;
+ -X|--extendsize)
+ INCSIZE="$2"
+ shift 2
+ ;;
*)
echo "*** Unknown parameter '$1'!"
exit 1
@@ -651,8 +953,8 @@ fi
# Either provide a block device, or else scan for a block device:
if [ -z "$TARGET" ]; then
if [ $SCAN -eq 1 ]; then
- echo "-- Waiting ${SCANWAIT} seconds for a USB stick to be inserted..."
- TARGET=$(scan_devices)
+ echo "--- Waiting ${SCANWAIT} seconds for a USB stick to be inserted..."
+ TARGET=$(scan_devices ${SCANWAIT})
if [ -z "$TARGET" ]; then
echo "*** No new USB device detected during $SCANWAIT seconds scan."
exit 1
@@ -661,6 +963,7 @@ if [ -z "$TARGET" ]; then
fi
else
echo "*** You must specify the Live USB devicename (option '-o')!"
+ echo "*** Alternatively, let the script scan for insertion (option '-s')!"
exit 1
fi
elif [ $SCAN -eq 1 ]; then
@@ -712,7 +1015,6 @@ else
KVER=$(strings $(find ${KMODDIR}/kernel/ -name "*.ko*" |head -1) |grep ^vermagic |cut -d= -f2 |cut -d' ' -f1)
if [ -z "${KVER}" ]; then
echo "*** Could not determine kernel version from the module directory"
- echo "*** (querying module kernel/fs/overlayfs/overlay.ko)!"
cleanup
exit 1
fi
@@ -726,7 +1028,16 @@ if [ -n "${LIVEINIT}" -a ! -f "${LIVEINIT}" ]; then
exit 1
fi
-if [ $CHANGES2SXZ -eq 1 ]; then
+if [ -n "${EXTENSION}" ]; then
+ if [ -z "${INCSIZE}" ]; then
+ echo "*** LUKS container '${EXTENSION}' defined but no extension size provided!"
+ echo "*** Not extending encrypted ${EXTENSION}, please use '-X' parameter."
+ cleanup
+ exit 1
+ fi
+fi
+
+if [ $CHANGES2SXZ -eq 1 ] || [ $UPKERNEL -eq 1 ]; then
# We need to create a module, so add squashfs to the required tools:
REQTOOLS="${REQTOOLS} mksquashfs"
fi
@@ -739,9 +1050,9 @@ for PROGN in ${REQTOOLS} ; do
fi
done
if [ ! -z "$PROG_MISSING" ] ; then
- echo "-- Required program(s) not found in search path '$PATH'!"
+ echo "--- Required program(s) not found in search path '$PATH'!"
echo -e ${PROG_MISSING}
- echo "-- Exiting."
+ echo "--- Exiting."
cleanup
exit 1
fi
@@ -766,7 +1077,7 @@ echo q |gdisk -l $TARGET 2>/dev/null | \
# If the user just used the scan option (-s) and did not select a task,
# we will exit the script gracefully now:
-if [[ $WAIT -lt 0 && $UPKERNEL -ne 1 && $RESTORE -ne 1 && $NETSUPPORT -ne 1 && $LIVEINIT = "" && $CHANGES2SXZ -ne 1 ]]; then
+if [[ $WAIT -lt 0 && $UPKERNEL -ne 1 && $RESTORE -ne 1 && $NETSUPPORT -ne 1 && $LIVEINIT = "" && $CHANGES2SXZ -ne 1 && $EXTENSION = "" ]]; then
cleanup
exit 0
else
@@ -786,15 +1097,19 @@ TARGETP1=$(fdisk -l $TARGET |grep ^$TARGET |cut -d' ' -f1 |grep -E '[^0-9]1$')
TARGETP2=$(fdisk -l $TARGET |grep ^$TARGET |cut -d' ' -f1 |grep -E '[^0-9]2$')
TARGETP3=$(fdisk -l $TARGET |grep ^$TARGET |cut -d' ' -f1 |grep -E '[^0-9]3$')
-# Create a temporary extraction directory for the initrd:
-mkdir -p /mnt
-IMGDIR=$(mktemp -d -p /mnt -t alienimg.XXXXXX)
-if [ ! -d $IMGDIR ]; then
- echo "*** Failed to create temporary extraction directory for the initrd!"
- cleanup
- exit 1
+# Normalize filepath:
+if [ -f "${EXTENSION}" ]; then
+ # Container is an actual file, so where are we mounted?
+ EXTPART=$(cd "$(dirname "${EXTENSION}")" ; df --output=source . |tail -1)
+ EXTMNT=$(cd "$(dirname "${EXTENSION}")" ; df --output=target . |tail -1)
+ if [ "${EXTPART}" == "${TARGETP3}" ]; then
+ # User already mounted the USB linux partition; remove mountpoint:
+ EXTENSION="${EXTENSION#$EXTMNT}"
+ fi
+elif [ "$(dirname ${EXTENSION})" == "." ]; then
+ # Containerfile was provided without leading slash, add one:
+ EXTENSION="/${EXTENSION}"
fi
-chmod 711 $IMGDIR
# Create temporary mount point for the USB device:
mkdir -p /mnt
@@ -832,13 +1147,27 @@ EFIPFREE=$(get_part_mb_free ${EFIMNT})
# Record the Slackware Live version:
OLDVERSION="$(cat ${USBMNT}/.isoversion 2>/dev/null)"
-echo "-- The medium '${TARGET}' contains '${OLDVERSION}'"
+echo "--- The medium '${TARGET}' contains '${OLDVERSION}'"
+
+# Try a write to the partition:
+if touch ${USBMNT}/.rwtest 2>/dev/null && rm ${USBMNT}/.rwtest 2>/dev/null
+then
+ echo "--- The partition '${TARGETP3}' is writable."
+else
+ echo "--- Trying to remount readonly partition '${TARGETP3}' as writable..."
+ mount -o remount,rw ${USBMNT}
+ if [ $? -ne 0 ]; then
+ echo "*** Failed to remount '${TARGETP3}' writable, unable to continue!"
+ cleanup
+ exit 1
+ fi
+fi
# Find out if the USB contains an EFI bootloader and use it:
if [ ! -f ${EFIMNT}/EFI/BOOT/boot*.efi ]; then
EFIBOOT=0
- echo "-- Note: UEFI boot file 'bootx64.efi' or 'bootia32.efi' not found on ISO."
- echo "-- UEFI boot will not be supported"
+ echo "--- Note: UEFI boot file 'bootx64.efi' or 'bootia32.efi' not found on ISO."
+ echo "--- UEFI boot will not be supported"
else
EFIBOOT=1
fi
@@ -853,10 +1182,10 @@ fi
OLDKERNELSIZE=$(du -sm "${KIMG}" |tr '\t' ' ' |cut -d' ' -f1)
# Collect data from the USB initrd:
-extract_initrd ${USBMNT}/boot/initrd.img
-read_initrd ${IMGDIR}
+IMGDIR="$( extract_initrd ${USBMNT}/boot/initrd.img )"
+read_initrddir ${IMGDIR} "DEF_KBD DEF_LOCALE DEF_TZ DISTRO LIVE_HOSTNAME LIVEMAIN LIVEUID MARKER MEDIALABEL PERSISTENCE CORE2RAMMODS SQ_EXT_AVAIL VERSION"
-# The read_initrd routine will set SUPPORTED to '0'
+# The read_initrddir routine will set SUPPORTED to '0'
# if it finds a non-standard configuration for kernel & modules:
if [ $KBACKUP -eq 1 ]; then
if [ $SUPPORTED -ne 1 ]; then
@@ -883,14 +1212,27 @@ if [ $KBACKUP -eq 1 ]; then
fi
# Update the initrd with regard to USB wait time, liveinit, kernel:
-update_initrd ${USBMNT}/boot/initrd.img
+update_initrd ${USBMNT}/boot/initrd.img ${IMGDIR}
+
+# Add the new modules as a squashfs module:
+if [ $UPKERNEL -eq 1 ] && [ $NOLIVEMODS -eq 0 ]; then
+ LIVE_MOD_SYS=$(dirname $(find ${USBMNT} -name "0099-${DISTRO}_zzzconf*.sxz" |head -1))
+ LIVE_MOD_ADD=$(dirname ${LIVE_MOD_SYS})/addons
+ MODNAME="0100-${DISTRO}_kernelmodules_${KVER}.sxz"
+ echo "--- Creating kernelmodules addon live module '${MODNAME}'"
+ rm -f ${LIVE_MOD_ADD}/${MODNAME}
+ mksquashfs ${KERDIR} ${LIVE_MOD_ADD}/${MODNAME} -e boot -noappend -comp xz -b 1M
+ unset LIVE_MOD_SYS LIVE_MOD_ADD MODNAME
+fi
# Take care of the kernel in the Linux partition:
if [ $UPKERNEL -eq 1 ]; then
if [ $KBACKUP -eq 1 ]; then
# We always make one backup with the suffix ".prev":
if [ $VERBOSE -eq 1 ]; then
- echo "-- Backing up ${KIMG} to ${USBMNT}/boot/$(basename \"${KIMG}\").prev"
+ echo "--- Backing up ${KIMG} to ${USBMNT}/boot/$(basename \"${KIMG}\").prev"
+ else
+ echo "--- Backing up old kernel"
fi
mv "${KIMG}" ${USBMNT}/boot/$(basename "${KIMG}").prev
else
@@ -898,15 +1240,21 @@ if [ $UPKERNEL -eq 1 ]; then
fi
# And we name our new kernel exactly as the old one:
if [ $VERBOSE -eq 1 ]; then
- echo "-- Copying \"${KERNEL}\" to ${USBMNT}/boot/$(basename \"${KIMG}\")"
+ echo "--- Copying \"${KERNEL}\" to ${USBMNT}/boot/$(basename \"${KIMG}\")"
+ else
+ echo "--- Adding new kernel"
fi
cp "${KERNEL}" ${USBMNT}/boot/$(basename "${KIMG}")
elif [ $RESTORE -eq 1 -a $KRESTORE -eq 1 ]; then
if [ $VERBOSE -eq 1 ]; then
- echo "-- Restoring ${USBMNT}/boot/$(basename \"${KIMG}\").prev to ${KIMG}"
+ echo "--- Restoring ${USBMNT}/boot/$(basename \"${KIMG}\").prev to ${KIMG}"
+ else
+ echo "--- Restoring old kernel"
fi
+ OLDKVER=$(file "${KIMG}" |sed 's/^.*\(version [^ ]* \).*$/\1/' |cut -d' ' -f2)
rm -f "${KIMG}"
mv ${USBMNT}/boot/$(basename "${KIMG}").prev "${KIMG}"
+ echo "--- You may remove obsolete 'addons/0100-${DISTRO}_kernelmodules_${OLDKVER}.sxz' module"
fi
if [ $EFIBOOT -eq 1 ]; then
@@ -936,12 +1284,24 @@ if [ $CHANGES2SXZ -eq 1 ]; then
LIVE_MOD_SYS=$(dirname $(find ${USBMNT} -name "0099-${DISTRO}_zzzconf*.sxz" |head -1))
LIVE_MOD_ADD=$(dirname ${LIVE_MOD_SYS})/addons
MODNAME="0100-${DISTRO}_customchanges-$(date +%Y%m%d%H%M%S).sxz"
- echo "-- Moving current persistence data into addons module '${MODNAME}'"
+ echo "--- Moving current persistence data into addons module '${MODNAME}'"
mksquashfs /mnt/live/changes ${LIVE_MOD_ADD}/${MODNAME} -noappend -comp xz -b 1M -e .wipe
fi
fi
fi
+# Should we extend the size of a container?
+if [ -n "${EXTENSION}" ]; then
+ if [ "$(basename ${EXTENSION} ${CNTEXT})" == "$(basename ${EXTENSION})" ];
+ then
+ echo "*** File '${EXTENSION}' does not have an '${CNTEXT}' extension!"
+ cleanup
+ exit 1
+ fi
+ # Expand existing container file:
+ expand_container ${TARGETP3} ${INCSIZE} ${USBMNT}/${EXTENSION}
+fi
+
# Unmount/remove stuff:
cleanup