You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

127 lines
2.7 KiB

  1. #!/bin/sh
  2. . /lib/functions.sh
  3. . /lib/upgrade/common.sh
  4. . /usr/share/libubox/jshn.sh
  5. OWRT_VOLUMES=owrt-volumes
  6. load_partitions() {
  7. local dev="$1"
  8. json_init
  9. json_load "$(sfdisk -J "$dev" 2>/dev/null)"
  10. json_select "partitiontable" || return 1
  11. return 0
  12. }
  13. get_partition_by_name_gpt() {
  14. local label part parts node name
  15. json_get_vars label
  16. [ "$label" = "gpt" ] || return
  17. json_select "partitions" || return
  18. json_get_keys parts
  19. for part in $parts; do
  20. json_select "$part"
  21. json_get_vars node name
  22. if [ "$1" = "$name" ]; then
  23. echo "$node"
  24. break
  25. fi
  26. json_select ..
  27. done
  28. json_select ..
  29. }
  30. get_partition_by_type_mbr() {
  31. local label part parts node type
  32. json_get_vars label
  33. [ "$label" = "dos" ] || return
  34. json_select "partitions" || return
  35. json_get_keys parts
  36. for part in $parts; do
  37. json_select "$part"
  38. json_get_vars node type
  39. if [ "$1" = "$type" ]; then
  40. echo "$node"
  41. break
  42. fi
  43. json_select ..
  44. done
  45. json_select ..
  46. }
  47. part_fixup() {
  48. echo "write" | sfdisk --force -q -w never "$1" 1>/dev/null 2>/dev/null
  49. }
  50. get_free_area() {
  51. local found=
  52. sfdisk -q -F "$1" 2>/dev/null | while read -r start end sectors size; do
  53. case $start in
  54. *"Unpartitioned"* | *"Units:"* | *"Sector"* | *"Start"* )
  55. continue
  56. ;;
  57. [0-9]*)
  58. case "$size" in
  59. *"k" | *"b")
  60. continue
  61. ;;
  62. *"M")
  63. [ "${size%%.*M}" -lt 100 ] && continue
  64. ;;
  65. *"G" | *"T")
  66. ;;
  67. esac
  68. [ "$found" ] || echo "start=$start, size=$((end - start))"
  69. found=1
  70. ;;
  71. esac
  72. done
  73. }
  74. create_lvm_part() {
  75. local disk="$1"
  76. local freepart
  77. freepart="$(get_free_area "$disk")"
  78. if [ "$freepart" ]; then
  79. echo "$freepart, type=lvm, name=$OWRT_VOLUMES" | sfdisk --force -w never -a "$disk" || return 1
  80. partx -a "$disk" 1>/dev/null 2>/dev/null || true
  81. return 0
  82. else
  83. return 1
  84. fi
  85. }
  86. lvm_init() {
  87. lvm pvcreate -f "$1"
  88. lvm vgcreate "$2" "$1"
  89. lvm vgs
  90. }
  91. autopart_init() {
  92. local diskdev
  93. local lvmpart
  94. local diskserial diskhash
  95. export_bootdevice && export_partdevice diskdev 0
  96. [ "$diskdev" ] || return
  97. [ -e "/sys/class/block/$diskdev/device/serial" ] && diskserial="$(cat "/sys/class/block/$diskdev/device/serial")"
  98. [ -e "/sys/class/block/$diskdev/device/cid" ] && diskserial="$diskserial$(cat "/sys/class/block/$diskdev/device/cid")"
  99. [ "$diskserial" ] || diskserial="$(cat /proc/sys/kernel/random/uuid)"
  100. diskhash="$(echo "$diskserial" | sha256sum | cut -d' ' -f1)"
  101. part_fixup "/dev/$diskdev"
  102. create_lvm_part "/dev/$diskdev" || return
  103. load_partitions "/dev/$diskdev" || return
  104. lvmpart="$(get_partition_by_name_gpt "$OWRT_VOLUMES")"
  105. [ "$lvmpart" ] || lvmpart="$(get_partition_by_type_mbr "8e")"
  106. [ "$lvmpart" ] || return
  107. lvm_init "$lvmpart" "${OWRT_VOLUMES}-${diskhash:0:16}"
  108. }
  109. autopart_init
  110. exit 0