--- /dev/null
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=autopart
+PKG_VERSION:=0.1
+PKG_RELEASE:=$(AUTORELEASE)
+
+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))
--- /dev/null
+#!/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