Recompress squashfs

squashfs

I have some squashfs files that are currently compressed with the default algorithm which is zlib/gzip. I would like to recompress them to zstd.

What would be the command to do this without extracting it to disk and recreating it from that extraction?

Best Answer

Doing this is suppported in Squashfs-tools 4.6 and later (released last year).

Converting a Squashfs filesystem from one compression type to another is mentioned in the documentation here (https://github.com/plougher/squashfs-tools/blob/master/README-4.6.1#L289).

As I wrote the above documentation (and Squashfs), there is no problem with me copying it here.

  1. Squashfs filesystems conversion (piping Unsquashfs output to Mksquashfs)

Sometimes you have an existing Squashfs filesystem which you want to regenerate using a different set of compression options, such as compression algorithm, block-size, tail-packing etc. Or you want to modify some parts of the filesystem such as excluding files, change ownership etc.

Obviously you have been able to mount the Squashfs filesystem and regenerate the filesystem by running mksquashfs on the mounted directory. But, this requires root access (which sometimes isn't available). The only other alternative until now has been to extract the Squashfs filesystem to an intermediate uncompressed directory, and then regenerate the filesystem by running mksquashfs on that. This, however, is slow and requires storage to store the uncompressed filesystem.

unsquashfs can now output a Pseudo file representing the input filesystem to stdout, and mksquashfs can now read a Pseudo file from stdin. This allows the output of unsquashfs to be piped to mksquashfs.

Some examples follow.

If you had a GZIP filesystem and wanted to convert it to ZSTD, you can do:

% unsquashfs -pf - image.sqsh | mksquashfs - new.sqsh -pf - -comp zstd

If you wanted to change to XZ compression, increase to a 1 Mbyte block size, and use -tailend packing, you could do:

% unsquashfs -pf - image.sqsh | mksquashfs - new.sqsh -pf - -comp xz -b 1M -tailends

If you only want the directory foobar you can tell Unsquashfs to only extract that:

% unsquashfs -pf - image.sqsh foobar | mksquashfs - new.sqsh -pf -

If you had inadvertently stored binary .o files, you can remove them by using the new "non-anchored" unsquashfs exclude file functionality:

% unsquashfs -excludes -pf - image.sqsh "... *.o" | mksquashfs - new.sqsh -pf -

If you want to update all the file timestamps to now, and make every file owned by phillip:

% unsquashfs -pf - image.sqsh | mksquashfs - new.sqsh -all-time now -force-uid phillip -pf -
Related Question