Invoking mount(2) in FreeBSD 8.x
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