From 6edb8a970e17a895d44c3b1401fbf9d02a1b7716 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 24 Apr 2023 09:45:58 +0200 Subject: Add support for machines mounts that span multiple physical devices --- doc/manual.cli | 6 ++++++ init | 68 ++++++++++++++++++++++++++++++++++++++-------------------- 2 files changed, 51 insertions(+), 23 deletions(-) diff --git a/doc/manual.cli b/doc/manual.cli index 5187e87..a994e9f 100644 --- a/doc/manual.cli +++ b/doc/manual.cli @@ -280,6 +280,12 @@ confirm over-provisioning, format the disk as \c{btrfs}, and label it as # ^D # Exit shell and reboot. \ +To create a single \c{btrfs} disk that spans multiple physical devices: + +\ +# mkfs.btrfs -L buildos.machines -d single -m single /dev/sda /dev/sdb +\ + \h#config-net|Network| Network is configured via DHCP. Initially, all Ethernet interfaces that have diff --git a/init b/init index 0eed64d..f7bd6f5 100755 --- a/init +++ b/init @@ -327,7 +327,8 @@ echo -n '' >$fstab l= state= -machines= +declare -A machines +machines_mode= while read l || [ -n "$l" ]; do d="$(sed -re 's/.*NAME=\"([^\"]+)\".*/\1/' <<<"$l")" t="$(sed -re 's/.*FSTYPE=\"([^\"]*)\".*/\1/' <<<"$l")" @@ -386,42 +387,29 @@ while read l || [ -n "$l" ]; do if [ "$l" = "machines" ]; then # Single mount. # - if [ -n "$machines" ]; then + if [ "$machines_mode" = "multiple" ]; then error "multiple disks labeled with buildos.machines/machines.*" fi m=/build/machines/default - machines="single" + machines["$m"]="${machines["$m"]} $d" + + machines_mode="single" else # Multiple mounts. # - if [ "$machines" = "single" ]; then + if [ "$machines_mode" = "single" ]; then error "multiple disks labeled with buildos.machines/machines.*" fi n="$(sed -n -re 's/^machines\.([^ ]+)$/\1/p' <<<"$l")" m="/build/machines/$n" - machines="multiple" - fi + machines["$m"]="${machines["$m"]} $d" - info "mounting $d (buildos.$l) on $m" - - # Check it. - # - if ! btrfs check -p "$d"; then - info "$d (buildos.$l) has errors; run btrfs check -p --repair $d" - error + machines_mode="multiple" fi - o="defaults,noatime,nodiratime,user_subvol_rm_allowed" - echo "$d $m btrfs $o 0 0" >>$fstab - - # Mount it and change the owner of the filesystem root. - # - mkdir -p "$m" - mount -t btrfs -o "$o" "$d" "$m" - chown build:build "$m" - + info "will be mounting $d (buildos.$l) on $m" continue fi done < <(lsblk --pairs --paths --output NAME,FSTYPE,LABEL) @@ -437,13 +425,47 @@ if [ -z "$state" ]; then error fi -if [ -z "$machines" ]; then +if [ "${#machines[@]}" -eq 0 ]; then info "no disks labaled with buildos.machines* among:" lsblk --paths --output NAME,TYPE,FSTYPE,SIZE,LABEL,UUID info "consider formatting and/or labelling a suitable disk" error fi +for m in "${!machines[@]}"; do + + ds="${machines["$m"]}" # Array-like list of devices. + + info "mounting $ds on $m" + + # Check the devices and collect them in options. + # + fd= + o= + for d in $ds; do + if ! btrfs check -p "$d"; then + info "$d has errors; run btrfs check -p --repair $d" + error + fi + + if [ -z "$fd" ]; then + fd="$d" + o="device=$d" + else + o="$o,device=$d" + fi + done + + o="$o,defaults,noatime,nodiratime,user_subvol_rm_allowed" + echo "$fd $m btrfs $o 0 0" >>$fstab + + # Mount it and change the owner of the filesystem root. + # + mkdir -p "$m" + mount -t btrfs -o "$o" "$fd" "$m" + chown build:build "$m" +done + # Create /build/tftp. We make it a size-limited tmpfs since potentially- # compromized VMs will be able to upload to. # -- cgit v1.1