]> git.ipfire.org Git - thirdparty/dracut-ng.git/commitdiff
feat(lsinitrd.sh): enable unpacking files from squash-root.img
authorSteffen Maier <maier@linux.ibm.com>
Thu, 26 Jan 2023 13:50:40 +0000 (14:50 +0100)
committerLaszlo Gombos <laszlo.gombos@gmail.com>
Tue, 16 Apr 2024 00:35:20 +0000 (20:35 -0400)
This is helpful for debugging some kdump mkdumprd that prefer dracut-squash.

To not break when unsquashfs upstream would change the default path prefix,
explicitly specify the prefix as argument so users always find files from
squash-root.img by using the same hardcoded prefix, both in the file listing
and when extracting files.

Regarding extract_files (without --unpack):
Unsquashfs cannot seem to extract to stdout, so take a detour via a temp
file.

Regarding --unpack:
Even though cpio for comparison would not overwrite files on extracing,
pass the force flag to unsquashfs on extracing individual files.
Otherwise, unsquashfs complains about its relative top-level directory
"squashfs-root" which already exists after the first file was extracted.
With the force flag, the user can specify multiple files to extract from
squash-root.img, or can invoke lsinitrd multiple times in the same
directory to extract multiple files from squash-root.img.

Signed-off-by: Steffen Maier <maier@linux.ibm.com>
lsinitrd.sh

index ada6cf516e6b7e455fa8e85edb629132f83c2648..25640ee1610bb1e486c943df8e9a654795c42980 100755 (executable)
@@ -173,6 +173,10 @@ dracutlibdirs() {
 }
 
 extract_files() {
+    SQUASH_IMG="squash-root.img"
+    SQUASH_TMPFILE="$TMPDIR/initrd.root.sqsh"
+    SQUASH_EXTRACT="$TMPDIR/squash-extract"
+
     ((${#filenames[@]} == 1)) && nofileinfo=1
     for f in "${!filenames[@]}"; do
         [[ $nofileinfo ]] || echo "initramfs:/$f"
@@ -181,6 +185,16 @@ extract_files() {
         [[ $f == *"\\x"* ]] && f=$(echo "$f" | sed 's/\\x.\{2\}/????/g')
         $CAT "$image" 2> /dev/null | cpio --extract --verbose --quiet --to-stdout "$f" 2> /dev/null
         ((ret += $?))
+        if [[ -z ${f/#squashfs-root*/} ]]; then
+            if [[ ! -s $SQUASH_TMPFILE ]]; then
+                $CAT "$image" 2> /dev/null | cpio --extract --verbose --quiet --to-stdout -- \
+                    $SQUASH_IMG > "$SQUASH_TMPFILE" 2> /dev/null
+            fi
+            unsquashfs -force -d "$SQUASH_EXTRACT" -no-progress "$SQUASH_TMPFILE" "${f#squashfs-root/}" > /dev/null 2>&1
+            ((ret += $?))
+            cat "$SQUASH_EXTRACT/${f#squashfs-root/}" 2> /dev/null
+            rm "$SQUASH_EXTRACT/${f#squashfs-root/}" 2> /dev/null
+        fi
         [[ $nofileinfo ]] || echo "========================================================================"
         [[ $nofileinfo ]] || echo
     done
@@ -214,22 +228,39 @@ list_squash_content() {
     if [[ -s $SQUASH_TMPFILE ]]; then
         echo "Squashed content ($SQUASH_IMG):"
         echo "========================================================================"
-        unsquashfs -ll "$SQUASH_TMPFILE" | tail -n +4
+        unsquashfs -d "squashfs-root" -ll "$SQUASH_TMPFILE" | tail -n +4
         echo "========================================================================"
     fi
 }
 
 unpack_files() {
+    SQUASH_IMG="squash-root.img"
+    SQUASH_TMPFILE="$TMPDIR/initrd.root.sqsh"
+
     if ((${#filenames[@]} > 0)); then
         for f in "${!filenames[@]}"; do
             # shellcheck disable=SC2001
             [[ $f == *"\\x"* ]] && f=$(echo "$f" | sed 's/\\x.\{2\}/????/g')
             $CAT "$image" 2> /dev/null | cpio -id --quiet $verbose "$f"
             ((ret += $?))
+            if [[ -z ${f/#squashfs-root*/} ]]; then
+                if [[ ! -s $SQUASH_TMPFILE ]]; then
+                    $CAT "$image" 2> /dev/null | cpio --extract --verbose --quiet --to-stdout -- \
+                        $SQUASH_IMG > "$SQUASH_TMPFILE" 2> /dev/null
+                fi
+                unsquashfs -force -d "squashfs-root" -no-progress "$SQUASH_TMPFILE" "${f#squashfs-root/}" > /dev/null
+                ((ret += $?))
+            fi
         done
     else
         $CAT "$image" 2> /dev/null | cpio -id --quiet $verbose
         ((ret += $?))
+        $CAT "$image" 2> /dev/null | cpio --extract --verbose --quiet --to-stdout -- \
+            $SQUASH_IMG > "$SQUASH_TMPFILE" 2> /dev/null
+        if [[ -s $SQUASH_TMPFILE ]]; then
+            unsquashfs -d "squashfs-root" -no-progress "$SQUASH_TMPFILE" > /dev/null
+            ((ret += $?))
+        fi
     fi
 }