diff options
Diffstat (limited to 'liveinit.tpl')
-rw-r--r-- | liveinit.tpl | 839 |
1 files changed, 664 insertions, 175 deletions
diff --git a/liveinit.tpl b/liveinit.tpl index 6fd9620..c4fd29a 100644 --- a/liveinit.tpl +++ b/liveinit.tpl @@ -1,8 +1,8 @@ -#!/bin/ash +#!/bin/sh # # Copyright 2004 Slackware Linux, Inc., Concord, CA, USA # Copyright 2007, 2008, 2009, 2010, 2012 Patrick J. Volkerding, Sebeka, MN, USA -# Copyright 2015, 2016, 2017, 2018 Eric Hameleers, Eindhoven, NL +# Copyright 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023 Eric Hameleers, Eindhoven, NL # All rights reserved. # # Redistribution and use of this script, with or without modification, is @@ -38,12 +38,18 @@ MEDIALABEL="@MEDIALABEL@" LIVEMAIN="@LIVEMAIN@" MARKER="@MARKER@" + PERSISTENCE="@PERSISTENCE@" +PERSISTPART="" +PERSISTPATH="." DISTRO="@DISTRO@" CDISTRO="@CDISTRO@" VERSION="@VERSION@" +CORE2RAMMODS="@CORE2RAMMODS@" +CORE2RAM=0 + LIVEUID="@LIVEUID@" LIVEMEDIA="" @@ -61,16 +67,20 @@ DEF_LOCALE=@DEF_LOCALE@ DEF_TZ=@DEF_TZ@ # By default, let the media determine if we can write persistent changes: -# However, if we define TORAM=1, we will also set VIRGIN=1 since we want -# to avoid anything that writes to disk after we copy the OS to RAM. +# However, if we define TORAM=1, we will also set VIRGIN=1 when we want +# to avoid anything that writes to disk after we copy the OS to RAM; +# unless we explicitly use a persistence directory on the computer's local disk. VIRGIN=0 # If set to '1', existing persistent data will be wiped: WIPE_PERSISTENCE=0 # Used for debugging the init; -# Set DEBUG to '1' to enable explicit pauses; '2' enables verbose script exec; -# and '4' dumps you into a debug shell right before the switch_root: +# Set DEBUG to '1' to enable explicit pauses showing blkid/mount info; +# '2' and higher enable verbose script execution; +# '3' pauses like '1' or '2' but won't show blkid/mount info; +# '4' dumps you into a debug shell right before the switch_root; +# '5' additionally saves the verbose init execution output to 'debug_init.log': DEBUG=0 DEBUGV=" " @@ -103,6 +113,40 @@ HNMAC_ALLOWED="YES" INTERFACE="" NFSHOST="" +# Assume the default to be a readonly media - we write to RAM: +UPPERDIR=/mnt/live/changes +OVLWORK=/mnt/live/.ovlwork + +# 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 +LIVEPW=$DEFPW + # Max wait time for DHCP client to configure an interface: DHCPWAIT=20 @@ -117,13 +161,18 @@ PATH="/sbin:/bin:/usr/sbin:/usr/bin" # Mount /proc and /sys: mount -n proc /proc -t proc mount -n sysfs /sys -t sysfs -mount -n tmpfs /run -t tmpfs -o mode=0755 +mount -n tmpfs /run -t tmpfs -o mode=0755,size=32M,nodev,nosuid,noexec if grep devtmpfs /proc/filesystems 1>/dev/null 2>/dev/null ; then DEVTMPFS=1 - mount -n devtmpfs /dev -t devtmpfs + mount -n devtmpfs /dev -t devtmpfs -o size=8M fi +# Mount if this directory exists (so the kernel supports efivarfs): +if [ -d /sys/firmware/efi/efivars ]; then + mount -o rw -t efivarfs none /sys/firmware/efi/efivars +fi + # Parse command line for ARG in $(cat /proc/cmdline); do case $ARG in @@ -143,9 +192,18 @@ for ARG in $(cat /proc/cmdline); do dhcpwait=*) DHCPWAIT=$(echo $ARG | cut -f2 -d=) ;; + domain=*) + # generic syntax: sub.domain.some + LIVE_DOMAIN=$(echo $ARG | cut -f2 -d=) + ;; hostname=*) # generic syntax: hostname=newname[,qualifier] LIVE_HOSTNAME=$(echo $ARG | cut -f2 -d= | cut -f1 -d,) + # Allow for the user to (mistakenly) add a domain component: + if [ -n "$(echo "$LIVE_HOSTNAME". |cut -d. -f2-)" ]; then + LIVE_DOMAIN=$(echo $LIVE_HOSTNAME |cut -d. -f2-) + LIVE_HOSTNAME=$(echo $LIVE_HOSTNAME |cut -d. -f1) + fi if [ "$(echo $ARG | cut -f2 -d= | cut -f2 -d,)" = "fixed" ]; then Keep hostname fixed i.e. never add a MAC address suffix: HNMAC_ALLOWED="NO" @@ -163,6 +221,7 @@ for ARG in $(cat /proc/cmdline); do livemedia=*) # generic syntax: livemedia=/dev/sdX # ISO syntax: livemedia=/dev/sdX:/path/to/slackwarelive.iso + # Scan partitions for ISO: livemedia=scandev:/path/to/slackwarelive.iso LM=$(echo $ARG | cut -f2 -d=) LIVEMEDIA=$(echo $LM | cut -f1 -d:) LIVEPATH=$(echo $LM | cut -f2 -d:) @@ -212,7 +271,22 @@ for ARG in $(cat /proc/cmdline); do fi ;; persistence=*) - PERSISTENCE=$(echo $ARG | cut -f2 -d=) + # Generic syntax: persistence=/path/to/persistencedir + # Dir on harddisk partition: persistence=/dev/sdX:/path/to/persistencedir + # Instead of device name, the value of its LABEL or UUID can be used too. + PD=$(echo $ARG | cut -f2 -d=) + PERSISTPART=$(echo $PD | cut -f1 -d:) + PERSISTPATH=$(dirname $(echo $PD | cut -f2 -d:)) + PERSISTENCE=$(basename $(echo $PD | cut -f2 -d:)) + unset PD + if [ "${PERSISTENCE})" = "changes" ]; then + echo "${MARKER}: Persistence directory cannot be called 'changes'." + echo "${MARKER}: Disabling persistence and recording changes in RAM." + PERSISTPART="" + PERSISTPATH="." + PERSISTENCE="@PERSISTENCE@" + VIRGIN=1 + fi ;; rescue) RESCUE=1 @@ -227,6 +301,32 @@ for ARG in $(cat /proc/cmdline); do TORAM=1 VIRGIN=1 # prevent writes to disk since we are supposed to run from RAM ;; + toram=*) + # Generic syntax: toram=type[,memperc] + # type: string value; os,core,all,none + # memperc: integer value, percentage RAM to reserve for liveslak + # You can use this parameter to change the percentage RAM + # used by liveslak, which is 50% for normal operation. + # For instance when you have an insane amount of RAM, you can specify + # a much lower percentage to be reserved for liveslak: + # toram=none,12 + TORAM=1 + TRTYPE="$(echo $ARG |cut -f2 -d= |cut -f1 -d,)" + if [ "$TRTYPE" = "os" ]; then + VIRGIN=0 # load OS modules into RAM, write persistent data to disk + elif [ "$TRTYPE" = "core" ]; then + CORE2RAM=1 # load Core OS modules into RAM + elif [ "$TRTYPE" = "all" ]; then + VIRGIN=1 # prevent writes to disk since we are supposed to run from RAM + elif [ "$TRTYPE" = "none" ]; then + TORAM=0 # we only want to change the percentage reserved memory + fi + RAMSIZE="$(echo $ARG |cut -f2 -d= |cut -f2 -d,)" + if [ "$RAMSIZE" = "$TRTYPE" ]; then + # memperc was not supplied on commandline: + unset RAMSIZE + fi + ;; tweaks=*) # Comma-separated set of usability tweaks. # nga: no glamor 2d acceleration. @@ -249,7 +349,17 @@ for ARG in $(cat /proc/cmdline); do done # Verbose boot script execution: -[ $DEBUG -ge 2 ] && set -x +if [ $DEBUG -ge 2 ]; then + if [ $DEBUG -ge 5 ]; then + # We save (verbose) shell output to local file; + # These busybox compile options make it possible: + # CONFIG_SH_IS_ASH=y + # CONFIG_ASH_BASH_COMPAT=y + exec 5> debug_init.log + export BASH_XTRACEFD="5" + fi + set -x +fi debugit () { if [ $DEBUG -eq 0 -o $DEBUG -gt 3 ]; then @@ -292,7 +402,7 @@ if [ -x /sbin/udevd -a -x /sbin/udevadm ]; then if [ -n "$NFSHOST" ]; then # We also need network devices if NFS root is requested: if [ -z "$(/sbin/udevadm trigger --subsystem-match=net --action=add -v -n |rev |cut -d/ -f1 |rev |grep -v lo)" ]; then - /sbin/udevadm trigger $DEBUGV + /sbin/udevadm trigger --action=add $DEBUGV else /sbin/udevadm trigger --subsystem-match=net --action=add $DEBUGV fi @@ -308,18 +418,11 @@ if [ ! -d /lib/modules/$(uname -r) ]; then elif [ -x ./load_kernel_modules ]; then # use load_kernel_modules script: echo "${MARKER}: Loading kernel modules from initrd image:" . ./load_kernel_modules 1>/dev/null 2>/dev/null -else # load modules (if any) in order: - if ls /lib/modules/$(uname -r)/*.*o 1> /dev/null 2> /dev/null ; then - echo "${MARKER}: Loading kernel modules from initrd image:" - for module in /lib/modules/$(uname -r)/*.*o ; do - /sbin/modprobe $module 1>/dev/null 2>/dev/null - done - unset module - fi fi # Sometimes the devices need extra time to be available. # A root filesystem on USB is a good example of that. +echo "${MARKER}: Sleeping $WAIT seconds to give slow USB devices some time." sleep $WAIT # Fire at least one blkid: blkid 1>/dev/null 2>/dev/null @@ -378,6 +481,8 @@ if [ "$RESCUE" = "" ]; then echo "/run/dhcpcd-${MYDEV}.pid" elif [ -s /run/dhcpcd-${MYDEV}-4.pid ]; then echo "/run/dhcpcd-${MYDEV}-4.pid" + elif [ -s /run/${MYDEV}.pid ]; then + echo "/run/${MYDEV}.pid" else echo UNKNOWNLOC fi @@ -480,7 +585,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 @@ -495,22 +600,35 @@ if [ "$RESCUE" = "" ]; then mknod -m660 $lodev b 7 $(echo $lodev |sed 's%/dev/loop%%') fi echo "$lodev" - } + } # End find_loop() mod_base() { MY_MOD="$1" echo $(basename ${MY_MOD}) |rev |cut -d. -f2- |rev - } + } # End mod_base() find_mod() { MY_LOC="$1" - - ( for MY_EXT in ${SQ_EXT_AVAIL} ; do - echo "$(find ${MY_LOC} -name "*.${MY_EXT}" 2>/dev/null)" - done - ) | sort - } + MY_SUBSYS=$(basename "$1") + MY_SYSROOT=$(dirname "$1") + MY_COREMODS="$(echo boot ${CORE2RAMMODS} zzzconf |tr ' ' '|')" + + # For all except core2ram, this is a simple find & sort, but for core2ram + # we have to search two locations (system and core2ram) and filter the + # results to return only the Core OS modules: + if [ "${MY_SUBSYS}" = "core2ram" ]; then + ( for MY_EXT in ${SQ_EXT_AVAIL} ; do + echo "$(find ${MY_SYSROOT}/core2ram/ ${MY_SYSROOT}/system/ -name "*.${MY_EXT}" 2>/dev/null |grep -Ew ${DISTRO}_"(${MY_COREMODS})")" + done + ) | sort + else + ( for MY_EXT in ${SQ_EXT_AVAIL} ; do + echo "$(find ${MY_LOC} -name "*.${MY_EXT}" 2>/dev/null)" + done + ) | sort + fi + } # End find_mod() find_modloc() { MY_LOC="$1" @@ -528,14 +646,19 @@ if [ "$RESCUE" = "" ]; then fi echo "${MY_LOC}" - } + } # End find_modloc() load_modules() { - # SUBSYS can be 'system', 'addons', 'optional': + # SUBSYS can be 'system', 'addons', 'optional', 'core2ram': SUBSYS="$1" # Find all supported modules: - for MODULE in $(find_mod /mnt/media/${LIVEMAIN}/${SUBSYS}/) ; do + SUBSYSSET="$(find_mod /mnt/media/${LIVEMAIN}/${SUBSYS}/) $(find_mod ${SUPERMNT}/${LIVESLAKROOT}/${LIVEMAIN}/${SUBSYS}/)" + if [ "$SUBSYS" = "optional" ]; then + # We need to load any core2ram modules first: + SUBSYSSET="$(find_mod /mnt/media/${LIVEMAIN}/core2ram/) $(find_mod ${SUPERMNT}/${LIVESLAKROOT}/${LIVEMAIN}/core2ram/ ${SUBSYSSET})" + fi + for MODULE in ${SUBSYSSET} ; do # Strip path and extension from the modulename: MODBASE="$(mod_base ${MODULE})" if [ "$SUBSYS" = "optional" ]; then @@ -571,13 +694,22 @@ if [ "$RESCUE" = "" ]; then else echo "${MARKER}: Failed to mount $SUBSYS module '${MODBASE}', excluding it from the overlay." echo "$MODBASE" >> /mnt/live/modules/failed + rmdir /mnt/live/modules/${MODBASE} 2>/dev/null fi fi done - } + + # Warn if Core OS modules were requested but none were found/mounted; + if [ "$SUBSYS" = "core2ram" ]; then + MY_COREMODS="$(echo ${CORE2RAMMODS} |tr ' ' '|')" + if [ -z "$(ls -1 /mnt/live/modules/ |grep -Ew ${DISTRO}_"(${MY_COREMODS})")" ] ; then + echo "${MARKER}: '$SUBSYS' modules were not found. Trouble ahead..." + fi + fi + } # End load_modules() # Function input is a series of device node names. Return all block devices: - ret_blockdev () { + ret_blockdev() { local OUTPUT="" for IDEV in $* ; do if [ -e /sys/block/$(basename $IDEV) ]; then @@ -587,10 +719,10 @@ if [ "$RESCUE" = "" ]; then done # Trim trailing space: echo $OUTPUT |cat - } + } # End ret_blockdev() # Function input is a series of device node names. Return all partitions: - ret_partition () { + ret_partition() { local OUTPUT="" for IDEV in $* ; do if [ -e /sys/class/block/$(basename $IDEV)/partition ]; then @@ -600,22 +732,178 @@ if [ "$RESCUE" = "" ]; then done # Trim trailing space: echo $OUTPUT |cat - } + } # End ret_partition() + + # 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 ret_ventoy() + + # Find partition on which a file resides: + # Function input: + # (param 1) Full path to the file we are looking for + # (param 2) Directory to mount the partition containing our file + # Use $(df $MYMNT |tail -1 |tr -s ' ' |cut -d' ' -f1) to find that partition, + # it will remain mounted on the provided mountpoint upon function return. + scan_part() { + local FILEPATH="$1" + local MYMNT="$2" + local ISOPART="" + local PARTFS="" + echo "${MARKER}: Scanning for '$FILEPATH'..." + for ISOPART in $(ret_partition $(blkid |cut -d: -f1)) $(ret_blockdev $(blkid |cut -d: -f1)) ; do + PARTFS=$(blkid $ISOPART |rev |cut -d'"' -f2 |rev) + mount -t $PARTFS -o ro $ISOPART ${MYMNT} + if [ -f "${MYMNT}/${FILEPATH}" ]; then + # Found our file! + unset ISOPART + break + else + umount $ISOPART + fi + done + if [ -n "$ISOPART" ]; then + echo "${MARKER}: Partition scan unable to find $(basename $FILEPATH), trouble ahead." + return 1 + else + return 0 + fi + } # End scan_part() ## End support functions ## # We need a mounted filesystem here to be able to do a switch_root later, # so we create one in RAM: if [ $TORAM -eq 1 ]; then - RAMSIZE=90% # need to be able to load the entire OS in RAM + RAMSIZE="${RAMSIZE:-90}%" # 90% by default to load the entire OS in RAM else - RAMSIZE=50% # the default value. + RAMSIZE="${RAMSIZE:-50}%" # 50% is the default value. fi mount -t tmpfs -o defaults,size=${RAMSIZE} none /mnt # 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 + # Newer Slackware will use 'efivars' rather than 'vars' directory; + VENTVAR="/sys/firmware/efi/efivars/${VENTID}" + fi + if [ -d "${VENTVAR}" ]; then + echo "${MARKER}: (UEFI) Ventoy ISO boot detected..." + ISOBOOT="ventoy" + VENTOSPARM="${VENTVAR}/data" + elif [ -f "${VENTVAR}" ]; then + # Kernel >= 6.x does not offer a clean data sctructure, so we need to + # find the offset of the data block in the efivars file: + cat "${VENTVAR}" > /vent.dmp + 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 + fi + if [ -f /vent.dmp ]; then + # Use 'strings' to find the decimal offset of the magic string; + # With 'xargs' we remove leading and ending spaces: + if strings -t d /vent.dmp 1>/dev/null 2>/dev/null ; then + # Busybox in Slackware 15.0 or newer: + OFFSET=$(strings -t d /vent.dmp |grep ' www.ventoy.net' |xargs |cut -d' ' -f1) + else + # Busybox in Slackware 14.2 or older: + OFFSET=$(strings -o /vent.dmp |grep ' www.ventoy.net' |xargs |cut -d' ' -f1) + fi + 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 @@ -631,6 +919,7 @@ if [ "$RESCUE" = "" ]; then VIRGIN=1 elif [ -z "$LIVEMEDIA" ]; then # LIVEMEDIA not specified on the boot commandline using "livemedia=" + # Start digging: # Filter out the block devices, only look at partitions at first: # The blkid function in busybox behaves differently than the regular blkid! # It will return all devices with filesystems and list LABEL UUID and TYPE. @@ -649,6 +938,7 @@ if [ "$RESCUE" = "" ]; then # We found a block device with the correct label (non-UEFI media). # Determine filesystem type ('iso9660' means we found a CDROM/DVD) LIVEFS=$(blkid $LIVEMEDIA |rev |cut -d'"' -f2 |rev) + [ "$LIVEFS" = "swap" ] && continue mount -t $LIVEFS -o ro $LIVEMEDIA /mnt/media else # Bummer.. label not found; the ISO was extracted to a different device. @@ -656,8 +946,10 @@ if [ "$RESCUE" = "" ]; then for SLDEVICE in $(ret_partition $(blkid |cut -d: -f1)) $(ret_blockdev $(blkid |cut -d: -f1)) ; do # We rely on the fact that busybox blkid puts TYPE"..." at the end: SLFS=$(blkid $SLDEVICE |rev |cut -d'"' -f2 |rev) + [ "$SLFS" = "swap" ] && continue mount -t $SLFS -o ro $SLDEVICE /mnt/media - if [ -d /mnt/media/${LIVEMAIN} ]; then + if [ -f /mnt/media/${LIVEMAIN}/system/0099-${DISTRO}_zzzconf-*.s* ]; + then # Found our media! LIVEALL=$SLDEVICE LIVEMEDIA=$SLDEVICE @@ -676,7 +968,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) @@ -693,39 +986,31 @@ 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 - # Scan partitions to find the one with the ISO and set LIVEMEDIA: - echo "${MARKER}: Scanning for '$LIVEPATH'..." - for ISOPART in $(ret_partition $(blkid |cut -d: -f1)) $(ret_blockdev $(blkid |cut -d: -f1)) ; do - PARTFS=$(blkid $ISOPART |rev |cut -d'"' -f2 |rev) - # Abuse the $SUPERMNT a bit, we will actually use it later: - mount -t $PARTFS -o ro $ISOPART ${SUPERMNT} - if [ -f ${SUPERMNT}/${LIVEPATH} ]; then - # Found our ISO! - LIVEMEDIA=$ISOPART - umount $ISOPART - unset ISOPART - break - else - umount $ISOPART - fi - done - if [ -n "$ISOPART" ]; then - echo "${MARKER}: Partition scan unable to find ISO, trouble ahead." - fi + # Scan partitions to find the one with the ISO and set LIVEMEDIA. + # Abuse the $SUPERMNT a bit, we will actually use it later. + # TODO: proper handling of scan_part return code. + scan_part ${LIVEPATH} ${SUPERMNT} + LIVEMEDIA="$(df ${SUPERMNT} 2>/dev/null |tail -1 |tr -s ' ' |cut -d' ' -f1)" + umount ${SUPERMNT} 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) @@ -733,11 +1018,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 @@ -767,8 +1064,8 @@ if [ "$RESCUE" = "" ]; then BLACKLIST KEYMAP LIVE_HOSTNAME LOAD LOCALE LUKSVOL \ NOLOAD RUNLEVEL TWEAKS TZ XKB ; do - if [ -n "${LIVEPARM}" ]; then - eval $(grep -w ${LIVEPARM} /mnt/media/${LIVEMAIN}/${DISTROCFG}) + if [ -z "$(eval echo \$${LIVEPARM})" ]; then + eval $(grep -w ^${LIVEPARM} /mnt/media/${LIVEMAIN}/${DISTROCFG}) fi done fi @@ -790,6 +1087,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 @@ -804,7 +1127,7 @@ if [ "$RESCUE" = "" ]; then # Load a custom keyboard mapping: if [ -n "$KEYMAP" ]; then - echo "${MARKER}: Loading '$KEYMAP' keyboard mapping:" + echo "${MARKER}: Loading '$KEYMAP' keyboard mapping." tar xzOf /etc/keymaps.tar.gz ${KEYMAP}.bmap | loadkmap fi @@ -824,88 +1147,223 @@ if [ "$RESCUE" = "" ]; then RODIRS="" FS2HD="" - # First, the base Slackware system components: - load_modules system - - # Next, the add-on (3rd party etc) components, if any: - # Remember, module name must adhere to convention: "NNNN-modname-*.sxz" - # where 'N' is a digit and 'modname' must not contain a dash '-'. - load_modules addons - - # And finally any explicitly requested optionals (like nvidia drivers): - # Remember, module name must adhere to convention: "NNNN-modname-*.sxz" - # where 'N' is a digit and 'modname' must not contain a dash '-'. - load_modules optional + if [ $CORE2RAM -eq 1 ]; then + # Only load the Core OS modules: + echo "${MARKER}: Loading Core OS into RAM." + load_modules core2ram + else + # First, the base Slackware system components: + load_modules system + + # Next, the add-on (3rd party etc) components, if any: + # Remember, module name must adhere to convention: "NNNN-modname-*.sxz" + # where 'N' is a digit and 'modname' must not contain a dash '-'. + load_modules addons + + # And finally any explicitly requested optionals (like nvidia drivers): + ## TODO: + ## Automatically load the nvidia driver if we find a supported GPU: + # NVPCIID=$(lspci -nn|grep NVIDIA|grep VGA|rev|cut -d'[' -f1|rev|cut -d']' -f1|tr -d ':'|tr [a-z] [A-Z]) + # if cat /mnt/media/${LIVEMAIN}/optional/nvidia-*xx.ids |grep -wq $NVPCIID ; + # then + # LOAD="nvidia,${LOAD}" + # fi + ## END TODO: + # Remember, module name must adhere to convention: "NNNN-modname-*.sxz" + # where 'N' is a digit and 'modname' must not contain a dash '-'. + load_modules optional + fi # Get rid of the starting colon: RODIRS=$(echo $RODIRS |cut -c2-) FS2HD=$(echo $FS2HD |cut -c2-) if [ $TORAM -ne 0 ]; then - echo "${MARKER}: Live OS copied to RAM, you can remove the Live medium." + echo "${MARKER}: Live OS has been copied to RAM." + # Inform user in case we won't do persistent writes and the medium + # does not contain LUKS-encrypted containers to mount: + if [ $VIRGIN -ne 0 -a -z "$LUKSVOL" ]; then + echo "${MARKER}: You can now safely remove the live medium." + fi if [ "LIVEFS" = "iso9660" ]; then eject ${LIVEMEDIA} fi fi - # Setup persistence in case our media is writable, *and* the user - # has created a directory "persistence" in the root of the media. - # otherwise we let the block changes accumulate in RAM only. - - # Create the mount point for the writable upper directory of the overlay: - # Assume the default to be a readonly media - we write to RAM: - UPPERDIR=/mnt/live/changes - OVLWORK=/mnt/live/.ovlwork - if [ "$VIRGIN" = "0" ]; then - if [ "LIVEFS" != "iso9660" -a -d /mnt/media/${PERSISTENCE} ]; then - # Looks OK, but we need to remount the media in order to write - # to the persistence directory: - mount -o remount,rw /mnt/media + # --------------------------------------------------------------- # + # # + # Setup persistence in case our media is writable, *and* the user # + # has created a persistence directory or container on the media, # + # otherwise we let the block changes accumulate in RAM only. # + # # + # --------------------------------------------------------------- # + + # Was a partition specified containing a persistence directory, + # and is it different from the live medium? + if [ -n "${PERSISTPART}" ]; then + # If partition was specified as UUID/LABEL, or as 'scandev', + # we need to figure out the partition device ourselves: + if [ "${PERSISTPART}" != "scandev" -a ! -b "${PERSISTPART}" ]; then + TEMPP=$(findfs UUID=${PERSISTPART} 2>/dev/null) || TEMPP=$(findfs LABEL=${PERSISTPART} 2>/dev/null) + if [ -n "${TEMPP}" ]; then + PERSISTPART=${TEMPP} + else + echo "${MARKER}: Partition '${PERSISTPART}' needed for persistence was not found." + echo "${MARKER}: Falling back to recording changes in RAM." + PERSISTPART="" + VIRGIN=1 + fi + unset TEMPP + elif [ "${PERSISTPART}" = "scandev" ]; then + # Scan partitions to find the one with the persistence directory: + echo "${MARKER}: Scanning for partition with '${PERSISTENCE}'..." + ppartdir=".persistence_$(od -An -N1 -tu1 /dev/urandom|tr -d ' ')" + mkdir -p /mnt/live/${ppartdir} + for PPART in $(ret_partition $(blkid |cut -d: -f1)) ; do + 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}${CNTEXT} ]; then + # Found our persistence directory/container! + PERSISTPART=$PPART + unset PPART + umount /mnt/live/${ppartdir} + break + else + umount /mnt/live/${ppartdir} + fi + done + rmdir /mnt/live/${ppartdir} + if [ -n "$PPART" ]; then + echo "${MARKER}: Partition scan unable to find persistence." + echo "${MARKER}: Falling back to recording changes in RAM." + PERSISTPART="" + VIRGIN=1 + fi + fi + fi + + debugit + + # ------------------------------------------------------------------ # + # # + # At this point, we either have determined the persistence partition # + # via UUID/LABEL/scandev, or else we failed to find one, # + # and then VIRGIN has been set to '1' and PERSISTPART to "". # + # # + # ------------------------------------------------------------------ # + + if [ -n "${PERSISTPART}" ]; then + # Canonicalize the input and the media devices, + # to ensure that we are talking about two different devices: + MPDEV=$(df /mnt/media |tail -1 |tr -s ' ' |cut -d' ' -f1) + 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}' 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': + 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), 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. + + # Create the mount point for the writable upper directory of the overlay. + # First, we deal with the case of persistence (VIRGIN=0) and then we + # deal with a pure Live system without persistence (VIRGIN=1): + + if [ $VIRGIN -eq 0 ]; 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} + if [ $? -ne 0 ]; then + echo "${MARKER}: Failed to mount persistence partition '${PERSISTPART}' read/write." + echo "${MARKER}: Falling back to recording changes in RAM." + VIRGIN=1 + fi + fi + fi + + # We have now checked whether the persistence area is actually writable. + + if [ $VIRGIN -eq 0 ]; then + # Persistence directory (either on writable USB or else on system harddisk): + if [ -d ${PPATHINTERNAL}/${PERSISTPATH}/${PERSISTENCE} ]; then # Try a write... just to be dead sure: - if touch /mnt/media/${PERSISTENCE}/.rwtest 2>/dev/null && rm /mnt/media/${PERSISTENCE}/.rwtest 2>/dev/null ; then + if touch ${PPATHINTERNAL}/${PERSISTPATH}/${PERSISTENCE}/.rwtest 2>/dev/null && rm ${PPATHINTERNAL}/${PERSISTPATH}/${PERSISTENCE}/.rwtest 2>/dev/null ; then # Writable media and we are allowed to write to it. - if [ "$WIPE_PERSISTENCE" = "1" -o -f /mnt/media/${PERSISTENCE}/.wipe ]; then - echo "${MARKER}: Wiping existing persistent data in '/${PERSISTENCE}'." - rm -f /mnt/media/${PERSISTENCE}/.wipe 2>/dev/null - find /mnt/media/${PERSISTENCE}/ -mindepth 1 -exec rm -rf {} \; 2>/dev/null + if [ "$WIPE_PERSISTENCE" = "1" -o -f ${PPATHINTERNAL}/${PERSISTPATH}/${PERSISTENCE}/.wipe ]; then + echo "${MARKER}: Wiping existing persistent data in '${PERSISTPATH}/${PERSISTENCE}'." + rm -f ${PPATHINTERNAL}/${PERSISTPATH}/${PERSISTENCE}/.wipe 2>/dev/null + find ${PPATHINTERNAL}/${PERSISTPATH}/${PERSISTENCE}/ -mindepth 1 -exec rm -rf {} \; 2>/dev/null fi - echo "${MARKER}: Writing persistent changes to media directory '/${PERSISTENCE}'." - UPPERDIR=/mnt/media/${PERSISTENCE} - OVLWORK=/mnt/media/.ovlwork + echo "${MARKER}: Writing persistent changes to media directory '${PERSISTENCE}'." + UPPERDIR=${PPATHINTERNAL}/${PERSISTPATH}/${PERSISTENCE} + OVLWORK=${PPATHINTERNAL}/${PERSISTPATH}/.ovlwork + else + echo "${MARKER}: Failed to write to persistence directory '${PERSISTENSE}'." + echo "${MARKER}: Falling back to recording changes in RAM." + VIRGIN=1 fi - elif [ "LIVEFS" != "iso9660" -a -f /mnt/media/${PERSISTENCE}.img ]; then - # Use a container file; the filesystem needs to be writable: - mount -o remount,rw /mnt/media + # 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=$(basename ${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 /mnt/media/${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 "Unlocking LUKS encrypted persistence file '/${PERSISTENCE}.img'" - cryptsetup luksOpen $prdev $(basename ${PERSISTENCE}) </dev/tty0 >/dev/tty0 2>&1 + 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 '/${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/$(basename ${PERSISTENCE}) + 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 '/${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}/$(basename ${PERSISTENCE})/.wipe ]; then - echo "${MARKER}: Wiping existing persistent data in '/${PERSISTENCE}.img'." - rm -f /mnt/live/${prdir}/$(basename ${PERSISTENCE})/.wipe 2>/dev/null - find /mnt/live/${prdir}/$(basename ${PERSISTENCE})/ -mindepth 1 -exec rm -rf {} \; 2>/dev/null + if [ "$WIPE_PERSISTENCE" = "1" -o -f /mnt/live/${prdir}/${PERSISTENCE}/.wipe ]; then + 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 '/${PERSISTENCE}.img'." - UPPERDIR=/mnt/live/${prdir}/$(basename ${PERSISTENCE}) + echo "${MARKER}: Writing persistent changes to file '${PERSISTPATH}/${PERSISTENCE}${CNTEXT}'." + UPPERDIR=/mnt/live/${prdir}/${PERSISTENCE} OVLWORK=/mnt/live/${prdir}/.ovlwork fi fi @@ -914,7 +1372,13 @@ 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 fi @@ -934,7 +1398,7 @@ if [ "$RESCUE" = "" ]; then # And this is the actual Live overlay: mount -t overlay -o workdir=${OVLWORK},upperdir=${UPPERDIR},lowerdir=${RODIRS} overlay /mnt/overlay MNTSTAT=$? - if [ "$VIRGIN" = "0" ]; then + if [ $VIRGIN -eq 0 ]; then if [ $MNTSTAT -ne 0 ]; then # Failed to create the persistent overlay - try without persistence: echo "${MARKER}: Failed to create persistent overlay, attempting to continue in RAM." @@ -980,6 +1444,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 @@ -988,6 +1458,44 @@ if [ "$RESCUE" = "" ]; then done fi + if [ ! -z "$LUKSVOL" ]; then + # Bind any LUKS container into the Live filesystem: + for luksvol in $(echo $LUKSVOL |tr ',' ' '); do + luksfil="$(echo $luksvol |cut -d: -f1)" + luksmnt="$(echo $luksvol |cut -d: -f2)" + luksnam="$(echo $(basename $luksfil) |tr '.' '_')" + if [ "$luksmnt" = "$luksfil" ]; then + # No optional mount point specified, so we use the default: /home/ + luksmnt="/home" + fi + + # Find a free loop device: + lodev=$(find_loop) + + 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 + echo "${MARKER}: Failed to unlock LUKS container '$luksfil'... trouble ahead." + else + # Create the mount directory if it does not exist (unlikely): + mkdir -p /mnt/overlay/$luksmnt + + # Let Slackware mount the unlocked container: + luksfs=$(blkid /dev/mapper/$luksnam |rev |cut -d'"' -f2 |rev) + if ! grep -q "^/dev/mapper/$luksnam" /mnt/overlay/etc/fstab ; then + echo "/dev/mapper/$luksnam $luksmnt $luksfs defaults 1 1" >> /mnt/overlay/etc/fstab + fi + # On shutdown, ensure that the container gets locked again: + if ! grep -q "$luksnam $luksmnt" /mnt/overlay/etc/crypttab ; then + echo "$luksnam $luksmnt" >> /mnt/overlay/etc/crypttab + fi + fi + done + fi + + debugit + if [ ! -z "$KEYMAP" ]; then # Configure custom keyboard mapping in console and X: echo "${MARKER}: Switching live console to '$KEYMAP' keyboard" @@ -1082,9 +1590,9 @@ EOT if [ ! -z "$TZ" -a -f /mnt/overlay/usr/share/zoneinfo/${TZ} ]; then # Configure custom timezone: echo "${MARKER}: Configuring timezone '$TZ'" - cp /mnt/overlay/usr/share/zoneinfo/${TZ} /mnt/overlay/etc/localtime + rm -f /mnt/overlay/etc/localtime + ln -s /usr/share/zoneinfo/${TZ} /mnt/overlay/etc/localtime rm -f /mnt/overlay/etc/localtime-copied-from - ln -s /usr/share/zoneinfo/${TZ} /mnt/overlay/etc/localtime-copied-from # Configure the hardware clock to be interpreted as localtime and not UTC: cat <<EOT > /mnt/overlay/etc/hardwareclock # /etc/hardwareclock @@ -1097,7 +1605,7 @@ EOT # file so QT5 fails to determine the timezone and falls back to UTC. Fix: echo ${TZ} > /mnt/overlay/etc/timezone - # KDE4 and PLASMA5 user timezone re-configuration: + # KDE4 and Plasma5 user timezone re-configuration: if [ -f /mnt/overlay/home/${LIVEUID}/.kde/share/config/ktimezonedrc ]; then sed -i -e "s%^LocalZone=.*%LocalZone=${TZ}%" \ /mnt/overlay/home/${LIVEUID}/.kde/share/config/ktimezonedrc @@ -1108,20 +1616,28 @@ EOT fi fi - if [ ! -z "$LIVEPW" ]; then + if [ -n "$LIVEPW" ] && [ "$LIVEPW" != "${DEFPW}" ]; then # User entered a custom live password on the boot commandline: echo "${MARKER}: Changing password for user '${LIVEUID}'." chroot /mnt/overlay /usr/sbin/chpasswd <<EOPW ${LIVEUID}:${LIVEPW} EOPW + elif [ -z "$LIVEPW" ]; then + # User requested an empty live password: + echo "${MARKER}: Removing password for user '${LIVEUID}'." + chroot /mnt/overlay /usr/bin/passwd -d ${LIVEUID} fi - if [ ! -z "$ROOTPW" ]; then + if [ -n "$ROOTPW" ] && [ "$ROOTPW" != "${DEFPW}" ]; then # User entered a custom root password on the boot commandline: echo "${MARKER}: Changing password for user 'root'." chroot /mnt/overlay /usr/sbin/chpasswd <<EOPW root:${ROOTPW} EOPW + elif [ -z "$ROOTPW" ]; then + # User requested an empty root password: + echo "${MARKER}: Removing password for user 'root'." + chroot /mnt/overlay /usr/bin/passwd -d root fi if [ ! -z "$HNMAC" -a "$HNMAC_ALLOWED" = "YES" ]; then @@ -1133,15 +1649,20 @@ EOPW fi fi + if [ -z "$LIVE_DOMAIN" ]; then + # No custom domain on the boot commandline: + LIVE_DOMAIN="home.arpa" + fi + if [ ! -z "$LIVE_HOSTNAME" ]; then # User entered a custom hostname on the boot commandline: echo "${MARKER}: Changing hostname to '$LIVE_HOSTNAME'." - echo "${LIVE_HOSTNAME}.example.net" > /mnt/overlay/etc/HOSTNAME + echo "${LIVE_HOSTNAME}.${LIVE_DOMAIN}" > /mnt/overlay/etc/HOSTNAME if [ -f /mnt/overlay/etc/NetworkManager/NetworkManager.conf ]; then sed -i -e "s/^hostname=.*/hostname=${LIVE_HOSTNAME}/" \ /mnt/overlay/etc/NetworkManager/NetworkManager.conf fi - sed -i -e "s/^\(127.0.0.1\t*\)@DARKSTAR@.*/\1${LIVE_HOSTNAME}.example.net ${LIVE_HOSTNAME}/" /mnt/overlay/etc/hosts + sed -i -e "s/^\(127.0.0.1\t*\)@DARKSTAR@.*/\1${LIVE_HOSTNAME}.${LIVE_DOMAIN} ${LIVE_HOSTNAME}/" /mnt/overlay/etc/hosts fi if [ -n "$NFSHOST" ]; then @@ -1152,7 +1673,7 @@ EOPW mkdir -p /mnt/overlay/run/dhcpcd mount --bind /run/dhcpcd /mnt/overlay/run/dhcpcd fi - cp -a /run/dhcpcd* /mnt/overlay/run/ + cp -a /run/dhcpcd* /run/${INTERFACE}.pid /mnt/overlay/run/ cat /etc/resolv.conf > /mnt/overlay/etc/resolv.conf # Disable NetworkManager: @@ -1274,6 +1795,7 @@ Xft.lcdfilter: lcddefault Xft.rgba: rgb Xft.autohint: 0 EOT + chroot /mnt/overlay/ chown ${LIVEUID}:users /home/${LIVEUID}/.Xresources elif [ -f /mnt/overlay/etc/profile.d/freetype.sh ]; then # Explicitly configure the non-default old v35 interpreter in freetype: cat <<EOT >> /mnt/overlay/etc/profile.d/freetype.sh @@ -1305,7 +1827,7 @@ EOT done if [ $RUN_DEPMOD -eq 1 ]; then # This costs a few seconds in additional boot-up time unfortunately: - echo "${MARKER}: Additional kernel module(s) found... need a bit" + echo "${MARKER}: Additional kernel module(s) found... need a bit" chroot /mnt/overlay /sbin/depmod -a fi unset RUN_DEPMOD @@ -1316,52 +1838,19 @@ EOT # In case of network boot, do not kill the network, umount NFS prematurely # or stop udevd on shutdown: if [ -n "$NFSHOST" ]; then - sed -i /mnt/overlay/etc/rc.d/rc.0 \ - -e "/on \/ type nfs/s%grep -q 'on / type nfs'%egrep -q 'on / type (nfs|tmpfs)'%" \ - -e '/umount.*nfs/s/nfs,//' \ - -e 's/rc.udev force-stop/rc.udev stop/' \ - -e 's/$(pgrep mdmon)/& $(pgrep udevd)/' + for RUNLVL in 0 6 ; do + sed -i /mnt/overlay/etc/rc.d/rc.${RUNLVL} \ + -e "/on \/ type nfs/s%grep -q 'on / type nfs'%egrep -q 'on / type (nfs|tmpfs)'%" \ + -e "s%'on / type nfs4'%& -e 'on / type overlay'%" \ + -e '/umount.*nfs/s/nfs,//' \ + -e 's/rc.udev force-stop/rc.udev stop/' \ + -e 's/$(pgrep mdmon)/& $(pgrep udevd)/' + done fi # Copy contents of rootcopy directory (may be empty) to overlay: cp -af /mnt/media/${LIVEMAIN}/rootcopy/* /mnt/overlay/ 2>/dev/null - # Bind any LUKS container into the Live filesystem: - if [ ! -z "$LUKSVOL" ]; then - for luksvol in $(echo $LUKSVOL |tr ',' ' '); do - luksfil="$(echo $luksvol |cut -d: -f1)" - luksmnt="$(echo $luksvol |cut -d: -f2)" - luksnam="$(echo $(basename $luksfil) |tr '.' '_')" - if [ "$luksmnt" = "$luksfil" ]; then - # No optional mount point specified, so we use the default: /home/ - luksmnt="/home" - fi - - # Find a free loop device: - lodev=$(find_loop) - - losetup $lodev /mnt/media/$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 - echo "${MARKER}: Failed to unlock LUKS container '$luksfil'... trouble ahead." - else - # Create the mount directory if it does not exist (unlikely): - mkdir -p /mnt/overlay/$luksmnt - - # Let Slackware mount the unlocked container: - luksfs=$(blkid /dev/mapper/$luksnam |rev |cut -d'"' -f2 |rev) - if ! grep -q /dev/mapper/$luksnam /mnt/overlay/etc/fstab ; then - echo "/dev/mapper/$luksnam $luksmnt $luksfs defaults 1 1" >> /mnt/overlay/etc/fstab - fi - # On shutdown, ensure that the container gets locked again: - if ! grep -q "$luksnam $luksmnt" /mnt/overlay/etc/crypttab ; then - echo "$luksnam $luksmnt" >> /mnt/overlay/etc/crypttab - fi - fi - done - fi - [ $DEBUG -gt 3 ] && rescue "DEBUG SHELL" # --------------------------------------------------------------------- # @@ -1393,8 +1882,8 @@ fi /sbin/udevadm control --exit unset ERR -umount /proc -umount /sys +umount /proc 2>/dev/null +umount /sys 2>/dev/null umount /run 2>/dev/null echo "${MARKER}: Slackware Live system is ready." |