Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Drake <dsd@laptop.org>2012-04-02 15:56:40 (GMT)
committer Daniel Drake <dsd@laptop.org>2012-04-03 20:40:11 (GMT)
commit2ac0e0db602e4bda40eb1dde57400c9ff964a788 (patch)
tree9fcfdc1b7da36694372cde17cd617f474ed26160
parent56e1ba4084a1f9096f05d018b737c42b0cc13d50 (diff)
sd_card_image: Calculate disk image size automatically
By default, calculate the output size of the resultant disk image based on the amount of data needed to be stored, plus some free space. The partition and filesystem will now be grown on first boot to fill the media by other parts of the system. The manual sizes can still be specified in the configuration if needed, but the idea here is that we no longer need to produce disk images of multiple sizes.
-rw-r--r--modules/sd_card_image/README24
-rw-r--r--modules/sd_card_image/image.50.makefs.sh58
-rw-r--r--modules/sd_card_image/postimage.50.makezd.sh36
3 files changed, 91 insertions, 27 deletions
diff --git a/modules/sd_card_image/README b/modules/sd_card_image/README
index 0deda30..aa1bde8 100644
--- a/modules/sd_card_image/README
+++ b/modules/sd_card_image/README
@@ -5,13 +5,22 @@ These images are in the "ZD" format, suitable for flashing via OpenFirmware's
fs-update command. Corresponding .zsp files are produced too. To disable
.zd/.zsp creation, set the make_zd option to 0 (default is 1).
-The SD card sizes must be specified, in bytes. This module can create
-filesystems for multiple SD card capacities. Simply provide a list of
-uniquely-named options that start with "size_", one for each SD card size.
-
-The value for each of these options is the disk size (in bytes), optionally
-followed by a comma and a custom extension. There can only be one un-named
-entry, which will default to the extension "zd".
+By default, a single disk image is produced, with it's size automatically
+calculated based on the size of the data included in the image, plus a small
+amount of free space. The system will resize the partition and filesystem to
+fill the media during first boot. Therefore, other than loading the module,
+no configuration is usually necessary.
+
+If you wish to create multiple images, or if you wish to specify a size,
+you can specify some uniquely-named options starting with "size_". (This
+will disable the default creation of an automatic-sized image as described
+above.)
+
+The value for each of these options is the disk size, optionally followed by
+a comma and a custom extension. There can only be one un-named entry, which
+will default to the extension "zd". The disk size is specified in bytes,
+but the special size "auto" will result in the disk size being calculated
+automatically as described above.
For example:
[sd_card_image]
@@ -51,4 +60,3 @@ The raw image file is archived in tar (in sparse mode) and then compressed with
gzip. Tar preserves the sparseness of the file (the fact that some part of the
image is made up of unallocated disk blocks). To disable this
archiving/compression, set the compress_disk_image option to 0 (default is 1).
-
diff --git a/modules/sd_card_image/image.50.makefs.sh b/modules/sd_card_image/image.50.makefs.sh
index 503da2f..c081b3e 100644
--- a/modules/sd_card_image/image.50.makefs.sh
+++ b/modules/sd_card_image/image.50.makefs.sh
@@ -5,6 +5,7 @@
versioned_fs=$(read_config base versioned_fs)
buildnr=$(read_buildnr)
BLOCK_SIZE=512
+ROOT_PARTITION_START_BLOCK=139264
NUM_HEADS=16
NUM_SECTORS_PER_TRACK=62
@@ -18,13 +19,49 @@ umount $ROOT &>/dev/null || :
mkdir -p $BOOT
mkdir -p $ROOT
+# Automatically determine a size for the output disk image (including root
+# and boot partitions).
+#
+# This is calculated by examining how much space was used in the intermediate
+# filesystem image, and by adding a small amount of free space for safety.
+auto_size()
+{
+ local rawfs=$intermediatesdir/rawfs.img
+ local edump=$(dumpe2fs "$rawfs")
+ local bsize=$(echo "$edump" | grep "^Block size:")
+ local bcount=$(echo "$edump" | grep "^Block count:")
+ local freeblocks=$(echo "$edump" | grep "^Free blocks:")
+
+ # Remove textual labels, we just want the numbers
+ bsize="${bsize##* }"
+ bcount="${bcount##* }"
+ freeblocks="${freeblocks##* }"
+
+ local usedblocks=$(( bcount - freeblocks ))
+ local usedsize=$(( usedblocks * bsize ))
+
+ # In my testing, the new image has about 100mb free even when we try
+ # to match the size exactly. So we use the exact size; if we find that
+ # we need to add some 'safety' space later, we can add it.
+ #local newsize=$(( usedsize + (20*1024*1024) ))
+ local newsize=$usedsize
+
+ # Increase by size of boot partition
+ (( newsize += $ROOT_PARTITION_START_BLOCK * $BLOCK_SIZE ))
+
+ echo $newsize
+}
make_image()
{
- local vals=$1
- local disk_size=${vals%,*}
- local ext=
- expr index "$vals" ',' &>/dev/null && ext=${vals#*,}
+ local disk_size=$1
+ local ext=$2
+ [ -z "$ext" ] && ext="zd"
+
+ if [ "$disk_size" = "auto" ]; then
+ disk_size=$(auto_size)
+ fi
+
echo "Making image of size $disk_size"
echo "Create disk and partitions..."
@@ -33,14 +70,13 @@ make_image()
local num_cylinders=$(($num_blocks / $NUM_HEADS / $NUM_SECTORS_PER_TRACK))
local image_size=$(($num_cylinders * $NUM_HEADS * $NUM_SECTORS_PER_TRACK * $BLOCK_SIZE))
- [ -z "$ext" ] && ext="zd"
local img=$intermediatesdir/$(image_name).$ext.disk.img
dd if=/dev/zero of=$img bs=$BLOCK_SIZE count=0 seek=$(($image_size / $BLOCK_SIZE))
/sbin/sfdisk -S 32 -H 32 --force -uS $img <<EOF
8192,131072,83,*
-139264,,,
+$ROOT_PARTITION_START_BLOCK,,,
EOF
disk_loop=$(losetup --show --find --partscan $img)
@@ -92,12 +128,20 @@ EOF
}
+found_val=0
oIFS=$IFS
IFS=$'\n'
for line in $(env); do
[[ "${line:0:24}" == "CFG_sd_card_image__size_" ]] || continue
val=${line#*=}
- make_image $val
+ disk_size=${val%,*}
+ ext=
+ expr index "$vals" ',' &>/dev/null && ext=${vals#*,}
+
+ make_image $disk_size $ext
+ found_val=1
done
IFS=$oIFS
+# If no sizes were specified, create an image with automatic size.
+[ "$found_val" = "1" ] || make_image auto
diff --git a/modules/sd_card_image/postimage.50.makezd.sh b/modules/sd_card_image/postimage.50.makezd.sh
index c35d001..dc605ea 100644
--- a/modules/sd_card_image/postimage.50.makezd.sh
+++ b/modules/sd_card_image/postimage.50.makezd.sh
@@ -5,20 +5,15 @@
compress=$(read_config sd_card_image compress_disk_image)
keep_img=$(read_config sd_card_image keep_disk_image)
make_zd=$(read_config sd_card_image make_zd)
+osname=$(image_name)
-oIFS=$IFS
-IFS=$'\n'
-for line in $(env); do
- [[ "${line:0:24}" == "CFG_sd_card_image__size_" ]] || continue
- vals=${line#*=}
- disk_size=${vals%,*}
- ext=
- expr index "$vals" ',' &>/dev/null && ext=${vals#*,}
+function make_zd() {
+ local ext=$1
[ -z "$ext" ] && ext="zd"
- osname=$(image_name)
- output_name=$osname.$ext
- diskimg=$intermediatesdir/$output_name.disk.img
- output=$outputdir/$output_name
+
+ local output_name=$osname.$ext
+ local diskimg=$intermediatesdir/$output_name.disk.img
+ local output=$outputdir/$output_name
if [[ "$make_zd" == 1 ]]; then
echo "Making ZD image for $output_name..."
@@ -39,5 +34,22 @@ for line in $(env); do
mv $diskimg $outputdir
fi
fi
+
+}
+
+found=0
+oIFS=$IFS
+IFS=$'\n'
+for line in $(env); do
+ [[ "${line:0:24}" == "CFG_sd_card_image__size_" ]] || continue
+ vals=${line#*=}
+ disk_size=${vals%,*}
+ ext=
+ expr index "$vals" ',' &>/dev/null && ext=${vals#*,}
+ make_zd $ext
+ found=1
done
IFS=$oIFS
+
+# When no size options were specified, we make a default image.
+[ "$found" = "1" ] || make_zd