plougher / squashfs-tools

tools to create and extract Squashfs filesystems
GNU General Public License v2.0
773 stars 196 forks source link

Filesystem LABEL and UUID #59

Open szycha76 opened 5 years ago

szycha76 commented 5 years ago

Label and UUID are extremely useful in automated failover scenarios. Could those be considered for next major release?

RatandeepSharma commented 3 years ago

Can you please tell how to assign label on squashfs partition?

jamesxuxd commented 2 years ago

As filesystem LABEL and UUID is actually quite important for liveOS etc., it will be really good to have them. On the other hand, since squashfs binary format is somehow fixed, maybe these information can be stored as two special files in the root directory? i.e. mksquashfs will create two files, /.label and /.uuid. Then the two special files can be read in "squashfs_fill_super" to fill the relative information into fs/super_block.

inixter commented 1 year ago

This feature is also very desirable for filesystem backups.

The user should have the option to specify the UUID when the filesystem is created, not just generate a random UUID.

szycha76 commented 1 year ago

[...] since squashfs binary format is somehow fixed, maybe these information can be stored as two special files in the root directory? i.e. mksquashfs will create two files, /.label and /.uuid. Then the two special files can be read in "squashfs_fill_super" to fill the relative information into fs/super_block.

Seems fair, though:

Some ideas where to put this two new chunks of information:

On the other hand, the UUID is just 16 bytes, and the label is a UTF-8 encoded string. Since the squashfs images are most frequently padded to the nearest 4KiB boundary, we could store this info at the end of all the *tables as a new simplistic structure:

  1. magic sequence (4 bytes?, i.e. SQID or whatever)
  2. UUID (16 bytes, set to all zeros if not present)
  3. Label Size (2 bytes), 0x0000 if no label (or 1 byte if You think 256 bytes for utf8 label is good enough for everyone)
  4. LABEL (utf8 encoded string of a length of Label Size bytes)

Procedure to read UUID/LABEL would be:

  1. read the superblock
  2. identify where the last FS header (footer?) structure ends
  3. seek for the magic sequence just after the FS end
  4. if present, read UUID (if not 0x0000....00) and label (if Label Size > 0)

Care should be taken to see if it won't break at least the kernel mounting such a structure, especially if the UUID+LABEL block would exceed the size required to pad FS to the nearest 4-KiB boundary. In that case, some additional gap could be introduced between other filesystem structures, so that we could fit in the padding to the next 4-KiB block. However, limited testing shows that kernel probably doesn't care much about squashfs trailing information, as long as it is 4-KiB padded, and unsquashfs doesn't care at all.

That would give us an option to have UUID and LABEL at no additional cost (I mean: fully backward compatible solution), that could easily be read, extracted, and modified if necessary.

jzvikart commented 1 year ago

+1, having support for UUID and label would be very useful.

chkno commented 1 year ago

Please see this patch (context) for a concrete example of the ad hoc workarounds that squashfs's lack of label support causes.

bcarnes commented 1 year ago

I'd added squashfs label & uuid capabilities for a project a few years back.

I did it via a superblock flag, and then (when that flag is present), an extra_info metadata block appears after the compression options metadata block.

It seemed to work quite nicely, with no changes needed to the linux kernel or other tools for backwards compatibility for mounting or extracting a squashfs with this extra info present.

The extra_info block is populated with (tag, length, value) triplets to be future proof, with tags defined for UUID and Label,

I cleaned it up a bit, and will create a pull request for comments - to see if this or something like it would be acceptable to merge upstream

Example of it in use:

$ mksquashfs stuff/ test.squashfs \
  -label MyLabel -uuid $(uuidgen) -noappend

$ blkid -p test.squashfs
test.squashfs: VERSION="4.0" FSBLOCKSIZE="131072" BLOCK_SIZE="131072" FSSIZE="4427708" LABEL="MyLabel" UUID="5a1b85ab-313a-4b75-bf9e-b282bf58ee72" TYPE="squashfs" USAGE="filesystem"

$ mkdir -p mnt && sudo mount test.squashfs mnt

$ ls -l /dev/disk/by-{label,uuid}
/dev/disk/by-label:
total 0
lrwxrwxrwx 1 root root 11 Sep  7 17:29 MyLabel -> ../../loop8

/dev/disk/by-uuid:
total 0
lrwxrwxrwx 1 root root 11 Sep  7 17:29 5a1b85ab-313a-4b75-bf9e-b282bf58ee72 -> ../../loop8

Example of building and deploying it (in a fresh Ubuntu 22.04 VM)

sudo apt install -y build-essential autoconf automake libtool pkg-config \
  git zlib1g-dev \
  gettext autopoint bison 

git clone -b uuid+label  https://github.com/bcarnes/squashfs-tools.git
git clone -b squashfs-uuid-label  https://github.com/bcarnes/util-linux.git

pushd squashfs-tools/squashfs-tools
make && sudo make install
popd

pushd util-linux
./autogen.sh && ./configure --prefix=/ && make && sudo make install
popd

# Avoid having to rebuild the systemd-udev's builtin blkid, for quick testing
sudo sed -i \
  's!IMPORT{builtin}="blkid"!IMPORT{program}="/sbin/blkid -o udev -p $tempnode"!' \
  /lib/udev/rules.d/60-persistent-storage.rules