autopart: add package
authorDaniel Golle <[email protected]>
Wed, 31 Mar 2021 23:07:03 +0000 (00:07 +0100)
committerDaniel Golle <[email protected]>
Wed, 31 Mar 2021 23:14:33 +0000 (00:14 +0100)
The 'autopart' package is intended for devices with rather large
block device storage (ie. SATA or MMC).
It automatically allocates the free space on the block device used
for booting into an LVM2 physical volume.

Signed-off-by: Daniel Golle <[email protected]>
utils/autopart/Makefile [new file with mode: 0644]
utils/autopart/files/autopart [new file with mode: 0644]

diff --git a/utils/autopart/Makefile b/utils/autopart/Makefile
new file mode 100644 (file)
index 0000000..dcd211b
--- /dev/null
@@ -0,0 +1,40 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=autopart
+PKG_VERSION:=0.1
+PKG_RELEASE:=$(AUTORELEASE)
+
+PKG_MAINTAINER:=Daniel Golle <[email protected]>
+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))
diff --git a/utils/autopart/files/autopart b/utils/autopart/files/autopart
new file mode 100644 (file)
index 0000000..6d946c6
--- /dev/null
@@ -0,0 +1,77 @@
+#!/bin/sh
+
+. /lib/functions.sh
+. /lib/upgrade/common.sh
+
+OWRT_VOLUMES=owrt-volumes
+
+part_fixup() {
+       echo "write" | sfdisk --force -q -w never $1
+}
+
+get_free_area() {
+       local found=
+       sfdisk -q -F "$1" 2>/dev/null | while read start end sectors size; do
+               case $start in
+               *"Unpartitioned"* | *"Units:"* | *"Sector"* | *"Start"* )
+                       continue
+                       ;;
+               [0-9]*)
+                       case "$size" in
+                               *"M")
+                                       [ "${size%%M}" -lt 100 ] && continue
+                                       ;;
+                               *"G" | *"T")
+                                       ;;
+                               *"k" | *"b")
+                                       continue
+                                       ;;
+                       esac
+                       [ "$found" ] || echo "start=$start, size=$((end - start))"
+                       found=1
+                       ;;
+               esac
+       done
+}
+
+create_lvm_part() {
+       local disk=$1
+       local freepart
+
+       freepart="$(get_free_area $disk)"
+       if [ "$freepart" ]; then
+               echo "$freepart, type=lvm, name=$OWRT_VOLUMES" | sfdisk --force -w never -a $disk
+               partx -a $disk 1>/dev/null 2>/dev/null || true
+               return 0
+       else
+               return 1
+       fi
+}
+
+lvm_init() {
+       lvm pvcreate -f $1
+       lvm vgcreate "$2" $1
+       lvm vgs
+}
+
+autopart_init() {
+       local diskdev
+       local lvmpart
+       local diskserial
+
+       export_bootdevice && export_partdevice diskdev 0
+
+       [ "$diskdev" ] || return
+
+       [ -e "/sys/class/block/$diskdev/device/serial" ] && diskserial=$(cat /sys/class/block/$diskdev/device/serial)
+
+       part_fixup /dev/$diskdev
+       create_lvm_part /dev/$diskdev || return
+       lvmpart=$(get_partition_by_name $diskdev $OWRT_VOLUMES)
+
+       [ "$lvmpart" ] || return
+       lvm_init /dev/$lvmpart "${OWRT_VOLUMES}${diskserial}"
+}
+
+autopart_init
+exit 0