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