#include <sys/param.h>
#include <sys/diskslice.h>
#include <sys/diskmbr.h>
#include <sys/stat.h>
#include <sys/mount.h>
#include <sys/sysctl.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stddef.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <uuid.h>
#include <err.h>
#include <assert.h>
#include <ctype.h>
#include <mntopts.h>
#define MOPT_UPDATE { "update", 0, MNT_UPDATE, 0 }
#define PLATFORM_LEN 16
static struct mntopt mopts[] = { MOPT_STDOPTS, MOPT_UPDATE, MOPT_NULL };
static void usage(void);
int
main(int ac, char **av)
{
struct vfsconf vfc;
int mount_flags = 0;
int error;
int ch;
int init_flags = 0;
char *mountpt, *hostdir;
size_t vsize;
char platform[PLATFORM_LEN] = {0};
mount_flags = 0;
while ((ch = getopt(ac, av, "o:u")) != -1) {
switch(ch) {
case 'u':
init_flags |= MNT_UPDATE;
break;
case 'o':
getmntopts(optarg, mopts, &mount_flags, NULL);
break;
default:
usage();
}
}
ac -= optind;
av += optind;
mount_flags |= init_flags;
vsize = PLATFORM_LEN;
error = sysctlbyname("hw.platform", &platform, &vsize, NULL,0);
if (error)
errx(1, "Failed to get hw.platform sysctl");
if (strnstr(platform, "vkernel", PLATFORM_LEN) == NULL)
errx(1, "dirfs is only available for vkernels.");
if (init_flags & MNT_UPDATE) {
if (ac != 1) {
usage();
}
mountpt = av[0];
if (mount(vfc.vfc_name, mountpt, mount_flags, NULL))
err(1, "mountpoint %s", mountpt);
exit(0);
}
if (ac < 2) {
usage();
}
hostdir = av[0];
mountpt = av[1];
error = getvfsbyname("dirfs", &vfc);
if (error && vfsisloadable("dirfs")) {
if (vfsload("dirfs") != 0)
err(1, "vfsload(dirfs)");
endvfsent();
error = getvfsbyname("dirfs", &vfc);
}
if (error)
errx(1, "dirfs filesystem is not available");
error = mount(vfc.vfc_name, mountpt, mount_flags, hostdir);
if (error)
err(1, "failed to mount %s on %s", hostdir, mountpt);
exit (0);
}
static
void
usage(void)
{
fprintf(stderr, "usage: mount_dirfs [-u] [-o options] "
"hostdir dir\n");
exit(1);
}