diff --git a/utils/uvol/Makefile b/utils/uvol/Makefile index 64fb0238da..f470e51431 100644 --- a/utils/uvol/Makefile +++ b/utils/uvol/Makefile @@ -63,10 +63,11 @@ define Package/autopart/install endef define Package/uvol/install - $(INSTALL_DIR) $(1)/usr/sbin $(1)/usr/libexec/uvol - $(INSTALL_BIN) ./files/uvol $(1)/usr/sbin + $(INSTALL_DIR) $(1)/etc/init.d $(1)/usr/libexec/uvol $(1)/usr/sbin + $(INSTALL_BIN) ./files/uvol.init $(1)/etc/init.d/uvol $(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 endef $(eval $(call BuildPackage,autopart)) diff --git a/utils/uvol/files/lvm.sh b/utils/uvol/files/lvm.sh index 158ab1c83d..4a20f628d1 100644 --- a/utils/uvol/files/lvm.sh +++ b/utils/uvol/files/lvm.sh @@ -30,6 +30,7 @@ lvm_cmd() { local cmd="$1" shift LVM_SUPPRESS_FD_WARNINGS=1 lvm "$cmd" "$@" + return $? } pvs() { @@ -109,19 +110,23 @@ exportvg() { done } +lv_active= +lv_name= lv_full_name= lv_path= lv_dm_path= lv_size= exportlv() { local reports rep lv lvs + lv_active= + lv_name= lv_full_name= lv_path= lv_dm_path= lv_size= json_init - json_load "$(lvs -o lv_full_name,lv_size,lv_path,lv_dm_path -S "lv_name=~^[rw][ow]_$1\$ && vg_name=$vg_name")" + json_load "$(lvs -o lv_active,lv_name,lv_full_name,lv_size,lv_path,lv_dm_path -S "lv_name=~^[rw][owp]_$1\$ && vg_name=$vg_name")" json_select report json_get_keys reports for rep in $reports; do @@ -130,7 +135,7 @@ exportlv() { json_get_keys lvs for lv in $lvs; do json_select "$lv" - json_get_vars lv_full_name lv_size lv_path lv_dm_path + json_get_vars lv_active lv_name lv_full_name lv_size lv_path lv_dm_path lv_size=${lv_size%B} json_select .. break @@ -153,12 +158,17 @@ getsize() { activatevol() { exportlv "$1" + [ "$lv_path" ] || return 2 case "$lv_path" in - /dev/*/wo_*) + /dev/*/wo_*|\ + /dev/*/wp_*) return 22 ;; *) - lvm_cmd lvchange -a y "$lv_full_name" + [ "$lv_active" = "active" ] && return 0 + lvm_cmd lvchange -a y "$lv_full_name" || return $? + lvm_cmd lvchange -k n "$lv_full_name" || return $? + ubus send block.volume "{\"name\": \"$1\", \"action\": \"up\", \"mode\": \"${lv_name:0:2}\", \"device\": \"$lv_dm_path\"}" return 0 ;; esac @@ -166,7 +176,20 @@ activatevol() { disactivatevol() { exportlv "$1" - lvm_cmd lvchange -a n "$lv_full_name" + [ "$lv_path" ] || return 2 + case "$lv_path" in + /dev/*/wo_*|\ + /dev/*/wp_*) + return 22 + ;; + *) + [ "$lv_active" = "active" ] || return 0 + lvm_cmd lvchange -a n "$lv_full_name" || return $? + lvm_cmd lvchange -k y "$lv_full_name" || return $? + ubus send block.volume "{\"name\": \"$1\", \"action\": \"down\", \"mode\": \"${lv_name:0:2}\", \"device\": \"$lv_dm_path\"}" + return 0 + ;; + esac } getstatus() { @@ -192,14 +215,14 @@ createvol() { ;; rw) lvmode=rw - mode=rw + mode=wp ;; *) return 22 ;; 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 ret=$? if [ ! $ret -eq 0 ] || [ "$lvmode" = "r" ]; then return $ret @@ -212,6 +235,9 @@ createvol() { else mke2fs -F -L "$1" "$lv_path" || return 1 fi + lvm_cmd lvrename "$vg_name" "wp_$1" "rw_$1" + exportlv "$1" + ubus send block.volume "{\"name\": \"$1\", \"action\": \"up\", \"mode\": \"${lv_name:0:2}\", \"device\": \"$lv_dm_path\"}" return 0 } @@ -219,6 +245,7 @@ removevol() { exportlv "$1" [ "$lv_full_name" ] || return 2 lvm_cmd lvremove -y "$lv_full_name" + ubus send block.volume "{\"name\": \"$1\", \"action\": \"down\", \"mode\": \"${lv_name:0:2}\", \"device\": \"$lv_dm_path\"}" } updatevol() { @@ -231,6 +258,7 @@ updatevol() { dd of=$lv_path lvm_cmd lvchange -p r "$lv_full_name" lvm_cmd lvrename "$lv_full_name" "${lv_full_name%%/*}/ro_$1" + ubus send block.volume "{\"name\": \"$1\", \"action\": \"up\", \"mode\": \"ro\", \"device\": \"$(getdev "$@")\"}" return 0 ;; default) @@ -264,6 +292,29 @@ listvols() { done } +boot() { + local reports rep lv lvs lv_name lv_dm_path lv_mode volname + json_init + json_load "$(lvs -o lv_name,lv_dm_path -S "lv_name=~^[rw][ow]_.*\$ && vg_name=$vg_name && lv_active=active")" + json_select report + json_get_keys reports + for rep in $reports; do + json_select "$rep" + json_select lv + json_get_keys lvs + for lv in $lvs; do + json_select "$lv" + json_get_vars lv_name lv_dm_path + lv_mode="${lv_name:0:2}" + lv_name="${lv_name:3}" + ubus send block.volume "{\"name\": \"$lv_name\", \"action\": \"up\", \"mode\": \"$lv_mode\", \"device\": \"$lv_dm_path\"}" + json_select .. + done + json_select .. + break + done +} + exportpv exportvg @@ -277,6 +328,9 @@ case "$cmd" in total) totalbytes ;; + boot) + boot + ;; list) listvols "$@" ;; diff --git a/utils/uvol/files/ubi.sh b/utils/uvol/files/ubi.sh index 7851a98df4..0a1b73093c 100644 --- a/utils/uvol/files/ubi.sh +++ b/utils/uvol/files/ubi.sh @@ -31,8 +31,15 @@ getdev() { local voldir volname devname for voldir in /sys/devices/virtual/ubi/${ubidev}/${ubidev}_*; do read volname < "${voldir}/name" - [ "$volname" = "uvol-ro-$1" ] || [ "$volname" = "uvol-wp-$1" ] || [ "$volname" = "uvol-rw-$1" ] || [ "$volname" = "uvol-wo-$1" ] || continue - basename "$voldir" + case "$volname" in + uvol-[rw][owpd]-$1) + basename "$voldir" + break + ;; + *) + continue + ;; + esac done } @@ -51,7 +58,9 @@ vol_is_mode() { getstatus() { local voldev=$(getdev "$@") [ "$voldev" ] || return 2 - vol_is_mode $voldev wo && return 1 + vol_is_mode $voldev wo && return 22 + vol_is_mode $voldev wp && return 16 + vol_is_mode $voldev wd && return 1 vol_is_mode $voldev ro && [ ! -e "/dev/ubiblock${voldev:3}" ] && return 1 return 0 } @@ -73,10 +82,17 @@ getuserdev() { fi } +mkubifs() { + local tmp_mp=$(mktemp -d) + mount -t ubifs $1 $tmp_mp + umount $tmp_mp + rmdir $tmp_mp +} + createvol() { local mode ret - local existdev=$(getdev "$@") - [ "$existdev" ] && return 17 + local voldev=$(getdev "$@") + [ "$voldev" ] && return 17 case "$3" in ro|wo) mode=wo @@ -91,37 +107,61 @@ createvol() { ubimkvol /dev/$ubidev -N "uvol-$mode-$1" -s "$2" ret=$? [ $ret -eq 0 ] || return $ret - ubiupdatevol -t /dev/$(getdev "$@") + voldev=$(getdev "$@") + ubiupdatevol -t /dev/$voldev [ "$mode" = "wp" ] || return 0 - local tmp_mp=$(mktemp -d) - mount -t ubifs /dev/$(getdev "$@") $tmp_mp - umount $tmp_mp - rmdir $tmp_mp + mkubifs /dev/$voldev ubirename /dev/$ubidev uvol-wp-$1 uvol-rw-$1 + ubus send block.volume "{\"name\": \"$1\", \"action\": \"up\", \"mode\": \"rw\", \"fstype\": \"ubifs\", \"device\": \"/dev/$voldev\"}" } removevol() { local voldev=$(getdev "$@") + local evdata [ "$voldev" ] || return 2 local volnum=${voldev#${ubidev}_} - ubirmvol /dev/$ubidev -n $volnum + if vol_is_mode $voldev rw ; then + evdata="{\"name\": \"$1\", \"action\": \"down\", \"device\": \"/dev/$voldev\"}" + elif vol_is_mode $voldev ro ; then + evdata="{\"name\": \"$1\", \"action\": \"down\", \"device\": \"/dev/ubiblock${voldev:3}\"}" + fi + ubirmvol /dev/$ubidev -n $volnum || return $? + ubus send block.volume "$evdata" } activatevol() { local voldev=$(getdev "$@") [ "$voldev" ] || return 2 - vol_is_mode $voldev wo || return 1 - vol_is_mode $voldev ro || return 0 - [ -e "/dev/ubiblock${voldev:3}" ] && return 0 - ubiblock --create /dev/$voldev + vol_is_mode $voldev rw && return 0 + 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 --create /dev/$voldev + ubus send block.volume "{\"name\": \"$1\", \"action\": \"up\", \"mode\": \"ro\", \"device\": \"/dev/ubiblock${voldev:3}\"}" + return 0 + elif vol_is_mode $voldev wd; then + ubirename /dev/$ubidev uvol-wd-$1 uvol-rw-$1 + ubus send block.volume "{\"name\": \"$1\", \"action\": \"up\", \"mode\": \"rw\", \"fstype\": \"ubifs\", \"device\": \"/dev/$voldev\"}" + return 0 + fi } disactivatevol() { local voldev=$(getdev "$@") [ "$voldev" ] || return 2 - vol_is_mode $voldev ro || return 0 - [ -e "/dev/ubiblock${voldev:3}" ] || return 0 - ubiblock --remove /dev/$voldev + 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 $? + ubus send block.volume "{\"name\": \"$1\", \"action\": \"down\", \"mode\": \"ro\", \"device\": \"/dev/ubiblock${voldev:3}\"}" + return 0 + elif vol_is_mode $voldev rw; then + ubirename /dev/$ubidev uvol-rw-$1 uvol-wd-$1 || return $? + ubus send block.volume "{\"name\": \"$1\", \"action\": \"down\", \"mode\": \"rw\", \"device\": \"/dev/$voldev\"}" + return 0 + fi } updatevol() { @@ -131,6 +171,8 @@ updatevol() { vol_is_mode $voldev wo || return 22 ubiupdatevol -s $2 /dev/$voldev - ubirename /dev/$ubidev uvol-wo-$1 uvol-ro-$1 + ubiblock --create /dev/$voldev + ubus send block.volume "{\"name\": \"$1\", \"action\": \"up\", \"mode\": \"ro\", \"device\": \"/dev/ubiblock${voldev:3}\"}" } listvols() { @@ -138,7 +180,7 @@ listvols() { for voldir in /sys/devices/virtual/ubi/${ubidev}/${ubidev}_*; do read volname < $voldir/name case "$volname" in - uvol-r[wo]*) + uvol-[rw][wod]*) read volsize < $voldir/data_bytes ;; *) @@ -151,6 +193,31 @@ listvols() { done } +bootvols() { + local volname volmode volsize voldev fstype + for voldir in /sys/devices/virtual/ubi/${ubidev}/${ubidev}_*; do + read volname < $voldir/name + voldev=$(basename $voldir) + fstype= + case "$volname" in + uvol-ro-*) + voldev="/dev/ubiblock${voldev:3}" + ubiblock --create /dev/$voldev + ;; + uvol-rw-*) + voldev="/dev/$voldev" + fstype="ubifs" + ;; + *) + continue + ;; + esac + volmode=${volname:5:2} + volname=${volname:8} + ubus send block.volume "{\"name\": \"$volname\", \"action\": \"up\", \"mode\": \"$volmode\",${fstype:+ \"fstype\": \"$fstype\", }\"device\": \"$voldev\"}" + done +} + case "$cmd" in align) echo "$ebsize" @@ -161,6 +228,9 @@ case "$cmd" in total) totalbytes ;; + boot) + bootvols + ;; list) listvols "$@" ;; diff --git a/utils/uvol/files/uvol b/utils/uvol/files/uvol index 0fea88f38c..a095b3efff 100644 --- a/utils/uvol/files/uvol +++ b/utils/uvol/files/uvol @@ -11,6 +11,7 @@ uvol storage volume manager syntax: uvol command ... commands: + boot get active volumes ready (called on boot) free show number of bytes available total show total number of bytes align show sector size in bytes diff --git a/utils/uvol/files/uvol.init b/utils/uvol/files/uvol.init new file mode 100644 index 0000000000..7c290d7323 --- /dev/null +++ b/utils/uvol/files/uvol.init @@ -0,0 +1,18 @@ +#!/bin/sh /etc/rc.common + +START=99 +USE_PROCD=1 +NAME=uvol +PROG=/usr/sbin/uvol + +start_service() { + [ "${__BOOT_UVOL}" = "1" ] || return 0 + procd_open_instance "$NAME" + procd_set_param command "$PROG" boot + procd_close_instance +} + +boot() { + __BOOT_UVOL=1 + start +}