uvol: emmit ubus events and bring up volumes on boot
Emmit ubus events when volumes come up/down. Make sure volume state is always well defined by introducing additional state 'write-prepare' (wp) during mkfs. Add init scripts to bring up volumes at boot. Signed-off-by: Daniel Golle <daniel@makrotopia.org>
This commit is contained in:
parent
e6f5e2cc62
commit
fc01307d7a
|
@ -63,10 +63,11 @@ define Package/autopart/install
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define Package/uvol/install
|
define Package/uvol/install
|
||||||
$(INSTALL_DIR) $(1)/usr/sbin $(1)/usr/libexec/uvol
|
$(INSTALL_DIR) $(1)/etc/init.d $(1)/usr/libexec/uvol $(1)/usr/sbin
|
||||||
$(INSTALL_BIN) ./files/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/ubi.sh $(1)/usr/libexec/uvol/20-ubi.sh
|
||||||
$(INSTALL_BIN) ./files/lvm.sh $(1)/usr/libexec/uvol/50-lvm.sh
|
$(INSTALL_BIN) ./files/lvm.sh $(1)/usr/libexec/uvol/50-lvm.sh
|
||||||
|
$(INSTALL_BIN) ./files/uvol $(1)/usr/sbin
|
||||||
endef
|
endef
|
||||||
|
|
||||||
$(eval $(call BuildPackage,autopart))
|
$(eval $(call BuildPackage,autopart))
|
||||||
|
|
|
@ -30,6 +30,7 @@ lvm_cmd() {
|
||||||
local cmd="$1"
|
local cmd="$1"
|
||||||
shift
|
shift
|
||||||
LVM_SUPPRESS_FD_WARNINGS=1 lvm "$cmd" "$@"
|
LVM_SUPPRESS_FD_WARNINGS=1 lvm "$cmd" "$@"
|
||||||
|
return $?
|
||||||
}
|
}
|
||||||
|
|
||||||
pvs() {
|
pvs() {
|
||||||
|
@ -109,19 +110,23 @@ exportvg() {
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lv_active=
|
||||||
|
lv_name=
|
||||||
lv_full_name=
|
lv_full_name=
|
||||||
lv_path=
|
lv_path=
|
||||||
lv_dm_path=
|
lv_dm_path=
|
||||||
lv_size=
|
lv_size=
|
||||||
exportlv() {
|
exportlv() {
|
||||||
local reports rep lv lvs
|
local reports rep lv lvs
|
||||||
|
lv_active=
|
||||||
|
lv_name=
|
||||||
lv_full_name=
|
lv_full_name=
|
||||||
lv_path=
|
lv_path=
|
||||||
lv_dm_path=
|
lv_dm_path=
|
||||||
lv_size=
|
lv_size=
|
||||||
json_init
|
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_select report
|
||||||
json_get_keys reports
|
json_get_keys reports
|
||||||
for rep in $reports; do
|
for rep in $reports; do
|
||||||
|
@ -130,7 +135,7 @@ exportlv() {
|
||||||
json_get_keys lvs
|
json_get_keys lvs
|
||||||
for lv in $lvs; do
|
for lv in $lvs; do
|
||||||
json_select "$lv"
|
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}
|
lv_size=${lv_size%B}
|
||||||
json_select ..
|
json_select ..
|
||||||
break
|
break
|
||||||
|
@ -153,12 +158,17 @@ getsize() {
|
||||||
|
|
||||||
activatevol() {
|
activatevol() {
|
||||||
exportlv "$1"
|
exportlv "$1"
|
||||||
|
[ "$lv_path" ] || return 2
|
||||||
case "$lv_path" in
|
case "$lv_path" in
|
||||||
/dev/*/wo_*)
|
/dev/*/wo_*|\
|
||||||
|
/dev/*/wp_*)
|
||||||
return 22
|
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
|
return 0
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
@ -166,7 +176,20 @@ activatevol() {
|
||||||
|
|
||||||
disactivatevol() {
|
disactivatevol() {
|
||||||
exportlv "$1"
|
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() {
|
getstatus() {
|
||||||
|
@ -192,14 +215,14 @@ createvol() {
|
||||||
;;
|
;;
|
||||||
rw)
|
rw)
|
||||||
lvmode=rw
|
lvmode=rw
|
||||||
mode=rw
|
mode=wp
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
return 22
|
return 22
|
||||||
;;
|
;;
|
||||||
esac
|
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=$?
|
ret=$?
|
||||||
if [ ! $ret -eq 0 ] || [ "$lvmode" = "r" ]; then
|
if [ ! $ret -eq 0 ] || [ "$lvmode" = "r" ]; then
|
||||||
return $ret
|
return $ret
|
||||||
|
@ -212,6 +235,9 @@ createvol() {
|
||||||
else
|
else
|
||||||
mke2fs -F -L "$1" "$lv_path" || return 1
|
mke2fs -F -L "$1" "$lv_path" || return 1
|
||||||
fi
|
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
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,6 +245,7 @@ removevol() {
|
||||||
exportlv "$1"
|
exportlv "$1"
|
||||||
[ "$lv_full_name" ] || return 2
|
[ "$lv_full_name" ] || return 2
|
||||||
lvm_cmd lvremove -y "$lv_full_name"
|
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() {
|
updatevol() {
|
||||||
|
@ -231,6 +258,7 @@ updatevol() {
|
||||||
dd of=$lv_path
|
dd of=$lv_path
|
||||||
lvm_cmd lvchange -p r "$lv_full_name"
|
lvm_cmd lvchange -p r "$lv_full_name"
|
||||||
lvm_cmd lvrename "$lv_full_name" "${lv_full_name%%/*}/ro_$1"
|
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
|
return 0
|
||||||
;;
|
;;
|
||||||
default)
|
default)
|
||||||
|
@ -264,6 +292,29 @@ listvols() {
|
||||||
done
|
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
|
exportpv
|
||||||
exportvg
|
exportvg
|
||||||
|
|
||||||
|
@ -277,6 +328,9 @@ case "$cmd" in
|
||||||
total)
|
total)
|
||||||
totalbytes
|
totalbytes
|
||||||
;;
|
;;
|
||||||
|
boot)
|
||||||
|
boot
|
||||||
|
;;
|
||||||
list)
|
list)
|
||||||
listvols "$@"
|
listvols "$@"
|
||||||
;;
|
;;
|
||||||
|
|
|
@ -31,8 +31,15 @@ getdev() {
|
||||||
local voldir volname devname
|
local voldir volname devname
|
||||||
for voldir in /sys/devices/virtual/ubi/${ubidev}/${ubidev}_*; do
|
for voldir in /sys/devices/virtual/ubi/${ubidev}/${ubidev}_*; do
|
||||||
read volname < "${voldir}/name"
|
read volname < "${voldir}/name"
|
||||||
[ "$volname" = "uvol-ro-$1" ] || [ "$volname" = "uvol-wp-$1" ] || [ "$volname" = "uvol-rw-$1" ] || [ "$volname" = "uvol-wo-$1" ] || continue
|
case "$volname" in
|
||||||
basename "$voldir"
|
uvol-[rw][owpd]-$1)
|
||||||
|
basename "$voldir"
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
continue
|
||||||
|
;;
|
||||||
|
esac
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,7 +58,9 @@ vol_is_mode() {
|
||||||
getstatus() {
|
getstatus() {
|
||||||
local voldev=$(getdev "$@")
|
local voldev=$(getdev "$@")
|
||||||
[ "$voldev" ] || return 2
|
[ "$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
|
vol_is_mode $voldev ro && [ ! -e "/dev/ubiblock${voldev:3}" ] && return 1
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
@ -73,10 +82,17 @@ getuserdev() {
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mkubifs() {
|
||||||
|
local tmp_mp=$(mktemp -d)
|
||||||
|
mount -t ubifs $1 $tmp_mp
|
||||||
|
umount $tmp_mp
|
||||||
|
rmdir $tmp_mp
|
||||||
|
}
|
||||||
|
|
||||||
createvol() {
|
createvol() {
|
||||||
local mode ret
|
local mode ret
|
||||||
local existdev=$(getdev "$@")
|
local voldev=$(getdev "$@")
|
||||||
[ "$existdev" ] && return 17
|
[ "$voldev" ] && return 17
|
||||||
case "$3" in
|
case "$3" in
|
||||||
ro|wo)
|
ro|wo)
|
||||||
mode=wo
|
mode=wo
|
||||||
|
@ -91,37 +107,61 @@ createvol() {
|
||||||
ubimkvol /dev/$ubidev -N "uvol-$mode-$1" -s "$2"
|
ubimkvol /dev/$ubidev -N "uvol-$mode-$1" -s "$2"
|
||||||
ret=$?
|
ret=$?
|
||||||
[ $ret -eq 0 ] || return $ret
|
[ $ret -eq 0 ] || return $ret
|
||||||
ubiupdatevol -t /dev/$(getdev "$@")
|
voldev=$(getdev "$@")
|
||||||
|
ubiupdatevol -t /dev/$voldev
|
||||||
[ "$mode" = "wp" ] || return 0
|
[ "$mode" = "wp" ] || return 0
|
||||||
local tmp_mp=$(mktemp -d)
|
mkubifs /dev/$voldev
|
||||||
mount -t ubifs /dev/$(getdev "$@") $tmp_mp
|
|
||||||
umount $tmp_mp
|
|
||||||
rmdir $tmp_mp
|
|
||||||
ubirename /dev/$ubidev uvol-wp-$1 uvol-rw-$1
|
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() {
|
removevol() {
|
||||||
local voldev=$(getdev "$@")
|
local voldev=$(getdev "$@")
|
||||||
|
local evdata
|
||||||
[ "$voldev" ] || return 2
|
[ "$voldev" ] || return 2
|
||||||
local volnum=${voldev#${ubidev}_}
|
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() {
|
activatevol() {
|
||||||
local voldev=$(getdev "$@")
|
local voldev=$(getdev "$@")
|
||||||
[ "$voldev" ] || return 2
|
[ "$voldev" ] || return 2
|
||||||
vol_is_mode $voldev wo || return 1
|
vol_is_mode $voldev rw && return 0
|
||||||
vol_is_mode $voldev ro || return 0
|
vol_is_mode $voldev wo && return 22
|
||||||
[ -e "/dev/ubiblock${voldev:3}" ] && return 0
|
vol_is_mode $voldev wp && return 16
|
||||||
ubiblock --create /dev/$voldev
|
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() {
|
disactivatevol() {
|
||||||
local voldev=$(getdev "$@")
|
local voldev=$(getdev "$@")
|
||||||
[ "$voldev" ] || return 2
|
[ "$voldev" ] || return 2
|
||||||
vol_is_mode $voldev ro || return 0
|
vol_is_mode $voldev wo && return 22
|
||||||
[ -e "/dev/ubiblock${voldev:3}" ] || return 0
|
vol_is_mode $voldev wp && return 16
|
||||||
ubiblock --remove /dev/$voldev
|
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() {
|
updatevol() {
|
||||||
|
@ -131,6 +171,8 @@ updatevol() {
|
||||||
vol_is_mode $voldev wo || return 22
|
vol_is_mode $voldev wo || return 22
|
||||||
ubiupdatevol -s $2 /dev/$voldev -
|
ubiupdatevol -s $2 /dev/$voldev -
|
||||||
ubirename /dev/$ubidev uvol-wo-$1 uvol-ro-$1
|
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() {
|
listvols() {
|
||||||
|
@ -138,7 +180,7 @@ listvols() {
|
||||||
for voldir in /sys/devices/virtual/ubi/${ubidev}/${ubidev}_*; do
|
for voldir in /sys/devices/virtual/ubi/${ubidev}/${ubidev}_*; do
|
||||||
read volname < $voldir/name
|
read volname < $voldir/name
|
||||||
case "$volname" in
|
case "$volname" in
|
||||||
uvol-r[wo]*)
|
uvol-[rw][wod]*)
|
||||||
read volsize < $voldir/data_bytes
|
read volsize < $voldir/data_bytes
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
|
@ -151,6 +193,31 @@ listvols() {
|
||||||
done
|
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
|
case "$cmd" in
|
||||||
align)
|
align)
|
||||||
echo "$ebsize"
|
echo "$ebsize"
|
||||||
|
@ -161,6 +228,9 @@ case "$cmd" in
|
||||||
total)
|
total)
|
||||||
totalbytes
|
totalbytes
|
||||||
;;
|
;;
|
||||||
|
boot)
|
||||||
|
bootvols
|
||||||
|
;;
|
||||||
list)
|
list)
|
||||||
listvols "$@"
|
listvols "$@"
|
||||||
;;
|
;;
|
||||||
|
|
|
@ -11,6 +11,7 @@ uvol storage volume manager
|
||||||
syntax: uvol command ...
|
syntax: uvol command ...
|
||||||
|
|
||||||
commands:
|
commands:
|
||||||
|
boot get active volumes ready (called on boot)
|
||||||
free show number of bytes available
|
free show number of bytes available
|
||||||
total show total number of bytes
|
total show total number of bytes
|
||||||
align show sector size in bytes
|
align show sector size in bytes
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
Loading…
Reference in New Issue