uvol: update to version 0.3
authorDaniel Golle <redacted>
Sat, 24 Jul 2021 03:35:10 +0000 (04:35 +0100)
committerDaniel Golle <redacted>
Sat, 24 Jul 2021 23:40:41 +0000 (00:40 +0100)
 * genrate UCI fstab configs for each volume before first 'up'
 * remove UCI section on volume remove
 * use autofs automounter for read-only volumes
 * try umount on 'down'
 * emulate hotplug events for UBI volume up/down
 * more robust error paths

Signed-off-by: Daniel Golle <redacted>
utils/uvol/Makefile
utils/uvol/files/common.sh [new file with mode: 0644]
utils/uvol/files/lvm.sh
utils/uvol/files/ubi.sh

index f470e51431f3084576fe3f196026d9c67de44da1..f929ba51546f655498d15738fe48927dc1a96437 100644 (file)
@@ -1,7 +1,7 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=uvol
-PKG_VERSION:=0.2
+PKG_VERSION:=0.3
 PKG_RELEASE:=$(AUTORELEASE)
 
 PKG_MAINTAINER:=Daniel Golle <daniel@makrotopia.org>
@@ -28,6 +28,7 @@ define Package/uvol
   CATEGORY:=Utilities
   SUBMENU:=Disc
   TITLE:=OpenWrt UBI/LVM volume abstraction
+  DEPENDS:=+blockd
   PKGARCH=all
 endef
 
@@ -63,8 +64,9 @@ define Package/autopart/install
 endef
 
 define Package/uvol/install
-       $(INSTALL_DIR) $(1)/etc/init.d $(1)/usr/libexec/uvol $(1)/usr/sbin
+       $(INSTALL_DIR) $(1)/etc/init.d $(1)/usr/libexec/uvol $(1)/usr/sbin $(1)/lib/functions
        $(INSTALL_BIN) ./files/uvol.init $(1)/etc/init.d/uvol
+       $(INSTALL_BIN) ./files/common.sh $(1)/lib/functions/uvol.sh
        $(INSTALL_BIN) ./files/ubi.sh $(1)/usr/libexec/uvol/20-ubi.sh
        $(INSTALL_BIN) ./files/lvm.sh $(1)/usr/libexec/uvol/50-lvm.sh
        $(INSTALL_BIN) ./files/uvol $(1)/usr/sbin
