From 2ed7c3ae98aa671d504eba254fdd89ea26fe15c8 Mon Sep 17 00:00:00 2001 From: Michael Chang Date: Thu, 7 Mar 2019 16:31:19 +0800 Subject: [PATCH] Use /tmp over /var/lib for transient files Create transient mount point in directory /tmp rather than /var/lib which is not available during transactional update. Also clean up the count_last_label function for not relying on /var/lib/os-prober/labels file for the caculation. https://en.opensuse.org/openSUSE:Packaging_for_transactional-updates v2: - Fix accidental deletion of btrfs subvolume (boo#1130669). - Fix detection of btrfs boot subvolume if its /etc/fstab entry contains leading slash for subvol= mount option. --- common.sh | 37 ++++++++++++++------------------ linux-boot-prober | 2 +- linux-boot-probes/common/50mounted-tests | 2 +- os-prober | 3 --- os-probes/common/50mounted-tests | 2 +- 5 files changed, 19 insertions(+), 27 deletions(-) Index: os-prober-1.76/common.sh =================================================================== --- os-prober-1.76.orig/common.sh +++ os-prober-1.76/common.sh @@ -21,31 +21,26 @@ require_tmpdir() { fi } -count_for() { - _labelprefix="$1" - _result=$(grep "^${_labelprefix} " /var/lib/os-prober/labels 2>/dev/null || true) - - if [ -z "$_result" ]; then - return - else - echo "$_result" | cut -d' ' -f2 - fi -} - +OS_PROBER_LABELS="" count_next_label() { - require_tmpdir - _labelprefix="$1" - _cfor="$(count_for "${_labelprefix}")" - - if [ -z "$_cfor" ]; then - echo "${_labelprefix} 1" >> /var/lib/os-prober/labels + _count="" + _labels="" + for i in $OS_PROBER_LABELS; do + _label="`echo $i | cut -d: -f1`" + if [ x"$_labelprefix" = x"$_label" ]; then + _count=`echo $i | cut -d: -f2` + _labels="$_labels $_label:`expr $_count + 1`" + else + _labels="$_labels $i" + fi + done + if [ -z "$_count" ]; then + OS_PROBER_LABELS="$OS_PROBER_LABELS $_labelprefix:1" else - sed "s/^${_labelprefix} ${_cfor}/${_labelprefix} $(($_cfor + 1))/" /var/lib/os-prober/labels > "$OS_PROBER_TMP/os-prober.tmp" - mv "$OS_PROBER_TMP/os-prober.tmp" /var/lib/os-prober/labels + OS_PROBER_LABELS="$_labels" fi - - echo "${_labelprefix}${_cfor}" + echo "${_labelprefix}${_count}" } progname= Index: os-prober-1.76/linux-boot-prober =================================================================== --- os-prober-1.76.orig/linux-boot-prober +++ os-prober-1.76/linux-boot-prober @@ -7,11 +7,6 @@ newns "$@" require_tmpdir ERR="n" -tmpmnt=/var/lib/os-prober/mount -if [ ! -d "$tmpmnt" ]; then - mkdir "$tmpmnt" -fi - mounted= bootmnt= bootsv= @@ -45,23 +40,21 @@ if [ "x$ERR" != xn ]; then fi if [ "$type" = btrfs ]; then + tmpmnt="$(mktemp -d /tmp/linux-boot-prober.XXXXXX)" # handle all of the btrfs stuff here if [ ! -e "/proc/self/mountinfo" ]; then warn "/proc/self/mountinfo does not exist, exiting" - umount "$tmpmnt" 2>/dev/null rmdir "$tmpmnt" 2>/dev/null exit 1 fi mpoint=$(grep "btrfs" /proc/self/mountinfo | grep " /$subvol " | grep " $partition " | cut -d ' ' -f 5) if [ "$mpoint" = "/" ]; then warn "specifying active root not valid, exiting" - umount "$tmpmnt" 2>/dev/null rmdir "$tmpmnt" 2>/dev/null exit 1 fi if [ "$mpoint" = "$tmpmnt" ]; then warn "btrfs subvol=$subvool, UUID=$UUID, already mounted on $tmpmnt **ERROR**" - umount "$tmpmnt" 2>/dev/null rmdir "$tmpmnt" 2>/dev/null exit 1 fi @@ -74,8 +67,6 @@ if [ "$type" = btrfs ]; then if ! mount $opts -t btrfs -U $UUID "$tmpmnt" 2>/dev/null; then warn "error mounting btrfs subvol=$subvol UUID=$UUID" - umount "$tmpmnt/boot" 2>/dev/null - umount "$tmpmnt" 2>/dev/null rmdir "$tmpmnt" 2>/dev/null exit 1 fi @@ -83,8 +74,6 @@ if [ "$type" = btrfs ]; then # bind-mount if ! mount -o bind "$mpoint" "$tmpmnt" 2>/dev/null; then warn "error mounting btrfs bindfrom=$mpoint subvol=$subvol UUID=$UUID" - umount "$tmpmnt/boot" 2>/dev/null - umount "$tmpmnt" 2>/dev/null rmdir "$tmpmnt" 2>/dev/null exit 1 fi @@ -103,27 +92,34 @@ if [ "$type" = btrfs ]; then bootsv="$subvol" elif echo "$bootmnt" | cut -d ' ' -f 3 | grep -q "btrfs"; then # separate btrfs /boot subvolume - bootsv=$(echo "$bootmnt" | cut -d ' ' -f 4 | grep "^subvol=" | sed "s/subvol=//" ) - bootuuid=$(echo "$bootmnt" | cut -d ' ' -f 1 | grep "^UUID=" | sed "s/UUID=//" ) + bootsv=$(echo "$bootmnt" | cut -d ' ' -f 4 | sed -n 's!\(^subvol=\|.*,subvol=\)\([^,]\+\).*!\2!p') + if [ -z "$bootsv" ]; then + warn "no subvolume in entry: $bootmnt" + umount "$tmpmnt" 2>/dev/null + rmdir "$tmpmnt" 2>/dev/null + exit 1 + fi + bootuuid=$(echo "$bootmnt" | cut -d ' ' -f 1 | sed -n 's/UUID=\("\(.*\)"\|\(.*\)\)/\2\3/p') debug "mounting btrfs $tmpmnt/boot UUID=$bootuuid subvol=$bootsv" bindfrom=$(check_btrfs_mounted $bootsv $bootuuid) if [ -n "$bindfrom" ]; then # already mounted some place if ! mount -o bind $bindfrom "$tmpmnt/boot" 2>/dev/null; then warn "error bind mounting btrfs boot subvol=$bootsv, from=$bindfrom" - umount "$tmpmnt/boot" 2>/dev/null umount "$tmpmnt" 2>/dev/null rmdir "$tmpmnt" 2>/dev/null exit 1 fi elif ! mount -o subvol=$bootsv -t btrfs -U $bootuuid "$tmpmnt/boot" 2>/dev/null; then warn "error mounting btrfs boot partition subvol=$bootsv, UUID=$bootuuid" - umount "$tmpmnt/boot" 2>/dev/null umount "$tmpmnt" 2>/dev/null rmdir "$tmpmnt" 2>/dev/null exit 1 fi - bootpart=$(grep " btrfs " /proc/self/mountinfo | grep " /$bootsv " | cut -d ' ' -f 10) + bootpart=$(grep " btrfs " /proc/self/mountinfo | grep " `echo /$bootsv | tr -s /` " | cut -d ' ' -f 10) + if [ -z "$bootpart" ]; then + warn "no bootpart for $bootsv in /proc/self/mountinfo" + fi else # non-btrfs partition or logical volume linux_mount_boot $partition $tmpmnt Index: os-prober-1.76/linux-boot-probes/common/50mounted-tests =================================================================== --- os-prober-1.76.orig/linux-boot-probes/common/50mounted-tests +++ os-prober-1.76/linux-boot-probes/common/50mounted-tests @@ -42,10 +42,7 @@ elif [ -z "$types" ]; then types="$(grep -v nodev /proc/filesystems)" fi -tmpmnt=/var/lib/os-prober/mount -if [ ! -d "$tmpmnt" ]; then - mkdir "$tmpmnt" -fi +tmpmnt="$(mktemp -d /tmp/linux-boot-probes-50mounted-tests.XXXXXX)" mounted= if type grub2-mount >/dev/null 2>&1 && \ Index: os-prober-1.76/os-prober =================================================================== --- os-prober-1.76.orig/os-prober +++ os-prober-1.76/os-prober @@ -141,9 +141,6 @@ parse_proc_mdstat () { done } -# Needed for idempotency -rm -f /var/lib/os-prober/labels - for prog in /usr/lib/os-probes/init/*; do if [ -x "$prog" ] && [ -f "$prog" ]; then "$prog" || true Index: os-prober-1.76/os-probes/common/50mounted-tests =================================================================== --- os-prober-1.76.orig/os-probes/common/50mounted-tests +++ os-prober-1.76/os-probes/common/50mounted-tests @@ -58,10 +58,7 @@ elif [ -z "$types" ]; then exit 0 fi -tmpmnt=/var/lib/os-prober/mount -if [ ! -d "$tmpmnt" ]; then - mkdir "$tmpmnt" -fi +tmpmnt="$(mktemp -d /tmp/os-probes-50mounted-tests.XXXXXX)" mounted= @@ -105,7 +102,7 @@ probe_subvol () local UUID=$3 local tmpmnt=$4 - mounted= + local mounted= mpoint="$(grep btrfs /proc/self/mountinfo | grep "$partition " | grep "/$subvol " | cut -d ' ' -f 5)" ret=1 @@ -115,13 +112,18 @@ probe_subvol () if [ -n "$mpoint" ]; then if [ "x$mpoint" = "x/" ]; then - continue # this is the root for the running system + return 1 fi - mounted=1 else # again, do not mount btrfs ro - mount -t btrfs $opts -U "$UUID" "$tmpmnt" - mpoint="$tmpmnt" + if mount -t btrfs $opts -U "$UUID" "$tmpmnt" 2>/dev/null; then + debug "btrfs volume $UUID mounted with $opt" + mpoint="$tmpmnt" + mounted=1 + else + warn "cannot mount btrfs volume $UUID with $opt" + return 1 + fi fi test="/usr/lib/os-probes/mounted/90linux-distro" if [ -f "$test" ] && [ -x "$test" ]; then @@ -131,7 +133,7 @@ probe_subvol () ret=0 fi fi - if [ -z "$mounted" ]; then + if [ "$mounted" ]; then if ! umount "$tmpmnt"; then warn "failed to umount $tmpmnt" fi Index: os-prober-1.76/linux-boot-probes/mounted/common/40grub2 =================================================================== --- os-prober-1.76.orig/linux-boot-probes/mounted/common/40grub2 +++ os-prober-1.76/linux-boot-probes/mounted/common/40grub2 @@ -15,7 +15,7 @@ found_item=0 entry_result () { if [ "x$type" = "xbtrfs" ]; then - bsv=${bootsv:+/}${bootsv} + bsv=`echo ${bootsv:+/}${bootsv} | tr -s /` # if path is not relative to subvolume make it relative kernel=${kernel#${bsv}} kernelfile=$kernel