openwrt-packages/utils/uvol/files/ubi.sh

358 lines
7.0 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}"
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