diff --git a/utils/uvol/files/common.sh b/utils/uvol/files/common.sh
new file mode 100644 (file)
index 0000000..0eee6d4
--- /dev/null
@@ -0,0 +1,66 @@
+#!/bin/sh
+
+UCI_SPOOLDIR="/var/spool/uvol"
+
+_uvol_init_spooldir() {
+       [ ! -d "$(dirname "$UCI_SPOOLDIR")" ] && mkdir -p "$(dirname "$UCI_SPOOLDIR")"
+       mkdir -m 0700 -p "$UCI_SPOOLDIR"
+}
+
+uvol_uci_add() {
+       local volname="$1"
+       local devname="$2"
+       local mode="$3"
+       local autofs uuid uciname
+
+       uciname=${volname//-/_}
+       uuid="$(/sbin/block info | grep "^$2" | xargs -n 1 echo | grep "^UUID=.*")"
+       [ "$uuid" ] || return 22
+       _uvol_init_spooldir
+       uuid="${uuid:5}"
+       autofs=0
+       [ "$mode" = "ro" ] && autofs=1
+       if [ -e "${UCI_SPOOLDIR}/remove-$1" ]; then
+               rm "${UCI_SPOOLDIR}/remove-$1"
+       fi
+
+       cat >"${UCI_SPOOLDIR}/add-$1" <<EOF
+set fstab.$uciname=mount
+set fstab.$uciname.uuid=$uuid
+set fstab.$uciname.target=/var/run/uvol/$volname
+set fstab.$uciname.options=$mode
+set fstab.$uciname.autofs=$autofs
+set fstab.$uciname.enabled=1
+commit fstab
+EOF
+}
+
+uvol_uci_remove() {
+       local volname="$1"
+       local uciname
+
+       uciname=${volname//-/_}
+       if [ -e "${UCI_SPOOLDIR}/add-$1" ]; then
+               rm "${UCI_SPOOLDIR}/add-$1"
+               return
+       fi
+       _uvol_init_spooldir
+       cat >"${UCI_SPOOLDIR}/remove-$1" <<EOF
+delete fstab.$uciname
+commit fstab
+EOF
+}
+
+uvol_uci_commit() {
+       local volname="$1"
+
+       if [ -e "${UCI_SPOOLDIR}/add-$1" ]; then
+               uci batch < "${UCI_SPOOLDIR}/add-$1"
+               rm "${UCI_SPOOLDIR}/add-$1"
+       elif [ -e "${UCI_SPOOLDIR}/remove-$1" ]; then
+               uci batch < "${UCI_SPOOLDIR}/remove-$1"
+               rm "${UCI_SPOOLDIR}/remove-$1"
+       fi
+
+       return $?
+}
index 082be5f253d303fdd793218db1761f6d8437015c..c06e2f1020b4511dbf91d7128a9c942efedce295 100644 (file)
@@ -11,6 +11,7 @@ fi
 command -v lvm >/dev/null || return 1
 
 . /lib/functions.sh
+. /lib/functions/uvol.sh
 . /lib/upgrade/common.sh
 . /usr/share/libubox/jshn.sh
 
@@ -147,15 +148,21 @@ exportlv() {
 
 getdev() {
        local dms dm_name
-       existvol "$1" || return 1
-       exportlv "$1"
 
        for dms in /sys/devices/virtual/block/dm-* ; do
+               [ "$dms" = "/sys/devices/virtual/block/dm-*" ] && break
                read -r dm_name < "$dms/dm/name"
                [ $(basename "$lv_dm_path") = "$dm_name" ] && echo "$(basename "$dms")"
        done
 }
 
+getuserdev() {
+       local dms dm_name
+       existvol "$1" || return 1
+       exportlv "$1"
+       getdev "$@"
+}
+
 getsize() {
        exportlv "$1"
        [ "$lv_size" ] && echo "$lv_size"
@@ -171,8 +178,9 @@ activatevol() {
                        ;;
                *)
                        [ "$lv_active" = "active" ] && return 0
-                       lvm_cmd lvchange -k n "$lv_full_name" || return $?
+                       uvol_uci_commit "$1"
                        lvm_cmd lvchange -a y "$lv_full_name" || return $?
+                       lvm_cmd lvchange -k n "$lv_full_name" || return $?
                        return 0
                        ;;
        esac
@@ -180,6 +188,7 @@ activatevol() {
 
 disactivatevol() {
        exportlv "$1"
+       local devname
        [ "$lv_path" ] || return 2
        case "$lv_path" in
                /dev/*/wo_*|\
@@ -188,7 +197,9 @@ disactivatevol() {
                        ;;
                *)
                        [ "$lv_active" = "active" ] || return 0
-                       lvm_cmd lvchange -a n "$lv_full_name" || return $?
+                       devname="$(getdev "$1")"
+                       [ "$devname" ] && /sbin/block umount "$devname"
+                       lvm_cmd lvchange -a n "$lv_full_name"
                        lvm_cmd lvchange -k y "$lv_full_name" || return $?
                        return 0
                        ;;
@@ -225,30 +236,41 @@ createvol() {
                        ;;
        esac
 
-       lvm_cmd lvcreate -p "$lvmode" -a n -y -W n -Z n -n "${mode}_$1" -l "$size_ext" "$vg_name"
+       lvm_cmd lvcreate -p "$lvmode" -a n -y -W n -Z n -n "${mode}_$1" -l "$size_ext" "$vg_name" || return $?
        ret=$?
        if [ ! $ret -eq 0 ] || [ "$lvmode" = "r" ]; then
                return $ret
        fi
        exportlv "$1"
        [ "$lv_full_name" ] || return 22
-       lvm_cmd lvchange -a y "$lv_full_name" || return 1
+       lvm_cmd lvchange -a y "$lv_full_name" || return $?
        if [ "$lv_size" -gt $(( 100 * 1024 * 1024 )) ]; then
                mkfs.f2fs -f -l "$1" "$lv_path"
                ret=$?
-               [ $ret != 0 ] && [ $ret != 134 ] && return 1
+               [ $ret != 0 ] && [ $ret != 134 ] && {
+                       lvm_cmd lvchange -a n "$lv_full_name" || return $?
+                       return $ret
+               }
        else
-               mke2fs -F -L "$1" "$lv_path" || return 1
+               mke2fs -F -L "$1" "$lv_path" || {
+                       ret=$?
+                       lvm_cmd lvchange -a n "$lv_full_name" || return $?
+                       return $ret
+               }
        fi
-       lvm_cmd lvrename "$vg_name" "wp_$1" "rw_$1"
-       exportlv "$1"
+       uvol_uci_add "$1" "/dev/$(getdev "$1")" "rw"
+       lvm_cmd lvchange -a n "$lv_full_name" || return $?
+       lvm_cmd lvrename "$vg_name" "wp_$1" "rw_$1" || return $?
        return 0
 }
 
 removevol() {
        exportlv "$1"
        [ "$lv_full_name" ] || return 2
-       lvm_cmd lvremove -y "$lv_full_name"
+       [ "$lv_active" = "active" ] && return 16
+       lvm_cmd lvremove -y "$lv_full_name" || return $?
+       uvol_uci_remove "$1"
+       uvol_uci_commit "$1"
 }
 
 updatevol() {
@@ -257,12 +279,13 @@ updatevol() {
        [ "$lv_size" -ge "$2" ] || return 27
        case "$lv_path" in
                /dev/*/wo_*)
-                       lvm_cmd lvchange -p rw "$lv_full_name"
-                       lvm_cmd lvchange -a y "$lv_full_name"
+                       lvm_cmd lvchange -p rw "$lv_full_name" || return $?
+                       lvm_cmd lvchange -a y "$lv_full_name" || return $?
                        dd of="$lv_path"
-                       lvm_cmd lvchange -a n "$lv_full_name"
-                       lvm_cmd lvchange -p r "$lv_full_name"
-                       lvm_cmd lvrename "$lv_full_name" "${lv_full_name%%/*}/ro_$1"
+                       uvol_uci_add "$1" "/dev/$(getdev "$1")" "ro"
+                       lvm_cmd lvchange -a n "$lv_full_name" || return $?
+                       lvm_cmd lvchange -p r "$lv_full_name" || return $?
+                       lvm_cmd lvrename "$lv_full_name" "${lv_full_name%%/*}/ro_$1" || return $?
                        return 0
                        ;;
                default)
@@ -344,7 +367,7 @@ case "$cmd" in
                removevol "$@"
                ;;
        device)
-               getdev "$@"
+               getuserdev "$@"
                ;;
        size)
                getsize "$@"
index 3eb79adb95fa69a79da9c5dc98b6e25e370922f5..9ddda54da43a96f3c0b72b9e668e8b638d089bcf 100644 (file)
@@ -17,6 +17,8 @@ ubidev=$(ls -1 /sys/devices/virtual/ubi | head -n 1)
 
 read -r ebsize < "/sys/devices/virtual/ubi/${ubidev}/eraseblock_size"
 
+. /lib/functions/uvol.sh
+
 freebytes() {
        read -r availeb < "/sys/devices/virtual/ubi/${ubidev}/avail_eraseblocks"
        echo $((availeb * ebsize))
@@ -87,9 +89,10 @@ getuserdev() {
 mkubifs() {
        local tmp_mp
        tmp_mp="$(mktemp -d)"
-       mount -t ubifs "$1" "$tmp_mp"
-       umount "$tmp_mp"
-       rmdir "$tmp_mp"
+       mount -t ubifs "$1" "$tmp_mp" || return $?
+       umount "$tmp_mp" || return $?
+       rmdir "$tmp_mp" || return $?
+       return 0
 }
 
 createvol() {
@@ -107,22 +110,33 @@ createvol() {
                        return 22
                        ;;
        esac
-       ubimkvol "/dev/$ubidev" -N "uvol-$mode-$1" -s "$2"
+       ubimkvol "/dev/$ubidev" -N "uvol-$mode-$1" -s "$2" || return $?
        ret=$?
        [ $ret -eq 0 ] || return $ret
        voldev="$(getdev "$@")"
-       ubiupdatevol -t "/dev/$voldev"
+       ubiupdatevol -t "/dev/$voldev" || return $?
        [ "$mode" = "wp" ] || return 0
-       mkubifs "/dev/$voldev"
-       ubirename "/dev/$ubidev" "uvol-wp-$1" "uvol-wd-$1"
+       mkubifs "/dev/$voldev" || return $?
+       uvol_uci_add "$1" "/dev/$voldev" "rw"
+       ubirename "/dev/$ubidev" "uvol-wp-$1" "uvol-wd-$1" || return $?
 }
 
 removevol() {
-       local voldev
+       local voldev volnum
        voldev=$(getdev "$@")
        [ "$voldev" ] || return 2
-       local volnum="${voldev#${ubidev}_}"
+       vol_is_mode "$voldev" rw && return 16
+       vol_is_mode "$voldev" ro && return 16
+       volnum="${voldev#${ubidev}_}"
        ubirmvol "/dev/$ubidev" -n "$volnum" || return $?
+       uvol_uci_remove "$1"
+       uvol_uci_commit "$1"
+}
+
+block_hotplug() {
+       export ACTION="$1"
+       export DEVNAME="$2"
+       /sbin/block hotplug
 }
 
 activatevol() {
@@ -133,12 +147,15 @@ activatevol() {
        vol_is_mode "$voldev" ro && return 0
        vol_is_mode "$voldev" wo && return 22
        vol_is_mode "$voldev" wp && return 16
+       uvol_uci_commit "$1"
        if vol_is_mode "$voldev" rd; then
-               ubirename "/dev/$ubidev" "uvol-rd-$1" "uvol-ro-$1"
-               ubiblock --create "/dev/$voldev"
+               ubirename "/dev/$ubidev" "uvol-rd-$1" "uvol-ro-$1" || return $?
+               ubiblock --create "/dev/$voldev" || return $?
+               block_hotplug add "ubiblock${voldev:3}"
                return 0
        elif vol_is_mode "$voldev" wd; then
-               ubirename "/dev/$ubidev" "uvol-wd-$1" "uvol-rw-$1"
+               ubirename "/dev/$ubidev" "uvol-wd-$1" "uvol-rw-$1" || return $?
+               block_hotplug add "$voldev"
                return 0
        fi
 }
@@ -152,12 +169,14 @@ disactivatevol() {
        vol_is_mode "$voldev" wo && return 22
        vol_is_mode "$voldev" wp && return 16
        if vol_is_mode "$voldev" ro; then
-               [ -e "/dev/ubiblock${voldev:3}" ] || return 0
-               ubiblock --remove "/dev/$voldev" || return $?
+               /sbin/block umount "ubiblock${voldev:3}"
+               ubiblock --remove "/dev/$voldev"
                ubirename "/dev/$ubidev" "uvol-ro-$1" "uvol-rd-$1" || return $?
                return 0
        elif vol_is_mode "$voldev" rw; then
+               /sbin/block umount "$voldev"
                ubirename "/dev/$ubidev" "uvol-rw-$1" "uvol-wd-$1" || return $?
+               block_hotplug remove "$voldev"
                return 0
        fi
 }
@@ -169,6 +188,7 @@ updatevol() {
        [ "$2" ] || return 22
        vol_is_mode "$voldev" wo || return 22
        ubiupdatevol -s "$2" "/dev/$voldev" -
+       uvol_uci_add "$1" "/dev/$voldev" "ro"
        ubirename "/dev/$ubidev" "uvol-wo-$1" "uvol-rd-$1"
 }
 
@@ -199,7 +219,7 @@ bootvols() {
                case "$volname" in
                        uvol-ro-*)
                                voldev="/dev/ubiblock${voldev:3}"
-                               ubiblock --create "/dev/$voldev"
+                               ubiblock --create "/dev/$voldev" || return $?
                                ;;
                        *)
                                continue
git clone https://git.99rst.org/PROJECT