Wie erstelle ich ein kleines Disk-Image mit großen Partitionen?

7

Ich erstelle ein Disk-Image für ein eingebettetes System (das auf einer 4-GB-SD-Karte gespeichert werden soll). Ich möchte, dass das System zwei Partitionen hat. Eine 'Root'-Partition (200 MB) und eine' Data'-Partition (800 MB).

Ich erstelle eine leere 1 GB Datei mit dd. Dann benutze ich parted, um die Partitionen einzurichten. Ich montiere sie jeweils in einem Loop-Gerät und formatiere sie dann. ext2 für 'Root' ext4 für 'Data'. Fügen Sie mein Root-Dateisystem zur 'Root'-Partition hinzu und lassen Sie' Data 'leer.

Hier liegt das Problem. Ich habe jetzt ein 1-GB-Bild mit nur 200 MB Daten. Sollte ich theoretisch nicht in der Lage sein, das Image auf 201 MB zu kürzen und das Dateisystem trotzdem einbindbar zu machen? Leider habe ich dies nicht festgestellt.

Ich erinnere mich, dass ich in der Vergangenheit eine Build-Umgebung von Freescale verwendet habe, in der 30-MB-Images erstellt wurden, die Partitionen für die Verwendung einer gesamten 4-GB-SD-Karte enthält. Leider kann ich zu diesem Zeitpunkt nicht herausfinden, wie sie das gemacht haben.

Ich habe das Format auf der Festplatte für das ext-Dateisystem gelesen, und wenn nach dem ersten Superblock keine Daten mehr vorhanden sind (außer Backup-Superblöcken und nicht verwendeten Blocktabellen), dachte ich, ich könnte dort abschneiden.

Wenn ich das mache, flippt das Montagesystem leider aus. Ich kann dann FSCK ausführen, die Superblöcke und Blocktabellen wiederherstellen und es dann problemlos bereitstellen. Ich denke einfach nicht, dass das notwendig sein sollte.

Vielleicht könnte ein anderes Dateisystem funktionieren? Irgendwelche Ideen?

Vielen Dank,

bearbeiten

Partition geändert, um Dateisystem zu lesen. Die Partition ist noch vorhanden und ändert sich nicht, aber das Dateisystem wird nach dem Abschneiden des Images zerstört.

bearbeiten

Ich habe festgestellt, dass das Dateisystem, wenn ich die Datei auf eine Größe abschneide, die nur größer ist als der erste Satz von 'Daten'-Partitions-Superblock- und Inode / Block-Tabellen (irgendwo im Datenblock-Bereich), ohne dass dies möglich ist ein fsck, um den Rest der Superblöcke und Block / Inode-Tabellen wiederherzustellen

AllenKll
quelle
Ich verstehe den Titel nicht. Ich denke, es sollte lauten: „Wie verkleinere ich ein Dateisystem und eine Partition?
Strg-Alt-Delor
Würde es Ihnen etwas ausmachen zu klären, wenn Sie sagen ... * Ich habe nicht festgestellt, dass dies der Fall ist ... * Was haben Sie als der Fall befunden? Und Sie sollten wahrscheinlich aufhören zu verwenden parted- bei diesem Programm geht es nicht um Partitionstabellen, sondern um ein seltsames Zusammenspiel von Partitionstabellen + Dateisystemen. Im Allgemeinen ist der Versuch, beide zu kombinieren, schlecht. Partitionstabellen und Dateisysteme existieren völlig unabhängig voneinander.
Mikeserv
Möchten Sie dieses Bild mit 800 MB Speicherplatz erstellen, damit Sie es auf SD-Karten kopieren können? Aber Sie möchten beim Speichern des Bildes keinen Platz verschwenden.
Strg-Alt-Delor
Die Partitionstabelle befindet sich am Kopf der Festplatte - nirgendwo anders. Sie können die Partitionstabelle mit wipefsund abrufen und ddeinfach tardie fs-Daten oder was auch immer aktualisieren und beim Erstellen des Images entpacken.
Mikeserv
@richard Ich möchte das Dateisystem nicht verkleinern. nur das Bild davon. Ich möchte, dass es die tatsächliche Größe
behält

Antworten:

4

