* auto-created meta volume Automatically create volume '.meta' sized 0.01% of the total space managed by uvol, the minimum size being 4 MiB. This volume should be used to keep metadata about stored volumes, such as container runtime configuration (in /var/run/uvol/.meta/uxc) or the database of installed container packages. * configurable LVM volume group Allow setting volume group to be used by uvol using UCI. This is useful on devices which do not boot off the device which should be used for uvol and hence cannot make use of autopart and physical volume detection based on kernel cmdline. Use option vg_name in uvol section of fstab UCI config package. Signed-off-by: Daniel Golle <daniel@makrotopia.org>
358 lines
7 KiB
Bash
358 lines
7 KiB
Bash
#!/bin/sh
|
|
|
|
cmd="$1"
|
|
shift
|
|
|
|
if [ "$cmd" = "name" ]; then
|
|
echo "UBI"
|
|
return 0
|
|
fi
|
|
|
|
test -e /sys/class/ubi/version || return 0
|
|
read -r ubiver < /sys/class/ubi/version
|
|
[ "$ubiver" = "1" ] || return 1
|
|
test -e /sys/devices/virtual/ubi || return 0
|
|
|
|
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))
|
|
}
|
|
|
|
totalbytes() {
|
|
read -r totaleb < "/sys/devices/virtual/ubi/${ubidev}/total_eraseblocks"
|
|
echo $((totaleb * ebsize))
|
|
}
|
|
|
|
getdev() {
|
|
local voldir volname
|
|
for voldir in "/sys/devices/virtual/ubi/${ubidev}/${ubidev}_"*; do
|
|
read -r volname < "${voldir}/name"
|
|
case "$volname" in
|
|
uvol-[rw][owpd]-$1)
|
|
basename "$voldir"
|
|
break
|
|
;;
|
|
*)
|
|
continue
|
|
;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
vol_is_mode() {
|
|
local voldev="$1"
|
|
local volname
|
|
read -r volname < "/sys/devices/virtual/ubi/${ubidev}/${voldev}/name"
|
|
case "$volname" in
|
|
uvol-$2-*)
|
|
return 0
|
|
;;
|
|
esac
|
|
return 1
|
|
}
|
|
|
|
getstatus() {
|
|
local voldev
|
|
voldev="$(getdev "$@")"
|
|
[ "$voldev" ] || return 2
|
|
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
|
|
}
|
|
|
|
getsize() {
|
|
local voldev
|
|
voldev="$(getdev "$@")"
|
|
[ "$voldev" ] || return 2
|
|
cat "/sys/devices/virtual/ubi/${ubidev}/${voldev}/data_bytes"
|
|
}
|
|
|
|
getuserdev() {
|
|
local voldev
|
|
voldev="$(getdev "$@")"
|
|
[ "$voldev" ] || return 2
|
|
if vol_is_mode "$voldev" ro ; then
|
|
echo "/dev/ubiblock${voldev:3}"
|
|
elif vol_is_mode "$voldev" rw ; then
|
|
echo "/dev/$voldev"
|
|
fi
|
|
}
|
|
|
|
mkubifs() {
|
|
local tmp_mp
|
|
tmp_mp="$(mktemp -d)"
|
|
mount -t ubifs "$1" "$tmp_mp" || return $?
|
|
umount "$tmp_mp" || return $?
|
|
rmdir "$tmp_mp" || return $?
|
|
return 0
|
|
}
|
|
|
|
createvol() {
|
|
local mode ret voldev
|
|
voldev=$(getdev "$@")
|
|
[ "$voldev" ] && return 17
|
|
case "$3" in
|
|
ro|wo)
|
|
mode=wo
|
|
;;
|
|
rw)
|
|
mode=wp
|
|
;;
|
|
*)
|
|
return 22
|
|
;;
|
|
esac
|
|
ubimkvol "/dev/$ubidev" -N "uvol-$mode-$1" -s "$2" || return $?
|
|
ret=$?
|
|
[ $ret -eq 0 ] || return $ret
|
|
voldev="$(getdev "$@")"
|
|
ubiupdatevol -t "/dev/$voldev" || return $?
|
|
[ "$mode" = "wp" ] || return 0
|
|
mkubifs "/dev/$voldev" || return $?
|
|
uvol_uci_add "$1" "/dev/$voldev" "rw"
|
|
ubirename "/dev/$ubidev" "uvol-wp-$1" "uvol-wd-$1" || return $?
|
|
}
|
|
|
|
removevol() {
|
|
local voldev volnum
|
|
voldev=$(getdev "$@")
|
|
[ "$voldev" ] || return 2
|
|
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() {
|
|
local voldev
|
|
voldev="$(getdev "$@")"
|
|
[ "$voldev" ] || return 2
|
|
vol_is_mode "$voldev" rw && return 0
|
|
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" || return $?
|
|
ubiblock --create "/dev/$voldev" || return $?
|
|
return 0
|
|
elif vol_is_mode "$voldev" wd; then
|
|
ubirename "/dev/$ubidev" "uvol-wd-$1" "uvol-rw-$1" || return $?
|
|
block_hotplug add "$voldev"
|
|
return 0
|
|
fi
|
|
}
|
|
|
|
disactivatevol() {
|
|
local voldev
|
|
voldev="$(getdev "$@")"
|
|
[ "$voldev" ] || return 2
|
|
vol_is_mode "$voldev" rd && return 0
|
|
vol_is_mode "$voldev" wd && return 0
|
|
vol_is_mode "$voldev" wo && return 22
|
|
vol_is_mode "$voldev" wp && return 16
|
|
if vol_is_mode "$voldev" ro; then
|
|
/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
|
|
}
|
|
|
|
updatevol() {
|
|
local voldev
|
|
voldev="$(getdev "$@")"
|
|
[ "$voldev" ] || return 2
|
|
[ "$2" ] || return 22
|
|
vol_is_mode "$voldev" wo || return 22
|
|
ubiupdatevol -s "$2" "/dev/$voldev" -
|
|
ubiblock --create "/dev/$voldev"
|
|
uvol_uci_add "$1" "/dev/ubiblock${voldev:3}" "ro"
|
|
ubiblock --remove "/dev/$voldev"
|
|
ubirename "/dev/$ubidev" "uvol-wo-$1" "uvol-rd-$1"
|
|
}
|
|
|
|
listvols() {
|
|
local volname volmode volsize json_output json_notfirst
|
|
if [ "$1" = "-j" ]; then
|
|
json_output=1
|
|
shift
|
|
echo "["
|
|
fi
|
|
for voldir in "/sys/devices/virtual/ubi/${ubidev}/${ubidev}_"*; do
|
|
read -r volname < "$voldir/name"
|
|
case "$volname" in
|
|
uvol-[rw][wod]*)
|
|
read -r volsize < "$voldir/data_bytes"
|
|
;;
|
|
*)
|
|
continue
|
|
;;
|
|
esac
|
|
volmode="${volname:5:2}"
|
|
volname="${volname:8}"
|
|
[ "${volname:0:1}" = "." ] && continue
|
|
if [ "$json_output" = "1" ]; then
|
|
[ "$json_notfirst" = "1" ] && echo ","
|
|
echo -e "\t{"
|
|
echo -e "\t\t\"name\": \"$volname\","
|
|
echo -e "\t\t\"mode\": \"$volmode\","
|
|
echo -e "\t\t\"size\": $volsize"
|
|
echo -n -e "\t}"
|
|
json_notfirst=1
|
|
else
|
|
echo "$volname $volmode $volsize"
|
|
fi
|
|
done
|
|
|
|
if [ "$json_output" = "1" ]; then
|
|
[ "$json_notfirst" = "1" ] && echo
|
|
echo "]"
|
|
fi
|
|
}
|
|
|
|
bootvols() {
|
|
local volname volmode volsize voldev fstype
|
|
for voldir in "/sys/devices/virtual/ubi/${ubidev}/${ubidev}_"*; do
|
|
read -r volname < "$voldir/name"
|
|
voldev="$(basename "$voldir")"
|
|
fstype=
|
|
case "$volname" in
|
|
uvol-ro-*)
|
|
ubiblock --create "/dev/$voldev" || return $?
|
|
;;
|
|
*)
|
|
continue
|
|
;;
|
|
esac
|
|
volmode="${volname:5:2}"
|
|
volname="${volname:8}"
|
|
done
|
|
}
|
|
|
|
detect() {
|
|
local volname voldev volmode voldev fstype tmpdev=""
|
|
for voldir in "/sys/devices/virtual/ubi/${ubidev}/${ubidev}_"*; do
|
|
read -r volname < "$voldir/name"
|
|
voldev="$(basename "$voldir")"
|
|
fstype=
|
|
case "$volname" in
|
|
uvol-r[od]-*)
|
|
if ! [ -e "/dev/ubiblock${voldev:3}" ]; then
|
|
ubiblock --create "/dev/$voldev" || return $?
|
|
fi
|
|
case "$volname" in
|
|
uvol-rd-*)
|
|
tmpdev="$tmpdev $voldev"
|
|
;;
|
|
esac
|
|
;;
|
|
*)
|
|
continue
|
|
;;
|
|
esac
|
|
volmode="${volname:5:2}"
|
|
volname="${volname:8}"
|
|
done
|
|
|
|
uvol_uci_init
|
|
|
|
for voldir in "/sys/devices/virtual/ubi/${ubidev}/${ubidev}_"*; do
|
|
read -r volname < "$voldir/name"
|
|
voldev="$(basename "$voldir")"
|
|
case "$volname" in
|
|
uvol-[rw][wod]*)
|
|
true
|
|
;;
|
|
*)
|
|
continue
|
|
;;
|
|
esac
|
|
volmode="${volname:5:2}"
|
|
volname="${volname:8}"
|
|
case "$volmode" in
|
|
"ro" | "rd")
|
|
uvol_uci_add "$volname" "/dev/ubiblock${voldev:3}" "ro"
|
|
;;
|
|
"rw" | "wd")
|
|
uvol_uci_add "$volname" "/dev/${voldev}" "rw"
|
|
;;
|
|
esac
|
|
done
|
|
|
|
uvol_uci_commit
|
|
|
|
for voldev in $tmpdev ; do
|
|
ubiblock --remove "/dev/$voldev" || return $?
|
|
done
|
|
}
|
|
|
|
case "$cmd" in
|
|
align)
|
|
echo "$ebsize"
|
|
;;
|
|
free)
|
|
freebytes
|
|
;;
|
|
total)
|
|
totalbytes
|
|
;;
|
|
detect)
|
|
detect
|
|
;;
|
|
boot)
|
|
bootvols
|
|
;;
|
|
list)
|
|
listvols "$@"
|
|
;;
|
|
create)
|
|
createvol "$@"
|
|
;;
|
|
remove)
|
|
removevol "$@"
|
|
;;
|
|
device)
|
|
getuserdev "$@"
|
|
;;
|
|
size)
|
|
getsize "$@"
|
|
;;
|
|
up)
|
|
activatevol "$@"
|
|
;;
|
|
down)
|
|
disactivatevol "$@"
|
|
;;
|
|
status)
|
|
getstatus "$@"
|
|
;;
|
|
write)
|
|
updatevol "$@"
|
|
;;
|
|
*)
|
|
echo "unknown command"
|
|
return 1
|
|
;;
|
|
esac
|