From ec66632ec6601e89f8843231d4fae397cb88b98c Mon Sep 17 00:00:00 2001 From: Iru Cai Date: Tue, 24 May 2022 22:04:17 +0800 Subject: support udisks2 mount tool, fall back to system mount/unmount --- README.md | 3 +- buildlive | 18 ++++------- functions.sh | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 93 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 18cbad2..293ac0f 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,8 @@ A presentation in Chinese is at https://wehack.space/vimacs/liveusb-builder.odp. You need these packages on your GNU/Linux system to use liveusb-builder. - libarchive: for ISO image extraction -- udevil: for mounting USB disk partitions +- udisks2 (optional,recommended): for mounting USB disk partitions without being root +- udevil (optional): for mounting USB disk partitions and ISO images without being root - wget: for downloading - syslinux (recommended): bootloader for legacy BIOS - GRUB: bootloader for legacy BIOS if there's no syslinux, and bootloader for UEFI diff --git a/buildlive b/buildlive index 120c14d..bc2c12e 100755 --- a/buildlive +++ b/buildlive @@ -20,15 +20,6 @@ CLEAN_USB=0 . functions.sh -msg() { - echo -e "$1" >&2 -} - -fatalerror() { - msg "\x1b[1;31m$1\x1b[0m" - exit 1 -} - usage() { >&2 cat << EOF $0 [--root ] [options] [--distro= ] [distro] ... @@ -52,7 +43,7 @@ try_mount() { then if ! findmnt "$1" > /dev/null then - udevil mount "$1" > /dev/null + mount_block "$1" > /dev/null mnt=$(findmnt -n -o TARGET "$1") else mnt=$(findmnt -n -o TARGET "$1") @@ -63,6 +54,9 @@ try_mount() { echo "$mnt" } +detect_block_mount_tool 2>/dev/null +detect_iso_mount_tool 2>/dev/null + unset ISOPATH CFGFILE="$HOME/.liveusb-builder" test -f "$CFGFILE" && source "$CFGFILE" || true @@ -263,9 +257,9 @@ fi if [ "$UMOUNT_BOOT" == 1 ]; then msg 'Trying to umount the boot mountpoint, you may need to wait for sync() to complete.' - udevil umount "$BOOTPATH" + unmount_block "$BOOTPATH" fi if [ "$UMOUNT_ROOT" == 1 -a "$ROOTPATH" != "$BOOTPATH" ]; then msg 'Trying to umount the root mountpoint, you may need to wait for sync() to complete.' - udevil umount "$ROOTPATH" + unmount_block "$ROOTPATH" fi diff --git a/functions.sh b/functions.sh index 8f9db5f..b967388 100644 --- a/functions.sh +++ b/functions.sh @@ -1,6 +1,26 @@ # Copyright (C) 2016-2018 Iru Cai # SPDX-License-Identifier: GPL-3.0-or-later +msg() { + echo -e "$1" >&2 +} + +fatalerror() { + msg "\x1b[1;31m$1\x1b[0m" + exit 1 +} + +as-root() { + echo as-root "$*" + if [ "$UID" == 0 ]; then + "$@" + elif type -p sudo > /dev/null; then + sudo "$@" + elif type -p su > /dev/null; then + su -c "$*" + fi +} + checksum_verify() { local _hashtool _hashsum _cksum if [ -n "$SHA512" ]; then @@ -194,6 +214,69 @@ get_iso_label() { file -b "$1" | cut -d\' -f2 } +# We try to a proper mount tool to mount block devices and iso files, +# if we cannot find it, use the system mount tool. +# Both udisks2 and udevil can mount block devices, but only udevil +# can mount iso files. +detect_block_mount_tool() { + if (udisksctl status | grep DEVICE > /dev/null); then + BLOCKMOUNT=udisks2 + elif (udevil | grep 'udevil version' > /dev/null); then + BLOCKMOUNT=udevil + else + BLOCKMOUNT=system + fi +} + +detect_iso_mount_tool() { + if (udevil | grep 'udevil version' > /dev/null); then + ISOMOUNT=udevil + else + ISOMOUNT=system + fi +} + +udevil_mount() { + udevil mount "$1" +} + +udevil_unmount() { + udevil umount "$1" +} + +udisks2_mount() { + udisksctl mount -b "$1" +} + +udisks2_unmount() { + local mnt_source + mnt_source="$(findmnt -n -o SOURCE "$1")" + udisksctl unmount -b "${mnt_source}" +} + +system_mount() { + local mountpoint + local uid + mountpoint="$(mktemp -d)" + uid="$(id -u)" + # first try uid= option of mount(1) + if ! as-root mount -o "uid=$uid" "$1" "$mountpoint" 2> /dev/null; then + as-root mount "$1" "$mountpoint" + fi +} + +system_unmount() { + as-root umount "$1" +} + +mount_block() { + ${BLOCKMOUNT}_mount "$1" +} + +unmount_block() { + ${BLOCKMOUNT}_unmount "$1" +} + mount_iso() { LOOPDEV=$(/sbin/losetup -n -O NAME -j "${ISO_FILEPATH}") if [[ -n "$LOOPDEV" ]] @@ -202,7 +285,7 @@ mount_iso() { umount_iso fi - udevil mount "${ISO_FILEPATH}" + ${ISOMOUNT}_mount "${ISO_FILEPATH}" LOOPDEV=$(/sbin/losetup -n -O NAME -j "${ISO_FILEPATH}") if [[ -n "$LOOPDEV" ]] then @@ -211,7 +294,7 @@ mount_iso() { } umount_iso() { - udevil umount "$ISOMNT" + ${ISOMOUNT}_unmount "$ISOMNT" } # iso_extract: extract files from iso image to destination path @@ -247,17 +330,6 @@ getdiskbypart() { done } -as-root() { - echo as-root "$*" - if [ "$UID" == 0 ]; then - "$@" - elif type -p sudo > /dev/null; then - sudo "$@" - elif type -p su > /dev/null; then - su -c "$*" - fi -} - syslinux_header() { cat << EOF UI menu.c32 -- cgit v1.2.3