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.

Andi Giga
  • 513
  • 1
  • 7
  • 17
  • 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 '19 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 '19 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 '19 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 '19 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 '19 at 22:06
  • I mean because extending it solves the problem, the data cannot be corrupt. Buster might expect the SD to be bigger then the shrunk size and that may lead to an err. – Andi Giga Aug 29 '19 at 22:08
  • @goldilocks it can also mean that partition #6 (root partition for a NOOBS system) needs to be fsck'd. PINN includes a tool todo that NOOBS doesn't. So you have to pull the card, boot another and use an SDCard reader to run `sudo fsck -f -y /dev/sda6` [Note: that can be done on a Raspberry or any other Linux system.] – Dougie Aug 31 '19 at 07:50
  • Point taken. I suppose what I meant was it is likely a mistake in cmdline.txt *if* the 6th partition doesn't exist. The root partition here is the second one (notice the `-02` in the PARTUUID), which makes this pretty confusing. – goldilocks Aug 31 '19 at 14:08
  • Andi, if you run `blkid` *on the card* (not a partition), you should be able to get the PARTUUID (`blkid` shows it as `PTUUID`); some tool on windows should be able to as well since it is a FAT artifact. If that's *not* `387ea050`, there is a fatal flaw. It might not be *the* fatal flaw, but it needs to be fixed by replacing the value in `cmdline.txt` with the correct one (from `blkid` or whatever). I did not look closely enough at that script to say for sure that it doesn't deal with this, but since it is copying partitions and not a device image, it needs to do that explicitly. – goldilocks Aug 31 '19 at 14:12
  • Basically, the SD has two partitions boot, and the linux one or am I confusing s.th. here? So root is on the second, right? If I run `blkid /dev/sdb` on the extended card I get `/dev/sdb: PTUUID="387ea050" PTTYPE="dos"`. – Andi Giga Sep 02 '19 at 11:15

0 Answers0