From f4afa4189e7ae35aa1ba1a6a60f5ed7dba877f6c Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Sat, 24 Jul 2021 04:35:10 +0100 Subject: [PATCH] uvol: update to version 0.3 * 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 --- utils/uvol/Makefile | 6 ++-- utils/uvol/files/common.sh | 66 ++++++++++++++++++++++++++++++++++++++ utils/uvol/files/lvm.sh | 57 ++++++++++++++++++++++---------- utils/uvol/files/ubi.sh | 50 ++++++++++++++++++++--------- 4 files changed, 145 insertions(+), 34 deletions(-) create mode 100644 utils/uvol/files/common.sh diff --git a/utils/uvol/Makefile b/utils/uvol/Makefile index f470e5143..f929ba515 100644 --- a/utils/uvol/Makefile +++ b/utils/uvol/Makefile @@ -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 @@ -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 index 000000000..0eee6d432 --- /dev/null +++ b/utils/uvol/files/common.sh @@ -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" <"${UCI_SPOOLDIR}/remove-$1" </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 "$@" diff --git a/utils/uvol/files/ubi.sh b/utils/uvol/files/ubi.sh index 3eb79adb9..9ddda54da 100644 --- a/utils/uvol/files/ubi.sh +++ b/utils/uvol/files/ubi.sh @@ -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