For my work I'm preparing a live USB with Clonezilla. It runs a custom bash script to clone disks. This USB is going to be cloned to several other USBs so they can be used in multiple machines.
It's not possible to run Clonezilla to RAM since the image to clone (22G) is in the USB.
I want to replicate, in my script, the standard behavior of live Linux distributions installer, that ask to remove the USB medium and then press enter to reboot the machine.
Example script using eject
, but this doesn't seem right:
eject /dev/sdb
read -r -p 'Remove USB and press Enter' # not executed since the USB is no longer plugged
reboot
I want to be very sure that the USB(s) are removed safely, since they are from work, they are many, and of course taking the risk of ruining them is not an option.
What would be the best and safest way to do this?
Now, why so much effort for a seemingly trivial thing? The USBs are going to be deployed to hundreds of machines. All that can be automated is needed to gain time and avoid errors. The users need to check the cloning worked, hence the reboot. But if the USB is still plugged, the machine will boot it instead of the local OS.
This question is related but I understand it doesn't apply to a live system.
This is the script that seems to do this, from a Lubuntu that I got unsquashing the filesystem.squashfs
file from the ISO. I'm still trying to understand it, any help appreciated.
#! /bin/sh
Author: Mathieu Trudel-Lapierre <mathieu.trudel-lapierre@canonical.com>
Tollef Fog Heen <tfheen@canonical.com>
Marco Amadori <marco.amadori@gmail.com>
PATH=/usr/sbin:/usr/bin:/sbin:/bin
NAME=casper
SCRIPTNAME=/etc/init.d/${NAME}
DO_SNAPSHOT=/sbin/${NAME}-snapshot
Exit if system was not booted by casper
[ -f /run/.casper-boot ] || exit 0
Exit if the system was booted from an ISO image rather than a physical CD
grep -qs find_iso= /proc/cmdline && exit 0
Read configuration variable file if it is present
[ -r /etc/$NAME.conf ] && . /etc/$NAME.conf
Try to cache everything we're likely to need after ejecting. This
is fragile and simple-minded, but our options are limited.
cache_path() {
path="$1"
if [ -d "$path" ]; then
for f in $(find "$path" -type f); do
cache_path "$f"
done
elif [ -f "$path" ] && [ ! -L "$path" ]; then
if [ -x "$path" ]; then
if file -L "$path" | grep -q 'dynamically linked'; then
for lib in $(ldd "$path" | awk '{ print $3 }'); do
cache_path "$lib"
done
fi
fi
echo -n >> "$path"
fi
}
do_stop ()
{
logger -t ${NAME} "resyncing snapshots and caching reboot files..."
if [ ! -z "${ROOTSNAP}" ]; then
$DO_SNAPSHOT --resync-string="${ROOTSNAP}"
fi
if [ ! -z "${HOMESNAP}" ]; then
$DO_SNAPSHOT --resync-string="${HOMESNAP}"
fi
# check for netboot
if [ ! -z "${NETBOOT}" ] || grep -qs netboot /proc/cmdline || grep -qsi root=/dev/nfs /proc/cmdline || grep -qsi root=/dev/cifs /proc/cmdline ; then
return 0
fi
# Don't prompt to eject the SD card on Babbage board, where we reuse it
# as a quasi-boot-floppy. Technically this uses a bit of ubiquity
# (archdetect), but since this is mostly only relevant for
# installations, who cares ...
if type archdetect >/dev/null 2>&1; then
subarch="$(archdetect)"
case $subarch in
arm*/imx51)
return 0
;;
esac
fi
prompt=1
if grep -qs noprompt /proc/cmdline || [ -e /run/casper-no-prompt ]; then
prompt=
fi
for path in $(which halt) $(which reboot) /bin/chvt /etc/rc?.d /etc/default $(which stty) /bin/plymouth /lib/plymouth /lib/*/plymouth /lib/systemd /etc/systemd /lib/*/libnss_files* /etc/nsswitch.conf /usr/share/fonts/truetype/dejavu/DejaVuSans.ttf /usr/share/fonts/truetype/ubuntu/Ubuntu-R.ttf /usr/share/fonts/truetype/ubuntu/UbuntuMono-R.ttf /etc/fonts/fonts.conf /etc/fonts/conf.d/60-latin.conf; do
cache_path "$path"
done
device="$(grep " /cdrom " /proc/mounts | cut -d' ' -f1)" || device=
# If /cdrom isn't mounted, don't try to eject it
if [ -z "$device" ]; then
return 0
fi
# If the device exists but can't be found in /sys/block, it's most likely a partition
# so unmount it (lazy mode) and sync
if [ -b "$device" ] && [ ! -f "/sys/block/$(basename $device)/removable" ]; then
umount -l $device >/dev/null 2>&1
sync
# from now on operate on the partition's block device
device=/dev/$(basename "$(readlink -f /sys/class/block/$(basename $device)/..)")
fi
# If we're still there, then we're probably a cdrom or other media
# ship the eject if the kernel says the media isn't removable
if [ "$(cat /sys/block/$(basename $device)/removable)" = "0" ]; then
return 0
fi
# XXX - i18n
MSG="Please remove the installation medium, then press ENTER: "
MSG_FALLBACK="Please remove the installation medium, then reboot."
if [ "$prompt" ]; then
if [ -x /bin/plymouth ] && plymouth --ping; then
chvt 63
plymouth message --text="$MSG"
clear > /dev/tty1
echo $MSG_FALLBACK > /dev/tty1
else
stty sane < /dev/console
echo $MSG > /dev/console
fi
fi
eject -p -m $device >/dev/null 2>&1
[ "$prompt" ] || return 0
if [ -x /bin/plymouth ] && plymouth --ping; then
plymouth watch-keystroke > /dev/null
else
read x < /dev/console
fi
}
do_stop
toram
, which means that you can unmount and unplug the USB drive and still have the live system running. – sudodus Dec 14 '21 at 16:42