Personal tools
Views
Translators
Contents |
What are translators?
Translators are a massively important thing in the Hurd; they mount filesystems, handle device nodes, and can provide symlinks to filesystems which don't support them natively. But what are they, exactly? Consider your every-day average *NIX filesystem. It contains files, directories, and device nodes. These things look similar, but have very different properties. In, say, Linux if you wanted to add something new you'd need to write a device driver or a FUSE filesystem, which requires a kernel module running anyway. In the Hurd, things are a little different. If you want something new, you write a translator to handle it and, unless it requires accessing any low-level stuff, you can leave the kernel alone and run it in userspace.
Put simply, a translator sits between the user and the filesystem, and handles requests from the user in different ways. An example is the translator for /dev/null. In Linux, this is a device implemented in the kernel, in the Hurd, a user-space translator provides it. Another example is your root filesystem. The ext2fs translator receives incoming requests to read or write data, and passes those on to the kernel as requests to do things with the partition, ext2fs then returns the data to the user. Obviously, that is a translator which does require kernel-level code to work.
What about symlinks? Well, most filesystems used in *NIX provide some functionality for symlinks, but what about a filesystem with no symlink support? You could write a translator to sit in a specific file, and redirect all requests to another file. Thus, symlinks are formed.
Passive and Active Translators
There are two types of translators in the Hurd, passive and active. When you start an active translator, it starts immediately, regardless of whether you ever try to use it. In contrast, a passive translator starts running when you access it. For example, you could 'mount' a filesystem, but rather than mount it immediately, have it mount only when you try to access it.
The other main difference between active and passive translators is persistance. If an active translator dies or is killed at some point, it stays dead until you manually restart it. However, a passive translator has information about itself written to the underlying filesystem, and so can be restarted, even between boots.
Examples
Hello, world!
Of course, Hurd has a hello world translator:
settrans -cg hello /hurd/hello cat hello
Behold, the text "Hello, world!" appears! Now, what just happened here? Well, you started the hello translator watching a file named hello, and then tried to read that file. The read request was sent to the translator, which returned the string "Hello, world!". Of course, you can achieve the same effect by having a file containing that text, but it serves as a simple example of how translators work.
Delete the translator by stopping it:
settrans -fg hello
Satisfy yourself that the file which remains is, in fact, empty, and then delete it.
Mount
In Hurd, the mount command is actually a wrapper around settrans. You may have noticed there is no umount. Do you want to know how to really 'mount' things in Hurd? This is what your mount command does:
settrans -a $path /hurd/ext2fs --writable $device
That's not just a regular mount, that's a mount which will persist between reboots. You don't even need an /etc/fstab file for permanent mounts, translators make this simple to achieve on the Hurd. But how do you unmount things? Well, it's the same way you kill any other translator:
settrans -fg $path
But for internal HDDs (the only kind you'll be dealing with, as the Hurd doesn't support USB yet), there is no need to unmount partitions before rebooting, the translator will handle that for you. And when you boot up again, if you didn't kill the translator, simply accessing the mounted partition will have the translator mount it for you.
Translators
The following translators are included in the hurd package in ArchHurd, you don't have to install them. You don't have to be root to use translators. They're all located in /hurd.
The options -fg are used to force the translator to go away.
nfs
With the nfs translator you can mount nfs shares in Hurd.
settrans -cafg /mount/point/ /hurd/nfs server:/share
You can also use mount for this task.
mount -t nfs server:/share /mount/point
ftpfs
ftpfs makes it possible to access ftp shares.
settrans -cfg ftp /hurd/ftpfs SERVER:/remote/path
hostmux
A translator for invoking host-specific translators.
This translator creates pseudo directories by accessing the node with different arguments.
Here an example with the nfs translator.
settrans -cafg nfs: /hurd/hostmux /hurd/nfs SERVER
Now you can access the shares on the server.
ls nfs:/public
ls nfs:/path/to/nothing/
You can also access different servers with this method
settrans -cafg nfs: /hurd/hostmux /hurd/nfs /
ls nfs:/SERVER/path
ls nfs:/192.168.0.1
Pretty cool, isn't it?
usermux
A translator for invoking user-specific translators.
Somewhat more complicated than hostmux and no example for real use at the moment.
unionfs
This translator allows to join different directories into one directory.
settrans -cafg union /hurd/unionfs /bin /home /lib
storeio
storeio is like losetup on linux, but with more advantages. It also supports compression with gzip and bzib2 or normal files.
It creates a block device with the given file or arguments.
settrans -ca loop0 /hurd/storeio -T file FILE
settrans -ca loop1 /hurd/storeio -T gunzip FILE.gz
ATTENTION: storeio can not size the given file. A possibility to create a file with a given size is to use dd.
dd if=/dev/null of=FILE bs=42MB
This will create an empty file with the size of 42MB. You can now work with the new block device. You can use it as temporary filesystem (ramdisk) or as portable filesystem.
ramdisk
settrans -ca ramdisk0 /hurd/storeio -T copy zero:32M mkfs.ext2 -F -b 4096 ramdisk0 settrans -ao ramdisk0 /hurd/ext2fs.static ramdisk0
First we create a buffer with copy and getting the size with zero. (Just like dd, but without invoking a file) Then we create the filesystem on our blockdevice and mounting it with ext2fs. The argument -o (orphan) replaces the previous translator with a new one without forcing it away.
portable vfs
The following example shows how to create virtual filesystems in a file.
dd if=/dev/zero of=your.img bs=SIZE settrans -ca loop0 /hurd/storio -T file your.img mkfs.ext2 -F -b 4096 loop0 settrans -ca mount /hurd/ext2fs.static loop0
Fist create a file with any size and create the block device with storeio then create the filesystem and mount it.
You can also lay the translators on top of each other.
settrans -a your.img /hurd/storeio -T file your.img settrans -ao your.img /hurd/ext2fs your.img
The file your.img is now a directory and you can use it as such.
cp your things your.img/ ls your.img/things/
To unmount the filesystem.
settrans -g your.img
ATTENTION: I noticed that if you lay one translator onto another you can only remove the one on top. I don't know if this is a feature or bug, but after that procedure you only need to use ext2fs to mount the image, which is pretty handy after all. nsmux/filter allows you to access a translator deeper inside the stack.