From 87ac99146e7e46f0ccf6f82f3a8a5cce04b664c3 Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Thu, 1 Apr 2021 00:07:03 +0100 Subject: [PATCH] autopart: add package 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 --- utils/autopart/Makefile | 40 ++++++++++++++++++ utils/autopart/files/autopart | 77 +++++++++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 utils/autopart/Makefile create mode 100644 utils/autopart/files/autopart diff --git a/utils/autopart/Makefile b/utils/autopart/Makefile new file mode 100644 index 000000000..dcd211ba8 --- /dev/null +++ b/utils/autopart/Makefile @@ -0,0 +1,40 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=autopart +PKG_VERSION:=0.1 +PKG_RELEASE:=$(AUTORELEASE) + +PKG_MAINTAINER:=Daniel Golle +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 index 000000000..6d946c699 --- /dev/null +++ b/utils/autopart/files/autopart @@ -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