Zum einen wird eine spärliche Bild auf eine Festplatte zu schreiben nicht in irgendetwas , sondern die Gesamtheit der Größe dieser Bilddatei führen - Löcher und alle - für den Datenträger. Dies liegt daran , Handhabung von Dateien mit geringer Dichte ist eine Qualität des Dateisystems - und ein Raw - Gerät (wie dem, an das Sie das Bild schreiben) hat keine solche Sache noch . Eine Datei mit geringer Dichte kann gespeichert von einem Dateisystem gesteuert sicher und sicher auf einem Medium , das versteht Sparse - Dateien (wie ein ext4 - Gerät) , aber sobald Sie es schreiben , es wird alles einhüllen , dass Sie es wollen. Sie sollten also entweder Folgendes tun:

  1. Speichern Sie es einfach auf einem fs, das spärliche Dateien versteht, bis Sie bereit sind, es zu schreiben.

  2. Machen Sie es zwei Schichten tief ...

    • Das heißt, schreiben Sie Ihr Hauptbild in eine Datei, erstellen Sie ein anderes übergeordnetes Bild mit einem fs, das spärliche Dateien versteht, und kopieren Sie dann Ihr Bild in das übergeordnete Bild und ...

    • Wenn es Zeit ist, das Bild zu schreiben, schreiben Sie zuerst Ihr übergeordnetes Bild und dann Ihr Hauptbild.

So geht's 2:

  • Erstellen Sie eine 1 GB Sparse-Datei ...

    dd bs=1kx1k seek=1k of=img </dev/null
  • Schreiben Sie zwei ext4Partitionen in die Partitionstabelle: 1 200 MB, 2 800 MB ...

    printf '%b\n\n\n\n' n '+200M\nn\n' 'w\n\c' | fdisk img
  • Erstellen Sie zwei ext4Dateisysteme auf einem -PGerät mit künstlicher Schleife und legen Sie eine Kopie des zweiten auf das erste ...

    sudo sh -c '
        for p in "$(losetup --show -Pf img)p"*        ### the for loop will iterate
        do    mkfs.ext4 "$p"                          ### over fdisks two partitions
              mkdir -p ./mnt/"${p##*/}"               ### and mkfs, then mount each
              mount "$p" ./mnt/"${p##*/}"             ### on dirs created for them
        done; sync; cd ./mnt/*/                       ### next we cp a sparse image
        cp --sparse=always "$p" ./part2               ### of part2 onto part1
        dd bs=1kx1k count=175 </dev/zero >./zero_fill ### fill out part1 w/ zeroes
        sync; cd ..; ls -Rhls .                       ### sync, and list contents
        umount */; losetup -d "${p%p*}"               ### last umount, destroy
        rm -rf loop*p[12]/ '                          ### loop devs and mount dirs

    mke2fs 1.42.12 (29-Aug-2014)
    Discarding device blocks: done
    Creating filesystem with 204800 1k blocks and 51200 inodes
    Filesystem UUID: 2f8ae02f-4422-4456-9a8b-8056a40fab32
    Superblock backups stored on blocks:
        8193, 24577, 40961, 57345, 73729
    
    Allocating group tables: done
    Writing inode tables: done
    Creating journal (4096 blocks): done
    Writing superblocks and filesystem accounting information: done
    
    mke2fs 1.42.12 (29-Aug-2014)
    Discarding device blocks: done
    Creating filesystem with 210688 4k blocks and 52752 inodes
    Filesystem UUID: fa14171c-f591-4067-a39a-e5d0dac1b806
    Superblock backups stored on blocks:
        32768, 98304, 163840
    
    Allocating group tables: done
    Writing inode tables: done
    Creating journal (4096 blocks): done
    Writing superblocks and filesystem accounting information: done
    
    175+0 records in
    175+0 records out
    183500800 bytes (184 MB) copied, 0.365576 s, 502 MB/s
    ./:
    total 1.0K
    1.0K drwxr-xr-x 3 root root 1.0K Jul 16 20:49 loop0p1
       0 drwxr-xr-x 2 root root   40 Jul 16 20:42 loop0p2
    
    ./loop0p1:
    total 176M
     12K drwx------ 2 root root  12K Jul 16 20:49 lost+found
     79K -rw-r----- 1 root root 823M Jul 16 20:49 part2
    176M -rw-r--r-- 1 root root 175M Jul 16 20:49 zero_fill
    
    ./loop0p1/lost+found:
    total 0
    
    ./loop0p2:
    total 0
  • Das ist eine Menge Ausgabe - meistens von mkfs.ext4- aber beachten Sie besonders die lsBits unten. ls -szeigt die tatsächliche -sGröße einer Datei auf der Festplatte an - und sie wird immer in der ersten Spalte angezeigt.

  • Jetzt können wir unser Image grundsätzlich nur auf die erste Partition reduzieren ...

    fdisk -l img

    Disk img: 1 GiB, 1073741824 bytes, 2097152 sectors
    Units: sectors of 1 * 512 = 512 bytes
    Sector size (logical/physical): 512 bytes / 512 bytes
    I/O size (minimum/optimal): 512 bytes / 512 bytes
    Disklabel type: dos
    Disk identifier: 0xc455ed35
    
    Device Boot  Start     End Sectors  Size Id Type
    img1          2048  411647  409600  200M 83 Linux
    img2        411648 2097151 1685504  823M 83 Linux
  • Dort fdiskerfahren wir, dass sich in der ersten Partition von img... 411647 +1 512-Byte-Sektoren befinden.

    dd seek=411648 of=img </dev/null
  • Dadurch wird die imgDatei nur auf ihre erste Partition gekürzt. Sehen?

    ls -hls img

    181M -rw-r--r-- 1 mikeserv mikeserv 201M Jul 16 21:37 img
    
  • ... aber wir können diese Partition trotzdem mounten ...

    sudo mount "$(sudo losetup -Pf --show img)p"*1 ./mnt
  • ... und hier sind die Inhalte ...

    ls -hls ./mnt

    total 176M
     12K drwx------ 2 root root  12K Jul 16 21:34 lost+found
     79K -rw-r----- 1 root root 823M Jul 16 21:34 part2
    176M -rw-r--r-- 1 root root 175M Jul 16 21:34 zero_fill
  • Und wir können das gespeicherte Image der zweiten Partition an die erste anhängen ...

    sudo sh -c '
        dd seek=411648 if=./mnt/part2 of=img
        umount ./mnt; losetup -D
        mount "$(losetup -Pf --show img)p"*2 ./mnt
        ls ./mnt; umount ./mnt; losetup -D'

    1685504+0 records in
    1685504+0 records out
    862978048 bytes (863 MB) copied, 1.96805 s, 438 MB/s
    lost+found
  • Jetzt ist unsere imgDatei gewachsen : Sie ist nicht mehr spärlich ...

    ls -hls img

    1004M -rw-r--r-- 1 mikeserv mikeserv 1.0G Jul 16 21:58 img
  • ... aber das zu entfernen ist beim zweiten Mal genauso einfach wie beim ersten natürlich ...

    dd seek=411648 of=img </dev/null
    ls -hls img

    181M -rw-r--r-- 1 mikeserv mikeserv 201M Jul 16 22:01 img
    
