Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 08 Jul 2014 13:24:15 -0600
From:      Ian Lepore <ian@FreeBSD.org>
To:        Warren Block <wblock@wonkity.com>
Cc:        freebsd-arm@FreeBSD.org
Subject:   Re: /tmp, /var/log, /var/tmp as /dev/md - why?
Message-ID:  <1404847455.65432.67.camel@revolution.hippie.lan>
In-Reply-To: <alpine.BSF.2.11.1407031134240.3872@wonkity.com>
References:  <201407010925.s619PHeT006679@mech-cluster241.men.bris.ac.uk> <44a6e8a451a.810fa8f@mail.schwarzes.net> <53B3EB29.4030908@gmail.com> <alpine.BSF.2.11.1407030436060.99346@wonkity.com> <20140703105519.GA37593@zibbi.meraka.csir.co.za> <1404396464.20883.404.camel@revolution.hippie.lan> <alpine.BSF.2.11.1407031134240.3872@wonkity.com>

next in thread | previous in thread | raw e-mail | index | archive | help

--=-G5VN/5bc443ZriXVTaAl
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit

On Thu, 2014-07-03 at 11:49 -0600, Warren Block wrote:
> On Thu, 3 Jul 2014, Ian Lepore wrote:
> > On Thu, 2014-07-03 at 12:55 +0200, John Hay wrote:
> >> On Thu, Jul 03, 2014 at 04:47:24AM -0600, Warren Block wrote:
> >>>
> >>> So a limited-size tmpfs will be faster and use less memory overall.  A
> >>> benchmark comparison would be interesting.
> >>
> >> Last time I looked the rc scripts that create /etc, /var and /tmp
> >> ramdisks only did it using md devices. It would be great if it was
> >> easily tunable from say rc.conf or if could detect which one is
> >> available and use that.
> >
> > I have patches ready to commit that do exactly that, but they weren't
> > exactly enthusiastically received when I posted them on arch@ for
> > review.
> 
> This thread?
> http://lists.freebsd.org/pipermail/freebsd-arch/2014-March/015141.html
> 
> Have not read it fully yet, but it sounds exactly right: everything acts 
> the same, the user can just pick tmpfs or mfs.

Yeah, that one.  I've reworked it this morning to incorporate the
earlier suggestion to avoid adding a FEATURE macro to indicate the
presence of tmpfs.  With today's changes it will work right if tmpfs is
either already in the kernel or available to load as tmpfs.ko.  I'll
attach the updated patchset in case anyone wants to test it.

The only blocker to committing it at this point is that the mdmfs(8)
manpage needs a lot of changes to become less md(4)-centric and more
about how it configures and mounts memory filesystems.  I'm not sure
when I'll find time for that.

-- Ian


--=-G5VN/5bc443ZriXVTaAl
Content-Disposition: inline; filename="mdmfs_tmpfs2.diff"
Content-Type: text/x-patch; name="mdmfs_tmpfs2.diff"; charset="us-ascii"
Content-Transfer-Encoding: 7bit

Index: sbin/mdmfs/mdmfs.c
===================================================================
--- sbin/mdmfs/mdmfs.c	(revision 268402)
+++ sbin/mdmfs/mdmfs.c	(working copy)
@@ -34,6 +34,7 @@
 __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
+#include <sys/linker.h>
 #include <sys/mdioctl.h>
 #include <sys/mount.h>
 #include <sys/stat.h>
@@ -41,6 +42,7 @@ __FBSDID("$FreeBSD$");
 
 #include <assert.h>
 #include <err.h>
+#include <errno.h>
 #include <fcntl.h>
 #include <grp.h>
 #include <paths.h>
@@ -78,7 +80,8 @@ static void	 debugprintf(const char *, ...) __prin
 static void	 do_mdconfig_attach(const char *, const enum md_types);
 static void	 do_mdconfig_attach_au(const char *, const enum md_types);
 static void	 do_mdconfig_detach(void);
-static void	 do_mount(const char *, const char *);
+static void	 do_mount_md(const char *, const char *);
+static void	 do_mount_tmpfs(const char *, const char *);
 static void	 do_mtptsetup(const char *, struct mtpt_info *);
 static void	 do_newfs(const char *);
 static void	 extract_ugid(const char *, struct mtpt_info *);
