aboutsummaryrefslogtreecommitdiff
path: root/utils/uvol/files/autopart.defaults
blob: b403dd6df6205ddcc7b63e88e532fb422fcd5c38 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#!/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 --bytes -q -F "$1" 2>/dev/null | while read -r start end sectors size; do
		case $start in
		*"Unpartitioned"* | *"Units:"* | *"Sector"* | *"Start"* )
			continue
			;;
		[0-9]*)
			[ "$size" -lt $((100 * 1024 * 1024)) ] && continue
			[ "$found" ] || echo "start=$start, size=$sectors"
			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