commit 81de27190947d4e15fadc485e971efb8bc525690
parent 672365e1bb751a10c79d3c342aaaa27c0e903332
Author: Jan Pobrislo <ccx@webprojekty.cz>
Date: Fri, 3 Jul 2015 03:30:38 +0200
imporved parted listing parser, gpt support
Diffstat:
1 file changed, 120 insertions(+), 12 deletions(-)
diff --git a/zsh-functions/confz_fs_init b/zsh-functions/confz_fs_init
@@ -30,22 +30,73 @@ fs_blkid_probe() {
# helper for listing partition table
fs_parted_list() {
- unset fs_parted_start fs_parted_end fs_parted_size fs_parted_type fs_parted_other
- typeset -gA fs_parted_start fs_parted_end fs_parted_size fs_parted_type fs_parted_other
- local out number start end size type other
+ unset fs_parted_start fs_parted_end fs_parted_size fs_parted_type
+ unset fs_parted_filesystem fs_parted_name fs_parted_flags
+ typeset -gA fs_parted_start fs_parted_end fs_parted_size fs_parted_type
+ typeset -gA fs_parted_filesystem fs_parted_name fs_parted_flags
+ local line got_header number
+ local NumberE StartB StartE EndB EndE SizeB SizeE FSB FSE NameB NameE FlagsB
+ local TypeB TypeE
[[ -b $1 ]] || die "no such block device: ${(qqq)1}"
out=$( parted --script $1 -- unit s print ) || \
die "parted print of device failed: ${(qqq)1}"
- while read number start end size type other; do
- [[ $number == [0-9]* ]] || continue
- fs_parted_start[$number]=$start
- fs_parted_end[$number]=$end
- fs_parted_size[$number]=$size
- fs_parted_type[$number]=$type
- fs_parted_other[$number]=$other
+ got_header=0
+ while IFS= read line; do
+ if ((got_header)); then
+ number=${${line[1,$NumberE]}// }
+ fs_parted_start[$number]=${${line[$StartB,$StartE]}// }
+ fs_parted_end[$number]=${${line[$EndB,$EndE]}// }
+ fs_parted_size[$number]=${${line[$SizeB,$SizeE]}// }
+ fs_parted_flags[$number]=${line[$FlagsB,-1]}
+
+ [[ -n $TypeB ]] && \
+ fs_parted_type[$number]=${${line[$TypeB,$TypeE]}// }
+
+ [[ -n $NameB ]] && \
+ fs_parted_name[$number]=${${line[$NameB,$NameE]}// }
+
+ [[ -n $FSB ]] && \
+ fs_parted_filesystem[$number]=${${line[$FSB,$FSE]}// }
+
+ elif [[ line == Number* ]]; then
+ got_header=1
+
+ [[ $line =~ 'Number +' ]] || die "malformed header: ${(qqq)line}"
+ NumberE=$MEND
+
+ [[ $line =~ 'Start +' ]] || die "malformed header: ${(qqq)line}"
+ StartB=$MBEGIN
+ StartE=$MEND
+
+ [[ $line =~ 'End +' ]] || die "malformed header: ${(qqq)line}"
+ EndB=$MBEGIN
+ EndE=$MEND
+
+ [[ $line =~ 'Size +' ]] || die "malformed header: ${(qqq)line}"
+ SizeB=$MBEGIN
+ SizeE=$MEND
+
+ [[ $line =~ 'Flags +' ]] || die "malformed header: ${(qqq)line}"
+ FlagsB=$MBEGIN
+
+ if [[ $line =~ 'Type +' ]]; then
+ TypeB=$MBEGIN
+ TypeE=$MEND
+ fi
+
+ if [[ $line =~ 'Name +' ]]; then
+ NameB=$MBEGIN
+ NameE=$MEND
+ fi
+
+ if [[ $line =~ 'File system +' ]]; then
+ FSB=$MBEGIN
+ FSE=$MEND
+ fi
+ fi
done <<<"$out"
}
@@ -67,6 +118,23 @@ confz_disklabel_dos_check() {
}
+# check for GPT partition table on device
+confz_disklabel_gpt_check() {
+ checkvars device
+
+ fs_blkid_probe $vars[device]
+ if (($fs_blkid_result)); then
+ # empty label
+ do_command=( parted --script $vars[device] -- mklabel gpt )
+ return 1
+ elif [[ ${fs_blkid_output[PTTYPE]:-} == gpt ]]; then
+ return 0
+ else
+ die "$0: non-GPT label already present on device: ${(qqq)vars[device]}"
+ fi
+}
+
+
# embed file in MBR
confz_mbr_code_check() {
checkvars device from
@@ -78,6 +146,46 @@ confz_mbr_code_check() {
}
+# check for gpt partition
+confz_gpt_partition_check() {
+ local prev option
+ checkvars device number name
+ defvar fs ext2
+ require disklabel_gpt :device
+ fs_parted_list $vars[device]
+ (( $+vars[size] || $+vars[end] )) || die "$0: requires either size or end"
+ if [[ $vars[number] != 1 ]]; then
+ prev=$[ $vars[number] - 1 ]
+ (( $+fs_parted_start[$prev] )) || die "$0: missing preceding partition"
+ : ${vars[start]:=${fs_parted_start[$prev]}}
+ else
+ checkvars start
+ fi
+ if ! (($+vars[end])); then
+ vars[end]=$[${${vars[start]}%s} + ${${vars[size]}%s}]s
+ fi
+ if (( $+fs_parted_start[$vars[number]] )); then
+ [[ $fs_parted_name[$vars[number]] == $vars[name] ]] || \
+ die "Partition $vars[number] has name ${(qqq)fs_parted_name[$vars[number]}, want ${(qqq)vars[name]}"
+ return 0
+ else
+ do_command=( parted --script )
+ (($+vars[align])) && do_command+=( --align $vars[align] )
+ do_command+=(
+ $vars[device] -- unit s
+ mkpart $vars[name] $vars[fs] $vars[start] $vars[end]
+ )
+ (($+vars[align])) && do_command+=(
+ align-check $vars[align] $vars[number]
+ )
+ (($+vars[options])) && for option in ${(z)vars[options]}; do
+ do_command+=( set $vars[number] $option on )
+ done
+ return 1
+ fi
+}
+
+
# check for primary partition
confz_primary_partition_check() {
local prev option
@@ -121,9 +229,9 @@ confz_bootable_partition_check() {
checkvars device number
require disklabel_dos :device
fs_parted_list $vars[device]
- (( $+fs_parted_other[$vars[number]] )) || \
+ (( $+fs_parted_flags[$vars[number]] )) || \
die "$0: device ${(q)vars[device]} partition ${(q)vars[number]} not found"
- if [[ $fs_parted_other[$vars[number]] = *boot* ]]; then
+ if [[ $fs_parted_flags[$vars[number]] = *boot* ]]; then
return 0
else
do_command=( parted --script $vars[device] -- set $vars[number] boot on )