Thanks to visit codestin.com
Credit goes to github.com

Skip to content

jaylogue/retro-fuse

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

32 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

retro-fuse

A user-space filesystem (FUSE) for accessing ancient Unix filesystems.

retro-fuse provides a way to mount filesystems created by ancient Unix systems on modern OSes. The initial version of retro-fuse supports filesystems created by both fifth and sixth-edition Unix (v5 and v6 Unix). It can also initialize such filesystems. Support for additional ancient filesystems, such as seventh-edition and early BSD filesystems, is planned for the future.

The design of retro-fuse is novel in that it incorprates source code from the original v6 Unix kernel. The ancient code has been "lightly" modernized to be palatable to current compilers, and adapted to run in userspace. This approach (made possible by Caldera’s generous open source license for ancient Unix) allows retro-fuse to support both reading and writing of ancient filesystems, while ensuring the historical fidelity of the on-disk structures.

retro-fuse provides support for a broad array of modern filesystem operations on top the basic capabilities of the original code. This includes support for modern rename(2) semantics and filesystem statistics gathering (e.g. via df(1)). Additionally, the code provides a modern C API, making it possible to incorporate ancient filesystem access into other projects.

The current version of retro-fuse runs on Linux. Support for MacOS is in the works (as of 2021/02).

Building

retro-fuse requires the libfuse-dev package, which can be installed on Ubuntu/debian-based systems as follows:

$ sudo apt install libfuse-dev

After the prerequisites have been installed, building is as simple as running make:

$ make

This produces an executable called v6fs. This program can be run directly, or it can be installed into /usr/local/sbin, which will allow v6 filesystems to be mounted using the standard mount(8) command (via the -t fuse.v6fs option).

Usage

To mount a v6 filesystem, run the v6fs command as follows:

v6fs [<options>] <device-or-image-file> <mount-point>

Alternatively, if the v6fs program has been installed in /sbin or /usr/local/sbin, you can use the mount command:

sudo mount -t fuse.v6fs [<options>] <device-or-image-file> <mount-point>

When executed directly, the v6fs program can be run by a non-root user. This is often more convenient than using the mount command, which must always be run as root.

Filesystem Location

The first non-option argument to the v6fs command is the storage location of the filesystem. This can be a regular file containing an image of the filesystem, or a standard Unix block device. In the case of a block device, it may be useful to specify an offset to the start of the filesystem using the -o fsoffset option.

Options

v6fs accepts the standard set of options supported by the mount(8) command, as well as the FUSE mount options described in mount.fuse(8). Additionally, it provides its own set of options useful for dealing with ancient filesystems.

The following is a summary of some of the more useful options:

-o ro

Mount the filesystem in read-only mode.

-o rw

Mount the filesystem in read-write mode. This is the default.

-o allow_root

Allow the root user to access the filesystem, in addition to the mounting user. Mutually exclusive with the allow_other option.

-o allow_other

Allow any user to access the filesystem, including root and the mounting user. Mutually exclusive with the allow_root option.

-o mapuid=<host-uid>:<fs-uid>
-o mapgid=<host-gid>:<fs-gid>

Map a particular user or group id on the host system to different id on the mounted filesystem. This is useful when accessing a filesystem containing files owned by root or other special users.

The specified id mapping applies both ways. Specifically, the uid/gid on the host is mapped to the corresponding id in the filesystem when performing access control checking, or when the id is stored with a file or directory. Conversely, the filesystem id is mapped to the host id whenever a file is stat()ed or a directory is read.

Multiple mapping options may be given, up to a limit of 100.

-o fssize=<blocks>

The size of the filesystem, in 512-byte blocks. This is used to limit I/O on the underlying device/image file, e.g. to protect against the case where the filesystem contains malformed block pointers. Defaults to the size given in the filesystem superblock.

-o fsoffset=<blocks>

Offset into the device/image at which the filesystem starts, in 512-byte blocks. Defaults to 0.

