Partition einen Images vergrössern

Du kommst mit der Installation nicht voran oder willst noch was nachfragen? Schau auch in den "Tipps und Tricks"-Bereich.
Antworten
bors
Beiträge: 5
Registriert: 23.08.2016 11:30:42

Partition einen Images vergrössern

Beitrag von bors » 02.12.2016 18:15:02

Hallo Zusammen

Ich habe ein 4GB grosses Image eines Debian-Rechners:

Code: Alles auswählen

Platte raw.img: 4224 MByte, 4224761856 Byte
130 Köpfe, 62 Sektoren/Spur, 1023 Zylinder, zusammen 8251488 Sektoren
Einheiten = Sektoren von 1 × 512 = 512 Bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

  Gerät  boot.     Anfang        Ende     Blöcke   Id  System
raw.img1   *          62     2345459     1172699   83  Linux
raw.img2         2345460     5271239     1462890   83  Linux
raw.img3         5271240     7810139     1269450   83  Linux
Nun möchte ich die letzte Partition vergrössern, so dass das Image 8GB gross wird.
Normalerweise gehe ich wiefolgt vor:

-Image auf eine CF Karte kopieren:

Code: Alles auswählen

sudo dd if=raw.img of=/dev/sdb
-/dev/sdb in Gparted öffnen und die letzte Partition vergrössern.

-Wieder ein Image aus /dev/sda erzeugen:

Code: Alles auswählen

sudo dd if=/dev/sdb of=raw2.img
Das Image sieht danach wiefolgt aus:

Code: Alles auswählen

Platte raw2.img: 7800 MByte, 7800356352 Byte
130 Köpfe, 62 Sektoren/Spur, 1890 Zylinder, zusammen 15235071 Sektoren
Einheiten = Sektoren von 1 × 512 = 512 Bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

   Gerät  boot.     Anfang        Ende     Blöcke   Id  System
raw2.img1   *          62     2345459     1172699   83  Linux
raw2.img2         2345460     5271239     1462890   83  Linux
raw2.img3         5271240    15235071     4981916   83  Linux

Nun würde ich mir gerne den Umweg über die CF Karte sparen.
Ich dachte mir es sollte möglich sein, das Image als loopdevice zu mounten und dann die Grösse anzupassen.
Dazu schrieb ich folgendes Script:

Code: Alles auswählen

#!/bin/bash

#Remove previously used loopdevice
losetup -D &> /dev/null

set -e

#Copy image
cp -v $1 tmp.img

#Resize image to the new size
qemu-img resize -f raw tmp.img $2

#Make loopdevice
losetup /dev/loop0 tmp.img

#Resize the last partition to the maximum possible size
parted /dev/loop0 resizepart 3 100%
e2fsck -f -y -v -C 0 /dev/loop0p3
resize2fs -p /dev/loop0p3

#Remove loopdevice
losetup -D

#Rename
mv tmp.img "resized_${1}"
$1 ist der Pfad des Images und $2 ist die Imagegrösse in Bytes.

Leider ist danach das Bootflag weg und wenn ich das Image boote gibt fdisk -l diverse Fehlermeldung aus wie z.B.:
Partition 1 endet nicht an einer Zylindergrenze
Partition 2 endet nicht an einer Zylindergrenze
Partition 3 endet nicht an einer Zylindergrenze

Weiss jemand was der Fehler sein könnte, oder kennt jemand eine bessere Methode?

Danke

Benutzeravatar
sbruder
Beiträge: 333
Registriert: 24.06.2016 13:54:36
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Franken

Re: Partition einen Images vergrössern

Beitrag von sbruder » 04.12.2016 00:26:44


rendegast
Beiträge: 15041
Registriert: 27.02.2006 16:50:33
Lizenz eigener Beiträge: MIT Lizenz

Re: Partition einen Images vergrössern

Beitrag von rendegast » 04.12.2016 14:57:29

Leider ist danach das Bootflag weg und wenn ich das Image boote gibt fdisk -l diverse Fehlermeldung aus wie z.B.:
Partition 1 endet nicht an einer Zylindergrenze
Partition 2 endet nicht an einer Zylindergrenze
Partition 3 endet nicht an einer Zylindergrenze
ist wohl von untergeordneter Bedeutung.
Ich vermute ein älteres fdisk-Programm.

raw2.img1 * 62 2345459 1172699 83 Linux
Partitioniere das 8G-Image doch neu.
fdisk legt Partitionen mittlerweile (ab wheezy?) im default 1MB-aligned an.

Die Partitionen vom einen geloopten Image auf die des neuen schreiben, zBsp. per 'dd'.
Die Devices /dev/loopXpY werden mittlerweile automatisch angelegt,
dann muß mensch sich nicht mit offset herumschlagen.

Die Dateisysteme werden dann den etwas größeren neuen Partitionen mit den entsprechenden Dateisystem-Tools angepaßt.



----------------------------------------------------
Beim Modul 'loop' schraube ich die Optionen etwas höher

