confz_fs_init (19618B)
1 # vim: ft=zsh noet ts=4 sts=4 sw=4 2 3 # 4 # confz functions for dealing with filesystem and mounting 5 # 6 7 # load the zstat builtin and keep stat external 8 zmodload -F zsh/stat b:zstat 9 10 # helper for finding disk drives by their metadata 11 fs_smartctl_probe() { 12 (($+smartctl_probed)) && (($smartctl_probed)) && return 0 13 local dev item val rest 14 typeset -g smartctl_probed 15 typeset -ga smartctl_devices 16 typeset -gA smartctl_info 17 smartctl --scan | while read dev rest; do 18 smartctl_devices+=( $dev ) 19 smartctl -i $dev | while IFS=':' read item val; do smartctl_info[${dev}:${${item:l}// /_}]=${val/# #}; done 20 done 21 smartctl_probed=1 22 } 23 24 # helper for probing devices 25 fs_blkid_probe() { 26 unset fs_blkid_output fs_blkid_result 27 typeset -gA fs_blkid_output 28 typeset -g fs_blkid_result 29 local out key val 30 fs_blkid_output=( ) 31 32 [[ -b $1 ]] || die "no such block device: ${(qqq)1}" 33 34 out=$( blkid -o export -p $1 ) 35 fs_blkid_result=$? 36 37 case $fs_blkid_result in 38 (2);; 39 (0) while IFS='=' read key val; do 40 [[ $key == *' '* ]] && die "Malformed blkid output for \"export\" format." 41 fs_blkid_output[$key]=$val 42 done <<<$out;; 43 (*) die "blkid probe failed on device: ${(qqq)1}" 44 esac 45 } 46 47 # Check that given device is formatted with given type (return 0) or blank (return 1), die otherwise 48 fs_check_type() { 49 local device fstype kind 50 device=$1 51 fstype=$2 52 kind=${3:-TYPE} # TYPE = filesystem type, PTTYPE = partition format 53 fs_blkid_probe $device 54 if (($fs_blkid_result)); then 55 # empty label 56 return 1 57 elif (( $+fs_blkid_output[$kind] )); then 58 if [[ ${fs_blkid_output[$kind]:-} == $fstype ]]; then 59 return 0 60 else 61 die "$0: non-$fstype label (${fs_blkid_output[$kind]}) already present on device: ${(qqq)device}" 62 fi 63 else 64 local -a labels 65 local k v 66 for k v in "${(kv)fs_blkid_output[@]}"; do 67 # Filter out the information about partition layout rather than content 68 case $k in 69 (DEVNAME) continue;; 70 (PART_ENTRY_*) continue;; 71 (*) labels+=( "$k=${(qqq)v}" ) 72 esac 73 done 74 if (( $#labels )); then 75 die "$0: unexpected filesystem labels present on device: ${(qqq)device} $labels[*]" 76 fi 77 # empty label 78 return 1 79 fi 80 } 81 82 # helper for listing partition table 83 fs_parted_list() { 84 unset fs_parted_start fs_parted_end fs_parted_size fs_parted_type 85 unset fs_parted_filesystem fs_parted_name fs_parted_flags 86 typeset -gA fs_parted_start fs_parted_end fs_parted_size fs_parted_type 87 typeset -gA fs_parted_filesystem fs_parted_name fs_parted_flags 88 local line got_header number out 89 local NumberE StartB StartE EndB EndE SizeB SizeE FSB FSE NameB NameE FlagsB 90 local TypeB TypeE 91 local MATCH MBEGIN MEND 92 93 [[ -b $1 ]] || die "no such block device: ${(qqq)1}" 94 95 out=$( parted --script $1 -- unit s print ) || \ 96 die "parted print of device failed: ${(qqq)1}" 97 98 got_header=0 99 while IFS= read line; do 100 if ((got_header)); then 101 number=${${line[1,$NumberE]}// } 102 fs_parted_start[$number]=${${line[$StartB,$StartE]}// } 103 fs_parted_end[$number]=${${line[$EndB,$EndE]}// } 104 fs_parted_size[$number]=${${line[$SizeB,$SizeE]}// } 105 fs_parted_flags[$number]=${line[$FlagsB,-1]} 106 107 [[ -n $TypeB ]] && \ 108 fs_parted_type[$number]=${${line[$TypeB,$TypeE]}// } 109 110 [[ -n $NameB ]] && \ 111 fs_parted_name[$number]=${${line[$NameB,$NameE]}// } 112 113 [[ -n $FSB ]] && \ 114 fs_parted_filesystem[$number]=${${line[$FSB,$FSE]}// } 115 116 elif [[ $line == Number* ]]; then 117 got_header=1 118 119 [[ $line =~ 'Number +' ]] || die "malformed header: ${(qqq)line}" 120 NumberE=$MEND 121 122 [[ $line =~ 'Start +' ]] || die "malformed header: ${(qqq)line}" 123 StartB=$MBEGIN 124 StartE=$MEND 125 126 [[ $line =~ 'End +' ]] || die "malformed header: ${(qqq)line}" 127 EndB=$MBEGIN 128 EndE=$MEND 129 130 [[ $line =~ 'Size +' ]] || die "malformed header: ${(qqq)line}" 131 SizeB=$MBEGIN 132 SizeE=$MEND 133 134 [[ $line =~ 'Flags *' ]] || die "malformed header: ${(qqq)line}" 135 FlagsB=$MBEGIN 136 137 if [[ $line =~ 'Type +' ]]; then 138 TypeB=$MBEGIN 139 TypeE=$MEND 140 fi 141 142 if [[ $line =~ 'Name +' ]]; then 143 NameB=$MBEGIN 144 NameE=$MEND 145 fi 146 147 if [[ $line =~ 'File system +' ]]; then 148 FSB=$MBEGIN 149 FSE=$MEND 150 fi 151 fi 152 done <<<"$out" 153 } 154 155 # Find disks by their IDs 156 confz_disk_id_check() { 157 # arguments: device device_model serial_number 158 if ! (($+vars[device] + $+vars[device_model] + $+vars[serial_number])); then 159 die "$0: requires one or more arguments: device device_model serial_number" 160 fi 161 162 do_command=( true ) 163 fs_smartctl_probe 164 local device 165 local -a found 166 167 for device in $smartctl_devices; do 168 if (($+vars[device])); then 169 [[ $vars[device] != $device ]] && continue 170 fi 171 if (($+vars[device_model])); then 172 [[ $vars[device_model] != $smartctl_info[${device}:device_model] ]] && continue 173 fi 174 if (($+vars[serial_number])); then 175 [[ $vars[serial_number] != $smartctl_info[${device}:serial_number] ]] && continue 176 fi 177 found+=( $device $smartctl_info[${device}:device_model] $smartctl_info[${device}:serial_number] ) 178 done 179 180 (( $#found )) || die "$0: found no matching devices" 181 (( $#found % 3 )) && die "$0: internal error parsing device information" 182 [[ $#found -ne 3 ]] && die "$0: found too many matching devices" 183 vars[device]=$found[1] 184 vars[device_model]=$found[2] 185 vars[serial_number]=$found[3] 186 } 187 188 # check for DOS-style MBR on device 189 confz_disklabel_dos_check() { 190 checkvars device 191 192 do_command=( parted --script $vars[device] -- mklabel msdos ) 193 fs_check_type $vars[device] dos PTTYPE 194 } 195 196 197 # check for GPT partition table on device 198 confz_disklabel_gpt_check() { 199 checkvars device 200 201 do_command=( parted --script $vars[device] -- mklabel gpt ) 202 fs_check_type $vars[device] gpt PTTYPE 203 } 204 205 206 # embed file in MBR 207 confz_mbr_code_check() { 208 checkvars device from 209 do_command=( dd bs=440 count=1 if=$vars[from] of=$vars[device] ) 210 dd if=$vars[device] bs=440 count=1 | cmp -s - $vars[from] 211 } 212 213 214 # check for gpt partition 215 confz_gpt_partition_check() { 216 local prev option 217 checkvars device number name 218 defvar fs ext2 219 require disklabel_gpt :device 220 fs_parted_list $vars[device] 221 (( $+vars[size] || $+vars[end] )) || die "$0: requires either size or end" 222 if [[ $vars[number] != 1 ]]; then 223 prev=$[ $vars[number] - 1 ] 224 (( $+fs_parted_start[$prev] )) || die "$0: missing preceding partition" 225 : ${vars[start]:=${fs_parted_start[$prev]}} 226 else 227 checkvars start 228 fi 229 if ! (($+vars[end])); then 230 vars[end]=$[${${vars[start]}%s} + ${${vars[size]}%s}]s 231 fi 232 if (( $+fs_parted_start[$vars[number]] )); then 233 [[ $fs_parted_name[$vars[number]] == $vars[name] ]] || \ 234 die "Partition $vars[number] has name ${(qqq)fs_parted_name[$vars[number]}, want ${(qqq)vars[name]}" 235 return 0 236 else 237 do_command=( parted --script ) 238 (($+vars[align])) && do_command+=( --align $vars[align] ) 239 do_command+=( 240 $vars[device] -- unit s 241 mkpart $vars[name] $vars[fs] $vars[start] $vars[end] 242 ) 243 (($+vars[align])) && do_command+=( 244 align-check $vars[align] $vars[number] 245 ) 246 (($+vars[options])) && for option in ${=vars[options]}; do 247 do_command+=( set $vars[number] $option on ) 248 done 249 return 1 250 fi 251 } 252 253 254 # check for primary partition 255 confz_primary_partition_check() { 256 local prev option 257 checkvars device number 258 defvar fs ext2 259 require disklabel_dos :device 260 fs_parted_list $vars[device] 261 (( $+vars[size] || $+vars[end] )) || die "$0: requires either size or end" 262 if [[ $vars[number] != 1 ]]; then 263 prev=$[ $vars[number] - 1 ] 264 (( $+fs_parted_start[$prev] )) || die "$0: missing preceding partition" 265 : ${vars[start]:=${fs_parted_start[$prev]}} 266 else 267 checkvars start 268 fi 269 if ! (($+vars[end])); then 270 vars[end]=$[${${vars[start]}%s} + ${${vars[size]}%s}]s 271 fi 272 if (( $+fs_parted_start[$vars[number]] )); then 273 return 0 274 else 275 do_command=( parted --script ) 276 (($+vars[align])) && do_command+=( --align $vars[align] ) 277 do_command+=( 278 $vars[device] -- unit s 279 mkpart primary $vars[fs] $vars[start] $vars[end] 280 ) 281 (($+vars[align])) && do_command+=( 282 align-check $vars[align] $vars[number] 283 ) 284 (($+vars[options])) && for option in ${=vars[options]}; do 285 do_command+=( set $vars[number] $option on ) 286 done 287 return 1 288 fi 289 } 290 291 292 # check for bootable flag on primary partition 293 confz_bootable_partition_check() { 294 checkvars device number 295 require disklabel_dos :device 296 fs_parted_list $vars[device] 297 (( $+fs_parted_flags[$vars[number]] )) || \ 298 die "$0: device ${(q)vars[device]} partition ${(q)vars[number]} not found" 299 if [[ $fs_parted_flags[$vars[number]] = *boot* ]]; then 300 return 0 301 else 302 do_command=( parted --script $vars[device] -- set $vars[number] boot on ) 303 return 1 304 fi 305 } 306 307 308 # create swap partition 309 confz_swap_check() { 310 checkvars device 311 312 do_command=( mkswap $vars[device] ) 313 314 fs_check_type $vars[device] swap 315 } 316 317 318 # enable swap device 319 confz_swapon_check() { 320 local out device rest 321 322 checkvars device 323 require swap :device 324 325 out=$(swapon -s) || die "$0: swapon -s comman failed" 326 while read device rest; do 327 [[ $device == $vars[device] ]] && return 0 328 done <<<$out 329 330 do_command=( swapon $vars[device] ) 331 return 1 332 } 333 334 335 # set up /dev/md* device 336 confz_mdraid_check() { 337 local line level out seen_level seen_header devices all_empty ret 338 local -a seen_devices devices device_numbers 339 local -A level_map 340 341 checkvars md_device raid_devices level 342 defvar metadata default 343 defvar bitmap none 344 345 devices=( "${(Q@)${(z)vars[raid_devices]}}" ) 346 347 level_map=( 348 linear linear 349 raid0 0 350 0 0 351 stripe 0 352 raid1 1 353 1 1 354 mirror 1 355 raid4 4 356 4 4 357 raid5 5 358 5 5 359 raid6 6 360 6 6 361 raid10 10 362 10 10 363 multipath multipath 364 mp multipath 365 faulty faulty 366 container container 367 ) 368 level=${level_map[${vars[level]}]} 369 370 for device in $devices; do 371 [[ -b $device ]] || die "$0: not a block device: ${(qqq)device}" 372 device_numbers+=( $(zstat +rdev $device) ) || die "$0: could not stat ${(qqq)device}" 373 done 374 375 if [[ -b $vars[md_device] ]]; then 376 out=$( mdadm --detail $vars[md_device] ) 377 ret=$? 378 case $ret in 379 (0) ;; 380 (1) ;; # return 1;; 381 (*) die "$0: mdadm --detail ${(qqq)vars[md_device]} returned $ret";; 382 esac 383 seen_header=0 384 while read line; do 385 if ! (($seen_header)); then 386 case $line in 387 ('Raid Level :'*) 388 seen_level=$level_map[${line#* : }];; 389 (Number*Major*Minor*RaidDevice*State) 390 seen_header=1;; 391 esac 392 else 393 seen_devices+=( $(( ${${=line}[2]} << 8 + ${${=line}[3]} )) ) 394 fi 395 done <<<$out 396 397 if (($seen_header)); then 398 [[ $level == $seen_level ]] || \ 399 die "$0: raid level mismatch." \ 400 "expected: ${(q)level} got: ${(q)seen_level}" 401 402 [[ ${(j.:.)${(o)device_numbers}} == ${(j.:.)${(o)seen_devices}} ]] || \ 403 die $0$': raid device mismatch\nexpected:' \ 404 ${(oqqq)device_numbers}$'\ngot:' \ 405 ${(oqqq)seen_devices} 406 407 return 0 408 fi 409 fi 410 411 all_empty=1 412 for device in $devices; do 413 # all devices either need to have empty labels or be linux_raid_member 414 if fs_check_type $device linux_raid_member; then 415 all_empty=0 416 fi 417 done 418 419 if (($all_empty)); then 420 # empty labels 421 do_command=( 422 mdadm --create 423 -l $level 424 --metadata=$vars[metadata] 425 --bitmap=$vars[bitmap] 426 -n $#devices 427 $vars[md_device] 428 $devices 429 ) 430 else 431 # already created 432 do_command=( mdadm --assemble $vars[md_device] $devices ) 433 fi 434 return 1 435 } 436 437 438 # set up LVM2 physical volume 439 confz_physical_volume_check() { 440 checkvars device 441 do_command=( lvm pvcreate $vars[device] ) 442 fs_check_type $vars[device] LVM2_member 443 } 444 445 446 # configure LVM2 volume group 447 confz_volume_group_check() { 448 local -A devices volumes 449 local -a vg_devices 450 local device 451 452 [[ -n ${vars[vg_name]:=${DEFAULT_VG}} ]] || \ 453 die "$0: DEFAULT_VG is unset and no 'vg_name' was passed" 454 455 checkvars vg_devices 456 457 vg_devices=( "${(Q@)${(z)vars[vg_devices]}}" ) 458 for device in $vg_devices; do 459 require physical_volume device=$device 460 done 461 462 volumes=( $(lvm vgs --noheadings -o vg_name,pv_count) ) || \ 463 die "$0: lvm vgs command returned error" 464 if ! (($+volumes[${vars[vg_name]}])); then 465 do_command=( lvm vgcreate ${vars[vg_name]} $vg_devices ) 466 return 1 467 fi 468 devices=( $(lvm pvs --noheadings -o pv_name,vg_name) ) || \ 469 die "$0: lvm pvs command returned error" 470 do_command=( lvm vgextend ${vars[vg_name]} ) 471 for device in $vg_devices; do 472 [[ $+devices[$device] == 1 && $devices[$device] == $vars[vg_name] ]] || \ 473 do_command+=( $device ) 474 done 475 (( $#do_command == 3 )) 476 } 477 478 479 # configure LVM2 logical volume 480 confz_logical_volume_check() { 481 [[ -n ${vars[vg_name]:=${DEFAULT_VG}} ]] || \ 482 die "$0: DEFAULT_VG is unset and no 'vg_name' was passed" 483 484 [[ -n ${vars[size]:=${DEFAULT_VOLUME_SIZE}} ]] || \ 485 die "$0: DEFAULT_VOLUME_SIZE is unset and no 'size' was passed" 486 487 checkvars lv_name 488 489 setvar device /dev/mapper/$vars[vg_name]-$vars[lv_name] 490 491 do_command=( 492 lvcreate 493 --name ${vars[lv_name]} 494 --size ${vars[size]} 495 ${vars[vg_name]} 496 ) 497 498 fail_reason="not a block device: ${vars[device]}" 499 [[ -b ${vars[device]} ]] 500 } 501 502 # configure LVM2 logical volume 503 confz_logical_volume_extents_check() { 504 [[ -n ${vars[vg_name]:=${DEFAULT_VG}} ]] || \ 505 die "$0: DEFAULT_VG is unset and no 'vg_name' was passed" 506 507 checkvars lv_name pv_name extents 508 509 local vg_name lv_name pv_name pvseg_start pvseg_size segtype 510 local -A found 511 pvs --segments --noheadings --separator $'\t' \ 512 -o vg_name,lv_name,pv_name,pvseg_start,pvseg_size,segtype \ 513 | while IFS=$'\t' \ 514 read vg_name lv_name pv_name pvseg_start pvseg_size segtype 515 do 516 vg_name=${vg_name/# #} # strip preceding space 517 if matchvars vg_name $vg_name lv_name $lv_name; then 518 (($#found)) && die "$0: more than one segment found" 519 if [[ $segtype != linear ]] || ! matchvars pv_name $pv_name offset $pvseg_start extents $pvseg_size; then 520 die "$0: non-matching physical layout of the volume" 521 fi 522 found[offset]=$pvseg_start 523 fi 524 done 525 unify "${(kv@)found}" \ 526 device /dev/mapper/$vars[vg_name]-$vars[lv_name] 527 528 do_command=( 529 lvcreate 530 --name ${vars[lv_name]} 531 --extents ${vars[extents]} 532 ${vars[vg_name]} 533 $vars[pv_name]:$vars[offset]-$[ $vars[offset] + $vars[extents] ] 534 ) 535 536 if ! (($#found)); then 537 fail_reason="not found in pvs output: ${vars[vg_name]}/${vars[lv_name]}" 538 return 1 539 fi 540 541 fail_reason="not a block device: ${vars[device]}" 542 [[ -b ${vars[device]} ]] 543 } 544 545 546 # create filesystem on block device 547 confz_filesystem_check() { 548 [[ -n ${vars[filesystem]:=${DEFAULT_FS}} ]] || \ 549 die "$0: DEFAULT_FS is unset and no 'filesystem' was passed" 550 551 checkvars label device filesystem 552 defvar mkfs_opts '' 553 554 [[ -b ${vars[device]} ]] || \ 555 die "$0: not a block device: ${(qqq)vars[device]}" 556 557 do_command=( 558 mkfs -t ${vars[filesystem]} 559 ) 560 case $vars[filesystem] in 561 (xfs|btrfs|ext[234]) 562 do_command+=( -L "${vars[label]}" );; 563 (reiserfs) 564 # Asks questions without -q 565 do_command+=( -l "${vars[label]}" -q );; 566 (vfat) 567 do_command+=( -n "${vars[label]}" );; 568 (*) 569 if [[ -n $vars[label] ]]; then 570 die "$0: I don't know how to set label on ${(qqq)vars[filesystem]}" 571 fi 572 ;; 573 esac 574 [[ -n $vars[mkfs_opts] ]] && do_command+=( "${(Q@)${(z)vars[mkfs_opts]}}" ) 575 do_command+=( ${vars[device]} ) 576 577 local tries # blk_out DEVNAME LABEL UUID TYPE SEC_TYPE PARTLABEL PARTUUID 578 579 tries=10 580 while ((tries)); do 581 fs_blkid_probe $vars[device] 582 [[ $fs_blkid_result == 0 ]] && break 583 tries=$[$tries - 1] 584 done 585 586 fail_reason="no blkid signature found on $vars[device]" 587 # Check if anything was detected at all 588 (( $#fs_blkid_output )) || return 1 589 590 # Check if it is a filesystem 591 [[ -z ${fs_blkid_output[TYPE]:-} && -z ${fs_blkid_output[LABEL]:-} && -z ${fs_blkid_output[UUID]:-} ]] && return 1 592 593 # Check if it matches requirements 594 [[ ${fs_blkid_output[LABEL]:-} == ${vars[label]:-} && $fs_blkid_output[TYPE] == $vars[filesystem] ]] && return 0 595 596 die "$0: filesystem already present on ${(qqq)vars[device]}!" 597 } 598 599 600 # put mountpoint for device into /etc/fstab 601 confz_fstab_check() { 602 checkvars device mountpoint filesystem 603 defvar opts noatime 604 defvar dump 0 605 defvar fstab /etc/fstab 606 if [[ $vars[filesystem] == xfs ]]; then 607 defvar pass 0 608 else 609 defvar pass 2 610 fi 611 612 local device mountpoint filesystem opts dump pass 613 sed '/^[ \t]*#/d;s/#.*//;s/[ \t]\+/ /g' $vars[fstab] | \ 614 while read device mountpoint filesystem opts dump pass; do 615 if [[ $mountpoint == ${vars[mountpoint]} ]]; then 616 [[ $device == ${vars[device]} && opts != *bind* ]] || \ 617 die "$0: $mountpoint already present" \ 618 "with different device than ${(qqq)vars[device]}" 619 620 [[ $filesystem == ${vars[filesystem]} ]] || \ 621 die "$0: $mountpoint already present" \ 622 "with different filesystem than ${(qqq)vars[filesystem]}" 623 624 [[ $opts == ${vars[opts]} ]] || \ 625 die "$0: $mountpoint already present" \ 626 "with different opts than ${(qqq)vars[opts]}" 627 628 [[ $dump == ${vars[dump]} ]] || \ 629 die "$0: $mountpoint already present" \ 630 "with different dump than ${(qqq)vars[dump]}" 631 632 [[ $pass == ${vars[pass]} ]] || \ 633 die "$0: $mountpoint already present" \ 634 "with different pass than ${(qqq)vars[pass]}" 635 636 return 0 # found matching entry 637 fi 638 done 639 640 fail_reason="no entry for ${(qqq)vars[mountpoint]} in ${(qqq)vars[fstab]}" 641 return 1 # did not find matching entry 642 } 643 644 confz_fstab_do() { 645 print -r - >>$vars[fstab] ${vars[device]}$'\t'${vars[mountpoint]}$'\t'${vars[filesystem]}$'\t'${vars[opts]}$'\t'${vars[dump]}' '${vars[pass]} 646 } 647 648 649 # make device mounted on mountpoint 650 confz_mounted_check() { 651 checkvars device mountpoint 652 653 fail_reason="could not find ${vars[device]} ${vars[mountpoint]} in /proc/mounts" 654 grep -q "^${vars[device]} ${vars[mountpoint]} " /proc/mounts 655 } 656 657 confz_mounted_do() { 658 mkdir -p ${vars[mountpoint]} || return $? 659 mount "$@" ${vars[device]} ${vars[mountpoint]} 660 } 661 662 663 # make device mounted on mountpoint 664 confz_bind_mounted_check() { 665 checkvars device origin mountpoint 666 667 fail_reason="could not find ${vars[device]} ${vars[mountpoint]} in /proc/mounts" 668 grep -q "^${vars[device]} ${vars[mountpoint]} " /proc/mounts 669 } 670 671 confz_bind_mounted_do() { 672 mkdir -p ${vars[mountpoint]} || return $? 673 mount --bind "$@" ${vars[origin]} ${vars[mountpoint]} 674 } 675 676 677 # create LVM2 logical volume, and make sure it's in fstab and mounted 678 confz_mounted_volume_check() { 679 checkvars mountpoint 680 defvar lv_name ${${${vars[mountpoint]}##/}//\//_} 681 defvar filesystem xfs 682 defvar label ${${vars[lv_name]}[1,12]} 683 defvar root / 684 685 [[ $vars[mountpoint] == /* ]] || \ 686 die "$0: mountpoint must be absolute path, got: ${(qqq)vars[mountpoint]}" 687 require logical_volume %device \?vg_name :size :lv_name 688 require filesystem :device :label :filesystem \?mkfs_opts 689 require fstab fstab=${vars[root]%/}/etc/fstab \ 690 :device :mountpoint :filesystem \?opts \?dump \?pass 691 require mounted :device mountpoint=${vars[root]%/}/${vars[mountpoint]#/} 692 693 do_command=( true ) 694 } 695 696 697 confz_syslinux_modules_check() { 698 checkvars directory 699 if ! [[ -e $vars[directory]/menu.c32 ]]; then 700 do_command=( cp -v /usr/share/syslinux/*.c32 $vars[directory]/ ) 701 return 1 702 else 703 return 0 704 fi 705 } 706 707 # install extlinux 708 confz_extlinux_check() { 709 checkvars directory 710 defvar extlinux /sbin/extlinux 711 defvar install_touch_file $vars[directory]/.extlinux_installed 712 [[ -e $vars[directory]/extlinux.conf || -e $vars[directory]/syslinux.cfg ]] || \ 713 die "no configuration file for extlinux found" 714 require syslinux_modules :directory 715 [[ -e $vars[install_touch_file] ]] 716 return $? 717 } 718 719 confz_extlinux_do() { 720 $vars[extlinux] -i -r $vars[directory] || return $? 721 touch $vars[install_touch_file] || return $? 722 } 723 724 725 # install GRUB2 726 confz_grub2_check() { 727 checkvars device 728 defvar boot_directory /boot 729 defvar install_touch_file vars[boot_directory]/.grub2${${vars[device]}//\//.} 730 [[ -e $vars[install_touch_file] ]] 731 return $? 732 } 733 734 confz_grub2_do() { 735 grub2-install --boot-directory=$vars[boot_directory] $vars[device] || return $? 736 touch $vars[install_touch_file] || return $? 737 }