Aktionen

Linux VM Festplatte im laufenden Betrieb vergrößern Universalskript mit und ohne LVM oder LUKS: Unterschied zwischen den Versionen

Aus znilwiki

 
Zeile 160: Zeile 160:
</source>
</source>
und noch ausführbar machen:<br>
und noch ausführbar machen:<br>
  chmod +x addiskspaceluks.sh
  chmod +x adddiskspaceluks.sh
<br>
<br>
<br>
<br>

Aktuelle Version vom 27. Mai 2026, 22:03 Uhr

Changelog;

  • 15.05.2026 erste Version

Vorwort

Ich hatte heute meine neue Anleitung für Zabbix und Ubuntu geschrieben. Da gibt es einen Abschnitt um später im Betrieb die Festplatte im laufenden Betrieb zu vergrößern.
Denn hatte ich angefangen anzupassen damit das ganze neben VMware auch unter Proxmox oder Hyper-V funktioniert.
Und dann hatte ich die Idee es als vollautomatisches Skript zu machen.
Das Skript ist ausnahmsweise mal nicht von Hand entstanden sondern in einer langen Gemini-Sitzung, also KI generiert.
Die erste Version die 100% funktioniert war recht schnell gemacht, das ganze dann auch noch mit LUKS zum laufen zu bringen hat etwas länger gedauert.

Das Skirpt funktioniert mit und ohne LVM. Wenn mit LVM wird auch noch geprüft ob LUKS im Einsatz ist. Dabei sollte es sowohl bei direkter Verschlüsselung (also ganze Festplatte) als auch wenn nur eine Partition verschlüsselt ist funktionieren. Es fragt dann nach dem jeweiligen Passwort/Passphrase des verschlüsselten Bereichs. Sind mehr als eine verschlüsselte Festplatte im Einsatz, fragt er auch entsprechend oft. Also auch bei den Festplatten wo nichts zu tun ist, das schadet aber nicht.

Dis Skripte funktionieren mit ext2 / ext3 / ext4 und XFS Dateisystemen.


Version A: Universalskript mit LUKS

nano adddiskspaceluks.sh

Inhalt:

#!/bin/bash

# Prüfen auf Root-Rechte
if [ "$EUID" -ne 0 ]; then
  echo "Bitte als root ausführen."
  exit 1
fi

echo "--- Schritt 1: SCSI Rescan (alle Controller) ---"
for host_path in /sys/class/scsi_host/host*; do
    host_name=$(cat "$host_path/proc_name")
    echo "Rescanning $host_name (${host_path##*/})..."

    # Neue Geräte suchen
    [ -e "$host_path/scan" ] && echo "- - -" > "$host_path/scan"

    # Größenänderungen bestehender Geräte finden
    find /sys/devices/ -name rescan | grep "/${host_path##*/}/" | while read -r r; do
        echo 1 > "$r"
    done
done

echo -e "\n--- Schritt 2: Analyse und Vergrößerung der Datenträger ---"

# Wir laden die Disks in ein echtes Bash-Array, um I/O-Interferenzen der LVM-Tools komplett auszuschließen
mapfile -t disks < <(lsblk -dnio NAME,TYPE | grep "disk" | awk '{print $1}')

