From 0fd038326b554ae0a7a81c55ff512a88d469566c Mon Sep 17 00:00:00 2001 From: Christoph Date: Fri, 8 Aug 2025 22:36:51 +0200 Subject: [PATCH] Add script and documentation to expamd raid6. --- .gitignore | 1 + raid6-expand-interactive.sh | 425 ++++++++++++++++++++++++++++++++++++ raid6-expand.md | 140 ++++++++++++ raid6-expand.txt | 145 ++++++++++++ 4 files changed, 711 insertions(+) create mode 100755 raid6-expand-interactive.sh create mode 100644 raid6-expand.md create mode 100644 raid6-expand.txt diff --git a/.gitignore b/.gitignore index 1377554..66b35c6 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ *.swp +*.log diff --git a/raid6-expand-interactive.sh b/raid6-expand-interactive.sh new file mode 100755 index 0000000..78e0647 --- /dev/null +++ b/raid6-expand-interactive.sh @@ -0,0 +1,425 @@ +#!/usr/bin/env bash +set -euo pipefail + +# ========================================= +# RAID- und FS-Erweiterung (mdadm/Ext4/XFS) +# Interaktiv, Dry-Run-, Debug- und Yes-Option +# Mit Zeitstempeln, Logfile & farbigen Headern +# ========================================= + +# ---- Globale Defaults ---- +DRYRUN=0 +DEBUG=0 +ASSUME_YES=0 +FS_TYPE="ext4" # wird in prompt_inputs gesetzt; hier nur Default +LOG_FILE="./raid6-expand-$(date +%F-%H%M%S).log" + +# ---- Zeit & Logging ---- +ts() { date '+%F %T'; } +strip_ansi() { sed -r 's/\x1B\[[0-9;]*[A-Za-z]//g'; } + +log_plain() { + # Schreibt *ohne* ANSI-Farben ins Log mit Zeitstempel + { printf "[%s] %s\n" "$(ts)" "$(printf "%s" "$*" | strip_ansi)"; } >> "$LOG_FILE" +} + +# ---- Farben/Logging-Ausgaben ---- +cecho() { # $1=colorcode, $2=prefix, $3=msg... + local c="$1"; shift + local pfx="$1"; shift + printf "\e[%sm[%s] %s\e[0m\n" "$c" "$(ts)" "$pfx $*" + log_plain "$pfx $*" +} + +info() { cecho "36" "INFO " "$@"; } # cyan +warn() { cecho "33" "WARN " "$@"; } # gelb +ok() { cecho "32" "OK " "$@"; } # grün +err() { cecho "31" "ERROR" "$@"; } # rot +note() { cecho "35" "NOTE " "$@"; } # magenta + +header() { # Abschnittsüberschrift + local line="============================================================" + printf "\e[36m[%s] %s\e[0m\n" "$(ts)" "$line" + printf "\e[36m[%s] == %s ==\e[0m\n" "$(ts)" "$*" + printf "\e[36m[%s] %s\e[0m\n" "$(ts)" "$line" + log_plain "$line" + log_plain "== $* ==" + log_plain "$line" +} + +# ---- Usage ---- +usage() { + cat <<'USAGE' + +raid6-expand-interactive.sh — Vergrößert RAID-Mitglieds-Partitionen und das Array/FS + +Nutzung: + ./raid6-expand-interactive.sh [Optionen] + +Optionen: + -n, --dry-run Keine Änderungen; loggt nur, was passieren würde. + (Unterdrückt Rückfragen pro Partition; aktiviert --debug) + -d, --debug Zusätzliche Diagnosen (lsblk/blkid/sfdisk-Auszüge). + -y, --yes Bestätigt alle Rückfragen automatisch (produktiv praktisch). + -L, --log Schreibe Log nach (Default: ./raid6-expand-YYYY-MM-DD-HHMMSS.log) + -h, --help Diese Hilfe anzeigen. + +Ablauf (produktiv): + 1) Interaktive Eingaben (RAID-Device, Disks, Partitionsnummer, FS, ggf. Mountpoint) + 2) Status-Checks & Partitionstabellen-Backups + 3) Pro Platte: Partition bis maximal vergrößern (Start & Typ bleiben gleich) + 4) Nach jeder Platte: mdadm --grow --size=max + auf Resync warten + 5) Am Ende: Dateisystem vergrößern (resize2fs oder xfs_growfs) + +Voraussetzungen: + mdadm, sfdisk, lsblk, blkid, awk, partprobe, udevadm + (xfs_growfs nur, wenn FS_TYPE=xfs) + +USAGE +} + +# ---- Helfer ---- +need_bin() { command -v "$1" >/dev/null 2>&1 || { err "Fehlt: $1"; exit 1; }; } + +run() { + # Zeigt und loggt den Befehl; führt ihn in produktiv aus + printf "[%s] + %s\n" "$(ts)" "$*" | tee -a "$LOG_FILE" >/dev/null + if [[ "$DRYRUN" -eq 0 ]]; then + "$@" + fi +} + +confirm() { + # Auto-yes im Dry-Run oder wenn -y/--yes gesetzt ist, sonst interaktiv fragen + local prompt="$1" + if [[ "$DRYRUN" -eq 1 || "$ASSUME_YES" -eq 1 ]]; then + note "(auto) $prompt: yes" + return 0 + fi + read -r -p "$prompt [yes/NO] " a + if [[ "${a:-}" == "yes" ]]; then + log_plain "$prompt: yes" + return 0 + fi + log_plain "$prompt: NO" + return 1 +} + +confirm_summary() { + # Zusammenfassung IMMER bestätigen (auch im Dry-Run), außer -y/--yes + local prompt="$1" + if [[ "$ASSUME_YES" -eq 1 ]]; then + note "(auto) $prompt: yes" + return 0 + fi + read -r -p "$prompt [yes/NO] " a + if [[ "${a:-}" == "yes" ]]; then + log_plain "$prompt: yes" + return 0 + fi + log_plain "$prompt: NO" + return 1 +} + +check_clean() { + local md="$1" + if ! grep -q "$(basename "$md")" /proc/mdstat; then + err "$md nicht in /proc/mdstat gefunden." + exit 1 + fi + if ! mdadm --detail "$md" | grep -q "State : clean"; then + warn "$md ist nicht 'clean'. Details:" + mdadm --detail "$md" | sed 's/^/ /' | tee -a "$LOG_FILE" + confirm "Trotzdem fortfahren?" || exit 1 + fi +} + +wait_resync() { + local md="$1" + info "Warte auf Abschluss von Initialisierung/Resync auf $md ..." + if [[ "$DRYRUN" -eq 1 ]]; then + note "(Dry-Run) Würde auf Resync/Initialisierung warten und /proc/mdstat beobachten." + return 0 + fi + while :; do + local blk + blk=$(grep -E "^\s*$(basename "$md")" /proc/mdstat || true) + if [[ -z "$blk" ]]; then + err "$md nicht in /proc/mdstat gefunden!" + exit 1 + fi + if ! grep -Eiq "(resync|reshape|recovery|check)" /proc/mdstat; then + break + fi + printf "[%s] %s\n" "$(ts)" "$blk" | tee -a "$LOG_FILE" >/dev/null + sleep 20 + done + ok "Resync/Initialisierung abgeschlossen." +} + +backup_pt() { + local disk="$1" + local bkup="backup-$(basename "$disk")-$(date +%F-%H%M%S).sfdisk" + if [[ "$DRYRUN" -eq 1 ]]; then + note "(Dry-Run) Würde Partitionstabelle sichern: $bkup" + else + sfdisk -d "$disk" > "$bkup" + ok "Partitionstabelle gesichert: $bkup" + fi + if [[ "$DEBUG" -eq 1 ]]; then + header "DEBUG: sfdisk -d $disk" + sfdisk -d "$disk" | tee -a "$LOG_FILE" + fi +} + +# ---- Start & Typ via lsblk/blkid (robuster als sfdisk-parsing) ---- +get_part_start() { + local part="$1" + local start + start="$(lsblk -no START "$part" 2>/dev/null | head -n1 | tr -d '[:space:]')" + [[ -n "$start" ]] || { err "Konnte START für $part nicht ermitteln (lsblk)."; exit 1; } + printf "%s" "$start" +} + +get_part_type() { + local part="$1" + local ptype + ptype="$(blkid -s PART_ENTRY_TYPE -o value "$part" 2>/dev/null | head -n1 | tr -d '[:space:]' || true)" + if [[ -z "$ptype" ]]; then + ptype="$(lsblk -no PARTTYPE "$part" 2>/dev/null | head -n1 | tr -d '[:space:]' || true)" + fi + if [[ -z "$ptype" ]]; then + local line + line="$(sfdisk -d "${part%[0-9]*}" | awk -v p="$part" '$1==p {print; exit}')" + ptype="$(awk -F',' '{ + for(i=1;i<=NF;i++){ + gsub(/^ +| +$/,"",$i); + if($i ~ /^type=/){sub(/^type=/,"",$i); print $i} + } + }' <<< "$line" | tr -d '[:space:]')" + fi + [[ -n "$ptype" ]] || { err "Konnte Partitions-Typ für $part nicht ermitteln."; exit 1; } + printf "%s" "$ptype" +} + +expand_partition() { + local disk="$1" pn="$2" + local part="${disk}${pn}" + [[ -b "$part" ]] || { err "Partition $part existiert nicht."; exit 1; } + + if [[ "$DEBUG" -eq 1 ]]; then + header "DEBUG: lsblk/blkid für $part" + lsblk -no NAME,PATH,TYPE,SIZE,START,PARTTYPE "$part" | tee -a "$LOG_FILE" + blkid "$part" | tee -a "$LOG_FILE" || true + fi + + local pstart ptype + pstart="$(get_part_start "$part")" + ptype="$(get_part_type "$part")" + + warn "Geplante Änderung auf $part:" + note " Startsektor bleibt: $pstart" + note " Größe: bis maximal verfügbar" + note " Typ bleibt: $ptype" + + if [[ "$DRYRUN" -eq 1 || "$ASSUME_YES" -eq 1 ]]; then + note "(Dry-Run) Würde ${part} erweitern: Start=${pstart}, Typ=${ptype}, bis maximal verfügbar." + else + confirm "Jetzt ${part} erweitern?" || { warn "Übersprungen."; return; } + fi + + printf "[%s] + %s\n" "$(ts)" "printf ',,type=${ptype}\n' | sfdisk --no-reread --force -N ${pn} ${disk}" | tee -a "$LOG_FILE" >/dev/null + if [[ "$DRYRUN" -eq 0 ]]; then + printf ",,type=%s\n" "$ptype" | sfdisk --no-reread --force -N "$pn" "$disk" + run partprobe "$disk" || true + run udevadm settle || true + ok "Partition $part wurde bis ans Ende erweitert." + else + note "(Dry-Run) Würde Kernel neu einlesen: partprobe $disk ; udevadm settle" + fi +} + +grow_md_size() { + local md="$1" + run mdadm --grow "$md" --size=max || { :; } + if [[ "$DRYRUN" -eq 1 ]]; then + note "(Dry-Run) Würde mdadm-Grow ausführen." + fi +} + +final_fs_grow() { + local md="$1" fs="$2" mp="${3:-}" + case "$fs" in + ext4) + run resize2fs "$md" || { :; } + if [[ "$DRYRUN" -eq 1 ]]; then + note "(Dry-Run) Würde resize2fs ausführen." + fi + ;; + xfs) + [[ -n "$mp" ]] || { err "Für XFS muss ein Mountpoint angegeben werden."; exit 1; } + if ! mount | grep -qE "^$md on $mp "; then + warn "$md scheint nicht auf $mp gemountet zu sein (laut 'mount')." + mount | sed 's/^/ /' | tee -a "$LOG_FILE" + confirm "Trotzdem mit xfs_growfs $mp fortfahren?" || exit 1 + fi + run xfs_growfs "$mp" || { :; } + if [[ "$DRYRUN" -eq 1 ]]; then + note "(Dry-Run) Würde xfs_growfs ausführen." + fi + ;; + *) + err "Unbekanntes Dateisystem: $fs (erwartet: ext4 oder xfs)" + exit 1 + ;; + esac + ok "Dateisystem-Schritt abgeschlossen." +} + +# ---- Interaktive Eingabe ---- +prompt_inputs() { + echo + header "Interaktiver Modus: Eingaben sammeln" + [[ "$DRYRUN" -eq 1 ]] && note "Dry-Run aktiviert: Es werden KEINE Änderungen durchgeführt." + [[ "$DEBUG" -eq 1 ]] && note "Debug aktiviert: Zeige zusätzliche Diagnosen." + [[ "$ASSUME_YES" -eq 1 ]] && note "--yes aktiviert: Bestätige alle Rückfragen automatisch." + note "Logfile: $LOG_FILE" + + read -r -p "RAID-Device (z.B. /dev/md4): " MDDEV + [[ -n "${MDDEV:-}" ]] || { err "RAID-Device darf nicht leer sein."; exit 1; } + [[ -b "$MDDEV" ]] || { err "$MDDEV ist kein Block-Device."; exit 1; } + + echo "Physikalische Geräte (ohne Partitionsnummer), leerzeichengetrennt (z.B. /dev/sda /dev/sdb /dev/sdc /dev/sdd):" + read -r -a DISKS + [[ "${#DISKS[@]}" -ge 2 ]] || { err "Mindestens zwei Geräte angeben."; exit 1; } + for d in "${DISKS[@]}"; do + [[ -b "$d" ]] || { err "$d ist kein Block-Device."; exit 1; } + done + + read -r -p "Partitionsnummer der RAID-Partition (Standard 1): " PARTNUM + PARTNUM="${PARTNUM:-1}" + [[ "$PARTNUM" =~ ^[0-9]+$ ]] || { err "Partitionsnummer muss numerisch sein."; exit 1; } + + read -r -p "Dateisystem auf $MDDEV [ext4|xfs] (Standard ext4): " FS_TYPE + FS_TYPE="${FS_TYPE:-ext4}" + FS_TYPE="$(echo "$FS_TYPE" | tr '[:upper:]' '[:lower:]')" + if [[ "$FS_TYPE" != "ext4" && "$FS_TYPE" != "xfs" ]]; then + err "Ungültiges Dateisystem: $FS_TYPE (erlaubt: ext4, xfs)" + exit 1 + fi + + MOUNTPOINT="" + if [[ "$FS_TYPE" == "xfs" ]]; then + read -r -p "Mountpoint des XFS-Dateisystems (z.B. /mnt/raid): " MOUNTPOINT + [[ -n "$MOUNTPOINT" ]] || { err "Mountpoint für XFS erforderlich."; exit 1; } + fi + + echo + header "ZUSAMMENFASSUNG" + note "Dry-Run : $([[ "$DRYRUN" -eq 1 ]] && echo "JA" || echo "NEIN")" + note "Debug : $([[ "$DEBUG" -eq 1 ]] && echo "JA" || echo "NEIN")" + note "Auto-Yes : $([[ "$ASSUME_YES" -eq 1 ]] && echo "JA" || echo "NEIN")" + note "RAID-Device: $MDDEV" + note "Disks : ${DISKS[*]}" + note "Part.-Nr. : $PARTNUM" + note "Filesystem : $FS_TYPE" + [[ "$FS_TYPE" == "xfs" ]] && note "Mountpoint : $MOUNTPOINT" + echo + + confirm_summary "Eingaben korrekt? Fortfahren?" || { warn "Abgebrochen."; exit 0; } +} + +# ---- Argumente parsen ---- +parse_args() { + + echo + + while [[ $# -gt 0 ]]; do + case "$1" in + -n|--dry-run) DRYRUN=1; DEBUG=1; shift ;; + -d|--debug) DEBUG=1; shift ;; + -y|--yes) ASSUME_YES=1; shift ;; + -L|--log) + shift || true + [[ $# -gt 0 ]] || { err "--log erfordert einen Pfad"; exit 1; } + LOG_FILE="$1"; shift + ;; + -h|--help) usage; echo; exit 0 ;; + *) err "Unbekannte Option: $1"; usage; echo; exit 1 ;; + esac + done + + # Logfile anlegen & Kopf schreiben + touch "$LOG_FILE" 2>/dev/null || { err "Kann Logfile nicht schreiben: $LOG_FILE"; exit 1; } + header "Start: raid6-expand-interactive | Log: $LOG_FILE" +} + +# ---- Main ---- +main() { + echo + + need_bin mdadm + need_bin sfdisk + need_bin lsblk + need_bin blkid + need_bin awk + need_bin partprobe + need_bin udevadm + + prompt_inputs + [[ "$FS_TYPE" == "xfs" ]] && need_bin xfs_growfs || true + + for d in "${DISKS[@]}"; do + local p="${d}${PARTNUM}" + [[ -b "$p" ]] || { err "Erwartete Partition $p existiert nicht."; exit 1; } + done + + header "RAID-Status vor Start" + mdadm --detail "$MDDEV" | sed 's/^/ /' | tee -a "$LOG_FILE" + echo + + check_clean "$MDDEV" + confirm "Letzte Chance vor Änderungen. Weiter?" || exit 0 + echo + + for d in "${DISKS[@]}"; do + local p="${d}${PARTNUM}" + + header "Bearbeite $d / $p" + if ! mdadm --detail "$MDDEV" | grep -q " active sync .*$(basename "$p")"; then + warn "$p scheint nicht als active sync im $MDDEV gelistet zu sein." + mdadm --detail "$MDDEV" | sed 's/^/ /' | tee -a "$LOG_FILE" + confirm "Trotzdem mit $p fortfahren?" || { echo; continue; } + fi + + backup_pt "$d" + expand_partition "$d" "$PARTNUM" + grow_md_size "$MDDEV" + wait_resync "$MDDEV" + ok "Fertig mit $p." + echo + done + + header "Final: Dateisystem vergrößern" + final_fs_grow "$MDDEV" "$FS_TYPE" "${MOUNTPOINT:-}" + echo + + header "Abschluss" + lsblk -o NAME,SIZE,TYPE,MOUNTPOINT | sed 's/^/ /' | tee -a "$LOG_FILE" + echo + mdadm --detail "$MDDEV" | sed 's/^/ /' | tee -a "$LOG_FILE" + echo + df -h | sed 's/^/ /' | tee -a "$LOG_FILE" + + echo + header "Ende" + echo +} + +# ---- Einstieg ---- +parse_args "$@" +main "$@" + +# (Ende) +echo + diff --git a/raid6-expand.md b/raid6-expand.md new file mode 100644 index 0000000..c82f8e7 --- /dev/null +++ b/raid6-expand.md @@ -0,0 +1,140 @@ +Perfekt — dann schreibe ich dir jetzt einen **minimal-Risiko-Plan**, damit du dein RAID6 (`/dev/md4`) mit Ext4 sauber und ohne Datenverlust auf die volle Größe bringst. + +Ich gehe davon aus, dass: + +* `/dev/sda1`, `/dev/sdb1`, `/dev/sdc1`, `/dev/sdd1` **die RAID-Mitglieder** sind. +* Jede Platte 20 TB groß ist, die Partitionen aktuell nur 10 TB. +* Das RAID ist **gesund** (`cat /proc/mdstat` zeigt „clean“). + +--- + +## **Schritt-für-Schritt Anleitung – Minimal Risk** + +### **1. Status checken** + +Bevor wir irgendwas anfassen, prüfen wir den Status: + +```bash +cat /proc/mdstat +mdadm --detail /dev/md4 +lsblk -o NAME,SIZE,TYPE,MOUNTPOINT +``` + +Es muss **clean** sein, und die Partitionen (`sdX1`) müssen ungefähr 10 TB groß sein. + +--- + +### **2. Backup der Partitionstabelle** + +Falls wir einen falschen Startsektor erwischen, ist das RAID im Eimer. +Deshalb sichern wir die Partitionstabellen **aller** Platten: + +```bash +sfdisk -d /dev/sda > sda.part +sfdisk -d /dev/sdb > sdb.part +sfdisk -d /dev/sdc > sdc.part +sfdisk -d /dev/sdd > sdd.part +``` + +Damit kannst du im Notfall zurückschreiben: + +```bash +sfdisk /dev/sda < sda.part +``` + +--- + +### **3. Eine Platte vergrößern (nacheinander!)** + +Wir machen das **Platte für Platte**, damit immer 3 von 4 Platten voll intakt bleiben. +Beispiel für `/dev/sda`: + +1. **Startsektor merken**: + +```bash +parted /dev/sda unit s print +``` + +Notiere die **Start-Sektor-Zahl** der Partition 1 (z. B. `2048s`). + +2. **Partition löschen und neu anlegen** (nur Metadaten, keine Daten!): + +```bash +parted /dev/sda +(parted) unit s +(parted) rm 1 +(parted) mkpart primary 2048s 100% +(parted) quit +``` + +3. **Kernel über neue Partition informieren**: + +```bash +partprobe /dev/sda +``` + +--- + +### **4. RAID Resync starten** + +Nach dem Anpassen der ersten Platte muss mdadm den neuen Bereich initialisieren: + +```bash +mdadm --grow /dev/md4 --size=max +``` + +⚠️ Das kann mehrere Stunden/Tage dauern. +Fortschritt beobachten: + +```bash +watch cat /proc/mdstat +``` + +Warte, bis der Status wieder **\[UUUU] clean** ist. + +--- + +### **5. Nächste Platten** + +Wiederhole **Schritt 3** für `/dev/sdb`, dann `/dev/sdc`, dann `/dev/sdd`. +Nach jeder Platte läuft ein **Teil-Resync** – auch hier **immer abwarten**, bis es fertig ist, bevor du die nächste Platte anfässt. + +--- + +### **6. Dateisystem vergrößern** + +Wenn alle Platten angepasst und der RAID-Resync komplett abgeschlossen ist: + +```bash +resize2fs /dev/md4 +``` + +Das Ext4-Dateisystem wird dann den gesamten neuen Platz nutzen. + +--- + +### **7. Kontrolle** + +```bash +df -h /mountpunkt +lsblk +mdadm --detail /dev/md4 +``` + +Jetzt solltest du die volle Kapazität sehen. + +--- + +## **Wichtige Sicherheitsregeln** + +* Immer nur **eine Platte gleichzeitig** verändern. +* Niemals den **Startsektor** ändern! +* Während Resyncs am besten keine großen Schreiblasten. +* Falls irgendetwas nicht clean ist → erst reparieren, dann weitermachen. + +--- + +Wenn du magst, kann ich dir **ein fertiges Shell-Skript** bauen, das dir pro Platte die Startsektoren automatisch liest, die Partition neu anlegt und sicherstellt, dass du dich nicht vertippst. +Das minimiert Tippfehler und verhindert den Super-GAU. + +Willst du, dass ich dir so ein Skript direkt schreibe? diff --git a/raid6-expand.txt b/raid6-expand.txt new file mode 100644 index 0000000..9ccb3a7 --- /dev/null +++ b/raid6-expand.txt @@ -0,0 +1,145 @@ +============================================================ +Anleitung: RAID-6 Array erweitern (mdadm, GPT, ext4/xfs) +============================================================ + +Diese Anleitung beschreibt die Erweiterung eines bestehenden +RAID-6-Arrays, nachdem die einzelnen RAID-Mitgliedsplatten physisch +durch größere Platten ersetzt wurden und ein Resync durchgeführt wurde. + +ACHTUNG: +- Nur durchführen, wenn RAID in "clean"-State ist. +- Backup wichtiger Daten wird dringend empfohlen. +- Root-Rechte erforderlich. +- Beispielangaben (Gerätenamen) anpassen! + +------------------------------------------------------------ +1) Vorbereitung & Kontrolle +------------------------------------------------------------ +1.1 Prüfen, dass alle neuen, größeren Platten erkannt werden: + lsblk -o NAME,SIZE,TYPE,MOUNTPOINT + +1.2 RAID-Status prüfen: + cat /proc/mdstat + mdadm --detail /dev/mdX + +1.3 Sicherstellen, dass der Status "clean" ist. + Falls "resync" oder "recovery" läuft → warten, bis fertig. + +------------------------------------------------------------ +2) Partitionstabellen sichern +------------------------------------------------------------ +Für jedes RAID-Mitgliedsgerät: + sfdisk -d /dev/sdX > backup-sdX-YYYYMMDD.sfdisk + +------------------------------------------------------------ +3) Partitionen auf Mitgliedsplatten vergrößern +------------------------------------------------------------ +Für jede Platte: + - Startsektor unverändert lassen! + - Partition bis zum maximal verfügbaren Platz vergrößern. + - GPT-Partitionstyp unverändert lassen. + + - TYP 'A19D880F-05FC-4D3B-A006-743F0F84911E' für Linux-RAID + + +1. Vergrößern auf maximal verfügbaren Platz mit sfdisk: + + - GPT-UUID ermitteln z.bsp. für partition 1 von /dev/sda1: + + lsblk -no PARTTYPE "/dev/sda1" + + - Partition 1 con /dev/sdX vergrößern + + sfdisk --no-reread --force -N 1 /dev/sdX < + +oder + +1. Vergrößern auf maximal verfügbaren Platz mit parted: + + parted /dev/sdX + (parted) print + (parted) resizepart 1 100% + (parted) quit + +oder in einer Zeile: + + parted -s /dev/sdX resizepart 1 100% + + + +2. Danach Partitionstabelle neu einlesen: + partprobe /dev/sdX + udevadm settle + + +Bemerkung 'parted' im Vergleich zu sfdisk: + + - sfdisk ist "roh", arbeitet auf Sektorebene - super für Skripte, aber etwas sperrig für Menschen. + + - parted versteht Größenangaben wie 100%, 10TiB, etc. und ist interaktiv angenehmer. resize verändert + nur die Größe, nicht den Typcode - der Linux-Typ bleibt also bestehen. + + - Für ein Skript wäre sfdisk robuster, weil es keine Rückfragen stellt und 100 % skriptfähig ist. + +------------------------------------------------------------ +4) RAID-Array vergrößern +------------------------------------------------------------ +Nachdem alle Partitionen angepasst sind: + mdadm --grow /dev/mdX --size=max + +Anschließend auf Abschluss des internen Resync warten: + watch cat /proc/mdstat + +------------------------------------------------------------ +5) Dateisystem vergrößern +------------------------------------------------------------ +Je nach Dateisystem: + +- ext4: + resize2fs /dev/mdX + +- xfs (muss gemountet sein): + xfs_growfs + +------------------------------------------------------------ +6) Abschließende Kontrolle +------------------------------------------------------------ +- Blockgeräte prüfen: + lsblk -o NAME,SIZE,TYPE,MOUNTPOINT + +- RAID-Details: + mdadm --detail /dev/mdX + +- Dateisystemgröße: + df -h + +------------------------------------------------------------ +Hinweise +------------------------------------------------------------ +- GPT-Typcode ermitteln - z.bsp. mit + + lsblk -no PARTTYPE /dev/sdX1 + + für Linux RAID Partition (bei dir): + A19D880F-05FC-4D3B-A006-743F0F84911E + +- Wenn nur einzelne Platten ersetzt/geändert werden: + Schrittweise vorgehen: Platte ersetzen - RAID resync - nächste Platte. + +- Bei Einsatz von LUKS oder LVM: Zusätzliche Schritte für LUKS-Resize + bzw. LVM PV Resize nach dem RAID-Resize durchführen.