Module Name:    src
Committed By:   pho
Date:           Wed Nov 23 14:33:29 UTC 2016

Modified Files:
        src/sbin/mount_puffs: mount_puffs.8 mount_puffs.c

Log Message:
Major rework on mount_puffs(8) so that it can actually start file servers

Now you can do
  # mount_puffs -o rdonly rot13fs#/home/foo /mnt/rot13

or in fstab
  rot13fs#/home/foo  /mnt/rot13  puffs  rdonly

to start rot13fs with arguments identical to
  # rot13fs -o rdonly /home/foo /mnt/rot13


To generate a diff of this commit:
cvs rdiff -u -r1.1 -r1.2 src/sbin/mount_puffs/mount_puffs.8
cvs rdiff -u -r1.4 -r1.5 src/sbin/mount_puffs/mount_puffs.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sbin/mount_puffs/mount_puffs.8
diff -u src/sbin/mount_puffs/mount_puffs.8:1.1 src/sbin/mount_puffs/mount_puffs.8:1.2
--- src/sbin/mount_puffs/mount_puffs.8:1.1	Thu Jan 14 21:25:48 2010
+++ src/sbin/mount_puffs/mount_puffs.8	Wed Nov 23 14:33:29 2016
@@ -1,4 +1,4 @@
-.\"	$NetBSD: mount_puffs.8,v 1.1 2010/01/14 21:25:48 pooka Exp $
+.\"	$NetBSD: mount_puffs.8,v 1.2 2016/11/23 14:33:29 pho Exp $
 .\"
 .\" Copyright (c) 2010 Antti Kantee.  All rights reserved.
 .\"
@@ -23,25 +23,107 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd January 14, 2010
+.Dd November 23, 2016
 .Dt MOUNT_PUFFS 8
 .Os
 .Sh NAME
 .Nm mount_puffs
-.Nd print arguments to puffs mounts
+.Nd helper utility for mounting puffs/refuse file systems
 .Sh SYNOPSIS
 .Nm
-.Fl o Ar getargs
-.Ar puffs
+.Op Fl o Ar options
+.Ar program Ns Op # Ns Ar source
 .Ar mount_point
 .Sh DESCRIPTION
 The
 .Nm
-program prints the kernel arguments for a puffs mount.
-It is typically executed by
+utility simply executes the given
+.Ar program ,
+allowing to mount
+.Xr puffs 4
+and
+.Xr refuse 3
+based file systems via
+.Ic mount -a
+or the
+.Xr fstab 5
+file.
+.Pp
+This command is usually only executed by
+.Xr mount 8 ,
+as users can directly execute file servers to mount them. The
+.Ar program
+parameter is either the path to the file server or the file name of
+it. In the latter case the
+.Ar program
+is searched in the
+.Ev PATH
+variable. The
+.Ar source
+parameter, when specified, will be passed to the
+.Ar program
+as its first non-option argument, with
+.Ar mount_point
+being the second one.
+.Pp
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl o
+Options are specified with a
+.Fl o
+flag followed by a comma separated string of options. They are passed to the
+.Ar program
+without any modifications except for
+.Cm getargs ,
+which is typically used by
 .Ic mount -vv .
+When there is
+.Cm getargs
+in the list,
+.Nm
+discards all the other options and prints the kernel arguments for a
+.Xr puffs 4
+file system already mounted at
+.Ar mount_point .
+.El
+.Sh EXAMPLES
+Mount
+.Ic dmesgfs
+at
+.Pa /dmesg :
+.Dl # mount_puffs dmesgfs /dmesg
+.Pp
+Or in
+.Xr fstab 5 :
+.Bd -literal -offset indent -compact
+dmegfs  /dmesg  puffs  rw
+.Ed
+.Pp
+These are equivalent to:
+.Dl # dmesgfs /dmesg
+.Pp
+Mount
+.Pa /usr/bin/rot13fs
+for
+.Pa /home/foo
+at
+.Pa /mnt/rot13
+with option
+.Fl o Cm rdonly :
+.Dl # mount_puffs -o rdonly /usr/bin/rot13fs#/home/foo /mnt/rot13
+.Pp
+Or in
+.Xr fstab 5 :
+.Bd -literal -offset indent -compact
+/usr/bin/rot13fs#/home/foo  /mnt/rot13  puffs  rdonly
+.Ed
+.Pp
+These are equivalent to:
+.Dl # /usr/bin/rot13fs -o rdonly /home/foo /mnt/rot13
 .Sh SEE ALSO
 .Xr puffs 4 ,
+.Xr refuse 3 ,
+.Xr fusermount 8 ,
 .Xr mount 8
 .Sh HISTORY
 The

Index: src/sbin/mount_puffs/mount_puffs.c
diff -u src/sbin/mount_puffs/mount_puffs.c:1.4 src/sbin/mount_puffs/mount_puffs.c:1.5
--- src/sbin/mount_puffs/mount_puffs.c:1.4	Mon Aug 29 14:35:02 2011
+++ src/sbin/mount_puffs/mount_puffs.c	Wed Nov 23 14:33:29 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: mount_puffs.c,v 1.4 2011/08/29 14:35:02 joerg Exp $	*/
+/*	$NetBSD: mount_puffs.c,v 1.5 2016/11/23 14:33:29 pho Exp $	*/
 
 /*
  * Copyright (c) 2010 Antti Kantee.  All Rights Reserved.
@@ -26,13 +26,14 @@
  */
 
 /*
- * This is to support -o getargs without having to replicate
- * it in every file server.
+ * This is to support -o getargs without having to replicate it in
+ * every file server. It also allows puffs filesystems to be mounted
+ * via "mount -a".
  */
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: mount_puffs.c,v 1.4 2011/08/29 14:35:02 joerg Exp $");
+__RCSID("$NetBSD: mount_puffs.c,v 1.5 2016/11/23 14:33:29 pho Exp $");
 #endif /* !lint */
 
 #include <sys/param.h>
