packages/utils/uvol/files/lvm.sh
Daniel Golle 312594f869
uvol: add new package
uvol is a wrapper-script which allows automated handling of storage
volumes. uvol currently comes with backend support for LVM2 and UBI,
covering practically all options for storage large enough to be
managed (NAND, SPI-NAND, eMMC, SATA, NVME, virtio-blk, ...).

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
2021-04-10 12:02:23 +01:00

195 lines
2.9 KiB
Bash

#!/bin/sh
command -v lvm || return 1
. /lib/functions.sh
. /lib/upgrade/common.sh
export_bootdevice
[ "$BOOTDEV_MAJOR" ] || return 1
export_partdevice rootdev 0
[ "$rootdev" ] || return 1
LVM_SUPPRESS_FD_WARNINGS=1
case "$rootdev" in
mtd*|\
ram*|\
ubi*)
return 1
esac
lvs() {
local cmd="$1"
local cb="$2"
local param="${3:+-S vg_name=${vgname} -S lv_name=~^r[ow]_$3\$}"
local oIFS="$IFS"
IFS=" "
set -- $(LVM_SUPPRESS_FD_WARNINGS=1 $cmd -c $param)
[ "$1" ] || {
IFS="$oIFS"
return 1
}
IFS=":"
set -- $1
IFS="$oIFS"
$cb "$@"
}
pvvars() {
case "${1:5}" in
"$rootdev"*)
partdev="$1"
vgname="$2"
;;
esac
}
vgvars() {
[ "$1" = "$vgname" ] || return
vgbs="${13}"
vgts="${14}"
vgus="${15}"
vgfs="${16}"
}
lvvars() {
lvpath="$1"
lvsize=$(( 512 * $7 ))
}
freebytes() {
echo $((vgfs * vgbs * 1024))
}
totalbytes() {
echo $((vgts * vgbs * 1024))
}
existvol() {
[ "$1" ] || return 1
test -e "/dev/$vgname/ro_$1" || test -e "/dev/$vgname/rw_$1"
return $?
}
getlvname() {
lvs lvdisplay lvvars "$1"
[ "$lvpath" ] && echo ${lvpath:5}
}
getdev() {
existvol "$1" || return 1
readlink /dev/$(getlvname "$1")
}
getsize() {
lvs lvdisplay lvvars "$1"
[ "$lvsize" ] && echo $lvsize
}
activatevol() {
LVM_SUPPRESS_FD_WARNINGS=1 lvchange -a y "$(getlvname "$1")"
}
disactivatevol() {
existvol "$1" || return 1
LVM_SUPPRESS_FD_WARNINGS=1 lvchange -a n "$(getlvname "$1")"
}
getstatus() {
lvs lvdisplay lvvars "$1"
[ "$lvsize" ] || return 2
existvol "$1" || return 1
return 0
}
createvol() {
local mode ret lvname
case "$3" in
ro)
mode=r
;;
rw)
mode=rw
;;
*)
return 22
;;
esac
LVM_SUPPRESS_FD_WARNINGS=1 lvcreate -p $mode -a n -y -W n -Z n -n "${3}_${1}" -L "$2" $vgname
ret=$?
if [ ! $ret -eq 0 ] || [ "$mode" = "r" ]; then
return $ret
fi
lvs lvdisplay lvvars "$1"
[ "$lvpath" ] || return 22
lvname=${lvpath:5}
LVM_SUPPRESS_FD_WARNINGS=1 lvchange -a y /dev/$lvname || return 1
if [ $lvsize -gt $(( 100 * 1024 * 1024 )) ]; then
mkfs.f2fs -f -l "$1" $lvpath || return 1
else
mke2fs -F -L "$1" $lvpath || return 1
fi
return 0
}
removevol() {
local lvname="$(getlvname "$1")"
[ "$lvname" ] || return 2
LVM_SUPPRESS_FD_WARNINGS=1 lvremove -y "$(getlvname "$1")"
}
updatevol() {
lvs lvdisplay lvvars "$1"
[ "$lvpath" ] || return 2
[ $lvsize -ge $2 ] || return 27
LVM_SUPPRESS_FD_WARNINGS=1 lvchange -a y -p rw ${lvpath:5}
dd of=$lvpath
case "$lvpath" in
/dev/*/ro_*)
LVM_SUPPRESS_FD_WARNINGS=1 lvchange -p r ${lvpath:5}
;;
esac
}
lvs pvdisplay pvvars
lvs vgdisplay vgvars
cmd="$1"
shift
case "$cmd" in
free)
freebytes
;;
total)
totalbytes
;;
create)
createvol "$@"
;;
remove)
removevol "$@"
;;
device)
getdev "$@"
;;
size)
getsize "$@"
;;
up)
activatevol "$@"
;;
down)
disactivatevol "$@"
;;
status)
getstatus "$@"
;;
write)
updatevol "$@"
;;
*)
echo "unknown command"
return 1
;;
esac