for dev in "${disks[@]}"; do
    disk="/dev/$dev"
    echo "========================================"
    echo "Untersuche Datenträger: $disk"
    echo "========================================"

    # 1. PRÜFUNG: Ist die nackte Festplatte direkt verschlüsselt oder ein LVM (ohne Partitionen)?
    is_raw_luks=false
    is_raw_lvm=false

    if blkid "$disk" | grep -qi "crypto_LUKS"; then
        is_raw_luks=true
    elif pvs --noheadings -o pv_name "$disk" &>/dev/null; then
        is_raw_lvm=true
    fi

    if [ "$is_raw_luks" = true ] || [ "$is_raw_lvm" = true ]; then
        echo "  -> Datenträger wird direkt (ohne Partitionstabelle) verwendet."
        target_dev="$disk"

        if [ "$is_raw_luks" = true ] ; then
            # Sucht gezielt nach dem crypt-Device direkt unter DIESER disk
            luks_name=$(lsblk -nlo NAME,TYPE "$disk" | grep "crypt" | awk '{print $1}' | head -n1)
            if [ -n "$luks_name" ]; then
                echo "  Geöffneter Raw-LUKS-Container gefunden: /dev/mapper/$luks_name"
                echo "  Vergrößere LUKS-Container..."
                cryptsetup resize "$luks_name" --batch-mode
                target_dev="/dev/mapper/$luks_name"
            else
                echo "  WARNUNG: Raw-LUKS-Container ist geschlossen! Überspringe."
                continue
            fi
        fi

        # --- LVM Check auf Raw-Device ---
        if pvs --noheadings -o pv_name "$target_dev" &>/dev/null; then
            echo "  LVM auf Raw-Device erkannt: Vergrößere Physical Volume..."
            pvresize "$target_dev"

            vg_name=$(pvs --noheadings -o vg_name "$target_dev" | xargs)
            lv_name=$(lvs "$vg_name" --noheadings -o lv_name --sort -lv_size | head -n1 | xargs)
            if [ -n "$lv_name" ]; then
                lv_path="/dev/${vg_name}/${lv_name}"
                echo "  Vergrößere Logical Volume $lv_path und Dateisystem..."
                lvextend -l +100%FREE -r "$lv_path"
            fi
        else
            # --- Non-LVM Resize ---
            echo "  Kein LVM: Vergrößere Dateisystem direkt..."
            lsblk -f "$target_dev" | grep -qi "xfs" && xfs_growfs "$target_dev" || resize2fs "$target_dev"
        fi

        continue # Wichtig: Direkt zur nächsten Disk im Array springen
    fi


    # 2. ABLAUF: Klassisch mit Partitionstabelle
    last_part_num=$(lsblk -nlo PARTN,TYPE "$disk" | grep "part" | awk '{print $1}' | sort -rn | head -n1)

    if [ -z "$last_part_num" ]; then
        echo "  Keine Partitionen oder bekannten Dateisysteme auf $disk gefunden, überspringe."
        continue
    fi

    partition="${disk}${last_part_num}"
    [[ "$disk" =~ [0-9]$ ]] && partition="${disk}p${last_part_num}"

    echo "  Letzte Partition identifiziert: $partition (Nummer $last_part_num)"

    # Versuch die Partition zu vergrößern
    growpart "$disk" "$last_part_num" 2>/dev/null
    growpart_status=$?

    if [ $growpart_status -eq 0 ] || [ $growpart_status -eq 1 ]; then
        target_dev="$partition"

        # --- LUKS Check auf Partition ---
        if blkid "$partition" | grep -qi "crypto_LUKS"; then
            echo "  LUKS-Verschlüsselung auf Partition $partition erkannt."
            luks_name=$(lsblk -nlo NAME,TYPE "$partition" | grep "crypt" | awk '{print $1}' | head -n1)

            if [ -n "$luks_name" ]; then
                echo "  Geöffneter LUKS-Container gefunden: /dev/mapper/$luks_name"
                echo "  Vergrößere LUKS-Container..."
                cryptsetup resize "$luks_name" --batch-mode
                target_dev="/dev/mapper/$luks_name"
            else
                echo "  WARNUNG: LUKS-Container ist geschlossen! Überspringe."
                continue
            fi
        fi

        # --- LVM Check auf Partition ---
        if pvs --noheadings -o pv_name "$target_dev" &>/dev/null; then
            echo "  LVM erkannt: Vergrößere Physical Volume..."
            pvresize "$target_dev"

            vg_name=$(pvs --noheadings -o vg_name "$target_dev" | xargs)
            lv_name=$(lvs "$vg_name" --noheadings -o lv_name --sort -lv_size | head -n1 | xargs)
            if [ -n "$lv_name" ]; then
                lv_path="/dev/${vg_name}/${lv_name}"
                echo "  Vergrößere Logical Volume $lv_path und Dateisystem..."
                lvextend -l +100%FREE -r "$lv_path"
            fi
        else
            # --- Non-LVM Resize ---
            echo "  Kein LVM: Vergrößere Dateisystem direkt..."
            lsblk -f "$target_dev" | grep -qi "xfs" && xfs_growfs "$target_dev" || resize2fs "$target_dev"
        fi
    fi
done

echo -e "\nFertig."

und noch ausführbar machen:

chmod +x adddiskspaceluks.sh



Beispielausgabe: Vergrößern der Festplatte sdb von 1 auf 1,5TB,
sda ist ebenfalls verschlüsselt, wurde aber nicht geändert.

--- Schritt 1: SCSI Rescan (alle Controller) ---
Rescanning virtio_scsi (host0)...
Rescanning virtio_scsi (host1)...
Rescanning ata_piix (host2)...
Rescanning ata_piix (host3)...

--- Schritt 2: Analyse und Vergrößerung der Datenträger ---
========================================
Untersuche Datenträger: /dev/sda
========================================
  Letzte Partition identifiziert: /dev/sda3 (Nummer 3)
NOCHANGE: partition 3 could only be grown by 2015 [fudge=2048]
  LUKS-Verschlüsselung auf Partition /dev/sda3 erkannt.
  Geöffneter LUKS-Container gefunden: /dev/mapper/dm_crypt-0
  Vergrößere LUKS-Container...
