fusefile(8)

πŸŽ€ NAME πŸŽ€

fusefile, fusedisk β€” a FUSE file mount for combining file fragments 🧩✨

So this is fusefile(8), bestie, straight outta the System Manager's Manual. Two names, one iconic little tool, and it's about to make your fragments look like one big slay file. πŸ’…


πŸ¦‹ SYNOPSIS πŸ¦‹

fusefile [fuse-opts] mountpoint [overlay] filename/from-to ...
fusefile -dump [fuse-opts] mountpoint [overlay] filename/from-to ...
fusefile -push [fuse-opts] mountpoint [overlay] filename/from-to ...
fusedisk [fuse-opts] mountpoint [overlay] filename/from-to ...

🌸 DESCRIPTION 🌸

Okay so picture this: fusefile is a FUSE file mount that takes a whole series of fragments from other files and presents them like they're one single, contiguous concatenation. 🫢 Technically, it bind mounts a driver on top of the filename mountpoint so you can access all those given file fragments as if they lived in one single, contiguous file. Main character energy, honestly.

fusefile is totally fine with over-writing on the fused file (that's the mountpoint, btw) β€” and those writes get distributed accordingly to the fragments. πŸ’– But heads up: neither the fused file nor the fragments can change size. Any writing just over-writes content, no truncating fragments, periodt. Also, all the fragment files stay held open the whole time fusefile is active. No cap.

If you use the optional -overlay:filename argument β€” and you slide it in between the mount point and the fragments β€” you can set up an overlay file. πŸ‘‘ That overlay file then gets used by fusefile to capture writes to the fused file (yep, the mountpoint). The overlay file will contain any new written fused file regions, followed by meta data so it can tell the difference between new, written content and old content that comes from the fragments. It's giving receipts. 🧾

Or, instead, use the -overlay:list argument, where list is a colon-separated list of filenames. Then fusefile uses those as an ordered stack of overlays and "injects" them as fragments on top of each other. Stacked. Layered. Iconic. 🌈

Now, the -dump option as the first argument, together with a fusefile setup, will print the setup to standard output instead of establishing a fusefile mount. πŸ’… This is most useful with a prior overlay setup, because then the printout includes the portions of updates that got captured in the overlay. The printout is the series of fusefile fragment arguments to give in order to intersperse those captured overlay portions according to the overlay table.

And the -push option as the first argument, together with a fusefile setup, will push the overlay into the sources (except for write-protected fragments, obviously πŸ™ˆ). This is only of use with a prior overlay setup, where the updates captured in the overlay get pushed into the fragments. Push it, push it. πŸ”₯

Then there's fusedisk, which is a helper script that sets up a fusefile as a block device (via fuseblk) by using the device mapper (dmsetup) to manage an empty block device mapping where content is handled at the mountpoint via fusefile. 🌸

Note, bestie: the same thing may be done with the device manager directly, but then all fragments need to be in sectors of N*512 bytes β€” whereas with fusedisk, only the fused file as a whole is "clipped" at the nearest N*512 bytes below actual size. πŸ‘‘

✨ FRAGMENT ARGUMENTS ✨

The fragment arguments include the filename of a source file, and optionally start and end byte positions. All in all there are five variations: πŸŽ€

  • filename or filename/ β€” include all of the file. A pathname that includes / must be ended with an extra /, because that last / is what separates the filename from the range detail. Don't forget it, fr fr.
  • filename/start:end β€” include the range from the given start to end. Either start or end or both may be omitted, meaning the beginning and end of the file respectively. And if start or end are less than 0, that means relative to the end of the file. πŸ’«
  • filename/start+length β€” include length bytes from the given start. A negative start means relative to the end of the file. If length is negative or omitted, it means that position relative to the end.
  • filename/start β€” include bytes from the given start. This is the same as "/start+".

Quick notes, because details matter: a negative start position gets clipped to 0, and a too-large end position gets clipped to the end of the file. No drama, just clipping. βœ‚οΈ

Character devices are treated as being of any given finite size, but have size 0 by default. So for example, "/dev/zero/:100" means a fragment of 100 NUL bytes. πŸ“


πŸ’… OPTIONS πŸ’…

This section enumerates the most interesting options to use with fuesfile. (Yes, that's how it's spelled up in here, bestie, we don't gatekeep.) See man fuse and man mount for more options. πŸ¦‹

  • -dump β€” the -dump "option" tells fusefile to print out the applicable fragment sequence for the current setup, including the overlay table, if any. The printout happens instead of setting up a mount point. 🫢
  • -oallow_other β€” the fuse option -oallow_other is needed for sharing the fused file with other users who otherwise won't have access to it (including "root"). ⚠️ Note however that this must first be enabled in /etc/fuse.conf.
  • -ononempty β€” the fuse option -ononempty may need to be used when reusing an existing file as a mountpoint. πŸŽ€
  • -ouid=... and -ogid=... β€” these mount options, where ... is a user or group id respectively, are useful for root when using fusedisk, and thereby give user or group ownership for the mount to the nominated user or group. πŸ‘‘

🌈 EXAMPLES 🌈

This section illustrates uses of fusefile. Get ready, these ate. πŸ”₯

⭐ Exanple 1.

Insert a file "y" into a file "x" at position 1200.

$ fusefile -ononempty x x/:1200 y x/1200:

This also shadows the original file "x" and presents the fused file instead. 🌸

⭐ Example 2.

Make fused file y be a swap of the beginning and end of file "x", at position 2442.

$ fusefile y x/2442: x/:2442

⭐ Example 3.

Replace partition 2 of an image file, A, with a different file, X. For this example the partition table looks as follows.

$ partx -oNR,START,SECTORS A
    NR   START  SECTORS
     1    2048  2097152
     2 2099200   409600
     3 2508800 14268383

As each sector is 512 bytes, the clipping points around partition 2 are 1074790400 and 1284505600, and the insertion size is 209715200 bytes. The fusefile comman will therefore be as follows. πŸ’–

$ fusefile -ononempty A A/:1074790400 X/:209715200 A/1284505600
Note that the fused file shadows the original file A. 🫢

⭐ Example 4.

Protect raw disk image file with an overlay:

$ fusefile -ononempty disk.raw -overlay:today disk.raw

By that set up, the overlay file, "today", will protect the disk image file, "disk.raw", from changes, and also override the pathname "disk.raw" to be the fused file. πŸ›‘οΈβœ¨

⭐ Example 5.

A fusefile mount with an overlay file is writable regardless of the fused fragments, but all updates are written to the overlay file instead of to the fragments.

$ fusefile -ononempty A -overlay:B A

The overlay file, B in the example, contains all changes to the shadowed original file, A. The overlay file contains only the newly written regions, and content is otherwise obtained from the original file. πŸ‘‘

To that end, the overlay file also contains a "marker table" at the end, as if appended to the fused file. That part of the file is outside of the fused file; and it's simply an element count followed by pairs of byte addresses that tell which regions of the fused file have been captured into the overlay file. (The marker table is of course maintained so that adjoining regions are collapsed. 🧩)

Thus, an overlay file may be reused to later re-establish the same fused file with overlay as previously, to continue capturing more changes. Reuse era. ♻️

⭐ Example 6.

As final example, we set up a fused block device y as a swap of the beginning and end of file "x", at position 2442:

$ sudo fusedisk -ouid=1000 y x/2442: x/:2442

Note the use of sudo for becoming root, which is required for block device handling, and also the -ouid=1000 option so as to make the block device y be owned by the user with id 1000. πŸ’œ


🧚 NOTES 🧚

fusefile opens the nominated source files before any bind mounting. With the fuse option -ononempty it will bind over an non-empty file, which may be useful. The source files remain open, but the source fragments are not recomputed. If a source file changes, the fused file will present the new content. But if a source is reduced in size, access will be inconsistent. 😭

Lowkey important, bestie β€” that inconsistent-access thing is real. Don't shrink your sources while this is mounted. πŸ’€

If the mountpoint file doesn't exist, then fusefile creates it. ✨

Unmounting is done with "fusermount -u mountpoint" as usual. A fusedisk mount is unmounted by root using umount. 🌸


πŸ”— SEE ALSO πŸ”—

fuse, fusermount, mount, dmsetup


πŸ‘‘ AUTHOR πŸ‘‘

Ralph RΓΆnnquist <ralph.ronnquist@gmail.com>.


And that's the whole vibe, bestie β€” this was the fusefile(8) page from the System Manager's Manual, mwah πŸ’‹, go stitch some files together and slay. πŸŽ€βœ¨πŸ¦‹

πŸ“¦ where this page comes from