summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.txt130
-rw-r--r--isocomp.sh763
-rw-r--r--liveinit.tpl276
-rwxr-xr-xmake_slackware_live.sh5
4 files changed, 1117 insertions, 57 deletions
diff --git a/README.txt b/README.txt
index 64d8ba9..79ae1f8 100644
--- a/README.txt
+++ b/README.txt
@@ -13,6 +13,8 @@ The USB version is "persistent" - meaning that the OS stores your updates on the
In order to protect your sensitive private data in case you lose your USB stick (or in case it gets stolen) you can enhance your persistent USB Live OS with an encrypted homedirectory and/or an encrypted persistence file, to be unlocked on boot with a passphrase that only you know.
+And even booting directly from the ISO file (see chapter ''Boot from an ISO file on disk'') you can use persistence and enjoy an encrypted homedirectory, without the need for any modification to the ISO file.
+
===== Why yet another Slackware Live =====
@@ -142,7 +144,9 @@ menuentry " LIVESLAK ISO" --class gnu-linux --class os --class icon-linux {
linux (loop)/boot/generic livemedia=scandev:$iso $bootparms
initrd (loop)/boot/initrd.img
}</code>
-This example will add a 'LIVESLAK ISO' menu entry to your local computer's boot menu, through which you can start a downloaded XFCE Live ISO pre-configured for a US keyboard, Dutch language and Amsterdam timezone.
+This example will add a 'LIVESLAK ISO' menu entry to your local computer's boot menu, through which you can start a XFCE Live ISO which you previously downloaded to directory ''/data/ISOS/'', pre-configured for a US keyboard, Dutch language and Amsterdam timezone.
+
+Alternatively you could look into Ventoy, which is a tool to create a bootable USB drive containing multiple ISO files. Ventoy allows you to boot from any of these ISOs by automatically generating on every boot a Grub menu containing all the images found on disk. Liveslak is fully Ventoy-compatible. Website: https://www.ventoy.net/ .
==== Transfering ISO content to USB stick ====
@@ -196,6 +200,80 @@ Examples:
You might have noticed that the "-P" parameter does not accept a size parameter. This is because the unencrypted container file is created as a 'sparse' file that starts at zero size and is allowed to grow dynmically to a maximum of 90% of the initial free space on the Linux partition of the USB stick.
+==== Adding functionality when booting directly off an ISO on disk ====
+
+
+An ISO companion script is available which enables you to add functionality in cases where you want to boot directly from an ISO file. For instance, when having added the ISO file as a selection in your Grub menu, or when using a 3rd-party boot manager like Ventoy. Typically, a Live ISO is immutable (its ISO-9660 filesystem is read-only) and when you boot off it, the Live OS does not have persistence. The system starts in a virgin state, every boot.
+
+The ISO companion script can add encrypted persistence and homedirectory container files to the disk partition which can be VFAT or EXFAT if you want. It also can create a directory structure on-disk from which liveslak can load additional live modules that are not present inside the ISO (both 'addons' and 'optional').
+
+The script is called 'isocomp.sh', and it accepts the following parameters: <code>
+ -d|--directory <path> Create a liveslak directory structure to store
+ additional modules. The parameter value is
+ used as the root path below which the
+ liveslak/{addons,optional} subdirectories
+ will be created.
+ -e|--examples Show some common usage examples.
+ -f|--force Force execution in some cases where the script
+ reports an issue.
+ -h|--help This help text.
+ -i|--iso <fullpath> Full path to your liveslak ISO image.
+ -l|--lukscontainer <fullpath> Full path to encrypted container file to be
+ created by this script, and to be mounted
+ in the live OS under /home
+ (or any other mountpoint you supply).
+ (filename needs to end in '.icc'!).
+ -p|--persistence <fullpath > Full path to encrypted persistence container
+ file to be created in the filesystem
+ (filename extension must be '.icc'!).
+ -x|--extend <fullpath> Full path to existing (encrypted) container
+ file that you want to extend in size
+ (filename needs to end in '.icc'!).
+ Limitations:
+ - container needs to be LUKS encrypted, and
+ - internal filesystem needs to be ext{2,3,4}.
+ -L|--lcsize <size|perc> Size of LUKS encrypted /home ; value is the
+ requested size of the container in kB, MB, GB,
+ or as a percentage of free space
+ (integer numbers only).
+ Examples: '-L 125M', '-L 2G', '-L 20%'.
+ -P|--perssize <size|perc> Size of persistence container ; value is the
+ requested size of the container in kB, MB, GB,
+ or as a percentage of free space
+ (integer numbers only).
+ Examples: '-P 125M', '-P 2G', '-P 20%'.
+ -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%'.
+</code>
+Some examples of what the script can do, are given when you run the script with the '-e' or '--examples' parameter. Here is an overview of those example commands. First, mount your USB partition, for instance a Ventoy disk will be mounted for you at /run/media/<user>/Ventoy/. Then:
+
+ * Create a 1GB encrypted persistence container:
+ # ./isocomp.sh -p /run/media/<user>/Ventoy/myfiles/persistence.icc -P 1G
+ * Create a 4GB encrypted home:
+ # ./isocomp.sh -l /run/media/<user>/Ventoy/somedir/lukscontainers.icc -L 4000M -i /run/media/<user>/Ventoy/slackware64-live-current.iso
+ * Increase the size of that encrypted home container with another 2GB:
+ # ./isocomp.sh -x /run/media/<user>/Ventoy/somedir/lukscontainers.icc -X 2G -i /run/media/<user>/Ventoy/slackware64-live-current.iso
+ * Create a 10GB encrypted container to be mounted on /data in the Live OS:
+ # ./isocomp.sh -l /run/media/<user>/Ventoy/somedir/mydata.icc:/data -L 10G -i /run/media/<user>/Ventoy/slackware64-live-current.iso
+ * Create a liveslak directory structure for adding extra live modules:
+ # ./isocomp.sh -d /run/media/<user>/Ventoy/myliveslak -i /run/media/<user>/Ventoy/slackware64-live-current.iso
+
+These enhancements are recorded in a configuration file next to the ISO, with the exact same name as that ISO but with extension '.cfg' instead of '.iso'. You can manually edit this configuration file if you want; the script will not change, remove or overwrite your customizations.
+
+Here is an example configuration file content: <code>
+# Liveslak ISO configuration file for SLACKWARE-CURRENT FOR X86_64 (LEAN LIVE 1.5.4)
+# Generated by isocomp.sh on 20220814_1554
+LIVESLAKROOT=/liveslak
+LUKSVOL=/liveslak/myhome.icc:/home
+ISOPERSISTENCE=/liveslak/persistence.icc
+TZ=Europe/Amsterdam
+</code>
+Note that this configuration file example is not complete; you can manually add custom values for the following additional liveslak parameters which avoids having to enter the corresponding boot parameters manually every time: BLACKLIST, KEYMAP, LIVE_HOSTNAME, LIVESLAKROOT, LOAD, LOCALE, LUKSVOL, NOLOAD, ISOPERSISTENCE, RUNLEVEL, TWEAKS, TZ and XKB.
+
+
==== Using the Live OS to install Slackware to hard disk ====
@@ -535,7 +613,7 @@ Stage two:
* 'root' and 'live' user accounts are created,
* an initial environment for the accounts is configured,
* the desktop environment is pre-configured for first use,
- * the liveslak scripts "makemod", "iso2usb.sh" and "upslak.sh" are copied to "/usr/local/sbin/" in the ISO for your convenience,
+ * the liveslak scripts "makemod", "iso2usb.sh", "isocomp.sh" and "upslak.sh" are copied to "/usr/local/sbin/" in the ISO for your convenience,
* The "setup2hd" script and the Slackware installer files are copied to "/usr/local/sbin" and "/usr/share/liveslak" respectively.
* slackpkg is configured,
* a locate database is created,
@@ -601,11 +679,48 @@ A second type of encrypted container exists, which can be used for storing your
For slow USB media, the default 5 seconds wait time during boot are sometimes insufficient to allow the kernel to detect the partitions on your USB device. The script can optionally add more wait time. It does this by editing the file "wait-for-root" in the initrd and updating the value which is stored there (by default "5" is written there by the "make_slackware_live.sh" script).
-=== makemod ===
+=== isocomp.sh ===
The third script:
+The "isocomp.sh" script's runtime usage is explained in detail in a previous paragraph "Adding functionality when booting directly off an ISO on disk".
+
+This section explains the inner workings of the script to enhance the functionality of booting directly from ISO.
+
+== Secondary liveslak root directory ==
+
+A secondary liveslak root directory can be created by the 'isocomp.sh' script: in the same filsystem where the ISO file is also present. The ISO contains the primary liveslak root, below which you will find directories 'system', 'addons', 'optional', 'core2ram' and so on. The secondary liveslak root can not contain a 'system' subdirectory but it can contain 'addons', 'optional', 'core2ram'.
+
+Additional Live modules can be placed in these directories. These will be loaded by the Live init after processing corresponding module locations below the primary liveslak root. Meaning, you can load all kinds of additional software without having to modify the official Live ISO.
+
+== Using container files for persistence or homedirectory ==
+
+Two types of encrypted container are supported by 'isocomp.sh', just like with the 'iso2usb.sh' script: to be used either for storing the Live OS persistence data, or for providing (additional) persistent storage space at a mount point such as ''/home''. Also, the functionality of the Live init has been extended to deal with all this.
+
+The sequence is as follows:
+ - Live init checks if the OS was booted from an ISO file.
+ - If yes, init will additionally check for the existence of an ISO configuration file with the same name as the ISO except its extension (which needs to be '.cfg' instead of '.iso').
+ - If the configuration file defines the ISOPERSISTENCE variable, Live init expects its value to be a container file which will be used to store the modifications to the Live OS persistently, instead of writing those to a RAM disk.
+ - If the configuration file defines the LUKSVOL variable, Live init parses it and mounts all container files defined in there at the mountpoints specified (or ''/home'' if not specified).
+ - If init determines that it deals with a LUKS-encrypted container, init asks you for its unlock passphrase.
+
+== Creating an encrypted container ==
+
+The script will create a file of requested size in the same disk partition that also contains the Live ISO, using the 'dd' command. A new loopback device is requested from the OS and the freshly created container file is mapped to the loop device using 'losetup'. The 'cryptsetup luksCreate' command initializes the encryption on this loop device, which causes the script to prompt you with "are you sure, type uppercase YES". After receiving your confirmation, cryptsetup requests you to enter an encryption passphrase three times (two for intializing, and one for unlocking the container subsequently).
+
+If the container is used for an encrypted /home, the script will copy the existing content of the ISO's /home into the container's filesystem which will later be mounted on top of the ISO's /home (thereby masking the existing /home).
+
+== Extending the size of an existing container file ==
+
+The 'isocomp.sh' script is able to extend your encrypted containers if you are running out of space on their enclosed filesystems. It does this by appending random bytes to the end of the file, unlocking and mounting the filesystem inside, and then resizing that filesystem so it grows to the new size of the container. Note that only containers with an internal ''ext4'' filesystem are supported.
+
+
+=== makemod ===
+
+
+The fourth script:
+
The "makemod" script allows you to create a Slackware Live module easily, with a Slackware package or a directory tree as its input parameter.
Usage:
@@ -622,7 +737,7 @@ You can copy the module you just created (minding the filename conventions for a
=== setup2hd ===
-The fourth script:
+The fifth script:
The "setup2hd" script is a modified Slackware installer, so you will be comfortable with the process. The 'SOURCE' section offers two types of choices: a regular Slackware network installation using a NFS, HTTP, FTP or Samba server, as well as a choice of installing the Live OS which you are running. The script knows where to find the squashfs modules, so the "Install Live OS" selection will not prompt further inputs.
* The Slackware network installation is identical to that of the official Slackware installation medium.
@@ -632,7 +747,7 @@ The "setup2hd" script is a modified Slackware installer, so you will be comforta
=== pxeserver ===
-The fifth script:
+The sixth script:
The ''pxeserver'' script works as follows:
* It requires a wired network; wireless PXE boot is impossible.
@@ -660,7 +775,7 @@ kbd=<server_kbd_layout>
=== upslak.sh ===
-The sixth script:
+The seventh script:
The "upslak.sh" script's runtime usage is explained in detail in a previous paragraph "Updating the kernel (and more) on a USB stick".
@@ -705,7 +820,7 @@ Creating an ISO image of Slackware Live Edition requires that you are running Sl
You also need the "liveslak" script collection which can be downloaded from any of the links at the bottom of this page.
-Liveslak is a directory tree containing scripts, bitmaps and configuration files. Only 6 scripts are meant to be run by you, the user. These scripts ("make_slackware_live.sh", "iso2usb.sh", "makemod", "setup2hd", "pxeserver" and "upslak.sh) are explained in more detail in the section "Scripts and tools" higher up. When creating a Live ISO from scratch, you only need to run the "make_slackware_live.sh" script.
+Liveslak is a directory tree containing scripts, bitmaps and configuration files. Only 7 scripts are meant to be run by you, the user. These scripts ("make_slackware_live.sh", "iso2usb.sh", "isocomp.sh", "makemod", "setup2hd", "pxeserver" and "upslak.sh) are explained in more detail in the section "Scripts and tools" higher up. When creating a Live ISO from scratch, you only need to run the "make_slackware_live.sh" script.
=== Liveslak sources layout ===
@@ -731,6 +846,7 @@ The toplevel 'liveslak' directory contains the following files:
* blueSW-128px.png , blueSW-64px.png - these are bitmaps of the Slackware "Blue S" logo, used for the "live" user icon and in the XDM theme.
* grub.tpl - the template file which is used to generate the grub menu for UEFI boot.
* iso2usb.sh - this script creates a bootable USB version wih persistence from a Slackware Live ISO.
+ * isocomp.sh - when you boot directly from a Slackware Live ISO using Grub or a multi-boot manager like Ventoy, this script adds capabilities like persistence, an encrypted home, and the ability to load further live modules from disk.
* languages - this file contains the input configuration for language support. One language per line contains the following fields: "code:name:kbd:tz:locale:xkb". Example: "nl:nederlands:nl:Europe/Amsterdam:nl_NL.utf8:"
* code = 2-letter language code
* name = descriptive name of the language
diff --git a/isocomp.sh b/isocomp.sh
new file mode 100644
index 0000000..a1884df
--- /dev/null
+++ b/isocomp.sh
@@ -0,0 +1,763 @@
+#!/bin/bash
+#
+# Copyright 2022 Eric Hameleers, Eindhoven, NL
+# All rights reserved.
+#
+# Redistribution and use of this script, with or without modification, is
+# permitted provided that the following conditions are met:
+#
+# 1. Redistributions of this script must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+# EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# -----------------------------------------------------------------------------
+#
+# This script can perform some specific changes on the USB stick
+# containing an ISO of Slackware Live Edition,
+# when you boot from that ISO using a multi-boot manager.
+# - create a directory structure on the USB partition to add more
+# functionality to the ISO (e.g. load extra addons/optional modules).
+# - create an encrypted container file for storing persistence data.
+# - create an encrypted container file to mount on /home .
+# - write all the above information into a configuration file for the ISO.
+#
+# -----------------------------------------------------------------------------
+
+# Be careful:
+set -e
+
+# Limit the search path:
+export PATH="/usr/sbin:/sbin:/usr/bin:/bin"
+
+# Use of force is sometimes needed:
+FORCE=0
+
+# Version is obtained from the ISO metadata:
+VERSION=""
+
+# The extension for containerfiles accompanying an ISO is '.icc',
+# whereas the persistent USB stick created with iso2usb.sh uses '.img'.
+DEFEXT=".icc"
+CNTEXT="${DEFEXT}"
+
+# Default mount point for a LUKS container if not specified:
+DEFMNT="/home"
+LUKSMNT=""
+
+# Values for container sizes:
+PERSSIZE=""
+LUKSSIZE=""
+INCSIZE=""
+LUKSVOL=""
+
+# Associative array to capture LUKSVOL definitions:
+declare -A CONTAINERS=()
+
+# Values obtained from a pre-existing .cfg file:
+ISOPERSISTENCE=""
+LUKSCNT=""
+LIVESLAKROOT=""
+
+# Define ahead of time, so that cleanup knows about them:
+IMGDIR=""
+ISOMNT=""
+CNTMNT=""
+EXTENSION=""
+PERSISTENCE=""
+
+# 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"
+
+# These tools are required by the script, we will check for their existence:
+REQTOOLS="cpio cryptsetup fsck gzip isoinfo lsblk resize2fs unsquashfs xz zstd"
+
+#
+# -- function definitions --
+#
+
+# Clean up in case of failure:
+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 ${CNTFILE} ${CNTEXT})
+ losetup -d ${LODEV}
+ fi
+ fi
+ [ -n "${ISOMNT}" ] && ( umount -f ${ISOMNT} 2>/dev/null; rmdir $ISOMNT 2>/dev/null )
+ [ -n "${CNTMNT}" ] && ( umount -f ${CNTMNT} 2>/dev/null; rmdir $CNTMNT 2>/dev/null )
+ [ -n "${IMGDIR}" ] && ( rm -rf $IMGDIR )
+ set -e
+} # End of cleanup()
+
+trap 'echo "*** $0 FAILED at line $LINENO ***"; cleanup; exit 1' ERR INT TERM
+
+# Show the help text for this script:
+showhelp() {
+cat <<EOT
+#
+# Purpose: enhance the functionality when booting a Slackware Live ISO file.
+# When supplying pathnames as parameter values below, use full pathnames in
+# your local filesystem. The script will figure out where your USB disk
+# partition is mounted and will adjust the path names accordingly
+# in the USB configuration.
+#
+# $(basename $0) accepts the following parameters:
+# -d|--directory <path> Create a liveslak directory structure to store
+# additional modules. The parameter value is
+# used as the root path below which the
+# liveslak/{addons,optional} subdirectories
+# will be created.
+# -e|--examples Show some common usage examples.
+# -f|--force Force execution in some cases where the script
+# reports an issue.
+# -h|--help This help text.
+# -i|--iso <fullpath> Full path to your liveslak ISO image.
+# -l|--lukscontainer <fullpath> Full path to encrypted container file to be
+# created by this script, and to be mounted
+# in the live OS under /home
+# (or any other mountpoint you supply).
+# (filename needs to end in '${CNTEXT}'!).
+# -p|--persistence <fullpath > Full path to encrypted persistence container
+# file to be created in the filesystem
+# (filename extension must be '${CNTEXT}'!).
+# -x|--extend <fullpath> Full path to existing (encrypted) container
+# file that you want to extend in size
+# (filename needs to end in '${CNTEXT}'!).
+# Limitations:
+# - container needs to be LUKS encrypted, and
+# - internal filesystem needs to be ext{2,3,4}.
+# -L|--lcsize <size|perc> Size of LUKS encrypted /home ; value is the
+# requested size of the container in kB, MB, GB,
+# or as a percentage of free space
+# (integer numbers only).
+# Examples: '-L 125M', '-L 2G', '-L 20%'.
+# -P|--perssize <size|perc> Size of persistence container ; value is the
+# requested size of the container in kB, MB, GB,
+# or as a percentage of free space
+# (integer numbers only).
+# Examples: '-P 125M', '-P 2G', '-P 20%'.
+# -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()
+
+# Show some common usage examples:
+showexamples() {
+cat <<EOT
+#
+# Some common usage examples for $(basename $0)
+# ---------------------------------------------------------------------------
+# First, mount your USB partition, for instance
+# a Ventoy disk will be mounted for you at /run/media/<user>/Ventoy/.
+# Then:
+# ---------------------------------------------------------------------------
+# Create a 1GB encrypted persistence container:
+# ./$(basename $0) -p /run/media/<user>/Ventoy/myfiles/persistence.icc -P 1G
+#
+# Create a 4GB encrypted home:
+# ./$(basename $0) -l /run/media/<user>/Ventoy/somedir/lukscontainers.icc -L 4000M -i /run/media/<user>/Ventoy/slackware64-live-current.iso
+#
+# Increase the size of that encrypted home container with another 2GB:
+# ./$(basename $0) -x /run/media/<user>/Ventoy/somedir/lukscontainers.icc -X 2G -i /run/media/<user>/Ventoy/slackware64-live-current.iso
+#
+# Create a 10GB encrypted container to be mounted on /data in the Live OS:
+# ./$(basename $0) -l /run/media/<user>/Ventoy/somedir/mydata.icc:/data -L 10G -i /run/media/<user>/Ventoy/slackware64-live-current.iso
+#
+# Create a liveslak directory structure for adding extra live modules:
+# ./$(basename $0) -d /run/media/<user>/Ventoy/myliveslak -i /run/media/<user>/Ventoy/slackware64-live-current.iso
+#
+EOT
+} # End of showexamples()
+
+# Uncompress the initrd based on the compression algorithm used:
+uncompressfs () {
+ if $(file "${1}" | grep -qi ": gzip"); then
+ gzip -cd "${1}"
+ elif $(file "${1}" | grep -qi ": XZ"); then
+ xz -cd "${1}"
+ fi
+} # End of uncompressfs()
+
+# Read configuration data from the initrd inside the ISO:
+read_initrd() {
+ local IMGDIR="$1"
+ cd ${IMGDIR}
+
+ # Read the values of liveslak template variables in the init script:
+ for TEMPLATEVAR in DISTRO LIVEMAIN MARKER MEDIALABEL ; do
+ eval $(grep "^ *${TEMPLATEVAR}=" ./init |head -1)
+ done
+} # End read_initrd()
+
+# Extract the initrd:
+extract_initrd() {
+ local IMGFILE="$1"
+ local IMGDIR=$(mktemp -d -p /tmp -t alienimg.XXXXXX)
+ if [ ! -d $IMGDIR ]; then
+ echo "*** Failed to create temporary extraction directory for the initrd!"
+ cleanup
+ exit 1
+ else
+ chmod 711 $IMGDIR
+ fi
+
+ cd ${IMGDIR}
+ uncompressfs ${IMGFILE} 2>/dev/null \
+ | cpio -i -d -m -H newc 2>/dev/null
+ echo "$IMGDIR"
+} # End of extract_initrd()
+
+# Determine size of a mounted partition (in MB):
+get_part_mb_size() {
+ local MYSIZE
+ MYSIZE=$(df -P -BM ${1} |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):
+get_part_mb_free() {
+ local MYSIZE
+ MYSIZE=$(df -P -BM ${1} |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):
+cont_mb() {
+ 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:
+expand_container() {
+ 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
+
+ # 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
+
+ # 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
+
+ # Unlock the LUKS encrypted container:
+ MYMAP=$(basename ${MYFILE} ${CNTEXT})
+ echo "--- Unlocking the LUKS container requires your passphrase..."
+ until cryptsetup luksOpen ${MYFILE} ${MYMAP} ; do
+ echo ">>> Did you type an incorrect passphrases?"
+ read -p ">>> Press [ENTER] to try again or Ctrl-C to abort ..." REPLY
+ done
+
+ # Run fsck so the filesystem is clean before we resize it:
+ fsck -fvy /dev/mapper/${MYMAP}
+ # Resize the filesystem to occupy the full new size:
+ resize2fs /dev/mapper/${MYMAP}
+ # Just to be safe:
+ fsck -fvy /dev/mapper/${MYMAP}
+} # End of expand_container()
+
+# Create container file in the empty space of the partition
+create_container() {
+ CNTPART=$1 # partition containing the ISO
+ CNTSIZE=$2 # size of the container file to create
+ CNTFILE=$3 # ${CNTEXT} filename with full path
+ CNTENCR=$4 # 'none' or 'luks'
+ CNTUSED=$5 # 'persistence', '/home' or custom mountpoint
+
+ # Create a container file or re-use previously created one:
+ if [ -f ${CNTFILE} ]; then
+ CNTSIZE=$(( $(du -sk ${CNTFILE} |tr '\t' ' ' |cut -f1 -d' ') / 1024 ))
+ echo "--- Keeping existing '${CNTFILE}' (size ${CNTSIZE} MB)."
+ return
+ fi
+
+ # Determine size of the target partition (in MB), and the free space:
+ PARTSIZE=$(get_part_mb_size ${CNTPART})
+ PARTFREE=$(get_part_mb_free ${CNTPART})
+
+ if [ $PARTFREE -lt ${MINFREE} ]; then
+ echo "*** Free space on USB partition is less than ${MINFREE} MB;"
+ echo "*** Not creating a container file!"
+ cleanup
+ exit 1
+ fi
+
+ # Determine requested container size in MB (allow for '%|k|K|m|M|g|G' suffix):
+ CNTSIZE=$(cont_mb ${CNTSIZE})
+
+ if [ $CNTSIZE -le 0 ]; then
+ echo "*** Container size must be larger than ZERO!"
+ echo "*** Check your commandline parameter."
+ cleanup
+ exit 1
+ elif [ $CNTSIZE -ge $PARTFREE ]; then
+ echo "*** Not enough free space for container file!"
+ echo "*** Check your commandline parameter."
+ cleanup
+ exit 1
+ fi
+
+ echo "--- Creating ${CNTSIZE} MB container file using 'dd if=/dev/urandom', patience please..."
+ mkdir -p $(dirname "${CNTFILE}")
+ # Create a sparse file (not allocating any space yet):
+ dd of=${CNTFILE} bs=1M count=0 seek=$CNTSIZE 2>/dev/null
+
+ # Setup a loopback device that we can use with cryptsetup:
+ LODEV=$(losetup -f)
+ losetup $LODEV ${CNTFILE}
+ if [ "${CNTENCR}" = "luks" ]; then
+ # Format the loop device with LUKS:
+ echo "--- Encrypting the container file with LUKS; takes SOME time..."
+ echo "--- enter 'YES' and a passphrase:"
+ until cryptsetup -y luksFormat $LODEV ; do
+ echo ">>> Did you type two different passphrases?"
+ read -p ">>> Press [ENTER] to try again or Ctrl-C to abort ..." REPLY
+ done
+ # Unlock the LUKS encrypted container:
+ echo "--- Unlocking the LUKS container requires your passphrase again..."
+ until cryptsetup luksOpen $LODEV $(basename ${CNTFILE} ${CNTEXT}) ; do
+ echo ">>> Did you type an incorrect passphrases?"
+ read -p ">>> Press [ENTER] to try again or Ctrl-C to abort ..." REPLY
+ done
+ CNTDEV=/dev/mapper/$(basename ${CNTFILE} ${CNTEXT})
+ # Now we allocate blocks for the LUKS device. We write encrypted zeroes,
+ # so that the file looks randomly filled from the outside.
+ # Take care not to write more bytes than the internal size of the container:
+ echo "--- Writing random data to encrypted container; takes LONG time..."
+ CNTIS=$(( $(lsblk -b -n -o SIZE $(readlink -f ${CNTDEV})) / 512))
+ dd if=/dev/zero of=${CNTDEV} bs=512 count=${CNTIS} 2>/dev/null || true
+ else
+ CNTDEV=$LODEV
+ # Un-encrypted container files remain sparse.
+ fi
+
+ # Format the now available block device with a linux fs:
+ mkfs.ext4 ${CNTDEV}
+ # Tune the ext4 filesystem:
+ tune2fs -m 0 -c 0 -i 0 ${CNTDEV}
+
+ if [ "${CNTUSED}" == "${DEFMNT}" ]; then
+ # Copy the original /home content into the container.
+ # NOTE: we only do this for /home, not for any other mountpoint!
+
+ # Create a mount point for the unlocked container:
+ CNTMNT=$(mktemp -d -p /var/tmp -t aliencnt.XXXXXX)
+ if [ ! -d $CNTMNT ]; then
+ echo "*** Failed to create temporary mount point for the LUKS container!"
+ cleanup
+ exit 1
+ else
+ chmod 711 $CNTMNT
+ fi
+ echo "--- Copying '${CNTUSED}' from ISO to container..."
+ HOMESRC=$(find ${ISOMNT} -name "0099-slackware_zzzconf*" |tail -1)
+ mount ${CNTDEV} ${CNTMNT}
+ unsquashfs -n -d ${CNTMNT}/temp ${HOMESRC} ${CNTUSED}
+ mv ${CNTMNT}/temp/${CNTUSED}/* ${CNTMNT}/
+ rm -rf ${CNTMNT}/temp
+ umount ${CNTDEV}
+ fi
+
+ # Don't forget to clean up after ourselves:
+ if [ "${CNTENCR}" = "luks" ]; then
+ cryptsetup luksClose $(basename ${CNTFILE} ${CNTEXT})
+ fi
+ losetup -d ${LODEV} || true
+
+} # End of create_container()
+
+read_config() {
+ local MYISO="${1}"
+ # Read ISO customization from the .cfg file if it exists:
+ if [ -f "${MYISO%.iso}.cfg" ]; then
+ for LIVEPARM in \
+ BLACKLIST KEYMAP LIVE_HOSTNAME LIVESLAKROOT LOAD LOCALE LUKSVOL \
+ NOLOAD ISOPERSISTENCE RUNLEVEL TWEAKS TZ XKB ;
+ do
+ # Read values from disk only if the variable has not been set yet:
+ if [ -z "$(eval echo \$${LIVEPARM})" ]; then
+ eval $(grep -w ^${LIVEPARM} ${MYISO%.iso}.cfg)
+ fi
+ done
+ fi
+} # End of read_config()
+
+write_config() {
+ local MYISO="${1}"
+ # Write updated customization into the ISO .cfg:
+ echo "# Liveslak ISO configuration file for ${VERSION}" > ${MYISO%.iso}.cfg 2>/dev/null
+ echo "# Generated by $(basename $0) on $(date +%Y%m%d_%H%M)" >> ${MYISO%.iso}.cfg 2>/dev/null
+ if [ $? -ne 0 ]; then
+ echo "*** Media '${USBPART}' read-only, cannot write config file."
+ else
+ for LIVEPARM in \
+ BLACKLIST KEYMAP LIVE_HOSTNAME LIVESLAKROOT LOAD LOCALE LUKSVOL \
+ NOLOAD ISOPERSISTENCE RUNLEVEL TWEAKS TZ XKB ;
+ do
+ if [ -n "$(eval echo \$$LIVEPARM)" ]; then
+ echo $LIVEPARM=$(eval echo \$$LIVEPARM) >> ${MYISO%.iso}.cfg
+ fi
+ done
+ fi
+} # End of write_config()
+
+#
+# -- end of function definitions --
+#
+
+# ===========================================================================
+
+# Parse the commandline parameters:
+if [ -z "$1" ]; then
+ showhelp
+ exit 1
+fi
+while [ ! -z "$1" ]; do
+ case $1 in
+ -d|--directory)
+ LIVESLAKROOT="$2"
+ [[ ${LIVESLAKROOT::1} != "/" ]] && LIVESLAKROOT="$(pwd)/${LIVESLAKROOT}"
+ shift 2
+ ;;
+ -e|--examples)
+ showexamples
+ exit
+ ;;
+ -f|--force)
+ FORCE=1
+ shift
+ ;;
+ -h|--help)
+ showhelp
+ exit
+ ;;
+ -i|--iso)
+ SLISO="$(cd "$(dirname "$2")"; pwd)/$(basename "$2")"
+ shift 2
+ ;;
+ -l|--lukscontainer)
+ LUKSMNT="$(echo "$2" |cut -f2 -d:)"
+ LUKSCNT="$(echo "$2" |cut -f1 -d:)"
+ # If no mountpoint was specified, use the default mountpoint (/home):
+ [ "$LUKSMNT" == "$LUKSCNT" ] && LUKSMNT=${DEFMNT}
+ LUKSCNT="$(cd "$(dirname "$LUKSCNT")"; pwd)/$(basename "$LUKSCNT")"
+ shift 2
+ ;;
+ -p|--persistence)
+ PERSISTENCE="$(cd "$(dirname "$2")"; pwd)/$(basename "$2")"
+ shift 2
+ ;;
+ -x|--extend)
+ EXTENSION="$(cd "$(dirname "$2")"; pwd)/$(basename "$2")"
+ shift 2
+ ;;
+ -L|--lcsize)
+ LUKSSIZE="$2"
+ shift 2
+ ;;
+ -P|--perssize)
+ PERSSIZE="$2"
+ shift 2
+ ;;
+ -X|--extendsize)
+ INCSIZE="$2"
+ shift 2
+ ;;
+ *)
+ echo "*** Unknown parameter '$1'!"
+ exit 1
+ ;;
+ esac
+done
+
+#
+# Sanity checks:
+#
+
+if [ "$(id -u)" != "0" ]; then
+ echo "*** You need to be root to run $(basename $0)."
+ exit 1
+fi
+
+# Are all the required tools present?
+PROG_MISSING=""
+for PROGN in ${REQTOOLS} ; do
+ if ! which $PROGN 1>/dev/null 2>/dev/null ; then
+ PROG_MISSING="${PROG_MISSING}-- $PROGN\n"
+ fi
+done
+if [ ! -z "$PROG_MISSING" ] ; then
+ echo "--- Required program(s) not found in search path '$PATH'!"
+ echo -e ${PROG_MISSING}
+ if [ $FORCE -eq 0 ]; then
+ echo "--- Exiting."
+ exit 1
+ fi
+fi
+
+if [ -z "${SLISO}" ]; then
+ echo "*** You must specify the path to the Live ISO (option '-i')!"
+ exit 1
+fi
+
+if [ ! -f "$SLISO" ]; then
+ echo "*** This is not a useable file: '$SLISO' !"
+ exit 1
+fi
+
+if [ -z "${LIVESLAKROOT}${LUKSCNT}${PERSISTENCE}${EXTENSION}" ]; then
+ echo "*** No action requested!"
+ exit 1
+fi
+
+if [ -n "${PERSISTENCE}" ]; then
+ if [ -z "${PERSSIZE}" ]; then
+ echo "*** Persistence filename '${PERSISTENCE}' defined but no filesize provided!"
+ echo "*** Not enabling persistence, please use '-P' parameter."
+ exit 1
+ elif [ "$(basename ${PERSISTENCE} ${CNTEXT})" == "$(basename ${PERSISTENCE})" ]; then
+ echo "*** File '${PERSISTENCE}' does not have an '${CNTEXT}' extension!"
+ if [ $FORCE -eq 0 ]; then
+ exit 1
+ else
+ CNTEXT=$(basename ${PERSISTENCE})
+ if [ "${CNTEXT}" != "${CNTEXT##*.}" ]; then
+ # File has a different extension:
+ echo "--- Accepting '${CNTEXT##*.}' extension for '${PERSISTENCE}'."
+ CNTEXT=${CNTEXT##*.}
+ else
+ # File does not have an extension at all, so we add one:
+ echo "--- Adding '${DEFEXT}' extension to '${PERSISTENCE}'."
+ PERSISTENCE="${PERSISTENCE}${DEFEXT}"
+ fi
+ fi
+ fi
+fi
+
+if [ -n "${LUKSCNT}" ]; then
+ if [ -z "${LUKSSIZE}" ]; then
+ echo "*** LUKS container '${LUKSCNT}' defined but no filesize provided!"
+ echo "*** Not adding encrypted ${LUKSMNT}, please use '-L' parameter."
+ exit 1
+ elif [ "$(basename ${LUKSCNT} ${CNTEXT})" == "$(basename ${LUKSCNT})" ]; then
+ echo "*** File '${LUKSCNT}' does not have an '${CNTEXT}' extension!"
+ if [ $FORCE -eq 0 ]; then
+ exit 1
+ else
+ CNTEXT=$(basename ${LUKSCNT})
+ if [ "${CNTEXT}" != "${CNTEXT##*.}" ]; then
+ # File has a different extension:
+ echo "--- Accepting '${CNTEXT##*.}' extension for '${LUKSCNT}'."
+ CNTEXT=${CNTEXT##*.}
+ else
+ # File does not have an extension at all, so we add one:
+ echo "--- Adding '${DEFEXT}' extension to '${LUKSCNT}'."
+ LUKSCNT="${LUKSCNT}${DEFEXT}"
+ fi
+ fi
+ fi
+fi
+
+if [ -n "${EXTENSION}" ]; then
+ if [ -z "${INCSIZE}" ]; then
+ echo "*** LUKS container '${EXTENSION}' defined but no extansion size provided!"
+ echo "*** Not extending encrypted ${EXTENSION}, please use '-X' parameter."
+ exit 1
+ elif [ "$(basename ${EXTENSION} ${CNTEXT})" == "$(basename ${EXTENSION})" ]; then
+ echo "*** File '${EXTENSION}' does not have an '${CNTEXT}' extension!"
+ if [ $FORCE -eq 0 ]; then
+ exit 1
+ else
+ CNTEXT=$(basename ${EXTENSION})
+ if [ "${CNTEXT}" != "${CNTEXT##*.}" ]; then
+ # File has a different extension:
+ echo "--- Accepting '${CNTEXT##*.}' extension for '${EXTENSION}'."
+ CNTEXT=${CNTEXT##*.}
+ else
+ # File does not have an extension at all, so we add one:
+ echo "--- Adding '${DEFEXT}' extension to '${EXTENSION}'."
+ EXTENSION="${EXTENSION}${DEFEXT}"
+ fi
+ fi
+ fi
+fi
+
+# Determine name and mountpoint of the partition containing the ISO:
+USBPART=$(cd $(dirname ${SLISO}) ; df . |tail -n -1 |tr -s ' ' |cut -d' ' -f1)
+USBMNT=$(cd $(dirname ${SLISO}) ; df . |tail -n -1 |tr -s ' ' |cut -d' ' -f6)
+
+# Determine size of the USB partition (in MB), and the free space:
+USBPSIZE=$(get_part_mb_size ${USBMNT})
+USBPFREE=$(get_part_mb_free ${USBMNT})
+
+# Report the Slackware Live version:
+VERSION=$(isoinfo -d -i "${SLISO}" 2>/dev/null |grep Application |cut -d: -f2-)
+echo "--- The ISO on medium '${USBPART}' is '${VERSION}'"
+
+# Create a mount point for the ISO:
+ISOMNT=$(mktemp -d -p /var/tmp -t alieniso.XXXXXX)
+if [ ! -d $ISOMNT ]; then
+ echo "*** Failed to create temporary mount point for the ISO!"
+ cleanup
+ exit 1
+else
+ chmod 711 $ISOMNT
+ mount -o loop ${SLISO} ${ISOMNT}
+fi
+
+# Collect data from the USB initrd:
+IMGDIR=$(extract_initrd ${ISOMNT}/boot/initrd.img)
+read_initrd ${IMGDIR}
+
+# Collect customization parameters for the ISO:
+read_config ${SLISO}
+
+# Determine where in LUKSVOL the /home is defined.
+# The LUKSVOL value looks like:
+# "/path/to/cntner1.icc:/mountpoint1,[/path/to/cntner2.icc:/mountpoint2,[...]]"
+# Break down the LUKSVOL value into container/mountpoint combo's:
+if [ -n "$LUKSVOL" ]; then
+ _container=""
+ _mount=""
+ for _luksvol in $(echo $LUKSVOL |tr ',' ' '); do
+ _container="$(echo $_luksvol |cut -d: -f1)"
+ _mount="$(echo $_luksvol |cut -d: -f2)"
+ if [ "$_mount" == "$_container" ]; then
+ # No optional mount point specified, so we use the default:
+ CONTAINERS["${DEFMNT}"]="$_container"
+ else
+ CONTAINERS["$_mount"]="$_container"
+ fi
+ done
+fi
+
+# Normalize paths on USB partition (remove mountpoint):
+if [ -n "${PERSISTENCE}" ]; then
+ PERSISTENCE="${PERSISTENCE#$USBMNT}"
+fi
+if [ -n "${LUKSCNT}" ]; then
+ LUKSCNT="${LUKSCNT#$USBMNT}"
+fi
+if [ -n "${EXTENSION}" ]; then
+ EXTENSION="${EXTENSION#$USBMNT}"
+fi
+
+# Should we create a liveslak root directory?
+if [ -n "${LIVESLAKROOT}" ]; then
+ # The directory may already exist, in which case we obtained its name
+ # from the configfile. But creating directory tree is harmless:
+ mkdir -p ${LIVESLAKROOT}/${LIVEMAIN}/{addons,optional,core2ram}
+ # Normalize the path, removing the mount point:
+ LIVESLAKROOT="$(cd "$(dirname "$LIVESLAKROOT")"; pwd)$(basename "$LIVESLAKROOT")"
+ LIVESLAKROOT="${LIVESLAKROOT#$USBMNT}"
+fi
+
+# Should we create a persistence container?
+if [ -n "${PERSISTENCE}" ]; then
+ # Create LUKS persistence container file (or re-use it if existing):
+ create_container ${USBPART} ${PERSSIZE} ${USBMNT}${PERSISTENCE} luks persistence
+ ISOPERSISTENCE="${PERSISTENCE}"
+fi
+
+# Should we add a LUKS container to mount at /home or specified other mount?
+if [ -n "${LUKSCNT}" ]; then
+ if [ -v 'CONTAINERS["${LUKSMNT}"]' ] && [ "${LUKSCNT}" != "${CONTAINERS["${LUKSMNT}"]}" ]; then
+ # The configfile specifies a different mount for container:
+ echo "*** On-disk configuration defines an existing mountpoint ${LUKSMNT}"
+ echo "*** at '${USBMNT}${CONTAINERS["${LUKSMNT}"]}',"
+ echo "*** which is different from your '-l ${USBMNT}${LUKSCNT}'."
+ if [ $FORCE -eq 0 ]; then
+ echo "*** Not adding encrypted container for ${LUKSMNT} , please fix the entry"
+ echo "*** in '${SLISO%.iso}.cfg',"
+ echo "*** or supply the correct value for the '-l' parameter!"
+ cleanup
+ exit 1
+ else
+ echo "--- Accepting new mountpoint '${LUKSMNT}' for encrypted container ${LUKSMNT}"
+ fi
+ fi
+ # Create LUKS container file for the mount point (or re-use it if existing):
+ create_container ${USBPART} ${LUKSSIZE} ${USBMNT}${LUKSCNT} luks ${LUKSMNT}
+ CONTAINERS["${LUKSMNT}"]="${LUKSCNT}"
+fi
+
+# Should we extend the size of a container?
+if [ -n "${EXTENSION}" ]; then
+ # Expand existing container file:
+ expand_container ${USBPART} ${INCSIZE} ${USBMNT}/${EXTENSION}
+fi
+
+if [ ${#CONTAINERS[@]} -gt 0 ]; then
+ # CONTAINERS array is non-empty; (re-)assemble the LUKSVOL variable.
+ # First zap the LUKSVOL value:
+ LUKSVOL=""
+ # Write the CONTAINERS array back into LUKSVOL in the correct format:
+ for _mount in "${!CONTAINERS[@]}"; do
+ LUKSVOL="${LUKSVOL}${CONTAINERS[$_mount]}:${_mount},"
+ done
+ # Remove the trailing ',':
+ LUKSVOL="${LUKSVOL::-1}"
+fi
+
+# Write customization parameters for the ISO to disk:
+write_config ${SLISO}
+
+# Write ISO version to the liveslak rootdir if that exists:
+if [ -d "${USBMNT}/${LIVESLAKROOT}" ]; then
+ echo "$VERSION" > ${USBMNT}/${LIVESLAKROOT}/.isoversion
+fi
+
+# Unmount/remove stuff:
+cleanup
+
+# THE END
+
diff --git a/liveinit.tpl b/liveinit.tpl
index d7d1550..92233f8 100644
--- a/liveinit.tpl
+++ b/liveinit.tpl
@@ -117,17 +117,31 @@ NFSHOST=""
UPPERDIR=/mnt/live/changes
OVLWORK=/mnt/live/.ovlwork
-# Persistence directory on writable media gets mounted on/mnt/media.
+# Persistence directory on writable media gets mounted below /mnt/media.
# If the user specifies a system partition instead,
# then the mount point will be a subdirectory of /mnt/live instead:
PPATHINTERNAL=/mnt/media
+# Where will we mount the partition containing the ISO we are booting?
+SUPERMNT=/mnt/super
+
# LUKS containers on writable media are found below /mnt/media,
# unless liveslak boots off an ISO image, in which case the container files
# are found below /mnt/super - the filesystem of the USB partition containing
# our ISO:
CPATHINTERNAL=/mnt/media
+# If we boot directly off the ISO file, we want to know to enable extras.
+# Possible values for ISOBOOT are 'diskpart','ventoy':
+ISOBOOT=""
+# The configuration file with customization for an ISO boot.
+# Defaults to full pathname of the ISO, with extension 'cfg' instead of 'iso'.
+ISOCFG=""
+
+# The extension for containerfiles accompanying an ISO is '.icc',
+# for a persistent USB stick the extension is '.img' and this is the default:
+CNTEXT=".img"
+
# Password handling, assign random initialization:
DEFPW="7af0aed2-d900-4ed8-89f0"
ROOTPW=$DEFPW
@@ -564,7 +578,7 @@ if [ "$RESCUE" = "" ]; then
find_loop() {
# The losetup of busybox is different from the real losetup - watch out!
- lodev=$(losetup -f)
+ lodev=$(losetup -f 2>/dev/null)
if [ -z "$lodev" ]; then
# We exhausted the available loop devices, so create the block device:
for NOD in $(seq 0 ${MAXLOOPS}); do
@@ -632,7 +646,7 @@ if [ "$RESCUE" = "" ]; then
SUBSYS="$1"
# Find all supported modules:
- for MODULE in $(find_mod /mnt/media/${LIVEMAIN}/${SUBSYS}/) ; do
+ for MODULE in $(find_mod /mnt/media/${LIVEMAIN}/${SUBSYS}/) $(find_mod ${SUPERMNT}/${LIVESLAKROOT}/${LIVEMAIN}/${SUBSYS}/) ; do
# Strip path and extension from the modulename:
MODBASE="$(mod_base ${MODULE})"
if [ "$SUBSYS" = "optional" ]; then
@@ -708,6 +722,69 @@ if [ "$RESCUE" = "" ]; then
echo $OUTPUT |cat
}
+ # Return device node of Ventoy partition if found:
+ # Function input:
+ # (param 1) Ventoy OS parameter block (512 bytes file).
+ # (param 2) action
+ # 'isopath' request: return full path to the ISO on the USB filesystem;
+ # 'devpartition' request:
+ # return the device node for the partition containing the ISO file;
+ # 'diskuuid' request: return the UUID for the disk;
+ # 'partnr' request: return the number of the partition containing the ISO;
+ ret_ventoy () {
+ local VOSPARMS="$1"
+ local VACTION="$2"
+ local DISKSIZE=""
+ local BDEV=""
+ local IPART=""
+ local VENTPART=""
+
+ if [ "$VACTION" == "isopath" ]; then
+ echo $(hexdump -s 45 -n 384 -e '384/1 "%01c""\n"' $VOSPARMS)
+ elif [ "$VACTION" == "diskuuid" ]; then
+ echo $(hexdump -s 481 -n 4 -e '4/1 "%02x "' ${VOSPARMS} \
+ | awk '{ for (i=NF; i>1; i--) printf("%s",$i); print $i; }' )
+ elif [ "$VACTION" == "partnr" ]; then
+ echo $(( 0x$(hexdump -s 41 -n 2 -e '2/1 "%02x "' ${VOSPARMS} \
+ | awk '{ for (i=NF; i>1; i--) printf("%s",$i); print $i; }' )
+ ))
+ elif [ "$VACTION" == "devpartition" ]; then
+ PARTNR=$(( 0x$(hexdump -s 41 -n 2 -e '2/1 "%02x "' ${VOSPARMS} \
+ | awk '{ for (i=NF; i>1; i--) printf("%s",$i); print $i; }' )
+ ))
+ DISKSIZE=$(( 0x$(hexdump -s 33 -n 8 -e '8/1 "%02x "' ${VOSPARMS} \
+ | awk '{ for (i=NF; i>1; i--) printf("%s",$i); print $i; }' )
+ ))
+ # Determine which block device (only one!) reports this disk size (bytes):
+ for BDEV in $(find /sys/block/* |grep -Ev '(ram|loop)') ; do
+ BDEV=$(basename $BDEV)
+ # The 'size' value is sectors, not bytes!
+ # Logical block size in Linux is commonly 512 bytes:
+ BDEVSIZE=$(( $(cat /sys/block/${BDEV}/size) * $(cat /sys/block/${BDEV}/queue/logical_block_size) ))
+ if [ $BDEVSIZE -eq $DISKSIZE ]; then
+ # Found a block device with matching size in bytes:
+ for IPART in $(ret_partition $(blkid |cut -d: -f1) | grep -v loop) ;
+ do
+ if [ -e /sys/block/$BDEV/$(basename $IPART)/partition ]; then
+ if [ $(cat /sys/block/$BDEV/$(basename $IPART)/partition) -eq $PARTNR ]; then
+ # Found the correct partition number on matching disk:
+ VENTPART="$IPART $VENTPART"
+ fi
+ fi
+ done
+ fi
+ done
+ if [ $(echo $VENTPART |wc -w) -eq 1 ]; then
+ # We found the Ventoy ISO-containing partition.
+ # Trim leading/trailing spaces:
+ echo $VENTPART |xargs
+ else
+ # Zero or multiple matching block devices found, fall back to 'scandev':
+ echo scandev
+ fi
+ fi
+ }
+
## End support functions ##
# We need a mounted filesystem here to be able to do a switch_root later,
@@ -722,6 +799,54 @@ if [ "$RESCUE" = "" ]; then
# Find the Slackware Live media.
# TIP: Increase WAIT to give USB devices a chance to be seen by the kernel.
mkdir /mnt/media
+
+ # Multi ISO boot managers first.
+
+ # --- Ventoy ---
+ # If we boot an ISO via Ventoy, this creates a device-mapped file
+ # '/dev/mapper/ventoy' which liveslak could use to mount that ISO,
+ # but specifying '-t iso9660' will fail to mount it.
+ # Omitting the '-t iso9660' makes the mount succceed.
+ # liveslak is 'Ventoy compatible':
+ # Ventoy will not execute its hooks and leaves all the detection to us.
+ # It will create the device-mapped file /dev/mapper/ventoy still.
+ VENTID="VentoyOsParam-77772020-2e77-6576-6e74-6f792e6e6574"
+ VENTVAR="/sys/firmware/efi/vars/${VENTID}"
+ if [ ! -d "${VENTVAR}" ]; then
+ VENTVAR="/sys/firmware/efi/efivars/${VENTID}"
+ fi
+ if [ -d "${VENTVAR}" ]; then
+ echo "${MARKER}: (UEFI) Ventoy ISO boot detected..."
+ ISOBOOT="ventoy"
+ VENTOSPARM="${VENTVAR}/data"
+ else
+ # Detect Ventoy in memory (don't use the provided hooks), see
+ # https://www.ventoy.net/en/doc_compatible_format.html:
+ dd if=/dev/mem of=/vent.dmp bs=1 skip=$((0x80000)) count=$((0xA0000-0x80000)) 2>/dev/null
+ # With 'xargs' we remove leading and ending spaces:
+ OFFSET=$(strings -t d /vent.dmp |grep ' www.ventoy.net' |xargs |cut -d' ' -f1)
+ if [ -n "${OFFSET}" ]; then
+ echo "${MARKER}: (BIOS) Ventoy ISO boot detected..."
+ ISOBOOT="ventoy"
+ # Save the 512-byte Ventoy OS Parameter block:
+ dd if=/vent.dmp of=/vent_os_parms bs=1 count=512 skip=$OFFSET 2>/dev/null
+ VENTOSPARM="/vent_os_parms"
+ fi
+ fi
+ if [ "$ISOBOOT" == "ventoy" ]; then
+ LIVEPATH=$(ret_ventoy $VENTOSPARM isopath)
+ if [ -e /dev/mapper/ventoy ]; then
+ LIVEMEDIA=$(dmsetup table /dev/mapper/ventoy |tr -s ' ' |cut -d' ' -f 4)
+ LIVEMEDIA=$(readlink -f /dev/block/${LIVEMEDIA})
+ # Having the ISO device-mapped to /dev/dm-0 prevents liveslak from
+ # mounting the underlying partition, so we delete the mapped device:
+ dmsetup remove /dev/mapper/ventoy
+ else
+ # Return Ventoy device partition (or 'scandev'):
+ LIVEMEDIA=$(ret_ventoy $VENTOSPARM devpartition)
+ fi
+ fi
+
if [ -n "$NFSHOST" ]; then
# NFS root. First configure our network interface:
setnet
@@ -737,14 +862,6 @@ if [ "$RESCUE" = "" ]; then
VIRGIN=1
elif [ -z "$LIVEMEDIA" ]; then
# LIVEMEDIA not specified on the boot commandline using "livemedia="
- # Note:
- # If we boot an ISO via Ventoy, this creates a device-mapped file
- # '/dev/mapper/ventoy' which liveslak uses to mount that ISO,
- # but specifying '-t iso9660' will fail to mount it.
- # Omitting the '-t iso9660' makes the mount succceed.
- if [ -e /dev/mapper/ventoy ]; then
- echo "${MARKER}: Ventoy ISO boot detected..."
- fi
# Start digging:
# Filter out the block devices, only look at partitions at first:
# The blkid function in busybox behaves differently than the regular blkid!
@@ -765,11 +882,7 @@ if [ "$RESCUE" = "" ]; then
# Determine filesystem type ('iso9660' means we found a CDROM/DVD)
LIVEFS=$(blkid $LIVEMEDIA |rev |cut -d'"' -f2 |rev)
[ "$LIVEFS" = "swap" ] && continue
- if [ -e /dev/mapper/ventoy ]; then
- mount -o ro $LIVEMEDIA /mnt/media
- else
- mount -t $LIVEFS -o ro $LIVEMEDIA /mnt/media
- fi
+ mount -t $LIVEFS -o ro $LIVEMEDIA /mnt/media
else
# Bummer.. label not found; the ISO was extracted to a different device.
# Separate partitions from block devices, look at partitions first:
@@ -777,12 +890,9 @@ if [ "$RESCUE" = "" ]; then
# We rely on the fact that busybox blkid puts TYPE"..." at the end:
SLFS=$(blkid $SLDEVICE |rev |cut -d'"' -f2 |rev)
[ "$SLFS" = "swap" ] && continue
- if [ -e /dev/mapper/ventoy ]; then
- mount -o ro $SLDEVICE /mnt/media
- else
- mount -t $SLFS -o ro $SLDEVICE /mnt/media
- fi
- if [ -d /mnt/media/${LIVEMAIN} ]; then
+ mount -t $SLFS -o ro $SLDEVICE /mnt/media
+ if [ -f /mnt/media/${LIVEMAIN}/system/0099-${DISTRO}_zzzconf-*.s* ];
+ then
# Found our media!
LIVEALL=$SLDEVICE
LIVEMEDIA=$SLDEVICE
@@ -801,7 +911,8 @@ if [ "$RESCUE" = "" ]; then
fi
sleep 1
else
- # LIVEMEDIA was specified on the boot commandline using "livemedia="
+ # LIVEMEDIA was specified on the boot commandline using "livemedia=",
+ # or ISO was booted by a compatible multi ISO bootmanager:
if [ "$LIVEMEDIA" != "scandev" -a ! -b "$LIVEMEDIA" ]; then
# Passed a UUID or LABEL?
LIVEALL=$(findfs UUID=$LIVEMEDIA 2>/dev/null) || LIVEALL=$(findfs LABEL=$LIVEMEDIA 2>/dev/null)
@@ -818,7 +929,6 @@ if [ "$RESCUE" = "" ]; then
# instead of just: "livemedia=/dev/sdX".
#
# First mount the partition and then loopmount the ISO:
- SUPERMNT=/mnt/super_$(od -An -N1 -tu1 /dev/urandom |tr -d ' ')
mkdir -p ${SUPERMNT}
#
if [ "$LIVEMEDIA" = "scandev" ]; then
@@ -843,14 +953,20 @@ if [ "$RESCUE" = "" ]; then
fi
fi
# At this point we know $LIVEMEDIA - either because the bootparameter
- # specified it or else because the 'scandev' found it for us:
+ # specified it or else because the 'scandev' found it for us.
+ # Next we will re-define LIVEMEDIA to point to the actual ISO file
+ # on the mounted live media:
SUPERFS=$(blkid $LIVEMEDIA |rev |cut -d'"' -f2 |rev)
- mount -t $SUPERFS -o ro $LIVEMEDIA ${SUPERMNT}
- if [ -f "${SUPERMNT}/$LIVEPATH" ]; then
- LIVEFS=$(blkid "${SUPERMNT}/$LIVEPATH" |rev |cut -d'"' -f2 |rev)
- LIVEALL="${SUPERMNT}/$LIVEPATH"
+ SUPERPART=$LIVEMEDIA
+ mount -t ${SUPERFS} -o ro ${SUPERPART} ${SUPERMNT}
+ if [ -f "${SUPERMNT}/${LIVEPATH}" ]; then
+ LIVEFS=$(blkid "${SUPERMNT}/${LIVEPATH}" |rev |cut -d'"' -f2 |rev)
+ LIVEALL="${SUPERMNT}/${LIVEPATH}"
LIVEMEDIA="$LIVEALL"
MOUNTOPTS="loop"
+ if [ -z "$ISOBOOT" ]; then
+ ISOBOOT="diskpart"
+ fi
fi
fi
LIVEFS=$(blkid $LIVEMEDIA |rev |cut -d'"' -f2 |rev)
@@ -858,11 +974,23 @@ if [ "$RESCUE" = "" ]; then
fi
fi
- # Finished determining the media availability, it should be mounted now.
+ if [ -n "${ISOBOOT}" ]; then
+ # Containerfiles used in conjunction with ISO files have '.icc' extension,
+ # aka 'ISO Container Companion' ;-)
+ CNTEXT=".icc"
+ # Search for containers in another place than the default /mnt/media:
+ CPATHINTERNAL=${SUPERMNT}
+ fi
+
+ # ---------------------------------------------------------------------- #
+ # #
+ # Finished determining the media availability, it should be mounted now. #
+ # #
+ # ---------------------------------------------------------------------- #
if [ ! -z "$LIVEMEDIA" ]; then
echo "${MARKER}: Live media found at ${LIVEMEDIA}."
- if [ ! -d /mnt/media/${LIVEMAIN} ]; then
+ if [ ! -f /mnt/media/${LIVEMAIN}/system/0099-${DISTRO}_zzzconf-*.s* ]; then
echo "${MARKER}: However, live media was not mounted... trouble ahead."
fi
if [ "$LIVEMEDIA" != "$LIVEALL" ]; then
@@ -915,6 +1043,32 @@ if [ "$RESCUE" = "" ]; then
fi
fi
+ # When booted from an ISO, liveslak optionally reads parameters
+ # from a file with the same full filename as the ISO,
+ # but with '.cfg' extension instead of '.iso':
+ if [ -n "$ISOBOOT" ] && [ -z "$CFGACTION" ]; then
+ # The partition's filesystem containing the ISO is mounted at ${SUPERMNT}:
+ ISOCFG="${SUPERMNT}/$(dirname ${LIVEPATH})/$(basename ${LIVEPATH} .iso).cfg"
+ if [ -f "$ISOCFG" ]; then
+ # Read ISO live customization from disk file if present,
+ # and set any variable from that file:
+ echo "${MARKER}: Reading ISO boot config from ${ISOCFG#$SUPERMNT})"
+ for LISOPARM in \
+ BLACKLIST KEYMAP LIVE_HOSTNAME LIVESLAKROOT LOAD LOCALE LUKSVOL \
+ NOLOAD ISOPERSISTENCE RUNLEVEL TWEAKS TZ XKB ;
+ do
+ eval $(grep -w ^${LISOPARM} ${ISOCFG})
+ done
+ # Handle any customization.
+ if [ -n "${ISOPERSISTENCE}" ]; then
+ # Persistence container located on the USB stick - strip the extension:
+ PERSISTENCE=$(basename ${ISOPERSISTENCE%.*})
+ PERSISTPATH=$(dirname ${ISOPERSISTENCE})
+ PERSISTPART=${SUPERPART}
+ fi
+ fi
+ fi
+
# Some variables require a value before continuing, so if they were not set
# on the boot commandline nor in a config file, we take care of it now:
if [ -z "$KEYMAP" ]; then
@@ -1025,7 +1179,7 @@ if [ "$RESCUE" = "" ]; then
PPARTFS=$(blkid $PPART |rev |cut -d'"' -f2 |rev)
# Mount the partition and peek inside for a directory or container:
mount -t $PPARTFS -o ro ${PPART} /mnt/live/${ppartdir}
- if [ -d /mnt/live/${ppartdir}/${PERSISTPATH}/${PERSISTENCE} ] || [ -f /mnt/live/${ppartdir}/${PERSISTPATH}/${PERSISTENCE}.img ]; then
+ if [ -d /mnt/live/${ppartdir}/${PERSISTPATH}/${PERSISTENCE} ] || [ -f /mnt/live/${ppartdir}/${PERSISTPATH}/${PERSISTENCE}${CNTEXT} ]; then
# Found our persistence directory/container!
PERSISTPART=$PPART
unset PPART
@@ -1045,6 +1199,8 @@ if [ "$RESCUE" = "" ]; then
fi
fi
+ debugit
+
# ------------------------------------------------------------------ #
# #
# At this point, we either have determined the persistence partition #
@@ -1060,27 +1216,37 @@ if [ "$RESCUE" = "" ]; then
REALMP=$(readlink -f ${MPDEV})
REALPP=$(readlink -f ${PERSISTPART})
if [ "${REALMP}" != "${REALPP}" ]; then
+ # The liveslak media is different from the persistence partition.
# Mount the partition readonly to access the persistence directory:
ppdir=".persistence_$(od -An -N1 -tu1 /dev/urandom|tr -d ' ')"
mkdir -p /mnt/live/${ppdir}
mount -o ro ${PERSISTPART} /mnt/live/${ppdir}
if [ $? -ne 0 ]; then
- echo "${MARKER}: Failed to mount persistence partition '${PERSISTPART}' read/write."
+ echo "${MARKER}: Failed to mount persistence partition '${PERSISTPART}' readonly."
echo "${MARKER}: Falling back to recording changes in RAM."
rmdir /mnt/live/${ppdir}
VIRGIN=1
else
# Explicitly configured persistence has priority over regular
# persistence settings, and also overrides the boot parameter 'nop':
- PPATHINTERNAL=/mnt/live/${ppdir}
+ if [ -n "${ISOBOOT}" ]; then
+ # Boot from ISO, persistence is on the filesystem containing the ISO:
+ PPATHINTERNAL=${SUPERMNT}
+ else
+ # We use the above created directory:
+ PPATHINTERNAL=/mnt/live/${ppdir}
+ fi
VIRGIN=0
fi
fi
fi
+ debugit
+
# At this point, if we use persistence then its partition is either
- # the live media (mounted on /mnt/media) or a system partition
- # (mounted on /mnt/live/${ppdir}).
+ # the live media (mounted on /mnt/media), a system partition
+ # (mounted on /mnt/live/${ppdir}) or the partition containing the ISO if we
+ # booted off that.
# The variable ${PPATHINTERNAL} points to its mount point,
# and the partition is mounted read-only.
@@ -1089,7 +1255,7 @@ if [ "$RESCUE" = "" ]; then
# deal with a pure Live system without persistence (VIRGIN=1):
if [ $VIRGIN -eq 0 ]; then
- if [ -d ${PPATHINTERNAL}/${PERSISTPATH}/${PERSISTENCE} ] || [ -f ${PPATHINTERNAL}/${PERSISTPATH}/${PERSISTENCE}.img ]; then
+ if [ -d ${PPATHINTERNAL}/${PERSISTPATH}/${PERSISTENCE} ] || [ -f ${PPATHINTERNAL}/${PERSISTPATH}/${PERSISTENCE}${CNTEXT} ]; then
# Remount the partition r/w - we need to write to the persistence area.
# The value of PPATHINTERNAL will be different for USB stick or harddisk:
mount -o remount,rw ${PPATHINTERNAL}
@@ -1122,37 +1288,37 @@ if [ "$RESCUE" = "" ]; then
echo "${MARKER}: Falling back to recording changes in RAM."
VIRGIN=1
fi
- # Use a container file instead of a dorectory for persistence:
- elif [ -f ${PPATHINTERNAL}/${PERSISTPATH}/${PERSISTENCE}.img ]; then
+ # Use a container file instead of a directory for persistence:
+ elif [ -f ${PPATHINTERNAL}/${PERSISTPATH}/${PERSISTENCE}${CNTEXT} ]; then
# Find a free loop device to mount the persistence container file:
prdev=$(find_loop)
- prdir=${PERSISTENCE}_$(od -An -N1 -tu1 /dev/urandom |tr -d ' ')
+ prdir=persistence_$(od -An -N1 -tu1 /dev/urandom |tr -d ' ')
mkdir -p /mnt/live/${prdir}
- losetup $prdev ${PPATHINTERNAL}/${PERSISTPATH}/${PERSISTENCE}.img
+ losetup $prdev ${PPATHINTERNAL}/${PERSISTPATH}/${PERSISTENCE}${CNTEXT}
# Check if the persistence container is LUKS encrypted:
if cryptsetup isLuks $prdev 1>/dev/null 2>/dev/null ; then
- echo "${MARKER}: Unlocking LUKS encrypted persistence file '${PERSISTPATH}/${PERSISTENCE}.img'"
+ echo "${MARKER}: Unlocking LUKS encrypted persistence file '${PERSISTPATH}/${PERSISTENCE}${CNTEXT}'"
cryptsetup luksOpen $prdev ${PERSISTENCE} </dev/tty0 >/dev/tty0 2>&1
if [ $? -ne 0 ]; then
- echo "${MARKER}: Failed to unlock persistence file '${PERSISTPATH}/${PERSISTENCE}.img'."
+ echo "${MARKER}: Failed to unlock persistence file '${PERSISTPATH}/${PERSISTENCE}${CNTEXT}'."
echo "${MARKER}: Falling back to RAM."
else
# LUKS properly unlocked; from now on use the mapper device instead:
prdev=/dev/mapper/${PERSISTENCE}
fi
fi
- prfs=$(blkid $prdev |rev |cut -d'"' -f2 |rev)
+ prfs=$(blkid $prdev 2>/dev/null |rev |cut -d'"' -f2 |rev)
mount -t $prfs $prdev /mnt/live/${prdir} 2>/dev/null
if [ $? -ne 0 ]; then
- echo "${MARKER}: Failed to mount persistence file '${PERSISTPATH}/${PERSISTENCE}.img'."
+ echo "${MARKER}: Failed to mount persistence file '${PERSISTPATH}/${PERSISTENCE}${CNTEXT}'."
echo "${MARKER}: Falling back to RAM."
else
if [ "$WIPE_PERSISTENCE" = "1" -o -f /mnt/live/${prdir}/${PERSISTENCE}/.wipe ]; then
- echo "${MARKER}: Wiping existing persistent data in '${PERSISTPATH}/${PERSISTENCE}.img'."
+ echo "${MARKER}: Wiping existing persistent data in '${PERSISTPATH}/${PERSISTENCE}${CNTEXT}'."
rm -f /mnt/live/${prdir}/${PERSISTENCE}/.wipe 2>/dev/null
find /mnt/live/${prdir}/${PERSISTENCE}/ -mindepth 1 -exec rm -rf {} \; 2>/dev/null
fi
- echo "${MARKER}: Writing persistent changes to file '${PERSISTPATH}/${PERSISTENCE}.img'."
+ echo "${MARKER}: Writing persistent changes to file '${PERSISTPATH}/${PERSISTENCE}${CNTEXT}'."
UPPERDIR=/mnt/live/${prdir}/${PERSISTENCE}
OVLWORK=/mnt/live/${prdir}/.ovlwork
fi
@@ -1162,7 +1328,11 @@ if [ "$RESCUE" = "" ]; then
if [ ! -z "$LUKSVOL" ]; then
# Even without persistence, we need to be able to write to the partition
# if we are using a LUKS container file:
- mount -o remount,rw /mnt/media
+ if [ -n "$ISOBOOT" ]; then
+ mount -o remount,rw ${SUPERMNT}
+ else
+ mount -o remount,rw /mnt/media
+ fi
else
mount -o remount,ro /mnt/media
fi
@@ -1230,6 +1400,12 @@ if [ "$RESCUE" = "" ]; then
mount --bind /mnt/live/toram /mnt/overlay/mnt/livemedia
fi
+ if [ -n "$ISOBOOT" ]; then
+ # Expose the filesystem on the USB stick when we booted off an ISO there:
+ mkdir -p /mnt/overlay/mnt/supermedia
+ mount --bind ${SUPERMNT} /mnt/overlay/mnt/supermedia
+ fi
+
if [ ! -z "$USE_SWAP" ]; then
# Use any available swap device:
for SWAPD in $(blkid |grep TYPE="\"swap\"" |cut -d: -f1) ; do
@@ -1252,7 +1428,7 @@ if [ "$RESCUE" = "" ]; then
# Find a free loop device:
lodev=$(find_loop)
- losetup $lodev ${CPATHINTERNAL}/$luksfil
+ losetup $lodev ${CPATHINTERNAL}$luksfil
echo "Unlocking LUKS encrypted container '$luksfil' at mount point '$luksmnt'"
cryptsetup luksOpen $lodev $luksnam </dev/tty0 >/dev/tty0 2>&1
if [ $? -ne 0 ]; then
@@ -1274,6 +1450,8 @@ if [ "$RESCUE" = "" ]; then
done
fi
+ debugit
+
if [ ! -z "$KEYMAP" ]; then
# Configure custom keyboard mapping in console and X:
echo "${MARKER}: Switching live console to '$KEYMAP' keyboard"
diff --git a/make_slackware_live.sh b/make_slackware_live.sh
index a97ea33..3428ca6 100755
--- a/make_slackware_live.sh
+++ b/make_slackware_live.sh
@@ -2092,7 +2092,7 @@ EOSL
# Add our scripts to the Live OS:
mkdir -p ${LIVE_ROOTDIR}/usr/local/sbin
-install -m0755 ${LIVE_TOOLDIR}/makemod ${LIVE_TOOLDIR}/iso2usb.sh ${LIVE_TOOLDIR}/upslak.sh ${LIVE_ROOTDIR}/usr/local/sbin/
+install -m0755 ${LIVE_TOOLDIR}/makemod ${LIVE_TOOLDIR}/iso2usb.sh ${LIVE_TOOLDIR}/isocomp.sh ${LIVE_TOOLDIR}/upslak.sh ${LIVE_ROOTDIR}/usr/local/sbin/
# Add PXE Server infrastructure:
mkdir -p ${LIVE_ROOTDIR}/var/lib/tftpboot/pxelinux.cfg
@@ -3497,6 +3497,9 @@ fi
# verbatim into the overlay root):
mkdir -p ${LIVE_STAGING}/${LIVEMAIN}/rootcopy
+# Mark our ISO as 'ventoy-compatible':
+echo "This ISO is compatible with Ventoy. See https://www.ventoy.net/en/compatible.html" >${LIVE_STAGING}/ventoy.dat
+
# Create an ISO file from the directories found below ${LIVE_STAGING}:
create_iso ${LIVE_STAGING}