Geben Sie die Passphrase für »/dev/sda3« ein:
  LVM erkannt: Vergrößere Physical Volume...
  Physical volume "/dev/mapper/dm_crypt-0" changed
  1 physical volume(s) resized or updated / 0 physical volume(s) not resized
  Vergrößere Logical Volume /dev/ubuntu-vg/ubuntu-lv und Dateisystem...
  New size (7406 extents) matches existing size (7406 extents).
  File system ext4 found on ubuntu-vg/ubuntu-lv mounted at /.
  Size of logical volume ubuntu-vg/ubuntu-lv unchanged from <28,93 GiB (7406 extents).
  Extending file system ext4 to <28,93 GiB (31063015424 bytes) on ubuntu-vg/ubuntu-lv...
resize2fs /dev/ubuntu-vg/ubuntu-lv
resize2fs 1.47.2 (1-Jan-2025)
Das Dateisystem ist bereits 7583744 (4k) Blöcke lang. Nichts zu tun!

resize2fs done
  Extended file system ext4 on ubuntu-vg/ubuntu-lv.
  Logical volume ubuntu-vg/ubuntu-lv successfully resized.
========================================
Untersuche Datenträger: /dev/sdb
========================================
  -> Datenträger wird direkt (ohne Partitionstabelle) verwendet.
  Geöffneter Raw-LUKS-Container gefunden: /dev/mapper/luks_sdb
  Vergrößere LUKS-Container...
Geben Sie die Passphrase für »/dev/sdb« ein:
  LVM auf Raw-Device erkannt: Vergrößere Physical Volume...
  Physical volume "/dev/mapper/luks_sdb" changed
  1 physical volume(s) resized or updated / 0 physical volume(s) not resized
  Vergrößere Logical Volume /dev/luks_sdb/opt und Dateisystem...
  File system ext4 found on luks_sdb/opt mounted at /opt.
  Size of logical volume luks_sdb/opt changed from 1023,98 GiB (262139 extents) to <1,50 TiB (393211 extents).
  Extending file system ext4 to <1,50 TiB (1649246470144 bytes) on luks_sdb/opt...
resize2fs /dev/luks_sdb/opt
resize2fs 1.47.2 (1-Jan-2025)
Dateisystem bei /dev/luks_sdb/opt ist auf /opt eingehängt; Online-Größenänderung ist
erforderlich
old_desc_blocks = 128, new_desc_blocks = 192
Das Dateisystem auf /dev/luks_sdb/opt is nun 402648064 (4k) Blöcke lang.

resize2fs done
  Extended file system ext4 on luks_sdb/opt.
  Logical volume luks_sdb/opt successfully resized.

Fertig.

Version B: Simplere Version

Wer ohne Verschlüsselung auskommt kann diese Version verwenden:

nano adddiskspace.sh

Inhalt:

#!/bin/bash

# Prüfen auf Root-Rechte
if [ "$EUID" -ne 0 ]; then 
  echo "Bitte als root ausführen."
  exit 1
fi

echo "--- Schritt 1: SCSI Rescan (alle Controller) ---"
for host_path in /sys/class/scsi_host/host*; do
    host_name=$(cat "$host_path/proc_name")
    echo "Rescanning $host_name (${host_path##*/})..."
    
    # Neue Geräte suchen
    [ -e "$host_path/scan" ] && echo "- - -" > "$host_path/scan"
    
    # Größenänderungen bestehender Geräte finden
    find /sys/devices/ -name rescan | grep "/${host_path##*/}/" | while read -r r; do
        echo 1 > "$r"
    done
done

echo -e "\n--- Schritt 2: Analyse und Vergrößerung der Datenträger ---"