Code: Alles auswählen

options loop max_loop=32 max_part=32
mfg rendegast
-----------------------
Viel Eifer, viel Irrtum; weniger Eifer, weniger Irrtum; kein Eifer, kein Irrtum.
(Lin Yutang "Moment in Peking")

bors
Beiträge: 5
Registriert: 23.08.2016 11:30:42

Re: Partition einen Images vergrössern

Beitrag von bors » 05.12.2016 18:20:39

Vielen Dank für die Tipps. :THX:

@ rendegast
Ja. Ich muss mal den Offset (62) anpassen. Leider bin ich noch nicht dazu gekommen.

Ich habe das Skript nun wiefolgt angepasst:

Code: Alles auswählen

#!/bin/bash

#Partition to extend.
PART_NR_EXTEND=3

abort()
{
    echo "Usage: sudo $0 <image_name> <newsize_megabytes>"  >&2
    echo "Output: resized_<image_name>"  >&2
    echo "Example extend to 8GB: sudo $0 <image_name> 8000"  >&2
    losetup -d $looppartdata $loopraw $looptmp
    rm -f tmp.img raw.img
    exit 1
}

trap 'abort' 0

set -e

#Copy image
cp -v $1 raw.img

#Check size
rawsize=`stat --printf="%s" raw.img`
targetsize=`echo "${2} * 1000000" | bc`
echo "Oldsize = ${rawsize} Bytes"
echo "Newsize = ${targetsize} Bytes"

if [ $rawsize -ge $targetsize ]; then 
	echo "Error: Oldsize (${rawsize} Bytes) is grater or equal to newsize (${targetsize} Bytes)"
	exit 1
fi

#Create empty image
dd if=/dev/zero of=tmp.img bs=1MB count=$2

#Make loopdevices
loopraw=`losetup -f --show raw.img`
looptmp=`losetup -f --show tmp.img`

#Clone the existing contents into the new image
dd if=$loopraw of=$looptmp

#Remove loopdevice raw
losetup -d $loopraw

#Remove raw image
rm -f raw.img

#Get start offset from the data partition
startoffset=`parted -s tmp.img unit B print |  awk '/^Nummer/{p=1;next}; p{gsub(/[^[:digit:]]/, "", $2); print $2}' | sed -n "${PART_NR_EXTEND}p"`
echo "startoffset = ${startoffset} Bytes"

#Resize the partition to the maximum size
parted -s $looptmp -- rm $PART_NR_EXTEND
parted -s $looptmp -- mkpart primary ${startoffset}b -1

#Resize filesystem
looppartdata=`losetup -f --show -o $startoffset tmp.img`
sectors=`parted -s tmp.img unit s print |  awk '/^Nummer/{p=1;next}; p{gsub(/[^[:digit:]]/, "", $4); print $4}' | sed -n "${PART_NR_EXTEND}p"`
echo "Sectors = ${sectors}"
blocksize=`blockdev --getbsz ${looppartdata}`
echo "Blocksize = ${blocksize}"
blocks=`echo "${sectors} / (4096 / ${blocksize})" | bc`
echo "Blocks = ${blocks}"
e2fsck -f $looppartdata
resize2fs -p $looppartdata

#Remove loopdevices
losetup -d $looppartdata $looptmp

#Rename
mv tmp.img "resized_${1}"

#Remove tmp image
rm -f tmp.img

trap : 0

echo >&2 '
Done
'

Dann habe ich das 4GB Image mithilfe des Skripts auf 8GB vergrössert:

Code: Alles auswählen

sudo ./resize_image_data_partition.sh image_4GB.img 8000

Danach sieht das Image wiefolgt aus:

Code: Alles auswählen

$ fdisk -l resized.img 

Platte resized.img: 8000 MByte, 8000000000 Byte
130 Köpfe, 62 Sektoren/Spur, 1938 Zylinder, zusammen 15625000 Sektoren
Einheiten = Sektoren von 1 × 512 = 512 Bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

   Gerät  boot.     Anfang        Ende     Blöcke   Id  System
resized.img1   *          62     2345459     1172699   83  Linux
resized.img2         2345460     5271239     1462890   83  Linux
resized.img3         5271240    15624999     5176880   83  Linux

Code: Alles auswählen

$ parted resized.img 
GNU Parted 2.3
Verwende resized.img
Willkommen zu GNU Parted! Geben Sie 'help' ein, um eine Liste der verfügbaren Kommados zu erhalten.
(parted) print                                                            
Modell:  (file)
Festplatte  resized.img:  8000MB
Sektorgröße (logisch/physisch): 512B/512B
Partitionstabelle: msdos

Nummer  Anfang  Ende    Größe   Typ      Dateisystem  Flags
 1      31.7kB  1201MB  1201MB  primary  ext3         boot
 2      1201MB  2699MB  1498MB  primary  ext3
 3      2699MB  8000MB  5301MB  primary  ext3