@@ -41,61 +42,29 @@ __RCSID("$NetBSD: mount_puffs.c,v 1.4 20
 #include <fs/puffs/puffs_msgif.h>
 
 #include <err.h>
-#include <mntopts.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
+#include <sys/cdefs.h>
 #include <unistd.h>
+#include <util.h>
 
-const struct mntopt getargmopt[] = {
-	MOPT_GETARGS,
-	MOPT_NULL,
-};
-
-__dead static void
+static int
 usage(void)
 {
 
-	fprintf(stderr, "usage: %s -o getargs spec dir\n", getprogname());
-	exit(1);
+	fprintf(stderr, "usage: %s [-o options] program[#source] mountpoint\n", getprogname());
+	return 1;
 }
 
-int
-main(int argc, char *argv[])
+static int show_puffs_mount_args(const char *mountpoint)
 {
 	const char *vtypes[] = { VNODE_TYPES };
 	struct puffs_kargs kargs;
-	mntoptparse_t mp;
-	int mntflags, f;
-	int ch;
-
-	if (argc < 3)
-		usage();
 
-	mntflags = 0;
-	while ((ch = getopt(argc, argv, "o:")) != -1) {
-		switch (ch) {
-		case 'o':
-			mp = getmntopts(optarg, getargmopt, &mntflags, &f);
-			if (mp == NULL)
-				err(1, "getmntopts");
-			freemntopts(mp);
-			break;
-		default:
-			usage();
-		}
-	}
-	argc -= optind;
-	argv += optind;
-
-	if (argc != 2)
-		usage();
-
-	if (mntflags != MNT_GETARGS)
-		usage();
-
-	if (mount(MOUNT_PUFFS, argv[1], mntflags, &kargs, sizeof(kargs)) == -1)
+	if (mount(MOUNT_PUFFS, mountpoint, MNT_GETARGS, &kargs, sizeof(kargs)) == -1)
 		err(1, "mount");
-	
+
 	printf("version=%d, ", kargs.pa_vers);
 	printf("flags=0x%x, ", kargs.pa_flags);
 
@@ -111,3 +80,104 @@ main(int argc, char *argv[])
 
 	return 0;
 }
+
+static int
+mount_puffs_filesystem(const char *program, const char *opts,
+					const char *source, const char *mountpoint)
+{
+	int argc = 0;
+	const char **argv;
+	int rv = 0;
+
+	/* Construct an argument vector:
+	 * program [-o opts] [source] mountpoint */
+	argv = ecalloc(1 + 2 + 1 + 1, sizeof(*argv));
+	argv[argc++] = program;
+	if (opts != NULL) {
+		argv[argc++] = "-o";
+		argv[argc++] = opts;
+	}
+	if (source != NULL) {
+		argv[argc++] = source;
+	}
+	argv[argc++] = mountpoint;
+	argv[argc] = NULL;
+
+	/* We intentionally use execvp(3) here because the program can
+	 * actually be a basename. */
+	if (execvp(program, __UNCONST(argv)) == -1) {
+		warn("Cannot execute %s", program);
+		rv = 1;
+	}
+
+	free(argv);
+	return rv;
+}
+
+static void add_opt(char **opts, const char *opt)
+{
+	const size_t orig_len = *opts == NULL ? 0 : strlen(*opts);
+
+	*opts = erealloc(*opts, orig_len + 1 + strlen(opt) + 1);
+
+	if (orig_len == 0) {
+		strcpy(*opts, opt);
+	}
+	else {
+		strcat(*opts, ",");
+		strcat(*opts, opt);
+	}
+}
+
+int
+main(int argc, char *argv[])
+{
+	int mntflags = 0;
+	int ch;
+	char *opts = NULL;
+	int rv = 0;
+
+	while ((ch = getopt(argc, argv, "o:")) != -1) {
+		switch (ch) {
+		case 'o':
+			for (char *opt = optarg; (opt = strtok(opt, ",")) != NULL; opt = NULL) {
+				if (strcmp(opt, "getargs") == 0) {
+					mntflags |= MNT_GETARGS;
+					break; /* No need to parse it any further. */
+				}
+				else {
+					add_opt(&opts, opt);
+				}
+			}
+			break;
+		default:
+			rv = usage();
+			goto free_opts;
+		}
+	}
+	argc -= optind;
+	argv += optind;
+
+	if (argc != 2) {
+		rv = usage();
+		goto free_opts;
+	}
+
+	if (mntflags & MNT_GETARGS) {
+		/* Special case for -o getargs: retrieve kernel arguments for
+		 * an already mounted filesystem. */
+		rv = show_puffs_mount_args(argv[1]);
+	}
+	else {
+		/* Split the program name and source. This is to allow
+		 * filesystems to be mounted via "mount -a" i.e. /etc/fstab */
+		char *source  = argv[0];
+		char *program = strsep(&source, "#");
+
+		rv = mount_puffs_filesystem(program, opts, source, argv[1]);
+	}
+
+free_opts:
+	free(opts);
+	return rv;
+}

Reply via email to