Skip to content

Commit

Permalink
bootiso: fix cleanup logic
Browse files Browse the repository at this point in the history
After successful installation, a message "user aborted" was displayed.
To circumvent the issue, two functions are now registered with trap
for cleanup logic. One on EXIT, and an other one on INT or TERM.
  • Loading branch information
jsamr committed May 17, 2020
1 parent 8c35d24 commit 3f035f6
Showing 1 changed file with 74 additions and 68 deletions.
142 changes: 74 additions & 68 deletions bootiso
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#
# bootiso - create a bootable USB drive from an image file
# Copyright (C) 2018-2020 jules randolph <[email protected]>
#
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
Expand Down Expand Up @@ -82,7 +82,7 @@ typeset st_hasActionDuration
typeset st_foundSyslinuxMbrBinary
typeset st_foundSyslinuxBiosFolder
typeset st_shouldMakePartition
typeset st_backgroundProcess
typeset st_backgroundProcess=''
typeset -A st_syslinuxBinaries
typeset -a st_temporaryAssets=()
typeset -a st_devicesList=()
Expand Down Expand Up @@ -131,16 +131,16 @@ typeset -A st_userVars=(
['data-part-fs']=''
)

# oo.ooooo. .oooo. oooo d8b
# 888' `88b `P )88b `888""8P
# 888 888 .oP"888 888
# 888 888 d8( 888 888
# 888bod8P' `Y888""8o d888b
# 888
# oo.ooooo. .oooo. oooo d8b
# 888' `88b `P )88b `888""8P
# 888 888 .oP"888 888
# 888 888 d8( 888 888
# 888bod8P' `Y888""8o d888b
# 888
# o888o
#
# PARAMETER GLOBAL VARIABLES (0)
#
#
# Global variables derived from program arguments or configuration.
# These are the only unprefixed global variables.

Expand All @@ -167,14 +167,14 @@ typeset disableHashCheck
typeset disableWimsplit
typeset disableDeviceEjection

# oooo
# `888
# .oooo.o 888 .oo.
# d88( "8 888P"Y88b
# `"Y88b. 888 888
# o. )88b 888 888
# 8""888P' o888o o888o
#
# oooo
# `888
# .oooo.o 888 .oo.
# d88( "8 888P"Y88b
# `"Y88b. 888 888
# o. )88b 888 888
# 8""888P' o888o o888o
#
#
# SH MODULE (1)