mikeserv
quelle
Ich musste das viermal lesen, um zu verstehen, was Sie präsentiert haben. und ich denke, es ist brillant und gut dokumentiert. Da dies ein Image auf dem Gerät sein wird, kann ich das Startskript überprüfen lassen, um festzustellen, ob es eine zweite formatierte Partition gibt. Beim ersten Start lautet die Antwort Nein, sodass die Partition extrahiert wird. Im Falle eines Upgrades sollte es in Ruhe gelassen werden ... und dann gibt es auch die zusätzliche Möglichkeit, eine Extraktion über ein vorhandenes Datendateisystem zu erzwingen, um auf die Werkseinstellungen zurückgesetzt zu werden. Wieder ... Genial!
AllenKll
1
Nicht genau das, wonach ich gefragt habe, aber es löst mit Sicherheit das Problem, das ich habe ... also markiere ich dieses als richtig. Ein großes Lob an Sie, Sir.
AllenKll
@ AllenKll - Ich freue mich, dass es Ihnen gefallen hat. Wenn Sie dies in einen automatisierten Upgrade-Prozess integrieren möchten, sollten Sie die ddBlockgrößen ein wenig optimieren . Bei der Kürzung spielt es keine Rolle - ddsucht sofort nach dem Versatz und schneidet die Datei genau dort ab. Beim Anhängen ist die Blockgröße von 512 Byte jedoch ziemlich langsam. Eigentlich wahrscheinlich der schnellste Weg , es zu tun ist , damit ddzu seekund erlauben catzu schreiben. { dd if=/dev/null seek=411648; cat; } <part2 1<>/dev/mmcblk1oder so, wenn du meinen Drift bekommst.
Mikeserv
6

