summaryrefslogtreecommitdiffstats
path: root/iso2usb.sh
diff options
context:
space:
mode:
Diffstat (limited to 'iso2usb.sh')
-rw-r--r--iso2usb.sh456
1 files changed, 337 insertions, 119 deletions
diff --git a/iso2usb.sh b/iso2usb.sh
index 237e553..dfe1eec 100644
--- a/iso2usb.sh
+++ b/iso2usb.sh
@@ -1,6 +1,6 @@
#!/bin/bash
#
-# Copyright 2015, 2016, 2017 Eric Hameleers, Eindhoven, NL
+# Copyright 2015, 2016, 2017, 2019, 2020, 2021, 2022, 2023 Eric Hameleers, Eindhoven, NL
# All rights reserved.
#
# Redistribution and use of this script, with or without modification, is
@@ -29,6 +29,23 @@ export PATH="/usr/sbin:/sbin:/usr/bin:/bin"
# Set to '1' if you want to ignore all warnings:
FORCE=0
+# The default layout of the USB stick is:
+# partition 1 (1MB),
+# partition 2 (100 MB)
+# partition 3 (claim all free space - specified as -1 MB).
+# The script allows for an amount of free space to be left at the end
+# (partition 4, un-used by liveslak) in case you need this:
+DEF_LAYOUT="1,100,-1,"
+
+# The extension for containerfiles accompanying an ISO is '.icc',
+# whereas the persistent USB stick created with iso2usb.sh uses '.img'.
+DEFEXT=".img"
+CNTEXT="${DEFEXT}"
+
+# Default filesystem for devices/containers:
+DEF_FS="ext4"
+FSYS="${DEF_FS}"
+
# By default, we use 'slhome.img' as the name of the LUKS home containerfile.
DEF_SLHOME="slhome"
SLHOME="${DEF_SLHOME}"
@@ -72,23 +89,24 @@ DOLUKS=0
REFRESH=0
# These tools are required by the script, we will check for their existence:
-REQTOOLS="blkid cpio extlinux fdisk gdisk isoinfo mkdosfs sgdisk syslinux"
+REQTOOLS="blkid cpio cryptsetup extlinux fdisk find gdisk gzip isoinfo losetup lsblk lzip mkdosfs sgdisk syslinux wipefs xz"
# Path to syslinux files:
if [ -d /usr/share/syslinux ]; then
SYSLXLOC="/usr/share/syslinux"
+ GPTMBRBIN=$(find $SYSLXLOC -name gptmbr.bin)
elif [ -d /usr/lib/syslinux ]; then
SYSLXLOC="/usr/lib/syslinux"
+ GPTMBRBIN=$(find $SYSLXLOC -name gptmbr.bin)
else
# Should not happen... in this case we use what we have on the ISO
# and hope for the best:
- SYSLXLOC=""
+ SYSLXLOC="/"
+ GPTMBRBIN="gptmbr.bin"
fi
# Initialize more variables:
-CNTBASE=""
CNTDEV=""
-CNTFILE=""
HLUKSSIZE=""
LUKSHOME=""
LODEV=""
@@ -100,6 +118,11 @@ CNTMNT=""
USBMNT=""
US2MNT=""
+# 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"
@@ -109,7 +132,7 @@ COMPR="xz --check=crc32"
#
# Clean up in case of failure:
-cleanup() {
+function cleanup() {
# Clean up by unmounting our loopmounts, deleting tempfiles:
echo "--- Cleaning up the staging area..."
# During cleanup, do not abort due to non-zero exit code:
@@ -119,7 +142,7 @@ cleanup() {
# In case of failure, only the most recent device should still be open:
if mount |grep -q ${CNTDEV} ; then
umount -f ${CNTDEV}
- cryptsetup luksClose $(basename ${CNTBASE})
+ cryptsetup luksClose $(basename ${CNTDEV})
losetup -d ${LODEV}
fi
fi
@@ -129,24 +152,25 @@ cleanup() {
[ -n "${US2MNT}" ] && ( umount -f ${US2MNT} 2>/dev/null; rmdir $US2MNT 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
-showhelp() {
+function showhelp() {
cat <<EOT
#
# Purpose: to transfer the content of Slackware's Live ISO image
-# to a standard USB thumb drive (which will be formatted and wiped!)
+# to a standard USB thumb drive (or some other kind of external storage)
# and thus create a Slackware Live USB media.
#
-# Your USB thumb drive may contain data!
-# This data will be *erased* !
+# WARNING: Your USB thumb drive may contain data!
+# If you are not using the refresh option '-r' then this data will be *erased* !
#
# $(basename $0) accepts the following parameters:
# -c|--crypt size|perc Add LUKS encrypted /home ; parameter is the
# requested size of the container in kB, MB, GB,
-# or as a percentage of free space.
-# Examples: '-c 125M', '-c 1.3G', '-c 20%'.
+# or as a percentage of free space
+# (integer numbers only).
+# Examples: '-c 125M', '-c 2G', '-c 20%'.
# -d|--devices List removable devices on this computer.
# -f|--force Ignore most warnings (except the back-out).
# -h|--help This help.
@@ -162,65 +186,131 @@ cat <<EOT
# providing a devicename (using option '-o').
# -u|--unattended Do not ask any questions.
# -v|--verbose Show verbose messages.
-# -w|--wait<number> Add <number> seconds wait time to initialize USB.
+# -w|--wait <number> Add <number> seconds wait time to initialize USB.
+# -y|--layout <x,x,x,x> Specify partition layout and sizes (in MB).
+# Default values: '$DEF_LAYOUT' for 3 partitions,
+# the '-1' value for partition 3 meaning
+# 'use all remaining space',
+# and an empty 4th value means 'do not reserve
+# free space for a custom 4th partition'.
# -C|--cryptpersistfile size|perc
# Use a LUKS-encrypted 'persistence' file instead
-# of a directory (for use on FAT filesystem).
+# of a directory (for use on FAT filesystem)
+# Format for size/percentage is the same
+# as for the '-c' parameter.
+# -F|--filesystem <fs> Specify filesystem to create when formatting
+# devices/containers. Defaults to '${DEF_FS}',
+# Choices are $(createfs).
+# Note that the linux partition will always be
+# formatted as 'ext4' because extlinux is used
+# as the BIOS bootloader.
# -P|--persistfile Use a 'persistence' container file instead of
# a directory (for use on FAT filesystem).
+# Persistent data will not be migrated
+# when switching from directory to container file.
#
# Examples:
#
# $(basename $0) -i ~/download/slackware64-live-14.2.iso -o /dev/sdX
-# $(basename $0) -i slackware64-live-xfce-current.iso -o /dev/sdX -c 750M -w 15
+# $(basename $0) -i slackware64-live-xfce-current.iso -o /dev/mmcblkX -c 750M -w 15
+# $(basename $0) -i slackware-live-current.iso -o /dev/sdX -y 1,200,-1,4096
#
EOT
-}
+} # End of showhelp()
+
+# Create a filesystem on a partition with optional label:
+function createfs () {
+ MYDEV="${1}"
+ MYFS="${2:-'ext4'}"
+ MYLABEL="${3}"
+
+ if [ -z "${MYDEV}" ]; then
+ # Without arguments given, reply with list of supported fs'es:
+ echo "btrfs,ext2,ext4,f2fs,jfs,xfs"
+ return
+ fi
+
+ if [ -n "${MYLABEL}" ]; then
+ case "${MYFS}" in
+ fs2s) MYLABEL="-l ${MYLABEL}" ;;
+ *) MYLABEL="-L ${MYLABEL}" ;;
+ esac
+ fi
+
+ case "${MYFS}" in
+ btrfs) mkfs.btrfs -f -d single -m single ${MYLABEL} ${MYDEV}
+ ;;
+ ext2) mkfs.ext2 -F -F ${MYLABEL} ${MYDEV}
+ # Tune the ext2 filesystem:
+ tune2fs -m 0 -c 0 -i 0 ${MYDEV}
+ ;;
+ ext4) mkfs.ext4 -F -F ${MYLABEL} ${MYDEV}
+ # Tune the ext4 filesystem:
+ tune2fs -m 0 -c 0 -i 0 ${MYDEV}
+ ;;
+ f2fs) mkfs.f2fs ${MYLABEL} -f ${MYDEV}
+ ;;
+ jfs) mkfs.jfs -q ${MYDEV}
+ ;;
+ xfs) mkfs.xfs -f ${MYDEV}
+ ;;
+ *) echo "*** Unsupported filesystem '${MYFS}'!"; exit 1
+ ;;
+ esac
+} # End of createfs()
# 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}"
+function uncompressfs () {
+ local IMGFILE="$1"
+ # Content is streamed to STDOUT:
+ if $(file "${IMGFILE}" | grep -qi ": gzip"); then
+ gzip -cd "${IMGFILE}"
+ elif $(file "${IMGFILE}" | grep -qi ": XZ"); then
+ xz -cd "${IMGFILE}"
+ elif $(file "${IMGFILE}" | grep -qi ": LZMA"); then
+ lzma -cd "${IMGFILE}"
+ elif $(file "${IMGFILE}" | grep -qi ": lzip"); then
+ lzip -cd "${IMGFILE}"
fi
-}
+} # End of uncompressfs()
# Scan for insertion of a USB device:
-scan_devices() {
+function scan_devices() {
+ local MYSCANWAIT="${1}"
local BD
# Inotifywatch does not trigger on symlink creation,
# so we can not watch /sys/block/
- BD=$(inotifywait -q -t ${SCANWAIT} -e create /dev 2>/dev/null |cut -d' ' -f3)
+ BD=$(inotifywait -q -t ${MYSCANWAIT} -e create /dev 2>/dev/null |cut -d' ' -f3)
echo ${BD}
} # End of scan_devices()
# Show a list of removable devices detected on this computer:
-show_devices() {
+function show_devices() {
local MYDATA="${*}"
if [ -z "${MYDATA}" ]; then
MYDATA="$(ls --indicator-style=none /sys/block/ |grep -Ev '(ram|loop|dm-)')"
fi
+ echo "#"
echo "# Removable devices detected on this computer:"
for BD in ${MYDATA} ; do
if [ $(cat /sys/block/${BD}/removable) -eq 1 ]; then
- echo "# /dev/${BD} : $(cat /sys/block/${BD}/device/vendor) $(cat /sys/block/${BD}/device/model): $(( $(cat /sys/block/${BD}/size) / 2048)) MB"
+ echo "# /dev/${BD} : $(cat /sys/block/${BD}/device/vendor 2>/dev/null) $(cat /sys/block/${BD}/device/model 2>/dev/null): $(( $(cat /sys/block/${BD}/size) / 2048)) MB"
fi
done
echo "#"
} # End of show_devices()
# Read configuration data from old initrd:
-read_initrd() {
+function read_initrd() {
IMGFILE="$1"
OLDPERSISTENCE=$(uncompressfs ${IMGFILE} |cpio -i --to-stdout init |grep "^PERSISTENCE" |cut -d '"' -f2 2>/dev/null)
OLDWAIT=$(uncompressfs ${IMGFILE} |cpio -i --to-stdout wait-for-root 2>/dev/null)
OLDLUKS=$(uncompressfs ${IMGFILE} |cpio -i --to-stdout luksdev 2>/dev/null)
-}
+} # End of read_initrd()
# Add longer USB WAIT to the initrd:
-update_initrd() {
+function update_initrd() {
IMGFILE="$1"
# USB boot medium needs a few seconds boot delay else the overlay will fail.
@@ -243,7 +333,7 @@ update_initrd() {
echo "--- Extracting Slackware initrd and adding rootdelay for USB..."
cd ${IMGDIR}
uncompressfs ${IMGFILE} \
- | cpio -i -d -H newc --no-absolute-filenames
+ | cpio -i -d -m -H newc
if [ $REFRESH -eq 1 ]; then
echo "--- Refreshing Slackware initrd..."
@@ -288,93 +378,133 @@ update_initrd() {
rm -rf $IMGDIR/*
} # End of update_initrd()
+# Determine size of a mounted partition (in MB):
+function get_part_mb_size() {
+ local MYPART="${1}"
+ local MYSIZE
+ MYSIZE=$(df -P -BM ${MYPART} |tail -n -1 |tr -s '\t' ' ' |cut -d' ' -f2)
+ echo "${MYSIZE%M}"
+} # End of get_part_mb_size()
+
+# Determine free space of a mounted partition (in MB):
+function get_part_mb_free() {
+ local MYPART="${1}"
+ local MYSIZE
+ MYSIZE=$(df -P -BM ${MYPART} |tail -n -1 |tr -s '\t' ' ' |cut -d' ' -f4)
+ echo "${MYSIZE%M}"
+} # End of get_part_mb_free()
+
+# Determine requested container size in MB (allow for '%|k|K|m|M|g|G' suffix):
+function cont_mb() {
+ # Uses global variables: PARTFREE
+ local MYSIZE="$1"
+ case "${MYSIZE: -1}" in
+ "%") MYSIZE="$(( $PARTFREE * ${MYSIZE%\%} / 100 ))" ;;
+ "k") MYSIZE="$(( ${MYSIZE%k} / 1024 ))" ;;
+ "K") MYSIZE="$(( ${MYSIZE%K} / 1024 ))" ;;
+ "m") MYSIZE="${MYSIZE%m}" ;;
+ "M") MYSIZE="${MYSIZE%M}" ;;
+ "g") MYSIZE="$(( ${MYSIZE%g} * 1024 ))" ;;
+ "G") MYSIZE="$(( ${MYSIZE%G} * 1024 ))" ;;
+ *) MYSIZE=-1 ;;
+ esac
+ echo "$MYSIZE"
+} # End of cont_mb()
+
# Create a container file in the empty space of the partition
-create_container() {
- CNTPART=$1
- CNTSIZE=$2
- CNTBASE=$3
- CNTENCR=$4 # 'none' or 'luks'
- CNTUSED=$5 # '/home' or 'persistence'
+function create_container() {
+ local CNTPART=$1 # partition containing the ISO
+ local CNTSIZE=$2 # size of the container file to create
+ local CNTFILE=$3 # ${CNTEXT} filename with full path
+ local CNTENCR=$4 # 'none' or 'luks'
+ local CNTUSED=$5 # '/home' or 'persistence'
+ local MYMAP
+ local MYMNT
+
+ # If containerfile extension is missing, add it now:
+ if [ "${CNTFILE%${CNTEXT}}" == "${CNTFILE}" ]; then
+ CNTFILE="${CNTFILE}${CNTEXT}"
+ fi
# Create a container file or re-use previously created one:
- if [ -f $USBMNT/${CNTBASE}.img ]; then
- CNTFILE="${CNTBASE}.img"
- CNTSIZE=$(( $(du -sk $USBMNT/${CNTFILE} |tr '\t' ' ' |cut -f1 -d' ') / 1024 ))
- echo "--- Keeping existing '${CNTFILE}' (size ${CNTSIZE} MB)."
+ if [ -f ${CNTFILE} ]; then
+ # Where are we mounted?
+ MYMNT=$(cd "$(dirname "${CNTFILE}")" ; df --output=target . |tail -1)
+ CNTSIZE=$(( $(du -sk ${CNTFILE} |tr '\t' ' ' |cut -f1 -d' ') / 1024 ))
+ echo "--- Keeping existing '${CNTFILE#${MYMNT}}' (size ${CNTSIZE} MB)."
return
fi
# Determine size of the target partition (in MB), and the free space:
- PARTSIZE=$(df -P -BM ${CNTPART} |tail -1 |tr -s '\t' ' ' |cut -d' ' -f2)
- PARTSIZE=${PARTSIZE%M}
- PARTFREE=$(df -P -BM ${CNTPART} |tail -1 |tr -s '\t' ' ' |cut -d' ' -f4)
- PARTFREE=${PARTFREE%M}
+ PARTSIZE=$(get_part_mb_size ${CNTPART})
+ PARTFREE=$(get_part_mb_free ${CNTPART})
- if [ $PARTFREE -lt 10 ]; then
- echo "*** Free space on USB partition is less than 10 MB;"
+ 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 (allow for '%|k|K|m|M|g|G' suffix):
- case "${CNTSIZE: -1}" in
- "%") CNTSIZE="$(( $PARTFREE * ${CNTSIZE%\%} / 100 ))" ;;
- "k") CNTSIZE="$(( ${CNTSIZE%k} / 1024 ))" ;;
- "K") CNTSIZE="$(( ${CNTSIZE%K} / 1024 ))" ;;
- "m") CNTSIZE="${CNTSIZE%m}" ;;
- "M") CNTSIZE="${CNTSIZE%M}" ;;
- "g") CNTSIZE="$(( ${CNTSIZE%g} * 1024 ))" ;;
- "G") CNTSIZE="$(( ${CNTSIZE%G} * 1024 ))" ;;
- *) ;;
- esac
+ # 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 '-c' commandline parameter."
+ cleanup
exit 1
elif [ $CNTSIZE -ge $PARTFREE ]; then
echo "*** Not enough free space for container file!"
echo "*** Check your '-c' commandline parameter."
+ cleanup
exit 1
fi
echo "--- Creating ${CNTSIZE} MB container file using 'dd if=/dev/urandom', patience please..."
- mkdir -p $USBMNT/$(dirname "${CNTBASE}")
- CNTFILE="${CNTBASE}.img"
- # Create a sparse file (not allocating any space yet):
- dd of=$USBMNT/${CNTFILE} bs=1M count=0 seek=$CNTSIZE
+ mkdir -p $(dirname "${CNTFILE}")
+ if [ $? ]; then
+ # Create a sparse file (not allocating any space yet):
+ dd of=${CNTFILE} bs=1M count=0 seek=$CNTSIZE 2>/dev/null
+ else
+ echo "*** Failed to create directory for the container file!"
+ cleanup
+ exit 1
+ fi
# Setup a loopback device that we can use with cryptsetup:
LODEV=$(losetup -f)
- losetup $LODEV $USBMNT/${CNTFILE}
+ losetup $LODEV ${CNTFILE}
+ MYMAP=$(basename ${CNTFILE} ${CNTEXT})
if [ "${CNTENCR}" = "luks" ]; then
# Format the loop device with LUKS:
- echo "--- Encrypting the container file with LUKS; enter 'YES' and a passphrase..."
+ echo "--- Encrypting the container file with LUKS via '${LODEV}'"
+ echo "--- This takes SOME time, please be patient..."
+ 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 ${CNTBASE}) ; do
+ until cryptsetup luksOpen $LODEV ${MYMAP} ; do
echo ">>> Did you type an incorrect passphrases?"
read -p ">>> Press [ENTER] to try again or Ctrl-C to abort ..." REPLY
done
- CNTDEV=/dev/mapper/$(basename ${CNTBASE})
+ CNTDEV=/dev/mapper/${MYMAP}
# 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 ${CNTSIZE} MB of 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} || true
+ dd if=/dev/zero of=${CNTDEV} bs=512 count=${CNTIS} status=progress || true
else
- CNTDEV=$LODEV
# Un-encrypted container files remain sparse.
+ CNTDEV=$LODEV
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}
+ createfs ${CNTDEV} ${FSYS}
if [ "${CNTUSED}" != "persistence" ]; then
# Create a mount point for the unlocked container:
@@ -388,7 +518,7 @@ create_container() {
fi
# Copy the original /home (or whatever mount) content into the container:
echo "--- Copying '${CNTUSED}' from LiveOS to container..."
- HOMESRC=$(find ${USBMNT} -name "0099-slackware_zzzconf*" |tail -1)
+ HOMESRC=$(find ${ISOMNT} -name "0099-slackware_zzzconf*" |tail -1)
mount ${CNTDEV} ${CNTMNT}
unsquashfs -n -d ${CNTMNT}/temp ${HOMESRC} ${CNTUSED}
mv ${CNTMNT}/temp/${CNTUSED}/* ${CNTMNT}/
@@ -398,10 +528,9 @@ create_container() {
# Don't forget to clean up after ourselves:
if [ "${CNTENCR}" = "luks" ]; then
- cryptsetup luksClose $(basename ${CNTBASE})
+ cryptsetup luksClose ${MYMAP}
fi
losetup -d ${LODEV} || true
-
} # End of create_container() {
#
@@ -470,12 +599,20 @@ while [ ! -z "$1" ]; do
WAIT="$2"
shift 2
;;
+ -y|--layout)
+ LAYOUT="$2"
+ shift 2
+ ;;
-C|--cryptpersistfile)
DOLUKS=1
PLUKSSIZE="$2"
PERSISTTYPE="file"
shift 2
;;
+ -F|--filesystem)
+ FSYS="$2"
+ shift 2
+ ;;
-P|--persistfile)
PERSISTTYPE="file"
shift
@@ -503,7 +640,7 @@ fi
if [ -z "$TARGET" ]; then
if [ $SCAN -eq 1 ]; then
echo "-- Waiting ${SCANWAIT} seconds for a USB stick to be inserted..."
- TARGET=$(scan_devices)
+ TARGET=$(scan_devices ${SCANWAIT})
if [ -z "$TARGET" ]; then
echo "*** No new USB device detected during $SCANWAIT seconds scan."
exit 1
@@ -524,16 +661,31 @@ if [ $FORCE -eq 0 -a ! -f "$SLISO" ]; then
exit 1
fi
-if [ ! -b $TARGET -a $FORCE -eq 0 ]; then
- echo "*** Not a block device: '$TARGET' !"
- show_devices
+if [ "${HLUKSSIZE%.*}" != "${HLUKSSIZE}" ] ; then
+ echo "*** Integer value required in '-c $HLUKSSIZE' !"
exit 1
-elif [ "$(echo ${TARGET%[0-9]})" != "$TARGET" -a $FORCE -eq 0 ]; then
- echo "*** You need to point to the USB device, not a partition ($TARGET)!"
- show_devices
+fi
+
+if [ "${PLUKSSIZE%.*}" != "${PLUKSSIZE}" ] ; then
+ echo "*** Integer value required in '-C $PLUKSSIZE' !"
exit 1
fi
+if [ $FORCE -eq 0 ]; then
+ if [ ! -e /sys/block/$(basename $TARGET) ]; then
+ echo "*** Not a block device: '$TARGET' !"
+ show_devices
+ exit 1
+ elif lsblk -l $TARGET |grep -w $(basename $TARGET) |grep -wq part ; then
+ echo "*** You need to point to the storage device itself, not a partition ($TARGET)!"
+ show_devices
+ exit 1
+ fi
+fi
+
+# Add required filesystem tools:
+REQTOOLS="${REQTOOLS} mkfs.${FSYS}"
+
# Are all the required not-so-common add-on tools present?
PROG_MISSING=""
for PROGN in ${REQTOOLS} ; do
@@ -576,8 +728,8 @@ fi
# Continue with the common text message:
cat <<EOT
# ---------------------------------------------------------------------------
-# Vendor : $(cat /sys/block/$(basename $TARGET)/device/vendor)
-# Model : $(cat /sys/block/$(basename $TARGET)/device/model)
+# Vendor : $(cat /sys/block/$(basename $TARGET)/device/vendor 2>/dev/null)
+# Model : $(cat /sys/block/$(basename $TARGET)/device/model 2>/dev/null)
# Size : $(( $(cat /sys/block/$(basename $TARGET)/size) / 2048)) MB
# ---------------------------------------------------------------------------
#
@@ -612,40 +764,100 @@ if [ $REFRESH -eq 0 ]; then
# - Make the Linux partition "legacy BIOS bootable"
# Make sure that there is no MBR nor a partition table anymore:
dd if=/dev/zero of=$TARGET bs=512 count=1 conv=notrunc
- # The first sgdisk command is allowed to have non-zero exit code:
+
+ # We have to use wipefs before sgdisk or else traces of an old 'cp' or 'dd'
+ # of a Live ISO image to the device will not be erased.
+ # The sgdisk wipe command is allowed to have non-zero exit code:
+ wipefs -af $TARGET
sgdisk -og $TARGET || true
+
+ # After the wipe, get the value of the last usable sector:
+ ENDSECT=$(sgdisk -E $TARGET)
+
+ # Calculate partition layout in MB.
+ # User may specify custom non-zero sizes, also for keeping some free space:
+ if [ -z "$LAYOUT" ]; then LAYOUT=${DEF_LAYOUT}; fi
+
+ # Let's first determine whether the user wanted space for a 4th partition:
+ LP4=$(echo $LAYOUT |cut -d, -f4)
+ if [ -z "$LP4" ]; then LP4=$(echo $DEF_LAYOUT |cut -d, -f4) ; fi
+
+ LP1=$(echo $LAYOUT |cut -d, -f1)
+ if [ -z "$LP1" ]; then LP1=$(echo $DEF_LAYOUT |cut -d, -f1) ; fi
+ LP1_START=2048
+ LP1_END=$(( ${LP1_START} + ( ${LP1} *2048 ) - 1 ))
+
+ LP2=$(echo $LAYOUT |cut -d, -f2)
+ if [ -z "$LP2" ]; then LP2=$(echo $DEF_LAYOUT |cut -d, -f2) ; fi
+ LP2_START=$(( ${LP1_END} + 1 ))
+ LP2_END=$(( ${LP2_START} + ( $LP2 *2048 ) - 1 ))
+
+ LP3=$(echo $LAYOUT |cut -d, -f3)
+ if [ -z "$LP3" ]; then LP3=$(echo $DEF_LAYOUT |cut -d, -f3) ; fi
+ LP3_START=$(( ${LP2_END} + 1 ))
+ # The end of partition 3 depends on both values of LP3 and LP4:
+ if [ -n "${LP4}" ] && [ ${LP4} -gt 0 ]; then
+ LP3_END=$(( $ENDSECT - ( $LP4 * 2048 ) -1 ))
+ elif [ -n "${LP3}" ] && [ ${LP3} -gt 0 ]; then
+ LP3_END=$(( ${LP3_START} + ( $LP3 *2048 ) - 1 ))
+ else
+ # Give all remaining space to partition 3:
+ LP3_END=0
+ fi
+
+ # END calculating partition layout in MB.
+
+ # Setup the disk partitions:
sgdisk \
- -n 1:2048:4095 -c 1:"BIOS Boot Partition" -t 1:ef02 \
- -n 2:4096:208895 -c 2:"EFI System Partition" -t 2:ef00 \
- -n 3:208896:0 -c 3:"Slackware Linux" -t 3:8300 \
+ -n 1:${LP1_START}:${LP1_END} -c 1:"BIOS Boot Partition" -t 1:ef02 \
+ -n 2:${LP2_START}:${LP2_END} -c 2:"EFI System Partition" -t 2:ef00 \
+ -n 3:${LP3_START}:${LP3_END} -c 3:"Slackware Linux" -t 3:8300 \
$TARGET
sgdisk -A 3:set:2 $TARGET
# Show what we did to the USB stick:
sgdisk -p -A 3:show $TARGET
+ # Determine partition names independently of storage architecture:
+ TARGETP1=$(fdisk -l $TARGET |grep ^$TARGET |cut -d' ' -f1 |grep -E '[^0-9]1$')
+ TARGETP2=$(fdisk -l $TARGET |grep ^$TARGET |cut -d' ' -f1 |grep -E '[^0-9]2$')
+ TARGETP3=$(fdisk -l $TARGET |grep ^$TARGET |cut -d' ' -f1 |grep -E '[^0-9]3$')
+
# Create filesystems:
# Not enough clusters for a 32 bit FAT:
- mkdosfs -s 2 -n "DOS" ${TARGET}1
- mkdosfs -F32 -s 2 -n "EFI" ${TARGET}2
+ mkdosfs -s 2 -n "DOS" ${TARGETP1}
+ mkdosfs -F32 -s 2 -n "ESP" ${TARGETP2}
# KDE tends to automount.. so try an umount:
- if mount |grep -qw ${TARGET}3 ; then
- umount ${TARGET}3 || true
+ if mount |grep -qw ${TARGETP3} ; then
+ umount ${TARGETP3} || true
fi
+ # We use extlinux to boot the stick, so other filesystems are not accepted:
+ createfs ${TARGETP3} ext4 "${LIVELABEL}"
# http://www.syslinux.org/wiki/index.php?title=Filesystem
- # As of Syslinux 6.03, "pure 64-bits" compression/encryption is not supported.
+ # As of Syslinux 6.03, "pure 64-bits" compression/encryption is unsupported.
# Modern mke2fs creates file systems with the metadata_csum and 64bit
# features enabled by default.
# Explicitly disable 64bit feature in the mke2fs command with '-O ^64bit';
# otherwise, the syslinux bootloader (>= 6.03) will fail.
# Note: older 32bit OS-es will trip over the '^64bit' feature so be gentle.
- mkfs.ext4 -F -F -L "${LIVELABEL}" ${TARGET}3
- if ! tune2fs -O ^64bit ${TARGET}3 1>/dev/null 2>/dev/null ; then
- FEAT_64BIT=""
- else
- FEAT_64BIT="-O ^64bit"
+ UNWANTED_FEAT=""
+ if tune2fs -O ^64bit ${TARGETP3} 1>/dev/null 2>/dev/null ; then
+ UNWANTED_FEAT="^64bit,"
fi
- tune2fs -c 0 -i 0 -m 0 ${FEAT_64BIT} ${TARGET}3
-
+ # Grub 2.0.6 stumbles over metadata_csum_seed which is enabled by default
+ # since e2fsprogs 1.47.0, so let's disable that too:
+ if tune2fs -O ^metadata_csum_seed ${TARGETP3} 1>/dev/null 2>/dev/null ; then
+ UNWANTED_FEAT="${UNWANTED_FEAT}^metadata_csum_seed,"
+ fi
+ if [ -n "${UNWANTED_FEAT}" ]; then
+ # We found unwanted feature(s), get rid of trailing comma:
+ UNWANTED_FEAT="-O ${UNWANTED_FEAT::-1}"
+ fi
+ tune2fs -c 0 -i 0 -m 0 ${UNWANTED_FEAT} ${TARGETP3}
+else
+ # Determine partition names independently of storage architecture:
+ TARGETP1=$(fdisk -l $TARGET |grep ^$TARGET |cut -d' ' -f1 |grep -E '[^0-9]1$')
+ TARGETP2=$(fdisk -l $TARGET |grep ^$TARGET |cut -d' ' -f1 |grep -E '[^0-9]2$')
+ TARGETP3=$(fdisk -l $TARGET |grep ^$TARGET |cut -d' ' -f1 |grep -E '[^0-9]3$')
fi # End [ $REFRESH -eq 0 ]
# Create temporary mount points for the ISO file and USB device:
@@ -678,7 +890,7 @@ else
fi
# Mount the Linux partition:
-mount -t auto ${TARGET}3 ${USBMNT}
+mount -t auto ${TARGETP3} ${USBMNT}
# Loop-mount the ISO (or 1st partition if this is a hybrid ISO):
mount -o loop "${SLISO}" ${ISOMNT}
@@ -738,9 +950,13 @@ if [ -n "$VERSION" ]; then
fi
if [ -n "${HLUKSSIZE}" ]; then
- # Create LUKS container file for /home:
- create_container ${TARGET}3 ${HLUKSSIZE} ${SLHOME} luks /home
- LUKSHOME=${CNTFILE}
+ # If file extension is missing in the containername, add it now:
+ if [ "${SLHOME%${CNTEXT}}" == "${SLHOME}" ]; then
+ SLHOME="${SLHOME}${CNTEXT}"
+ fi
+ # Create LUKS container file for /home ;
+ LUKSHOME="${SLHOME}"
+ create_container ${TARGETP3} ${HLUKSSIZE} "${USBMNT}/${LUKSHOME}" luks /home
fi
# Update the initrd with regard to USB wait time, persistence and LUKS.
@@ -756,15 +972,15 @@ if [ $REFRESH -eq 1 ]; then
# The user specified a nonstandard persistence, so move the old one first;
# hide any errors if it did not *yet* exist:
mkdir -p ${USBMNT}/$(dirname ${PERSISTENCE})
- mv ${USBMNT}/${OLDPERSISTENCE}.img ${USBMNT}/${PERSISTENCE}.img 2>/dev/null
+ mv ${USBMNT}/${OLDPERSISTENCE}${CNTEXT} ${USBMNT}/${PERSISTENCE}${CNTEXT} 2>/dev/null
mv ${USBMNT}/${OLDPERSISTENCE} ${USBMNT}/${PERSISTENCE} 2>/dev/null
fi
- if [ -f ${USBMNT}/${PERSISTENCE}.img ]; then
+ if [ -f ${USBMNT}/${PERSISTENCE}${CNTEXT} ]; then
# If a persistence container exists, we re-use it:
PERSISTTYPE="file"
- if cryptsetup isLuks ${USBMNT}/${PERSISTENCE}.img ; then
+ if cryptsetup isLuks ${USBMNT}/${PERSISTENCE}${CNTEXT} ; then
# If the persistence file is LUKS encrypted we need to record its size:
- PLUKSSIZE=$(( $(du -sk $USBMNT/${PERSISTENCE}.img |tr '\t' ' ' |cut -f1 -d' ') / 1024 ))
+ PLUKSSIZE=$(( $(du -sk $USBMNT/${PERSISTENCE}${CNTEXT} |tr '\t' ' ' |cut -f1 -d' ') / 1024 ))
fi
elif [ -d ${USBMNT}/${PERSISTENCE} -a "${PERSISTTYPE}" = "file" ]; then
# A persistence directory exists but the user wants a container now;
@@ -785,10 +1001,10 @@ elif [ "${PERSISTTYPE}" = "file" ]; then
# Note: the word "persistence" below is a keyword for create_container:
if [ -z "${PLUKSSIZE}" ]; then
# Un-encrypted container:
- create_container ${TARGET}3 90% ${PERSISTENCE} none persistence
+ create_container ${TARGETP3} 90% ${USBMNT}/${PERSISTENCE} none persistence
else
# LUKS-encrypted container:
- create_container ${TARGET}3 ${PLUKSSIZE} ${PERSISTENCE} luks persistence
+ create_container ${TARGETP3} ${PLUKSSIZE} ${USBMNT}/${PERSISTENCE} luks persistence
fi
else
echo "*** Unknown persistence type '${PERSISTTYPE}'!"
@@ -810,7 +1026,7 @@ extlinux --install ${USBMNT}/boot/extlinux
if [ $EFIBOOT -eq 1 ]; then
# Mount the EFI partition and copy /EFI as well as /boot directories into it:
- mount -t vfat -o shortname=mixed ${TARGET}2 ${US2MNT}
+ mount -t vfat -o shortname=mixed ${TARGETP2} ${US2MNT}
mkdir -p ${US2MNT}/EFI/BOOT
rsync -rlptD ${ISOMNT}/EFI/BOOT/* ${US2MNT}/EFI/BOOT/
mkdir -p ${USBMNT}/boot
@@ -833,23 +1049,25 @@ if [ $EFIBOOT -eq 1 ]; then
sync
fi
-# No longer needed:
+# No longer needed; umount the USB partitions so we can write a new MBR:
if mount |grep -qw ${USBMNT} ; then umount ${USBMNT} ; fi
if mount |grep -qw ${US2MNT} ; then umount ${US2MNT} ; fi
-# Unmount/remove stuff:
-cleanup
-
# Install a GPT compatible MBR record:
-if [ -f ${SYSLXLOC}/gptmbr.bin ]; then
- cat ${SYSLXLOC}/gptmbr.bin > ${TARGET}
-elif [ -f ${USBMNT}/boot/extlinux/gptmbr.bin ]; then
- cat ${USBMNT}/boot/extlinux/gptmbr.bin > ${TARGET}
+if [ -n "${GPTMBRBIN}" ]; then
+ if [ -f ${GPTMBRBIN} ]; then
+ cat ${GPTMBRBIN} > ${TARGET}
+ fi
+elif [ -f ${ISOMNT}/boot/syslinux/gptmbr.bin ]; then
+ cat ${ISOMNT}/boot/syslinux/gptmbr.bin > ${TARGET}
else
echo "*** Failed to make USB device bootable - 'gptmbr.bin' not found!"
cleanup
exit 1
fi
+# Unmount/remove stuff:
+cleanup
+
# THE END