0

The recent years I used a script to shrink my SD cards and then make an image from them. The good thing was it was rapid (~15min) and the image was also tiny, e.g. after a Rasbian lite installation ~2.3GB. I never encountered any problems on Jessie/Stretch and with a rpi3 so far.

With buster (and rpi4) when I use the same script and flash the image with etcher back to an SD (even the same SD) I get an error on boot: Kernel panic not syncing err 179,6

script

#!/bin/bash

device=$1
outfile=$2
optionZip=$3

# sanity checks on the command line parameters
if [ "${device}" == "" ]; then
    echo "Please specify device, e.g. $0 /dev/sda <filename>" 1>&2;
    exit 1;
fi;

if [ "${outfile}" == "" ]; then
    echo "Please specify filename, e.g. $0 <device> zymbit.img.zip" 2>&1;
    exit 1;
fi;

# sanity checks on the partition layout
fdisk -l "${device}" | grep -q "${device}1.*W95 FAT32"
if [ "$?" != "0" ]; then
    echo 'The first partition is expected to be FAT32' 1>&1;
    exit 1;
fi;

fdisk -l "${device}" | grep -q "${device}2.*Linux"
if [ "$?" != "0" ]; then
    echo 'The second partition is expected to be Linux' 1>&1;
    exit 1;
fi;

# converts and pads given bytes into MB
# Takes the given number in bytes and (by nature of integer division) rounds
# the number of bytes down to the nearest hundred bytes.  That value is then
# padded by 200MB.  The padding was determined by trial and error when
# attempting to image a 1.6GB linux partition.
# TODO: determine a better way to calculate the padding.
function convert_bytes()
{
    local bytes=$1
    local rounded=0

    let rounded="((${bytes}/100000000)+2)*100"

    echo ${rounded}
}

# start the dangerous stuff
linux_partition="${device}2"
umount "${device}2"

# do not continue of there are errors
set -e

e2fsck -f "${linux_partition}"

# call resize2fs to shrink the partition down to the minimum size it needs to be.
# parse the output to know how big the partition is in bytes
let bytes=$(resize2fs -M "${linux_partition}" 2>&1 | grep -i -e "The filesystem .*is .*blocks long" | sed -e 's/.*is [^ ]* \([0-9]*\) (4k) blocks.*/\1*4096/')
echo "resized partition"

# convert the value in bytes returned by resize2fs to MB
let megs_rounded=$(convert_bytes ${bytes})
echo "megs_rounded $megs_rounded"

# use parted to shrink the partition down.
# when shrinking the partition down parted will prompt for confirmation.  the
# following post notes to append yes to the operation:
# https://bugs.launchpad.net/ubuntu/+source/parted/+bug/1270203/comments/2
parted --align optimal "${device}" unit MB resizepart 2 "${megs_rounded}" yes
echo "resized 2"

# use last value in the `End` column to know how much to image
let total_bytes=$(parted "${device}" unit B print | grep -v '^$' | awk '{print $3}' | tail -n 1 | sed -e 's/B//');
let total_megs_rounded=$(convert_bytes ${total_bytes})

if [ "${optionZip}" == "true" ]; then
    # generate a zip file on the fly
    #time dd bs=1M if=${device} count=${total_megs_rounded} | gzip -9 > ${outfile}
    imgfile=$(echo "${outfile}" | sed -e 's/.zip$//')
    if [ "${imgfile}" == "${outfile}" ]; then
        imgfile=sdcard.img
    fi;

    # drop the .img to disk and then zip so that Macs can read the file
    dd bs=1M if="${device}" of="${imgfile}" count="${total_megs_rounded}"
    echo "copied"

    zip "${outfile}" "${imgfile}"
    echo "zipped"
    rm "${imgfile}"
else
    dd bs=1M if="${device}" of="${outfile}" count="${total_megs_rounded}"
    echo "copied"
fi;

# expand the filesystem back
full_size=$(parted "${device}" print | grep "Disk ${device}" | awk '{print $3}')
parted "${device}" resizepart 2 "${full_size}"
echo "expanded"
# wait up to 10 seconds for the linux partition to show up
for i in {0..9}; do
    [ -e "${linux_partition}" ] && break
    sleep 1
done;

# if the linux partition didn't show up, this will fail
resize2fs "${linux_partition}"
sudo eject "${device}"
echo "done"
exit 0;

I noticed there is a message after shrinking the image: You may need to update /etc/fstab/ Maybe buster is checking something Jessie didn't, and I need to specify the new size?

The original SD works after the shrinking and expanding, so no data should get corrupted during the shrinking.

Question:

Why do I run into the err above and how can I fix the script to make the images bootable again?

PS:

I've seen there other ways to copy and compress the SD. One is copying it first and zipping it, but this results in a larger file and takes very long because the SD is copied first and then compressed.

Or this script which is quite slow: https://github.com/qrti/shrink

I tried it with different SD cards and also with flashing on the same SD where I copied the backup from (to avoid diff. SD card size differences).

Size is significant to me because I offer the image as a download.

EDIT: If I split the script into two parts, the shrinking part and the restoring part. After running the shrinking part (on the original disk) I get the error without flashing it again, just be using the original (now shrunk) card. When I mount the SD to my Linux VM it complains as well. When I run the second part of the script and extend the card the SD is fine afterward. The same applies to a flashed image.

Now I can use the faster script which creates smaller images, but the images are not shareable because they are still broken (and need to be repaired before use).

So I assume that the shrunk image is fine it just needs some record that it has been shrunk.

10
  • I suggest to ask the author of the script on github or file a bug report there. Maybe it isn't updated yet to support Raspbian Buster together with RPi 4B?
    – Ingo
    Aug 29, 2019 at 16:11
  • It has open issues since 2016 I don't think it's maintained. But I would repair it and make a PR/fork
    – Andi Giga
    Aug 29, 2019 at 16:41
  • I added an edit. I think I need to set the new size somewhere after shrinking it down. Maybe buster checks that and the older versions didn't they did a lot of security improvements on buster.
    – Andi Giga
    Aug 29, 2019 at 16:44
  • The kernel error not syncing on 179,6 is a reference to the 6th partition on the SD card, which the rest of your post implies probably doesn't exist. Generally this is a mistake in cmdline.txt with regard to the root= filesystem.
    – goldilocks
    Aug 29, 2019 at 17:24
  • For what should I look in the cmdline.txt? This is the current file dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=PARTUUID=387ea050-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait . I didn't change anything there. As mentioned above my guess is that I need to inform buster somewhere that the SD has been resized. During the resize there is a notice that I might have to edit /etc/fstab.
    – Andi Giga
    Aug 29, 2019 at 22:06

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.