diff options
-rw-r--r-- | modules/dev.inc | 85 |
1 files changed, 49 insertions, 36 deletions
diff --git a/modules/dev.inc b/modules/dev.inc index 1ac57d3..f213fa0 100644 --- a/modules/dev.inc +++ b/modules/dev.inc @@ -79,53 +79,66 @@ dev_get_type() { elif [ "$( dd if="$dev" bs=1 count=8 skip=4096 2> /dev/null )" = "EFI PART" ]; then gpt=4096 fi + # Check if mbr signatur is there, no GPT label was in uevent, and no protective MBR + local t1="$( __read_mbrid "$dev" 0 1 )" if [ -z "$label" ] && [ "$number" -lt 1000 ] && [ "$number" -gt 0 ] \ - && [ "$( __read_mbrsig "$dev" 0 )" = "55aa" ]; then - # Get MBR ID - if [ "$number" -le 4 ]; then - # Primary - mbrid="$( __read_mbrid "$dev" 0 "$number" )" - else + && [ "$t1" != "ee" ] && [ "$( __read_mbrsig "$dev" 0 )" = "55aa" ]; then + # Then we consider parsing this as MBR + if [ "$number" -le 4 ]; then # 1-4 are primary partitions + # Validate start LBA matches sysfs + log_start="$( __read_mbrstart "$dev" 0 "$number" )" + if [ "$pstart" != "$log_start" ]; then + echo "Found partition $number, but start mismatch (want: $pstart found: $log_start)" >&2 + else + mbrid="$( __read_mbrid "$dev" 0 "$number" )" + return 0 + fi + else # part number 5+ -- must be logical volume in extended partition # Scan for Primary type 05, scan linked list of fake MBRs from there local no id ex_start log_id log_start next_id next_start current for no in 1 2 3 4; do id="$( __read_mbrid "$dev" 0 "$no" )" - echo "Scanning. Primary $no is type $id" >&2 [ "$id" = "05" ] && break done if [ "$id" != "05" ]; then echo "No matching extended primary partition found" >&2 - return 1 - fi - ex_start="$( __read_mbrstart "$dev" 0 "$no" )" - current="$ex_start" - no=5 # Count through logical partitions - while [ "$no" != 0 ]; do - [ "$( __read_mbrsig "$dev" "$current" )" = "55aa" ] || break - log_id="$( __read_mbrid "$dev" "$current" 1 )" - if [ "$no" = "$number" ]; then - log_start="$( __read_mbrstart "$dev" "$current" 1 )" - log_start="$(( log_start + current ))" - if [ "$pstart" != "$log_start" ]; then - echo "Found partition $no, but start mismatch (want: $pstart found: $log_start)" >&2 - return 1 + else + echo "Primary $no is extended partition" >&2 + ex_start="$( __read_mbrstart "$dev" 0 "$no" )" + current="$ex_start" + no=5 # Count through logical partitions. These start at 5. + while [ "$no" -le "$number" ]; do + if [ "$( __read_mbrsig "$dev" "$current" )" != "55aa" ]; then + echo "Unexpected end of logical partition list" >&2 + break fi - mbrid="$log_id" - break - fi - next_id="$( __read_mbrid "$dev" "$current" 2 )" - next_start="$( __read_mbrstart "$dev" "$current" 2 )" - echo "Extended id $log_id, next $next_id, $next_start" >&2 - if [ "$next_id" = "05" ] && [ "$next_start" -gt 0 ]; then - current="$(( next_start + ex_start ))" - no="$(( no + 1 ))" - else - return 1 # End of linked list - fi - done + log_id="$( __read_mbrid "$dev" "$current" 1 )" + if [ "$no" -eq "$number" ]; then + log_start="$( __read_mbrstart "$dev" "$current" 1 )" + # logical partition's start is relative to its fake MBR + log_start="$(( log_start + current ))" + if [ "$pstart" != "$log_start" ]; then + echo "Found partition $no, but start mismatch (want: $pstart found: $log_start)" >&2 + break + fi + mbrid="$log_id" + return 0 + fi + next_id="$( __read_mbrid "$dev" "$current" 2 )" + # next logical partition's fake MBR is relative to the extended partition's start + next_start="$( __read_mbrstart "$dev" "$current" 2 )" + echo "Extended id $log_id, next $next_id, $next_start" >&2 + if [ "$next_id" = "05" ] && [ "$next_start" -ge 512 ]; then + current="$(( next_start + ex_start ))" + no="$(( no + 1 ))" # Increase counter for next logical partition + else + break + fi + done + fi fi - return 0 - elif [ -n "$gpt" ]; then + fi + if [ -n "$gpt" ]; then # GPT local table_start current entries no entry_size log_start table_start="$( __read_le "$dev" "$(( gpt + 72 ))" 8 )" |