-o initfs
-o initfs=<isize>
-o initfs=<isize>:<n>:<m>

Create an empty filesystem on the underlying device/image file before mounting. When using the initfs option on an image file, the size of the filesystem must be specified via the fssize option.

isize gives the size of the filesystem’s inode table in 512-byte blocks (16 inodes per block). If not specified, or if 0 is given, the size of the inode table is computed automatically from the size of the filesystem, using the formula from the v6 mkfs(8) command.

n and m are the interleave parameters for the initial free block list. Traditionally, the v6 mkfs command used n=10,m=4 for rp devices, 24,3 for rk devices, and 1,1 (i.e. no interleave) for all other devices. If not specified, no interleave is used.

-f
--foreground

Run in foreground (useful for debugging).

-d
--debug

Enable debug output to stderr (implies -f)

-V
--version

Print version information

-h
--help

Print usage information.

Examples

Mount an image file containing v6 filesystem

$ v6fs root.dsk /mnt/tmp

Mount a v6 filesystem occupying a particular offset and size on a block device

$ v6fs -o fssize=4872,fsoffset=4194304 /dev/sdc /mnt/tmp

Mount a v6 filesystem, mapping the host’s user id 1000 to uid 3 on the filesystem

$ v6fs -o mapuid=1000:33 root.dsk /mnt/tmp

Mount a v6 filesystem as root, allowing other users to access it

$ sudo v6fs -oallow_other root.dsk /mnt/tmp

Initialize and mount a new filesystem having the same size as a DEC RK05 disk

$ v6fs -o initfs,fssize=4872 scratch.dsk /mnt/tmp

NOTE — When using the initfs option with an image file, the file must not exist when the command is invoked.

Initialize and mount a new filesystem with a specific number of inode blocks

$ v6fs -o initfs=200,fssize=4872 scratch.dsk /mnt/tmp

Unmount a filesystem that has been mounted by the active (non-root) user

$ fusermount -u /mnt/tmp

Unmount a filesystem that has been mounted by root or another user

$ sudo umount /mnt/tmp

Code Structure and Operation

The retro-fuse code has the following structure:

v6fs architecture

Source Modules

v6 kernel (ancient-src/v6/*.[ch]) — Modernized ancient Unix source code. Modifications to the ancient kernel code are purposefully minimal, and consist mostly of syntatical and type compatibility changes. Additionally, a series of #defines and selective hand editing is used to prefix functions and global variables with "v6_", so as to avoid conflicts with similarly named modern constructs.

v6adapt (src/v6adapt.[ch]) — Code supporting the modernized kernel code. This includes replacements for various Unix functions that either require significantly different behavior in the retro-fuse context, or were originally written in PDP-11 assembly.

v6fs (src/v6fs.[ch]) — Provides a modern API for accessing v6 filesystems. The v6fs API closely mimics the modern Unix filesystem API, with the notible exception that errors are returned as return values rather than via errno. This API is designed such that it could be reused outside of the context of a FUSE filesystem.

v6fuse (src/v6fuse.c) — Main program implementing a mountable FUSE filesystem. The primary purpose of the v6fuse module is to handle filesystem I/O requests from the host kernel via the libfuse library. Implements a variety of command-line options to make it easier to work with ancient filesystems.

dsk (src/dsk.[ch]) — Provides a simple abstraction of a virtual block-oriented disk device. Supports filesystems contained in image files as well as host block devices (e.g. a MicroSD card).

License

The modern portions of retro-fuse are licensed under the Apache 2.0 license. Code derived from ancient Unix source is licensed under Caldera open source license.

Release Notes

Version 2 / 2021/03/02 — Fixed bug in link(), unlink(), chmod() and chown() that caused the files modified time to be updated (this fixes problems with rsync). Minor modifications to error handling.

Version 1 / 2021/02/23 — Initial release.

About

A FUSE module for accessing ancient Unix filesystems.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published