From eea0a9b1616ab8321faec9971393041cfb1bb3c4 Mon Sep 17 00:00:00 2001 From: "Carl D. Roth" Date: Thu, 27 Jul 2017 14:07:57 -0700 Subject: [PATCH 1/3] Better handling for failed unzip (like, for disk full) --- .../base/all/initrds/loader-initrd-files/src/bin/swiprep | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/base/all/initrds/loader-initrd-files/src/bin/swiprep b/packages/base/all/initrds/loader-initrd-files/src/bin/swiprep index e0aa0da2..d7b621e2 100755 --- a/packages/base/all/initrds/loader-initrd-files/src/bin/swiprep +++ b/packages/base/all/initrds/loader-initrd-files/src/bin/swiprep @@ -144,12 +144,17 @@ case $(uname -m) in ARCH_LIST="arm64" ;; *) - q;; + ;; esac if test "${mode_install}${mode_overlay}"; then for arch in $ARCH_LIST; do - unzip -pq "$swipath" "rootfs-${arch}.sqsh" > "$workdir/rootfs.sqsh" + if unzip -pq "$swipath" "rootfs-${arch}.sqsh" > "$workdir/rootfs.sqsh"; then + : + else + echo "*** unzip of rootfs.sqsh failed" 1>&2 + rm -f "$workdir/rootfs.sqsh" + fi if test -s "$workdir/rootfs.sqsh"; then break; fi done if test ! -s "$workdir/rootfs.sqsh"; then From 14517423b268344dcf809555cae8258f21156682 Mon Sep 17 00:00:00 2001 From: "Carl D. Roth" Date: Thu, 27 Jul 2017 14:51:30 -0700 Subject: [PATCH 2/3] Handler larger SWI files - download SWI to a 1GiB tmpfs - determine of the embedded squashfs will fit in the tmpfs - resize the tmpfs if necessary --- .../initrds/loader-initrd-files/src/bin/boot | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/packages/base/all/initrds/loader-initrd-files/src/bin/boot b/packages/base/all/initrds/loader-initrd-files/src/bin/boot index a8cfd7af..9dcc1db7 100755 --- a/packages/base/all/initrds/loader-initrd-files/src/bin/boot +++ b/packages/base/all/initrds/loader-initrd-files/src/bin/boot @@ -85,10 +85,42 @@ shift [ ! "${testonly}" ] || set -x +# set up some tempfs for our download + +swi_kmin=1048576 + +workdir=$(mktemp -d -t boot-tmpfs-XXXXXX) + +export TMPDIR=$workdir +# export this tempfs as temporary space for swiprep below + +echo "creating ${swi_kmin}k of tmpfs in $workdir" +mount -v -t tmpfs -o size=${swi_kmin}k tmpfs $workdir +workmnt=$workdir + +do_cleanup() { + cd /tmp + if [ "$workmnt" ]; then + if grep -q "$workmnt" /proc/mounts; then + umount -v "$workmnt" || : + fi + fi + rm -fr "$workdir" +} +trap "do_cleanup" 0 1 + unset swipath host bhost port dir file dev user password scope case "${SWI}" in nfs://*/|dir:*) echo "Mounting ${SWI}" + + # do not use the ephemeral temporary directory for + # locally-mounted directories + if test "$workmnt"; then + umount "$workmnt" || : + fi + unset TMPDIR + swipath=$(swimount $SWI) if [ "$rootfs" ]; then [ -d "${swipath}/${rootfs}" ] || { echo "${SWI}${rootfs} must be an unpacked rootfs"; exit 1; } @@ -131,6 +163,10 @@ fi if [ "$testonly" ]; then echo "swipath=$swipath rootfs=$rootfs" echo "Stop here" + + trap "" 0 1 + # leave temporary directory and mounts + exit 0 fi @@ -140,6 +176,42 @@ if [ -d "${swipath}" ]; then umount -l /newroot 2>/dev/null || : mount --bind "${swipath}/${rootfs}" /newroot else + + ############################## + # + # swiprep will (1) unpack the squashfs image to a file, + # and (2) extract the filesystem to /newroot. + # + # We need to make sure there is enough disk space for this... + # + ############################## + + set dummy $(df -k -P "$workmnt" | tail -1) + tmpavail=$5 + + # estimate the squashfs size + squashsz=0 + ifs=$IFS; IFS=$CR + for line in $(unzip -ql "$swipath"); do + IFS=$ifs + set dummy $line + case "$5" in + *.sqsh) + squashsz=$(( $squashsz + $2 )) + ;; + esac + done + IFS=$ifs + + # pad by a little to account for inodes and such + squashsz=$(( $squashsz * 105 / 100 )) + + if [ $squashsz -gt $tmpavail ]; then + tmpsz=$(( $swi_kmin + $squashsz - $tmpavail )) + echo "Resizing tmpfs to ${tmpsz}k" + mount -o remount,size=${tmpsz}k $workmnt + fi + swiprep --overlay "${swipath}${rootfs}" --unmount --swiref "$swistamp" /newroot swiprep --record "${swipath}${rootfs}" --swiref "$swistamp" /newroot fi @@ -152,6 +224,10 @@ if [ -f /lib/boot-custom ]; then . /lib/boot-custom fi +# done with the temporary dirs and mounts +trap "" 0 1 +do_cleanup || : + echo "Switching rootfs" # limit 16 chars since serial buffer is not flushed kill -QUIT 1 # exec /bin/switchroot as PID 1 sleep 30 @@ -162,4 +238,5 @@ exit 1 # Local variables: # mode: sh # sh-basic-offset: 4 +# sh-indentation: 4 # End: From c0b3bd68ac241d8d5e5df0e9cd7e11e8050aab66 Mon Sep 17 00:00:00 2001 From: "Carl D. Roth" Date: Thu, 27 Jul 2017 16:54:16 -0700 Subject: [PATCH 3/3] Pick the largest squashfs --- packages/base/all/initrds/loader-initrd-files/src/bin/boot | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/base/all/initrds/loader-initrd-files/src/bin/boot b/packages/base/all/initrds/loader-initrd-files/src/bin/boot index 9dcc1db7..c83658d7 100755 --- a/packages/base/all/initrds/loader-initrd-files/src/bin/boot +++ b/packages/base/all/initrds/loader-initrd-files/src/bin/boot @@ -189,7 +189,8 @@ else set dummy $(df -k -P "$workmnt" | tail -1) tmpavail=$5 - # estimate the squashfs size + # estimate the squashfs size based on the largest one here + # (there may be more than one arch in the SWI file) squashsz=0 ifs=$IFS; IFS=$CR for line in $(unzip -ql "$swipath"); do @@ -197,7 +198,9 @@ else set dummy $line case "$5" in *.sqsh) - squashsz=$(( $squashsz + $2 )) + if [ "$2" -gt $squashsz ]; then + squashsz=$2 + fi ;; esac done