# Alle Blockgeräte finden (sdX, nvmeXnX, virtblkX), die Partitionen haben
# Wir filtern nach 'disk', um keine Loop-Devices oder Partitionen selbst zu greifen
lsblk -dnio NAME,TYPE | grep "disk" | awk '{print $1}' | while read -r dev; do
    disk="/dev/$dev"
    echo "Untersuche $disk..."

    # Alle Partitionen dieser Disk finden (sortiert nach Partitionsnummer, absteigend)
    # Wir wollen die LETZTE Partition vergrößern
    last_part_num=$(lsblk -nlo PARTN,TYPE "$disk" | grep "part" | awk '{print $1}' | sort -rn | head -n1)

    if [ -z "$last_part_num" ]; then
        echo "  Keine Partitionen auf $disk gefunden, überspringe."
        continue
    fi

    partition="${disk}${last_part_num}"
    # Sonderbehandlung für NVMe oder MMC (z.B. p1 am Ende)
    [[ "$disk" =~ [0-9]$ ]] && partition="${disk}p${last_part_num}"

    echo "  Letzte Partition identifiziert: $partition (Nummer $last_part_num)"

    # Versuch die Partition zu vergrößern (growpart gibt 0 bei Erfolg, 1 bei "kein Platz" zurück)
    growpart "$disk" "$last_part_num" 2>/dev/null
    if [ $? -eq 0 ]; then
        echo "  Partition $partition wurde vergrößert."
        
        # --- LVM Check ---
        # Prüfen, ob diese Partition ein LVM Physical Volume ist
        if pvs --noheadings -o pv_name "$partition" &>/dev/null; then
            echo "  LVM erkannt: Vergrößere Physical Volume..."
            pvresize "$partition"
            
            # Finde alle Logical Volumes auf diesem PV und vergrößere das LETZTE LV
            # (Wir nehmen hier an, dass das LV vergrößert werden soll, das den Platz braucht)
            lv_path=$(lvs --noheadings -o lv_path --sort -lv_size | head -n1 | xargs)
            if [ -n "$lv_path" ]; then
                echo "  Vergrößere Logical Volume $lv_path und Dateisystem..."
                lvextend -l +100%FREE -r "$lv_path"
            fi
        else
            # --- Non-LVM Resize ---
            echo "  Kein LVM: Vergrößere Dateisystem direkt..."
            # Erkennt automatisch ext2/3/4 oder XFS
            lsblk -f "$partition" | grep -qi "xfs" && xfs_growfs "$partition" || resize2fs "$partition"
        fi
    else
        echo "  Kein freier Platz nach Partition $last_part_num gefunden oder bereits maximal groß."
    fi
done

echo -e "\nFertig."

und noch Ausführbar machen:

chmod +x adddiskspace.sh



Beispiel 1: System mit LVM:

--- Schritt 1: SCSI Rescan (alle Controller) ---
Rescanning virtio_scsi (host0)...
Rescanning ata_piix (host1)...
Rescanning ata_piix (host2)...

--- Schritt 2: Analyse und Vergrößerung der Datenträger ---
Untersuche /dev/sda...
  Letzte Partition identifiziert: /dev/sda3 (Nummer 3)
CHANGED: partition=3 start=4198400 old: size=79685632 end=83884031 new: size=100659167 end=104857566
  Partition /dev/sda3 wurde vergrößert.
  LVM erkannt: Vergrößere Physical Volume...
  Physical volume "/dev/sda3" changed
  1 physical volume(s) resized or updated / 0 physical volume(s) not resized
  Vergrößere Logical Volume /dev/ubuntu-vg/ubuntu-lv und Dateisystem...
  File system ext4 found on ubuntu-vg/ubuntu-lv mounted at /.
  Size of logical volume ubuntu-vg/ubuntu-lv changed from <19,00 GiB (4863 extents) to <48,00 GiB (12287 extents).
  Extending file system ext4 to <48,00 GiB (51535413248 bytes) on ubuntu-vg/ubuntu-lv...
resize2fs /dev/ubuntu-vg/ubuntu-lv
resize2fs 1.47.2 (1-Jan-2025)
Dateisystem bei /dev/ubuntu-vg/ubuntu-lv ist auf / eingehängt; Online-Größenänderung ist
erforderlich
old_desc_blocks = 3, new_desc_blocks = 6
Das Dateisystem auf /dev/ubuntu-vg/ubuntu-lv is nun 12581888 (4k) Blöcke lang.

resize2fs done
  Extended file system ext4 on ubuntu-vg/ubuntu-lv.
  Logical volume ubuntu-vg/ubuntu-lv successfully resized.

Fertig.


Beispiel 2: System ohne LVM:

--- Schritt 1: SCSI Rescan (alle Controller) ---
Rescanning virtio_scsi (host0)...
Rescanning ata_piix (host1)...
Rescanning ata_piix (host2)...

--- Schritt 2: Analyse und Vergrößerung der Datenträger ---
Untersuche /dev/sda...
  Letzte Partition identifiziert: /dev/sda2 (Nummer 2)
CHANGED: partition=2 start=4096 old: size=67102720 end=67106815 new: size=83881951 end=83886046
  Partition /dev/sda2 wurde vergrößert.
  Kein LVM: Vergrößere Dateisystem direkt...
resize2fs 1.47.2 (1-Jan-2025)
Dateisystem bei /dev/sda2 ist auf / eingehängt; Online-Größenänderung ist
erforderlich
old_desc_blocks = 4, new_desc_blocks = 5
Das Dateisystem auf /dev/sda2 is nun 10485243 (4k) Blöcke lang.


Fertig.

Kommentare

Loading comments...