#!/bin/sh . /lib/functions.sh . /lib/upgrade/common.sh . /usr/share/libubox/jshn.sh OWRT_VOLUMES=owrt-volumes load_partitions() { local dev="$1" json_init json_load "$(sfdisk -J "$dev" 2>/dev/null)" json_select "partitiontable" || return 1 return 0 } get_partition_by_name_gpt() { local label part parts node name json_get_vars label [ "$label" = "gpt" ] || return json_select "partitions" || return json_get_keys parts for part in $parts; do json_select "$part" json_get_vars node name if [ "$1" = "$name" ]; then echo "$node" break fi json_select .. done json_select .. } get_partition_by_type_mbr() { local label part parts node type json_get_vars label [ "$label" = "dos" ] || return json_select "partitions" || return json_get_keys parts for part in $parts; do json_select "$part" json_get_vars node type if [ "$1" = "$type" ]; then echo "$node" break fi json_select .. done json_select .. } part_fixup() { echo "write" | sfdisk --force -q -w never "$1" 1>/dev/null 2>/dev/null } get_free_area() { local found= sfdisk -q -F "$1" 2>/dev/null | while read -r start end sectors size; do case $start in *"Unpartitioned"* | *"Units:"* | *"Sector"* | *"Start"* ) continue ;; [0-9]*) case "$size" in *"k" | *"b") continue ;; *"M") [ "${size%%.*M}" -lt 100 ] && continue ;; *"G" | *"T") ;; 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" || return 1 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 diskhash export_bootdevice && export_partdevice diskdev 0 [ "$diskdev" ] || return [ -e "/sys/class/block/$diskdev/device/serial" ] && diskserial="$(cat "/sys/class/block/$diskdev/device/serial")" [ -e "/sys/class/block/$diskdev/device/cid" ] && diskserial="$diskserial$(cat "/sys/class/block/$diskdev/device/cid")" [ "$diskserial" ] || diskserial="$(cat /proc/sys/kernel/random/uuid)" diskhash="$(echo "$diskserial" | sha256sum | cut -d' ' -f1)" part_fixup "/dev/$diskdev" create_lvm_part "/dev/$diskdev" || return load_partitions "/dev/$diskdev" || return lvmpart="$(get_partition_by_name_gpt "$OWRT_VOLUMES")" [ "$lvmpart" ] || lvmpart="$(get_partition_by_type_mbr "8e")" [ "$lvmpart" ] || return lvm_init "$lvmpart" "${OWRT_VOLUMES}-${diskhash:0:16}" } autopart_init exit 0