4

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?

usilo
  • 175

2 Answers2

11

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 -
3

Squashfs tools have very limited ability to manipulated an already created squashfs. As of this writing, the only available change to an existing image is to append to it by adding new files at the root (and either merging or renaming the old root).

However, squashfs is intended to be mounted. There's no reason to extract it, just mount it. (If you wanted to modify it, you could then use something like overlayfs to make changes.)

Once it is mounted, you can then use mksquashfs to rebuild the squash from the mounted squash using whatever options you want including alternate compression algorithms. If all you want to do is change the compression, even if the tools supported it, there would not be better way to handle this.

user10489
  • 2,081