So weit so gut. Das Bootflag wird übernommen und die Offsets sind gleich geblieben.
Doch wenn ich auf dem Target Boote bekomme ich eine komische Ausgabe von fdisk (nicht erschrecken, ich habe eine 32GB Karte genommen):

Code: Alles auswählen

$ fdisk -l

Platte /dev/sda: 31.5 GByte, 31488049152 Byte
130 Köpfe, 62 Sektoren/Spur, 7630 Zylinder
Einheiten = Zylinder von 8060 × 512 = 4126720 Bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

   Gerät  boot.     Anfang        Ende     Blöcke   Id  System
/dev/sda1   *           1         291     1172699   83  Linux
/dev/sda2             292         654     1462890   83  Linux
/dev/sda3             655        1939     5176880   83  Linux
Der Anfang steht plötzlich auf 1 und auch sonst sind Anfang und Ende zu klein.
Kann das daran liegen, dass ich auf dem Target eine veraltete Version von fdisk habe?

Code: Alles auswählen

$ fdisk -v
fdisk (util-linux-ng 2.17.2)
DF sieht so aus:

Code: Alles auswählen

$ df -a
Dateisystem          1K‐Blöcke   Benutzt Verfügbar Ben% Eingehängt auf
rootfs                 1154260    718316    377312  66% /
/dev/root              1154260    718316    377312  66% /
devtmpfs               1018792       156   1018636   1% /dev
proc                         0         0         0   -  /proc
sysfs                        0         0         0   -  /sys
udev                   1018792       156   1018636   1% /dev
/dev/sda2              1439848    143648   1223056  11% /opt
/dev/sda3              5097136     35292   4803004   1% /data
devpts                       0         0         0   -  /dev/pts

Danach habe ich nochmals zum Spass ein 7.8GB grosses Image erstellt. Mit Fdisk bekomme ich ein + am Ende der Anzahl Blöcke der dritten Partition.
Weiss jemand was das bedeutet? So viel ich weiss bedeutet das, dass das Filesystem grösser ist als die Partition.

Code: Alles auswählen

$ fdisk -l resized_7_8.img 

Platte resized_7_8.img: 7800 MByte, 7800000000 Byte
130 Köpfe, 62 Sektoren/Spur, 1890 Zylinder, zusammen 15234375 Sektoren
Einheiten = Sektoren von 1 × 512 = 512 Bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

   Gerät  boot.     Anfang        Ende     Blöcke   Id  System
resized_7_8.img1   *          62     2345459     1172699   83  Linux
resized_7_8.img2         2345460     5271239     1462890   83  Linux
resized_7_8.img3         5271240    15234374     4981567+  83  Linux

rendegast
Beiträge: 15041
Registriert: 27.02.2006 16:50:33
Lizenz eigener Beiträge: MIT Lizenz

Re: Partition einen Images vergrössern

Beitrag von rendegast » 05.12.2016 19:50:10

bors hat geschrieben: bekomme ich ein + am Ende der Anzahl Blöcke der dritten Partition.
Weiss jemand was das bedeutet?
...
resized_7_8.img3 5271240 15234374 4981567+ 83 Linux
1. Block der Partition = 527240, letzter = 15234374
-> Länge der Partition = 15234374 - (527240-1) = 9963135 Blöcke
== 4981567,5 1K-Blöcke
Wegen der 0,5 1K-Blöcke das '+'.

fdisk (util-linux-ng 2.17.2)
von 2010-03 https://www.kernel.org/pub/linux/utils/util-linux/ (Daten IN den ReleaseNotes)
Debianutil-linux, in wheezy 2.20, in jessie 2.25.
grml 2014.11 (current) auch 2.25.
mfg rendegast
-----------------------
Viel Eifer, viel Irrtum; weniger Eifer, weniger Irrtum; kein Eifer, kein Irrtum.
(Lin Yutang "Moment in Peking")

bors
Beiträge: 5
Registriert: 23.08.2016 11:30:42

Re: Partition einen Images vergrössern

Beitrag von bors » 06.12.2016 08:43:04

Danke.

Dann hat sich das auch geklärt.
Fdisk 2.17.2 wird wahrscheinlich einen Bug haben.

owl102

Re: Partition einen Images vergrössern

Beitrag von owl102 » 06.12.2016 09:58:23

bors hat geschrieben:Doch wenn ich auf dem Target Boote bekomme ich eine komische Ausgabe von fdisk (nicht erschrecken, ich habe eine 32GB Karte genommen):

Code: Alles auswählen

...
Einheiten = Zylinder von 8060 × 512 = 4126720 Bytes
...
Der Anfang steht plötzlich auf 1 und auch sonst sind Anfang und Ende zu klein.
Der Grund steht doch da: Es wird als Einheit die Zylindergröße genommen, was bei einer SD nur sehr bedingt sinnvoll ist. (Ältere Versionen von fdisk hatten dies als default.)

Mache mal "fdisk -l -u=sectors" stattdessen. (Wenn das nicht geht: "fdisk -l -u")

Antworten