@@ -90,13 +93,13 @@ main(int argc, char **argv)
 {
 	struct mtpt_info mi;		/* Mountpoint info. */
 	char *mdconfig_arg, *newfs_arg,	/* Args to helper programs. */
-	    *mount_arg;
+	    *mount_arg, *size_arg;
 	enum md_types mdtype;		/* The type of our memory disk. */
-	bool have_mdtype;
+	bool have_mdtype, mlmac;
 	bool detach, softdep, autounit, newfs;
-	char *mtpoint, *unitstr;
+	const char *mtpoint, *unitstr;
 	char *p;
-	int ch;
+	int ch, fileid;
 	void *set;
 	unsigned long ul;
 
@@ -105,6 +108,7 @@ main(int argc, char **argv)
 	detach = true;
 	softdep = true;
 	autounit = false;
+	mlmac = false;
 	newfs = true;
 	have_mdtype = false;
 	mdtype = MD_SWAP;
@@ -119,6 +123,7 @@ main(int argc, char **argv)
 	mdconfig_arg = strdup("");
 	newfs_arg = strdup("");
 	mount_arg = strdup("");
+	size_arg = NULL;
 
 	/* If we were started as mount_mfs or mfs, imply -C. */
 	if (strcmp(getprogname(), "mount_mfs") == 0 ||
@@ -175,6 +180,7 @@ main(int argc, char **argv)
 			loudsubs = true;
 			break;
 		case 'l':
+			mlmac = true;
 			argappend(&newfs_arg, "-l");
 			break;
 		case 'M':
@@ -213,7 +219,7 @@ main(int argc, char **argv)
 			softdep = false;
 			break;
 		case 's':
-			argappend(&mdconfig_arg, "-s %s", optarg);
+			size_arg = optarg;
 			break;
 		case 't':
 			argappend(&newfs_arg, "-t");
@@ -239,42 +245,68 @@ main(int argc, char **argv)
 	if (argc < 2)
 		usage();
 
-	/* Derive 'unit' (global). */
+	/*
+	 * Based on the command line 'md-device' either mount a tmpfs filesystem
+	 * or configure the md device then format and mount a filesystem on it.
+	 * If the device is "auto" use tmpfs if it is available and there is no
+	 * request for multilabel MAC (which tmpfs does not support) on the
+	 * filesystem.  The only way to know whether tmpfs is available is to
+	 * attempt to kldload() it.  If it loads (or fails with EEXIST because
+	 * it is already present) then we can use it.
+	 */
 	unitstr = argv[0];
-	if (strncmp(unitstr, "/dev/", 5) == 0)
-		unitstr += 5;
-	if (strncmp(unitstr, mdname, mdnamelen) == 0)
-		unitstr += mdnamelen;
-	if (!isdigit(*unitstr)) {
-		autounit = true;
-		unit = -1;
-		mdsuffix = unitstr;
+	mtpoint = argv[1];
+
+	if (strcmp(unitstr, "auto") == 0) {
+		fileid = kldload("tmpfs");
+		if (mlmac || (fileid == -1 && errno != EEXIST))
+			unitstr = "md";
+		else
+			unitstr = "tmpfs";
+	}
+
+	if (strcmp(unitstr, "tmpfs") == 0) {
+		if (size_arg != NULL)
+			argappend(&mount_arg, "-o size=%s", size_arg);
+		do_mount_tmpfs(mount_arg, mtpoint); 
 	} else {
-		ul = strtoul(unitstr, &p, 10);
-		if (ul == ULONG_MAX)
-			errx(1, "bad device unit: %s", unitstr);
-		unit = ul;
-		mdsuffix = p;	/* can be empty */
+		if (size_arg != NULL)
+			argappend(&mdconfig_arg, "-s %s", size_arg);
+		if (strncmp(unitstr, "/dev/", 5) == 0)
+			unitstr += 5;
+		if (strncmp(unitstr, mdname, mdnamelen) == 0)
+			unitstr += mdnamelen;
+		if (!isdigit(*unitstr)) {
+			autounit = true;
+			unit = -1;
+			mdsuffix = unitstr;
+		} else {
+			ul = strtoul(unitstr, &p, 10);
+			if (ul == ULONG_MAX)
+				errx(1, "bad device unit: %s", unitstr);
+			unit = ul;
+			mdsuffix = p;	/* can be empty */
+		}
+	
+		if (!have_mdtype)
+			mdtype = MD_SWAP;
+		if (softdep)
+			argappend(&newfs_arg, "-U");
+		if (mdtype != MD_VNODE && !newfs)
+			errx(1, "-P requires a vnode-backed disk");
+	
+		/* Do the work. */
+		if (detach && !autounit)
+			do_mdconfig_detach();
+		if (autounit)
+			do_mdconfig_attach_au(mdconfig_arg, mdtype);
+		else
+			do_mdconfig_attach(mdconfig_arg, mdtype);
+		if (newfs)
+			do_newfs(newfs_arg);
+		do_mount_md(mount_arg, mtpoint);
 	}
 
-	mtpoint = argv[1];
-	if (!have_mdtype)
-		mdtype = MD_SWAP;
-	if (softdep)
-		argappend(&newfs_arg, "-U");
-	if (mdtype != MD_VNODE && !newfs)
-		errx(1, "-P requires a vnode-backed disk");
-
-	/* Do the work. */
-	if (detach && !autounit)
-		do_mdconfig_detach();
-	if (autounit)
-		do_mdconfig_attach_au(mdconfig_arg, mdtype);
-	else
-		do_mdconfig_attach(mdconfig_arg, mdtype);
-	if (newfs)
-		do_newfs(newfs_arg);
-	do_mount(mount_arg, mtpoint);
 	do_mtptsetup(mtpoint, &mi);
 
 	return (0);
@@ -431,7 +463,7 @@ do_mdconfig_detach(void)
  * Mount the configured memory disk.
  */
 static void
-do_mount(const char *args, const char *mtpoint)
+do_mount_md(const char *args, const char *mtpoint)
 {
 	int rv;
 
@@ -442,6 +474,19 @@ static void
 }
 
 /*
+ * Mount the configured tmpfs.
+ */
+static void
+do_mount_tmpfs(const char *args, const char *mtpoint)
+{
+	int rv;
+
+	rv = run(NULL, "%s -t tmpfs %s tmp %s", _PATH_MOUNT, args, mtpoint);
+	if (rv)
+		errx(1, "tmpfs mount exited with error code %d", rv);
+}
+
+/*
  * Various configuration of the mountpoint.  Mostly, enact 'mip'.
  */
 static void
Index: etc/defaults/rc.conf
===================================================================
--- etc/defaults/rc.conf	(revision 268402)
+++ etc/defaults/rc.conf	(working copy)
@@ -51,6 +51,7 @@ tmpmfs_flags="-S"	# Extra mdmfs options for the mf
 varmfs="AUTO"		# Set to YES to always create an mfs /var, NO to never
 varsize="32m"		# Size of mfs /var if created
 varmfs_flags="-S"	# Extra mount options for the mfs /var
+mfs_type="auto"		# "md", "tmpfs", or "auto" to choose tmpfs when available
 populate_var="AUTO"	# Set to YES to always (re)populate /var, NO to never
 cleanvar_enable="YES" 	# Clean the /var directory
 local_startup="/usr/local/etc/rc.d" # startup script dirs.
Index: etc/rc.initdiskless
===================================================================
--- etc/rc.initdiskless	(revision 268402)
+++ etc/rc.initdiskless	(working copy)
@@ -198,7 +198,7 @@ handle_remount() { # $1 = mount point
 # Create a generic memory disk
 #
 mount_md() {
-    /sbin/mdmfs -S -i 4096 -s $1 -M md $2
+    /sbin/mdmfs -S -i 4096 -s $1 -M auto $2
 }
 
 # Create the memory filesystem if it has not already been created
Index: etc/rc.subr
===================================================================
--- etc/rc.subr	(revision 268402)
+++ etc/rc.subr	(working copy)
@@ -1728,7 +1728,7 @@ mount_md()
 	if [ -n "$3" ]; then
 		flags="$3"
 	fi
-	/sbin/mdmfs $flags -s $1 md $2
+	/sbin/mdmfs $flags -s $1 ${mfs_type} $2
 }
 
 # Code common to scripts that need to load a kernel module

--=-G5VN/5bc443ZriXVTaAl--




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1404847455.65432.67.camel>