Expand Down Expand Up @@ -306,7 +306,7 @@ function term_printLog() {
function term_indentAll() {
while read -r line; do
term_printColumn " " "$term_logPrefixLength" "$line"
done < "${1:-/dev/stdin}"
done <"${1:-/dev/stdin}"
}

# $*: The message to print.
Expand Down Expand Up @@ -491,15 +491,15 @@ function fs_mountUSB() {
st_usbMountPoint=$(fs_createMountFolder usb) || exit "$?"
st_temporaryAssets+=("$st_usbMountPoint")
term_echoinfo "Created USB device mount point at '$st_usbMountPoint'"
if ! mount -t "$_type" "$st_targetPartition" "$st_usbMountPoint" > /dev/null; then
if ! mount -t "$_type" "$st_targetPartition" "$st_usbMountPoint" >/dev/null; then
ps_failAndExit IO_ERROR "Could not mount USB device."
fi
}

# $1 - mountPoint
function fs_mountElToritoFile() {
local -r _mountPoint="$1"
if ! mount -r -o loop -- "$sourceImageFile" "$_mountPoint" > /dev/null; then
if ! mount -r -o loop -- "$sourceImageFile" "$_mountPoint" >/dev/null; then
ps_failAndExit IO_ERROR "Could not mount image file."
else
st_temporaryAssets+=("$_mountPoint")
Expand Down Expand Up @@ -585,20 +585,20 @@ function fs_syncWithProgress() {
fi
}

# .oooo.o oooo ooo .oooo.o
# d88( "8 `88. .8' d88( "8
# `"Y88b. `88..8' `"Y88b.
# o. )88b `888' o. )88b
# 8""888P' .8' 8""888P'
# .o..P'
# `Y8P'
# .oooo.o oooo ooo .oooo.o
# d88( "8 `88. .8' d88( "8
# `"Y88b. `88..8' `"Y88b.
# o. )88b `888' o. )88b
# 8""888P' .8' 8""888P'
# .o..P'
# `Y8P'
#
#
#
# OPERATING SYSTEM MODULE (1)

# $1 - The name of the command to check in $PATH.
function sys_hasCommand() {
command -v "$1" &> /dev/null
command -v "$1" &>/dev/null
return $?
}

Expand Down Expand Up @@ -649,13 +649,13 @@ function sys_isDeviceDisk() {
return $?
}

# oo.ooooo. .oooo.o
# 888' `88b d88( "8
# 888 888 `"Y88b.
# 888 888 o. )88b
# 888bod8P' 8""888P'
# 888
# o888o
# oo.ooooo. .oooo.o
# 888' `88b d88( "8
# 888 888 `"Y88b.
# 888 888 o. )88b
# 888bod8P' 8""888P'
# 888
# o888o
#
#
# PROCESS STATE MODULE (2)
Expand All @@ -681,7 +681,7 @@ typeset -Ar ps_exitStatus=(
[THIRD_PARTY_ERROR]=66
)

function ps_cleanup() {
function ps_cleanupOnExit() {
local _asset
function _removeTempAsset() {
if [[ "$1" =~ ^$ct_tempRoot ]] || [[ "$1" =~ ^$ct_mountRoot ]]; then
Expand All @@ -708,19 +708,7 @@ function ps_cleanup() {
fi
fi
}
function _waitBackgroundProcess() {
local -i _pid=$st_backgroundProcess
if [[ -n "$_pid" ]]; then
wait "$_pid"
fi
}
if ((EUID == 0)); then
echo
term_echowarn "User aborted!..." \
"Synchronizing pending writes before unmounting..." \
"PLEASE WAIT A LITTLE WHILE TO AVOID DAMAGING DEVICES!"
_waitBackgroundProcess
fs_syncdev
fs_umountElTorito
fs_umountUSB
for _asset in "${st_temporaryAssets[@]}"; do
Expand All @@ -731,6 +719,23 @@ function ps_cleanup() {
fi
}

function ps_cleanupOnInterrupt() {
function _waitBackgroundProcess() {
if [[ -n "$st_backgroundProcess" ]]; then
wait "$st_backgroundProcess"
fi
}
if ((EUID == 0)); then
echo
term_echowarn "Received INT or TERM signal!..." \
"Synchronizing pending writes before unmounting..." \
"PLEASE WAIT SYNC PROCEDURE COMPLETION TO AVOID DAMAGING DEVICES!"
_waitBackgroundProcess
fs_syncdev
ps_cleanupOnExit
fi
}

function ps_startTimer() {
st_execStartTime=$(date +%s)
}
Expand All @@ -756,7 +761,7 @@ function ps_failAndExit() {
term_echoerr "$@" "Exiting..."
fi
fi
if [ "$_statusCode" == STATE_ERROR ]; then
if [ "$_statusCode" == STATE_ERROR ]; then
term_echoerr "Provide a bug report at $ct_openBugReportMessage."
fi
exit "${ps_exitStatus[$_statusCode]}"
Expand Down Expand Up @@ -850,7 +855,7 @@ function asrt_checkSudo() {
if [[ -t 1 ]] && sys_hasCommand sudo; then
sudo --preserve-env "$0" "$@"
elif sys_hasCommand gksu; then
exec 1> output_file
exec 1>output_file
gksu --preserve-env "$0" "$@"
else
ps_failAndExit MISSING_PRIVILEGE "You must run $scriptName as root."
Expand Down Expand Up @@ -897,15 +902,15 @@ function asrt_checkImageHash() {
printf "%s" \
"You can disable this check with $(term_boldify "-H, --no-_hash-check") flags." | term_indentAll
st_temporaryAssets+=("$_hashStoreFile")
(
(
local _hash
local -i _status=0
_hash=$($_hashName "$_imageName" | awk "{print \$1; exit }")
_status=$?
if ((_status == 0)); then
printf "%s" "$_hash" > "$_hashStoreFile"
printf "%s" "$_hash" >"$_hashStoreFile"
else
printf "%s" 1 > "$_hashStoreFile"
printf "%s" 1 >"$_hashStoreFile"
fi
) &
st_backgroundProcess=$!
Expand Down Expand Up @@ -1010,7 +1015,7 @@ function asrt_checkPackages() {
sys_checkCommand "$_pkg"
done
# test grep supports -P option
if ! echo 1 | grep -P '1' &> /dev/null; then
if ! echo 1 | grep -P '1' &>/dev/null; then
ps_failAndExit MISSING_DEPENDENCY \
"You're using an old version of grep which does not support perl regular expression (-P option)."
fi
Expand Down Expand Up @@ -1095,7 +1100,7 @@ function asrt_checkFSType() {
ps_failAndExit SYNOPSIS_NONCOMPL "Filesystem type '$_fsType' not supported." \
"Supported FS types: $(sh_joinBy "," "${asrt_supportedFS[*]}")."
fi
if ! command -v "mkfs.$_fsType" &> /dev/null; then
if ! command -v "mkfs.$_fsType" &>/dev/null; then
ps_failAndExit MISSING_DEPENDENCY \
"Program 'mkfs.$_fsType' could not be found on your system." \
"Please install it and retry."
Expand Down Expand Up @@ -1286,7 +1291,7 @@ function devi_configureLabel() {
# Fallback to "USER_VENDOR" if format
if [[ "$targetAction" == format ]]; then
_user=${SUDO_USER:-$USER}
_vendor=$(lsblk -ldno VENDOR "$targetDevice" 2> /dev/null)
_vendor=$(lsblk -ldno VENDOR "$targetDevice" 2>/dev/null)
_vendor=${_vendor:-FLASH}
targetPartitionLabel=${targetPartitionLabel:-"${_user^^}_${_vendor^^}"}
else
Expand Down Expand Up @@ -1356,7 +1361,7 @@ function devi_addDataPartition() {
_diskReport=$(sfdisk -lJ "$targetDevice")
_partScheme=$(echo "$_diskReport" | jq -r '.partitiontable.label')
_partType=$(fs_inferFSType "$_partScheme" "$targetDataPartFstype")
sfdisk --append "$targetDevice" < <(echo "-,-,$_partType") |& term_indentAll || return 1
sfdisk --append "$targetDevice" < <(echo "-,-,$_partType") |& term_indentAll || return 1
_diskReport=$(sfdisk -lJ "$targetDevice")
_dataPartition=$(echo "$_diskReport" | jq -r '.partitiontable.partitions[-1].node')
fs_formatPartition "$targetDataPartFstype" "$_dataPartition" "DATA" || return 2
Expand Down Expand Up @@ -1440,7 +1445,7 @@ function devi_partitionUSB() {
# unmount any partition on selected device
mapfile -t devicePartitions < <(grep -oP "^\\K$targetDevice\\S*" /proc/mounts)
for _partition in "${devicePartitions[@]}"; do
if ! umount "$_partition" > /dev/null; then
if ! umount "$_partition" >/dev/null; then
ps_failAndExit IO_ERROR \
"Failed to unmount $_partition. It's likely that the partition is busy."
fi
Expand All @@ -1449,7 +1454,7 @@ function devi_partitionUSB() {
function _eraseDevice() {
term_echoinfo "Erasing contents of '$targetDevice'..."
# clean signature from selected device
wipefs --all --force "$targetDevice" &> /dev/null
wipefs --all --force "$targetDevice" &>/dev/null
# erase drive
dd if=/dev/zero of="$targetDevice" bs=512 count=1 conv=notrunc status=none |&
term_indentAll ||
Expand Down Expand Up @@ -1683,7 +1688,7 @@ function devi_inspectHybridImage() {
_supportsEFIBoot=false
fi
}
_diskReport=$(sfdisk -lJ -- "$sourceImageFile" 2> /dev/null)
_diskReport=$(sfdisk -lJ -- "$sourceImageFile" 2>/dev/null)
if (($? != 0)); then
ps_failAndExit IO_ERROR "sfdisk couldn't read the partition table on the image file, which is likely corrupted."
fi
Expand Down Expand Up @@ -1812,7 +1817,7 @@ function step_installBootloader() {
fi
fi
term_echoinfo "Found local SYSLINUX version '$_localSyslinuxVersion'"
sh_compute "$_localSyslinuxVersion == ${st_isoInspections[syslinuxVer]}" > /dev/null
sh_compute "$_localSyslinuxVersion == ${st_isoInspections[syslinuxVer]}" >/dev/null
_versionsMatch=$?
if ((_versionsMatch == 0)); then
term_echogood "image SYSLINUX version matches local version."
Expand Down Expand Up @@ -1860,7 +1865,7 @@ function step_installBootloader() {
if ! ${st_syslinuxBinaries['extBin']} --stupid --install "$_syslinuxFolder" |& term_indentAll; then
term_echowarn "Could not run SYSLINUX '$st_targetSyslinuxVersion' from kernel.org." \
"Attempting with local SYSLINUX install..."
_installWtLocalExtlinux > /dev/null
_installWtLocalExtlinux >/dev/null
fi
fs_syncdev
}
Expand Down Expand Up @@ -1900,7 +1905,7 @@ function step_copyWithRsync() {
term_echowarn "Detected a Windows install.wim file but wimsplit has been disabled with $(term_boldify '--no-wim-split') option."
fi
fi
(
(
# shellcheck disable=SC2086
rsync -r -q -I --no-links --no-perms --no-owner --no-group $_rsyncOptions "$st_elToritoMountPoint"/. "$st_usbMountPoint"
_status=$?
Expand All @@ -1909,7 +1914,7 @@ function step_copyWithRsync() {
echo
wimlib-imagex split "$_wimFile" "$st_usbMountPoint/sources/install.swm" 1024 |& term_indentAll
fi
echo "$_status" > "$_statusFile"
echo "$_status" >"$_statusFile"
) &
st_backgroundProcess=$!
echo -n "$scriptName: Copying files from image to USB device with 'rsync' "
Expand All @@ -1935,9 +1940,9 @@ function step_copyWithDD() {
local _status
_statusFile=$(fs_createTempFile "bootiso-status")
st_temporaryAssets+=("$_statusFile")
(
(
dd if="$sourceImageFile" of="$targetDevice" bs="$targetDDBusSize" status=none
echo "$?" > "$_statusFile"
echo "$?" >"$_statusFile"
) &
st_backgroundProcess=$!
echo -n "$scriptName: Copying files from image to USB device with 'dd' "
Expand Down Expand Up @@ -2524,5 +2529,6 @@ function main() {
step_finalize
}

trap ps_cleanup EXIT
trap ps_cleanupOnExit EXIT
trap ps_cleanupOnInterrupt INT TERM
main "$@"

0 comments on commit 3f035f6

Please sign in to comment.