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>lilik-openwrt-22.03
@ -0,0 +1,37 @@ | |||
include $(TOPDIR)/rules.mk | |||
PKG_NAME:=ap_config | |||
PKG_VERSION:=2021-03-21 | |||
PKG_RELEASE:=1 | |||
PKG_BUILD_PARALLEL:=1 | |||
PKG_INSTALL:=1 | |||
include $(INCLUDE_DIR)/package.mk | |||
define Package/ac_server | |||
SECTION:=utils | |||
CATEGORY:=Utilities | |||
TITLE:=ac_server | |||
DEPENDS:=+libaxl +libopenssl +libmariadbclient | |||
endef | |||
define Package/ac_client | |||
SECTION:=utils | |||
CATEGORY:=Utilities | |||
TITLE:=ac_client | |||
DEPENDS:=+libaxl +libopenssl | |||
endef | |||
define Package/ac_server/install | |||
$(INSTALL_DIR) $(1)/usr/sbin | |||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/ac_server $(1)/usr/sbin | |||
endef | |||
define Package/ap_client/install | |||
$(INSTALL_DIR) $(1)/usr/sbin | |||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/ac_client $(1)/usr/sbin | |||
endef | |||
$(eval $(call BuildPackage,ac_server)) | |||
$(eval $(call BuildPackage,ac_client)) |
@ -0,0 +1 @@ | |||
/usr/src/ap_config/.git |
@ -1,40 +0,0 @@ | |||
include $(TOPDIR)/rules.mk | |||
PKG_NAME:=autopart | |||
PKG_VERSION:=0.1 | |||
PKG_RELEASE:=$(AUTORELEASE) | |||
PKG_MAINTAINER:=Daniel Golle <daniel@makrotopia.org> | |||
PKG_LICENSE:=GPL-2.0-or-later | |||
include $(INCLUDE_DIR)/package.mk | |||
define Package/autopart | |||
SECTION:=utils | |||
CATEGORY:=Utilities | |||
SUBMENU:=Disc | |||
TITLE:=Automatically initialize LVM partition | |||
DEPENDS:=+lvm2 +partx-utils +sfdisk | |||
PKGARCH=all | |||
endef | |||
define Package/autopart/description | |||
Automatically allocate the GPT partition for LVM and initialize it | |||
on first boot. | |||
endef | |||
define Build/Prepare | |||
endef | |||
define Build/Configure | |||
endef | |||
define Build/Compile | |||
endef | |||
define Package/autopart/install | |||
$(INSTALL_DIR) $(1)/etc/uci-defaults | |||
$(INSTALL_BIN) ./files/autopart $(1)/etc/uci-defaults/30-autopart | |||
endef | |||
$(eval $(call BuildPackage,autopart)) |
@ -0,0 +1,42 @@ | |||
include $(TOPDIR)/rules.mk | |||
PKG_NAME:=modbus-utils | |||
PKG_VERSION:=2013-07-31 | |||
PKG_RELEASE=$(PKG_SOURCE_VERSION) | |||
PKG_SOURCE_PROTO:=git | |||
PKG_SOURCE_URL:=https://github.com/Krzysztow/modbus-utils.git | |||
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) | |||
PKG_SOURCE_VERSION:=c569dc0a11a1bedf3a8080fe4a1696de93e386ab | |||
# PKG_MIRROR_HASH:=3aed4146e06bd9f9bcc271824c6b1d75d1fc2a0bd980f2b729c3b4755c6f70a8 | |||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 | |||
PKG_FIXUP:=autoreconf | |||
PKG_BUILD_PARALLEL:=1 | |||
PKG_INSTALL:=1 | |||
PKG_MAINTAINER:=Daniel Golle <daniel@makrotopia.org> | |||
# supposed based on statement that source is based on libmodbus testcases | |||
PKG_LICENSE:=GPL-3.0+ LGPL-2.1+ | |||
include $(INCLUDE_DIR)/package.mk | |||
include $(INCLUDE_DIR)/nls.mk | |||
define Package/modbus-utils | |||
SECTION:=utils | |||
CATEGORY:=Utilities | |||
TITLE:=Modbus client/server utils | |||
DEPENDS:=+libmodbus | |||
endef | |||
define Package/modbus-utils/description | |||
endef | |||
define Package/modbus-utils/install | |||
$(INSTALL_DIR) $(1)/usr/bin | |||
# $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/mbrecorder $(1)/usr/bin/ | |||
endef | |||
$(eval $(call BuildPackage,modbus-utils)) |
@ -0,0 +1,73 @@ | |||
include $(TOPDIR)/rules.mk | |||
PKG_NAME:=uvol | |||
PKG_VERSION:=0.2 | |||
PKG_RELEASE:=$(AUTORELEASE) | |||
PKG_MAINTAINER:=Daniel Golle <daniel@makrotopia.org> | |||
PKG_LICENSE:=GPL-2.0-or-later | |||
include $(INCLUDE_DIR)/package.mk | |||
define Package/autopart | |||
SECTION:=utils | |||
CATEGORY:=Utilities | |||
SUBMENU:=Disc | |||
TITLE:=Automatically initialize LVM partition | |||
DEPENDS:=+lvm2 +partx-utils +sfdisk | |||
PKGARCH=all | |||
endef | |||
define Package/autopart/description | |||
Automatically allocate the GPT partition for LVM and initialize it | |||
on first boot. | |||
endef | |||
define Package/uvol | |||
SECTION:=utils | |||
CATEGORY:=Utilities | |||
SUBMENU:=Disc | |||
TITLE:=OpenWrt UBI/LVM volume abstraction | |||
PKGARCH=all | |||
endef | |||
define Package/uvol/description | |||
'uvol' is tool to automate storage volume handling on embedded | |||
devices in a generic way. | |||
Also install the 'autopart' package to easily make use of 'uvol' on | |||
block-storage based devices. | |||
Examples: | |||
uvol create example_volume_1 256MiB rw | |||
uvol up example_volume_1 | |||
uvol device example_volume_1 | |||
uvol create example_volume_2 9812733 ro | |||
cat example_volume_2.squashfs | uvol write example_volume_2 9812733 | |||
uvol up example_volume_2 | |||
uvol device example_volume_2 | |||
endef | |||
define Build/Prepare | |||
endef | |||
define Build/Configure | |||
endef | |||
define Build/Compile | |||
endef | |||
define Package/autopart/install | |||
$(INSTALL_DIR) $(1)/etc/uci-defaults | |||
$(INSTALL_BIN) ./files/autopart.defaults $(1)/etc/uci-defaults/30-autopart | |||
endef | |||
define Package/uvol/install | |||
$(INSTALL_DIR) $(1)/usr/sbin $(1)/usr/libexec/uvol | |||
$(INSTALL_BIN) ./files/uvol $(1)/usr/sbin | |||
$(INSTALL_BIN) ./files/ubi.sh $(1)/usr/libexec/uvol/20-ubi.sh | |||
$(INSTALL_BIN) ./files/lvm.sh $(1)/usr/libexec/uvol/50-lvm.sh | |||
endef | |||
$(eval $(call BuildPackage,autopart)) | |||
$(eval $(call BuildPackage,uvol)) |
@ -0,0 +1,195 @@ | |||
#!/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 |
@ -0,0 +1,160 @@ | |||
#!/bin/sh | |||
test -e /sys/class/ubi/version || return 0 | |||
read 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 ebsize < "/sys/devices/virtual/ubi/${ubidev}/eraseblock_size" | |||
freebytes() { | |||
read availeb < "/sys/devices/virtual/ubi/${ubidev}/avail_eraseblocks" | |||
echo $((availeb * ebsize)) | |||
} | |||
totalbytes() { | |||
read totaleb < "/sys/devices/virtual/ubi/${ubidev}/total_eraseblocks" | |||
echo $((totaleb * ebsize)) | |||
} | |||
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 | |||
basename "$voldir" | |||
done | |||
} | |||
needs_ubiblock() { | |||
local voldev="$1" | |||
local volname | |||
read volname < "/sys/devices/virtual/ubi/${ubidev}/${voldev}/name" | |||
case "$volname" in | |||
uvol-ro-*) | |||
return 0 | |||
;; | |||
esac | |||
return 1 | |||
} | |||
getstatus() { | |||
local voldev=$(getdev "$@") | |||
[ "$voldev" ] || return 2 | |||
needs_ubiblock $voldev && [ ! -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=$(getdev "$@") | |||
[ "$voldev" ] || return 2 | |||
if needs_ubiblock $voldev ; then | |||
echo "/dev/ubiblock${voldev:3}" | |||
else | |||
echo "/dev/$voldev" | |||
fi | |||
} | |||
createvol() { | |||
local mode | |||
local existdev=$(getdev "$1") | |||
[ "$existdev" ] && return 17 | |||
case "$3" in | |||
ro) | |||
mode=ro | |||
;; | |||
rw) | |||
mode=rw | |||
;; | |||
*) | |||
return 22 | |||
;; | |||
esac | |||
ubimkvol /dev/$ubidev -N "uvol-$mode-$1" -s "$2" | |||
} | |||
removevol() { | |||
local voldev=$(getdev "$@") | |||
[ "$voldev" ] || return 2 | |||
local volnum=${voldev#${ubidev}_} | |||
ubirmvol /dev/$ubidev -n $volnum | |||
} | |||
activatevol() { | |||
local voldev=$(getdev "$@") | |||
[ "$voldev" ] || return 2 | |||
needs_ubiblock $voldev || return 0 | |||
[ -e "/dev/ubiblock${voldev:3}" ] && return 0 | |||
ubiblock --create /dev/$voldev | |||
} | |||
disactivatevol() { | |||
local voldev=$(getdev "$@") | |||
[ "$voldev" ] || return 2 | |||
needs_ubiblock $voldev || return 0 | |||
[ -e "/dev/ubiblock${voldev:3}" ] || return 0 | |||
ubiblock --remove /dev/$voldev | |||
} | |||
updatevol() { | |||
local voldev=$(getdev "$@") | |||
[ "$voldev" ] || return 2 | |||
[ "$2" ] || return 22 | |||
needs_ubiblock $voldev || 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 | |||
} | |||
cmd="$1" | |||
shift | |||
case "$cmd" in | |||
free) | |||
freebytes | |||
;; | |||
total) | |||
totalbytes | |||
;; | |||
create) | |||
createvol "$@" | |||
;; | |||
remove) | |||
removevol "$@" | |||
;; | |||
device) | |||
getuserdev "$@" | |||
;; | |||
size) | |||
getsize "$@" | |||
;; | |||
up) | |||
activatevol "$@" | |||
;; | |||
down) | |||
disactivatevol "$@" | |||
;; | |||
status) | |||
getstatus "$@" | |||
;; | |||
write) | |||
updatevol "$@" | |||
;; | |||
*) | |||
echo "unknown command" | |||
return 1 | |||
;; | |||
esac |
@ -0,0 +1,9 @@ | |||
#!/bin/sh | |||
uvol_backend= | |||
for backend in /usr/libexec/uvol/*.sh; do | |||
total=$($backend total) | |||
[ "$total" ] && uvol_backend=$backend | |||
done | |||
flock -x /tmp/run/uvol.lock $uvol_backend "$@" |