xref: /dragonfly/sbin/mount_tmpfs/mount_tmpfs.c (revision 25a86e44)
17a2de9a4SMatthew Dillon /*	$NetBSD: mount_tmpfs.c,v 1.24 2008/08/05 20:57:45 pooka Exp $	*/
27a2de9a4SMatthew Dillon 
37a2de9a4SMatthew Dillon /*
47a2de9a4SMatthew Dillon  * Copyright (c) 2005, 2006 The NetBSD Foundation, Inc.
57a2de9a4SMatthew Dillon  * All rights reserved.
67a2de9a4SMatthew Dillon  *
77a2de9a4SMatthew Dillon  * This code is derived from software contributed to The NetBSD Foundation
87a2de9a4SMatthew Dillon  * by Julio M. Merino Vidal, developed as part of Google's Summer of Code
97a2de9a4SMatthew Dillon  * 2005 program.
107a2de9a4SMatthew Dillon  *
117a2de9a4SMatthew Dillon  * Redistribution and use in source and binary forms, with or without
127a2de9a4SMatthew Dillon  * modification, are permitted provided that the following conditions
137a2de9a4SMatthew Dillon  * are met:
147a2de9a4SMatthew Dillon  * 1. Redistributions of source code must retain the above copyright
157a2de9a4SMatthew Dillon  *    notice, this list of conditions and the following disclaimer.
167a2de9a4SMatthew Dillon  * 2. Redistributions in binary form must reproduce the above copyright
177a2de9a4SMatthew Dillon  *    notice, this list of conditions and the following disclaimer in the
187a2de9a4SMatthew Dillon  *    documentation and/or other materials provided with the distribution.
197a2de9a4SMatthew Dillon  *
207a2de9a4SMatthew Dillon  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
217a2de9a4SMatthew Dillon  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
227a2de9a4SMatthew Dillon  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
237a2de9a4SMatthew Dillon  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
247a2de9a4SMatthew Dillon  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
257a2de9a4SMatthew Dillon  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
267a2de9a4SMatthew Dillon  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
277a2de9a4SMatthew Dillon  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
287a2de9a4SMatthew Dillon  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
297a2de9a4SMatthew Dillon  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
307a2de9a4SMatthew Dillon  * POSSIBILITY OF SUCH DAMAGE.
317a2de9a4SMatthew Dillon  */
327a2de9a4SMatthew Dillon 
337a2de9a4SMatthew Dillon #include <sys/param.h>
347a2de9a4SMatthew Dillon #include <sys/mount.h>
357a2de9a4SMatthew Dillon #include <sys/stat.h>
367a2de9a4SMatthew Dillon 
37f3c171e4SMarkus Pfeiffer #include <vfs/tmpfs/tmpfs_mount.h>
387a2de9a4SMatthew Dillon 
397a2de9a4SMatthew Dillon #include <ctype.h>
407a2de9a4SMatthew Dillon #include <err.h>
417a2de9a4SMatthew Dillon #include <errno.h>
427a2de9a4SMatthew Dillon #include <grp.h>
432dc55a02SSascha Wildner #include <mntopts.h>
447a2de9a4SMatthew Dillon #include <pwd.h>
457a2de9a4SMatthew Dillon #include <stdio.h>
467a2de9a4SMatthew Dillon #include <stdlib.h>
477a2de9a4SMatthew Dillon #include <string.h>
487a2de9a4SMatthew Dillon #include <sysexits.h>
497a2de9a4SMatthew Dillon #include <unistd.h>
507a2de9a4SMatthew Dillon #include <inttypes.h>
51ef20d754SMatthew Dillon #include <libutil.h>
527a2de9a4SMatthew Dillon 
53b8170153SSascha Wildner #include "defs.h"
547a2de9a4SMatthew Dillon #include "mount_tmpfs.h"
557a2de9a4SMatthew Dillon 
567a2de9a4SMatthew Dillon /* --------------------------------------------------------------------- */
577a2de9a4SMatthew Dillon 
58817a2fd9SMatthew Dillon #define MOPT_TMPFSOPTS	\
59817a2fd9SMatthew Dillon 	{ "gid=",	0,	MNT_GID, 1},	\
60817a2fd9SMatthew Dillon 	{ "uid=",	0,	MNT_UID, 1},	\
61817a2fd9SMatthew Dillon 	{ "mode=",	0,	MNT_MODE, 1},	\
62817a2fd9SMatthew Dillon 	{ "inodes=",	0,	MNT_INODES, 1},	\
63817a2fd9SMatthew Dillon 	{ "size=",	0,	MNT_SIZE, 1},	\
64817a2fd9SMatthew Dillon 	{ "maxfilesize=",	0,	MNT_MAXFSIZE, 1}
65817a2fd9SMatthew Dillon 
66817a2fd9SMatthew Dillon 
677a2de9a4SMatthew Dillon static const struct mntopt mopts[] = {
687a2de9a4SMatthew Dillon 	MOPT_STDOPTS,
69817a2fd9SMatthew Dillon 	MOPT_TMPFSOPTS,
707a2de9a4SMatthew Dillon 	MOPT_NULL
717a2de9a4SMatthew Dillon };
727a2de9a4SMatthew Dillon 
73b8170153SSascha Wildner static int Cflag;
74b8170153SSascha Wildner 
757a2de9a4SMatthew Dillon /* --------------------------------------------------------------------- */
767a2de9a4SMatthew Dillon 
777a2de9a4SMatthew Dillon static gid_t	a_gid(char *);
787a2de9a4SMatthew Dillon static uid_t	a_uid(char *);
797a2de9a4SMatthew Dillon static mode_t	a_mask(char *);
80817a2fd9SMatthew Dillon static int64_t a_number(char *s);
817a2de9a4SMatthew Dillon static void	usage(void) __dead2;
827a2de9a4SMatthew Dillon 
837a2de9a4SMatthew Dillon /* --------------------------------------------------------------------- */
847a2de9a4SMatthew Dillon 
857a2de9a4SMatthew Dillon void
mount_tmpfs_parseargs(int argc,char * argv[],struct tmpfs_mount_info * args,int * mntflags,char * canon_dev,char * canon_dir)867a2de9a4SMatthew Dillon mount_tmpfs_parseargs(int argc, char *argv[],
87*25a86e44SMarkus Pfeiffer 	struct tmpfs_mount_info *args, int *mntflags,
887a2de9a4SMatthew Dillon 	char *canon_dev, char *canon_dir)
897a2de9a4SMatthew Dillon {
907a2de9a4SMatthew Dillon 	int gidset, modeset, uidset; /* Ought to be 'bool'. */
917a2de9a4SMatthew Dillon 	int ch;
927a2de9a4SMatthew Dillon 	gid_t gid;
937a2de9a4SMatthew Dillon 	uid_t uid;
947a2de9a4SMatthew Dillon 	mode_t mode;
957a2de9a4SMatthew Dillon 	struct stat sb;
96817a2fd9SMatthew Dillon 	int extend_flags = 0;
97817a2fd9SMatthew Dillon 	char *ptr, *delim;
987a2de9a4SMatthew Dillon 
997a2de9a4SMatthew Dillon 	/* Set default values for mount point arguments. */
1007a2de9a4SMatthew Dillon 	memset(args, 0, sizeof(*args));
1017a2de9a4SMatthew Dillon 	args->ta_version = TMPFS_ARGS_VERSION;
1027a2de9a4SMatthew Dillon 	args->ta_size_max = 0;
1037a2de9a4SMatthew Dillon 	args->ta_nodes_max = 0;
104817a2fd9SMatthew Dillon 	args->ta_maxfsize_max = 0;
1057a2de9a4SMatthew Dillon 	*mntflags = 0;
1067a2de9a4SMatthew Dillon 
1077a2de9a4SMatthew Dillon 	gidset = 0; gid = 0;
1087a2de9a4SMatthew Dillon 	uidset = 0; uid = 0;
1097a2de9a4SMatthew Dillon 	modeset = 0; mode = 0;
1107a2de9a4SMatthew Dillon 
1117a2de9a4SMatthew Dillon 	optind = optreset = 1;
112b8170153SSascha Wildner 	while ((ch = getopt(argc, argv, "Cf:g:m:n:o:s:u:")) != -1 ) {
1137a2de9a4SMatthew Dillon 		switch (ch) {
114b8170153SSascha Wildner 		case 'C':
115b8170153SSascha Wildner 			Cflag = 1;
116b8170153SSascha Wildner 			break;
117817a2fd9SMatthew Dillon 		case 'f':
118817a2fd9SMatthew Dillon 			args->ta_maxfsize_max = a_number(optarg);
119817a2fd9SMatthew Dillon 			break;
120817a2fd9SMatthew Dillon 
1217a2de9a4SMatthew Dillon 		case 'g':
1227a2de9a4SMatthew Dillon 			gid = a_gid(optarg);
1237a2de9a4SMatthew Dillon 			gidset = 1;
1247a2de9a4SMatthew Dillon 			break;
1257a2de9a4SMatthew Dillon 
1267a2de9a4SMatthew Dillon 		case 'm':
1277a2de9a4SMatthew Dillon 			mode = a_mask(optarg);
1287a2de9a4SMatthew Dillon 			modeset = 1;
1297a2de9a4SMatthew Dillon 			break;
1307a2de9a4SMatthew Dillon 
1317a2de9a4SMatthew Dillon 		case 'n':
132817a2fd9SMatthew Dillon 			args->ta_nodes_max = a_number(optarg);
1337a2de9a4SMatthew Dillon 			break;
1347a2de9a4SMatthew Dillon 
1357a2de9a4SMatthew Dillon 		case 'o':
136817a2fd9SMatthew Dillon 			getmntopts(optarg, mopts, mntflags, &extend_flags);
137817a2fd9SMatthew Dillon 			if (extend_flags & MNT_GID) {
138817a2fd9SMatthew Dillon 				ptr = strstr(optarg, "gid=");
139817a2fd9SMatthew Dillon 				if(ptr) {
140817a2fd9SMatthew Dillon 					delim = strstr(ptr, ",");
141817a2fd9SMatthew Dillon 					if (delim) {
142817a2fd9SMatthew Dillon 						*delim = '\0';
143817a2fd9SMatthew Dillon 						gid = a_gid(ptr + 4);
144817a2fd9SMatthew Dillon 						*delim = ',';
145817a2fd9SMatthew Dillon 					} else
146817a2fd9SMatthew Dillon 						gid = a_gid(ptr + 4);
147817a2fd9SMatthew Dillon 					gidset = 1;
148817a2fd9SMatthew Dillon 				}
149817a2fd9SMatthew Dillon 				extend_flags ^= MNT_GID;
150817a2fd9SMatthew Dillon 			}
151817a2fd9SMatthew Dillon 			if (extend_flags & MNT_UID) {
152817a2fd9SMatthew Dillon 				ptr = strstr(optarg, "uid=");
153817a2fd9SMatthew Dillon 				if(ptr) {
154817a2fd9SMatthew Dillon 					delim = strstr(ptr, ",");
155817a2fd9SMatthew Dillon 					if (delim) {
156817a2fd9SMatthew Dillon 						*delim = '\0';
157817a2fd9SMatthew Dillon 						uid = a_uid(ptr + 4);
158817a2fd9SMatthew Dillon 						*delim = ',';
159817a2fd9SMatthew Dillon 					} else
160817a2fd9SMatthew Dillon 						uid = a_uid(ptr + 4);
161817a2fd9SMatthew Dillon 					uidset = 1;
162817a2fd9SMatthew Dillon 				}
163817a2fd9SMatthew Dillon 				extend_flags ^= MNT_UID;
164817a2fd9SMatthew Dillon 			}
165817a2fd9SMatthew Dillon 			if (extend_flags & MNT_MODE) {
166817a2fd9SMatthew Dillon 				ptr = strstr(optarg, "mode=");
167817a2fd9SMatthew Dillon 				if(ptr) {
168817a2fd9SMatthew Dillon 					delim = strstr(ptr, ",");
169817a2fd9SMatthew Dillon 					if (delim) {
170817a2fd9SMatthew Dillon 						*delim = '\0';
171817a2fd9SMatthew Dillon 						mode = a_mask(ptr + 5);
172817a2fd9SMatthew Dillon 						*delim = ',';
173817a2fd9SMatthew Dillon 					} else
174817a2fd9SMatthew Dillon 						mode = a_mask(ptr + 5);
175817a2fd9SMatthew Dillon 					modeset = 1;
176817a2fd9SMatthew Dillon 				}
177817a2fd9SMatthew Dillon 				extend_flags ^= MNT_MODE;
178817a2fd9SMatthew Dillon 			}
179817a2fd9SMatthew Dillon 			if (extend_flags & MNT_INODES) {
180817a2fd9SMatthew Dillon 				ptr = strstr(optarg, "inodes=");
181817a2fd9SMatthew Dillon 				if(ptr) {
182817a2fd9SMatthew Dillon 					delim = strstr(ptr, ",");
183817a2fd9SMatthew Dillon 					if (delim) {
184817a2fd9SMatthew Dillon 						*delim = '\0';
185817a2fd9SMatthew Dillon 						args->ta_nodes_max = a_number(ptr + 7);
186817a2fd9SMatthew Dillon 						*delim = ',';
187817a2fd9SMatthew Dillon 					} else
188817a2fd9SMatthew Dillon 						args->ta_nodes_max = a_number(ptr + 7);
189817a2fd9SMatthew Dillon 				}
190817a2fd9SMatthew Dillon 				extend_flags ^= MNT_INODES;
191817a2fd9SMatthew Dillon 			}
192817a2fd9SMatthew Dillon 			if (extend_flags & MNT_SIZE) {
193817a2fd9SMatthew Dillon 				ptr = strstr(optarg, "size=");
194817a2fd9SMatthew Dillon 				if(ptr) {
195817a2fd9SMatthew Dillon 					delim = strstr(ptr, ",");
196817a2fd9SMatthew Dillon 					if (delim) {
197817a2fd9SMatthew Dillon 						*delim = '\0';
198817a2fd9SMatthew Dillon 						args->ta_size_max = a_number(ptr + 5);
199817a2fd9SMatthew Dillon 						*delim = ',';
200817a2fd9SMatthew Dillon 					} else
201817a2fd9SMatthew Dillon 						args->ta_size_max = a_number(ptr + 5);
202817a2fd9SMatthew Dillon 				}
203817a2fd9SMatthew Dillon 				extend_flags ^= MNT_SIZE;
204817a2fd9SMatthew Dillon 			}
205817a2fd9SMatthew Dillon 			if (extend_flags & MNT_MAXFSIZE) {
206817a2fd9SMatthew Dillon 				ptr = strstr(optarg, "maxfilesize=");
207817a2fd9SMatthew Dillon 				if(ptr) {
208817a2fd9SMatthew Dillon 					delim = strstr(ptr, ",");
209817a2fd9SMatthew Dillon 					if (delim) {
210817a2fd9SMatthew Dillon 						*delim = '\0';
211817a2fd9SMatthew Dillon 						args->ta_maxfsize_max = a_number(ptr + 12);
212817a2fd9SMatthew Dillon 						*delim = ',';
213817a2fd9SMatthew Dillon 					} else
214817a2fd9SMatthew Dillon 						args->ta_maxfsize_max = a_number(ptr + 12);
215817a2fd9SMatthew Dillon 				}
216817a2fd9SMatthew Dillon 				extend_flags ^= MNT_MAXFSIZE;
217817a2fd9SMatthew Dillon 			}
2187a2de9a4SMatthew Dillon 			break;
2197a2de9a4SMatthew Dillon 
2207a2de9a4SMatthew Dillon 		case 's':
221817a2fd9SMatthew Dillon 			args->ta_size_max = a_number(optarg);
2227a2de9a4SMatthew Dillon 			break;
2237a2de9a4SMatthew Dillon 
2247a2de9a4SMatthew Dillon 		case 'u':
2257a2de9a4SMatthew Dillon 			uid = a_uid(optarg);
2267a2de9a4SMatthew Dillon 			uidset = 1;
2277a2de9a4SMatthew Dillon 			break;
2287a2de9a4SMatthew Dillon 
2297a2de9a4SMatthew Dillon 		case '?':
2307a2de9a4SMatthew Dillon 		default:
2317a2de9a4SMatthew Dillon 			usage();
2327a2de9a4SMatthew Dillon 		}
2337a2de9a4SMatthew Dillon 	}
2347a2de9a4SMatthew Dillon 	argc -= optind;
2357a2de9a4SMatthew Dillon 	argv += optind;
2367a2de9a4SMatthew Dillon 
2377a2de9a4SMatthew Dillon 	if (argc != 2)
2387a2de9a4SMatthew Dillon 		usage();
2397a2de9a4SMatthew Dillon 
2407a2de9a4SMatthew Dillon 	strlcpy(canon_dev, argv[0], MAXPATHLEN);
2417a2de9a4SMatthew Dillon 	strlcpy(canon_dir, argv[1], MAXPATHLEN);
2427a2de9a4SMatthew Dillon 
2437a2de9a4SMatthew Dillon 	if (stat(canon_dir, &sb) == -1)
2447a2de9a4SMatthew Dillon 		err(EXIT_FAILURE, "cannot stat `%s'", canon_dir);
2457a2de9a4SMatthew Dillon 
2467a2de9a4SMatthew Dillon 	args->ta_root_uid = uidset ? uid : sb.st_uid;
2477a2de9a4SMatthew Dillon 	args->ta_root_gid = gidset ? gid : sb.st_gid;
2487a2de9a4SMatthew Dillon 	args->ta_root_mode = modeset ? mode : sb.st_mode;
2497a2de9a4SMatthew Dillon }
2507a2de9a4SMatthew Dillon 
2517a2de9a4SMatthew Dillon /* --------------------------------------------------------------------- */
2527a2de9a4SMatthew Dillon 
2537a2de9a4SMatthew Dillon static gid_t
a_gid(char * s)2547a2de9a4SMatthew Dillon a_gid(char *s)
2557a2de9a4SMatthew Dillon {
2567a2de9a4SMatthew Dillon 	struct group *gr;
2577a2de9a4SMatthew Dillon 	char *gname;
2587a2de9a4SMatthew Dillon 	gid_t gid;
2597a2de9a4SMatthew Dillon 
2607a2de9a4SMatthew Dillon 	if ((gr = getgrnam(s)) != NULL)
2617a2de9a4SMatthew Dillon 		gid = gr->gr_gid;
2627a2de9a4SMatthew Dillon 	else {
2637a2de9a4SMatthew Dillon 		for (gname = s; *s && isdigit(*s); ++s);
2647a2de9a4SMatthew Dillon 		if (!*s)
2657a2de9a4SMatthew Dillon 			gid = atoi(gname);
2667a2de9a4SMatthew Dillon 		else
2677a2de9a4SMatthew Dillon 			errx(EX_NOUSER, "unknown group id: %s", gname);
2687a2de9a4SMatthew Dillon 	}
2697a2de9a4SMatthew Dillon 	return (gid);
2707a2de9a4SMatthew Dillon }
2717a2de9a4SMatthew Dillon 
2727a2de9a4SMatthew Dillon static uid_t
a_uid(char * s)2737a2de9a4SMatthew Dillon a_uid(char *s)
2747a2de9a4SMatthew Dillon {
2757a2de9a4SMatthew Dillon 	struct passwd *pw;
2767a2de9a4SMatthew Dillon 	char *uname;
2777a2de9a4SMatthew Dillon 	uid_t uid;
2787a2de9a4SMatthew Dillon 
2797a2de9a4SMatthew Dillon 	if ((pw = getpwnam(s)) != NULL)
2807a2de9a4SMatthew Dillon 		uid = pw->pw_uid;
2817a2de9a4SMatthew Dillon 	else {
2827a2de9a4SMatthew Dillon 		for (uname = s; *s && isdigit(*s); ++s);
2837a2de9a4SMatthew Dillon 		if (!*s)
2847a2de9a4SMatthew Dillon 			uid = atoi(uname);
2857a2de9a4SMatthew Dillon 		else
2867a2de9a4SMatthew Dillon 			errx(EX_NOUSER, "unknown user id: %s", uname);
2877a2de9a4SMatthew Dillon 	}
2887a2de9a4SMatthew Dillon 	return (uid);
2897a2de9a4SMatthew Dillon }
2907a2de9a4SMatthew Dillon 
2917a2de9a4SMatthew Dillon static mode_t
a_mask(char * s)2927a2de9a4SMatthew Dillon a_mask(char *s)
2937a2de9a4SMatthew Dillon {
2947a2de9a4SMatthew Dillon 	int done, rv = 0;
2957a2de9a4SMatthew Dillon 	char *ep;
2967a2de9a4SMatthew Dillon 
2977a2de9a4SMatthew Dillon 	done = 0;
2987a2de9a4SMatthew Dillon 	if (*s >= '0' && *s <= '7') {
2997a2de9a4SMatthew Dillon 		done = 1;
300817a2fd9SMatthew Dillon 		rv = strtol(s, &ep, 8);
3017a2de9a4SMatthew Dillon 	}
3027a2de9a4SMatthew Dillon 	if (!done || rv < 0 || *ep)
3037a2de9a4SMatthew Dillon 		errx(EX_USAGE, "invalid file mode: %s", s);
3047a2de9a4SMatthew Dillon 	return (rv);
3057a2de9a4SMatthew Dillon }
3067a2de9a4SMatthew Dillon 
307817a2fd9SMatthew Dillon static int64_t
a_number(char * s)308817a2fd9SMatthew Dillon a_number(char *s)
309817a2fd9SMatthew Dillon {
310817a2fd9SMatthew Dillon 	int64_t rv = 0;
311817a2fd9SMatthew Dillon 
312817a2fd9SMatthew Dillon 	if (dehumanize_number(s, &rv) < 0 || rv < 0)
313817a2fd9SMatthew Dillon 		errx(EX_USAGE, "bad number for option: %s", s);
314817a2fd9SMatthew Dillon 	return (rv);
315817a2fd9SMatthew Dillon }
316817a2fd9SMatthew Dillon 
3177a2de9a4SMatthew Dillon static void
usage(void)3187a2de9a4SMatthew Dillon usage(void)
3197a2de9a4SMatthew Dillon {
320b8170153SSascha Wildner 	fprintf(stderr,
321b8170153SSascha Wildner 	    "Usage: %s [-C] [-g group] [-m mode] [-n nodes] [-o options] [-s size]\n"
322817a2fd9SMatthew Dillon 	    "           [-u user] [-f maxfilesize] tmpfs mountpoint\n", getprogname());
3237a2de9a4SMatthew Dillon 	exit(1);
3247a2de9a4SMatthew Dillon }
3257a2de9a4SMatthew Dillon 
3267a2de9a4SMatthew Dillon /* --------------------------------------------------------------------- */
3277a2de9a4SMatthew Dillon 
3287a2de9a4SMatthew Dillon int
mount_tmpfs(int argc,char * argv[])3297a2de9a4SMatthew Dillon mount_tmpfs(int argc, char *argv[])
3307a2de9a4SMatthew Dillon {
331*25a86e44SMarkus Pfeiffer 	struct tmpfs_mount_info args;
3327a2de9a4SMatthew Dillon 	char canon_dev[MAXPATHLEN], canon_dir[MAXPATHLEN];
3337a2de9a4SMatthew Dillon 	int mntflags;
3347a2de9a4SMatthew Dillon 	struct vfsconf vfc;
3357a2de9a4SMatthew Dillon 	int error;
336b93d6cf8SMatthew Dillon 	fsnode_t copyroot = NULL;
337b93d6cf8SMatthew Dillon 	fsnode_t copyhlinks = NULL;
3387a2de9a4SMatthew Dillon 
3397a2de9a4SMatthew Dillon 	mount_tmpfs_parseargs(argc, argv, &args, &mntflags,
3407a2de9a4SMatthew Dillon 	    canon_dev, canon_dir);
3417a2de9a4SMatthew Dillon 
3427a2de9a4SMatthew Dillon 	error = getvfsbyname("tmpfs", &vfc);
3437a2de9a4SMatthew Dillon 	if (error && vfsisloadable("tmpfs")) {
3447a2de9a4SMatthew Dillon 		if(vfsload("tmpfs"))
3457a2de9a4SMatthew Dillon 			err(EX_OSERR, "vfsload(%s)", "tmpfs");
3467a2de9a4SMatthew Dillon 		endvfsent();
3477a2de9a4SMatthew Dillon 		error = getvfsbyname("tmpfs", &vfc);
3487a2de9a4SMatthew Dillon 	}
3497a2de9a4SMatthew Dillon 	if (error)
3507a2de9a4SMatthew Dillon 		errx(EX_OSERR, "%s filesystem not available", "tmpfs");
3517a2de9a4SMatthew Dillon 
352b8170153SSascha Wildner 	if (Cflag)
353b8170153SSascha Wildner 		copyroot = FSCopy(&copyhlinks, canon_dir);
354b8170153SSascha Wildner 
355ef20d754SMatthew Dillon 	if (mount(vfc.vfc_name, canon_dir, mntflags, &args) == -1)
3567a2de9a4SMatthew Dillon 		err(EXIT_FAILURE, "tmpfs on %s", canon_dir);
3577a2de9a4SMatthew Dillon 
358b8170153SSascha Wildner 	if (Cflag)
359b8170153SSascha Wildner 		FSPaste(canon_dir, copyroot, copyhlinks);
360b8170153SSascha Wildner 
3617a2de9a4SMatthew Dillon 	return EXIT_SUCCESS;
3627a2de9a4SMatthew Dillon }
3637a2de9a4SMatthew Dillon 
3647a2de9a4SMatthew Dillon #ifndef MOUNT_NOMAIN
3657a2de9a4SMatthew Dillon int
main(int argc,char * argv[])3667a2de9a4SMatthew Dillon main(int argc, char *argv[])
3677a2de9a4SMatthew Dillon {
3687a2de9a4SMatthew Dillon 	setprogname(argv[0]);
3697a2de9a4SMatthew Dillon 	return mount_tmpfs(argc, argv);
3707a2de9a4SMatthew Dillon }
3717a2de9a4SMatthew Dillon #endif
372