Der einfachste Weg, dies zu tun, besteht darin, Ihre Sicherungsdatei als Sparse-Datei zu erstellen. das heißt, machen Sie es 1 GB mit truncate -s 1G disk.imganstelle von dd if=/dev/zero bs=1048576 count=1024 of=disk.img(oder was auch immer). Schön, truncateist auch viel schneller.

Wenn Sie eine ls -lDatei bearbeiten, wird sie als 1 GB angezeigt - dies ist jedoch nur die scheinbare Größe. du disk.imggibt die tatsächliche Größe an.

(Hinweis: Sie müssen Ihr Image auf einem Dateisystem haben, das Dateien mit geringer Dichte unterstützt. Alle gängigen Unix-Dateien funktionieren. Ext2 / 3/4 alle tun dies. FAT32 nicht. HFS + auch nicht.)

HINWEIS: Sparse-Dateien haben logischerweise immer noch die volle Größe. Nur die nie geschriebenen Abschnitte werden nicht physisch auf der Festplatte gespeichert. Der nicht tatsächlich gespeicherte Teil ist größtenteils vor Programmen verborgen. Einige Dienstprogramme unterstützen dies jedoch. (ZB dd conv=sparse, cp --sparse=auto/alwaysusw.). Ein tatsächlicher USB-Stick kann nicht spärlich sein. Und wenn Sie es dd conv=sparsezum Schreiben verwenden, wird es wahrscheinlich viel schneller sein, aber Sie werden alle Daten dort belassen, die zuvor vorhanden waren, anstatt der erwarteten Blöcke voller NULs (0x00). Sollte gut funktionieren (als freier Speicherplatz), hinterlässt aber alte Daten auf dem USB-Stick - möglicherweise ein Sicherheitsrisiko.

derobert
quelle
1
@mikeserv yep, das habe ich gemerkt und eine Notiz dazu hinzugefügt. Sie haben wahrscheinlich eine ältere Version gesehen ...
derobert
Ich habe experimentiert. und ja, du zeigst es als viel kleinere Größe, aber beim DDing auf die Karte wurde immer noch 1 GB kopiert, und beim Scping auf ein anderes System wurde 1 Gig kopiert. Ich bin nicht sicher, was Truncate -s wirklich bewirkt, aber obwohl es auf der Festplatte kleiner aussieht, bleibt es bei jeder Verwendung der Datei in seiner ursprünglichen Größe.
AllenKll
@mikeserv du hast recht, ich wollte /dev/zeronicht null schreiben . Hoppla! Wird behoben.
Derobert
Oh ja, / dev / zero wird definitiv keine spärliche Datei erstellen.
Mikeserv
1
@DavidFavor - die Zeit , die erforderlich ist , sofort mit einem der fallocate -l... img, truncate -s... img, dd seek=... of=img </dev/null, sind , von denen alle äquivalent.
Mikeserv
0

Möchten Sie dieses Bild mit 800 MB Speicherplatz erstellen, damit Sie es auf SD-Karten kopieren können? Aber Sie möchten beim Speichern des Bildes keinen Platz verschwenden. Wenn ja, kann ich eine Komprimierung vorschlagen, wie z bzip. Dies hängt jedoch davon ab, dass nicht verwendete Blöcke auf Null initialisiert werden.

Strg-Alt-Delor
quelle
Ja meistens. Ich habe gesehen, wie es ohne Reißverschluss gemacht wurde, ich möchte nur wissen, wie es geht. Auch zum Übertragen auf die Karte, um Zeit zu sparen. sowie Remote-Upgrades durchführen. um Bandbreite zu sparen.
AllenKll
-1

Hoffe ich verstehe die Frage richtig:

Verkleinern eines Dateisystems und einer Partition. Verwenden Sie gparted.

Strg-Alt-Delor
quelle
Dadurch wird die Größe der Partition geändert. Ich möchte das nicht. Ich möchte, dass die Partition gleich groß bleibt. nur das Bild dieser Partition soll kleiner sein. Außerdem brauche ich einen automatisierten Weg, um das zu tun. GUI-Tools funktionieren nicht.
AllenKll
Dann nur Sie der Dateisystem-Shrinker (der gparted / parted verwendet). Aber warum soll der größte Teil der Partition leer sein?
Strg-Alt-Delor