The random rantings of a concerned programmer.

Invoking mount(2) in FreeBSD 8.x

July 17th, 2011 | Category: Random

So I’m still writing Go bindings for a lot of common FreeBSD functionality. Yesterday I implemented a means to list all mounted filesystems, so today I’m writing the bindings to mount(2) to mount/umount them.

If you look at the man page for mount, you’ll see that the function signature looks like this:

    int mount(const char *type, const char *dir, int flags, void *data);

The void* should scare you.

I haven’t been able to dig up any information about what the fuck should be passed to it (granted, I haven’t looked very hard because, judging from the contents of src/sbin/mount_*/*.c in the FreeBSD sources, it’s been entirely superseded by nmount.

    int nmount(struct iovec *iov, u_int niov, int flags);

Poking around, struct iovec (eventually included from sys/uio.h) is defined as this:

struct iovec {
    void *iov_base;
    size_t iov_len;
}

Effectively, nmount takes an array of these structs which effectively form a flattened vector of (key, value) tuples. As far as I can tell, iov_base is always a NULL-terminated char*, and iov_len should be strlen(iov_base) + 1 (for the NULL terminator).

Unfortunately, the only hints that man 2 nmount gives us is

The following options are required by all file
     systems:
           fstype     file system type name (e.g., ``procfs'')
           fspath     mount point pathname (e.g., ``/proc'')

     Depending on the file system type, other options may be recognized or
     required; for example, most disk-based file systems require a ``from''
     option containing the pathname of a special device in addition to the
     options listed above.

So far, the only way I’ve been able to find the actual options is to dig through mount_* sources and see what they use, but it’s pretty gross. Take, for example, the following two filesystems:

  • nullfs simply layers one vnode on top of another, effectively grafting one directory over another.
  • unionfs (roughly) does the same thing, but still lets you access the grafted-over directory in read-only mode (and can be configured to do cool shit like copy-on-write).

They’re pretty close, but let’s look at the arguments that each of them take:

nullfs
  • fstype: “nullfs”
  • fspath: Path to the directory to graft over.
  • target: Path of the directory that’s being grafted onto another.

IMHO, "target" should be "from", bikesheds, et. al.

unionfs
  • fstype: “unionfs”
  • fspath: Path to the directory where the unionfs will be mounted.
  • from: Same as “target”, above.
  • below: Makes “fspath” writable, “from” read-only (swaps default behavior)
  • errmsg: …I have no fucking idea, a char[255] which presumably is used as a buffer instead of errno?
  • …anything else passed as -oyour=mom passed to mount_unionfs?!

Maybe this is more a gripe that unionfs seems to be very shitty. And maybe I just haven’t found a nice magical table of options that every filesystem takes. But FFFFFF SERIOUSLY >:(

2 comments