uvol: make volume creation atomic
Make sure filesystem is ready when volume becomes available. Use 'write-once' as initial state for read-only volumes, only allow writing to volumes in that state and transision to 'read-only' once write has completed. Also fix a typo which prevented 'list' command from working with LVM. Signed-off-by: Daniel Golle <daniel@makrotopia.org>
This commit is contained in:
parent
ee1a3654dc
commit
3d4d75c519
|
@ -41,7 +41,7 @@ vgs() {
|
|||
}
|
||||
|
||||
lvs() {
|
||||
lvm_cmd vgs --reportformat json --units b "$@"
|
||||
lvm_cmd lvs --reportformat json --units b "$@"
|
||||
}
|
||||
|
||||
freebytes() {
|
||||
|
@ -121,7 +121,7 @@ exportlv() {
|
|||
lv_size=
|
||||
json_init
|
||||
|
||||
json_load "$(lvs -o lv_full_name,lv_size,lv_path,lv_dm_path -S "lv_name=~^r[ow]_$1\$ && vg_name=$vg_name")"
|
||||
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_select report
|
||||
json_get_keys reports
|
||||
for rep in $reports; do
|
||||
|
@ -153,7 +153,15 @@ getsize() {
|
|||
|
||||
activatevol() {
|
||||
exportlv "$1"
|
||||
lvm_cmd lvchange -a y "$lv_full_name"
|
||||
case "$lv_path" in
|
||||
/dev/*/wo_*)
|
||||
return 22
|
||||
;;
|
||||
*)
|
||||
lvm_cmd lvchange -a y "$lv_full_name"
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
disactivatevol() {
|
||||
|
@ -169,7 +177,7 @@ getstatus() {
|
|||
}
|
||||
|
||||
createvol() {
|
||||
local mode ret
|
||||
local mode lvmode ret
|
||||
local volsize=$(($2))
|
||||
[ "$volsize" ] || return 22
|
||||
exportlv "$1"
|
||||
|
@ -178,10 +186,12 @@ createvol() {
|
|||
[ $((size_ext * vg_extent_size)) -lt $volsize ] && size_ext=$((size_ext + 1))
|
||||
|
||||
case "$3" in
|
||||
ro)
|
||||
mode=r
|
||||
ro|wo)
|
||||
lvmode=r
|
||||
mode=wo
|
||||
;;
|
||||
rw)
|
||||
lvmode=rw
|
||||
mode=rw
|
||||
;;
|
||||
*)
|
||||
|
@ -189,9 +199,9 @@ createvol() {
|
|||
;;
|
||||
esac
|
||||
|
||||
lvm_cmd lvcreate -p $mode -a n -y -W n -Z n -n "${3}_${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 ] || [ "$mode" = "r" ]; then
|
||||
if [ ! $ret -eq 0 ] || [ "$lvmode" = "r" ]; then
|
||||
return $ret
|
||||
fi
|
||||
exportlv "$1"
|
||||
|
@ -215,11 +225,16 @@ updatevol() {
|
|||
exportlv "$1"
|
||||
[ "$lv_full_name" ] || return 2
|
||||
[ $lv_size -ge $2 ] || return 27
|
||||
lvm_cmd lvchange -a y -p rw "$lv_full_name"
|
||||
dd of=$lv_path
|
||||
case "$lv_path" in
|
||||
/dev/*/ro_*)
|
||||
/dev/*/wo_*)
|
||||
lvm_cmd lvchange -a y -p rw "$lv_full_name"
|
||||
dd of=$lv_path
|
||||
lvm_cmd lvchange -p r "$lv_full_name"
|
||||
lvm_cmd lvrename "$lv_full_name" "${lv_full_name%%/*}/ro_$1"
|
||||
return 0
|
||||
;;
|
||||
default)
|
||||
return 22
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
@ -228,7 +243,7 @@ listvols() {
|
|||
local reports rep lv lvs lv_name lv_size lv_mode volname
|
||||
volname=${1:-.*}
|
||||
json_init
|
||||
json_load "$(lvs -o lv_name,lv_size -S "lv_name=~^r[ow]_$volname\$ && vg_name=$vg_name")"
|
||||
json_load "$(lvs -o lv_name,lv_size -S "lv_name=~^[rw][ow]_$volname\$ && vg_name=$vg_name")"
|
||||
json_select report
|
||||
json_get_keys reports
|
||||
for rep in $reports; do
|
||||
|
|
|
@ -31,17 +31,17 @@ 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-rw-$1" ] || continue
|
||||
[ "$volname" = "uvol-ro-$1" ] || [ "$volname" = "uvol-wp-$1" ] || [ "$volname" = "uvol-rw-$1" ] || [ "$volname" = "uvol-wo-$1" ] || continue
|
||||
basename "$voldir"
|
||||
done
|
||||
}
|
||||
|
||||
needs_ubiblock() {
|
||||
vol_is_mode() {
|
||||
local voldev="$1"
|
||||
local volname
|
||||
read volname < "/sys/devices/virtual/ubi/${ubidev}/${voldev}/name"
|
||||
case "$volname" in
|
||||
uvol-ro-*)
|
||||
uvol-$2-*)
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
|
@ -51,7 +51,8 @@ needs_ubiblock() {
|
|||
getstatus() {
|
||||
local voldev=$(getdev "$@")
|
||||
[ "$voldev" ] || return 2
|
||||
needs_ubiblock $voldev && [ ! -e "/dev/ubiblock${voldev:3}" ] && return 1
|
||||
vol_is_mode $voldev wo && return 1
|
||||
vol_is_mode $voldev ro && [ ! -e "/dev/ubiblock${voldev:3}" ] && return 1
|
||||
return 0
|
||||
}
|
||||
|
||||
|
@ -65,9 +66,9 @@ getsize() {
|
|||
getuserdev() {
|
||||
local voldev=$(getdev "$@")
|
||||
[ "$voldev" ] || return 2
|
||||
if needs_ubiblock $voldev ; then
|
||||
if vol_is_mode $voldev ro ; then
|
||||
echo "/dev/ubiblock${voldev:3}"
|
||||
else
|
||||
elif vol_is_mode $voldev rw ; then
|
||||
echo "/dev/$voldev"
|
||||
fi
|
||||
}
|
||||
|
@ -77,11 +78,11 @@ createvol() {
|
|||
local existdev=$(getdev "$@")
|
||||
[ "$existdev" ] && return 17
|
||||
case "$3" in
|
||||
ro)
|
||||
mode=ro
|
||||
ro|wo)
|
||||
mode=wo
|
||||
;;
|
||||
rw)
|
||||
mode=rw
|
||||
mode=wp
|
||||
;;
|
||||
*)
|
||||
return 22
|
||||
|
@ -91,6 +92,12 @@ createvol() {
|
|||
ret=$?
|
||||
[ $ret -eq 0 ] || return $ret
|
||||
ubiupdatevol -t /dev/$(getdev "$@")
|
||||
[ "$mode" = "wp" ] || return 0
|
||||
local tmp_mp=$(mktemp -d)
|
||||
mount -t ubifs /dev/$(getdev "$@") $tmp_mp
|
||||
umount $tmp_mp
|
||||
rmdir $tmp_mp
|
||||
ubirename /dev/$ubidev uvol-wp-$1 uvol-rw-$1
|
||||
}
|
||||
|
||||
removevol() {
|
||||
|
@ -103,7 +110,8 @@ removevol() {
|
|||
activatevol() {
|
||||
local voldev=$(getdev "$@")
|
||||
[ "$voldev" ] || return 2
|
||||
needs_ubiblock $voldev || return 0
|
||||
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
|
||||
}
|
||||
|
@ -111,7 +119,7 @@ activatevol() {
|
|||
disactivatevol() {
|
||||
local voldev=$(getdev "$@")
|
||||
[ "$voldev" ] || return 2
|
||||
needs_ubiblock $voldev || return 0
|
||||
vol_is_mode $voldev ro || return 0
|
||||
[ -e "/dev/ubiblock${voldev:3}" ] || return 0
|
||||
ubiblock --remove /dev/$voldev
|
||||
}
|
||||
|
@ -120,15 +128,9 @@ updatevol() {
|
|||
local voldev=$(getdev "$@")
|
||||
[ "$voldev" ] || return 2
|
||||
[ "$2" ] || return 22
|
||||
needs_ubiblock $voldev || return 22
|
||||
vol_is_mode $voldev wo || return 22
|
||||
ubiupdatevol -s $2 /dev/$voldev -
|
||||
}
|
||||
|
||||
getstatus() {
|
||||
local voldev=$(getdev "$@")
|
||||
[ "$voldev" ] || return 2
|
||||
needs_ubiblock $voldev && [ ! -e "/dev/ubiblock${voldev:3}" ] && return 1
|
||||
return 0
|
||||
ubirename /dev/$ubidev uvol-wo-$1 uvol-ro-$1
|
||||
}
|
||||
|
||||
listvols() {
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
|
||||
# uvol prototype
|
||||
# future development roadmap (aka. to-do):
|
||||
# * atomic create using temp volnames
|
||||
# * create read-only volumes as 'write-once', introduce 'pending' state until written
|
||||
# * re-implement in C (use libubox, execve lvm/ubi*)
|
||||
# * add atomic batch processing for use by container/package manager
|
||||
|
||||
|
|
Loading…
Reference in New Issue