Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 06 Mar 2014 16:26:53 -0700
From:      Ian Lepore <ian@FreeBSD.org>
To:        freebsd-arch <freebsd-arch@FreeBSD.org>, freebsd-rc@FreeBSD.org
Subject:   Teach mdmfs about tmpfs and use tmpfs in rc scripts
Message-ID:  <1394148413.1149.348.camel@revolution.hippie.lan>

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

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

A recent discussion on arm@ about using tmpfs instead of md(4) spurred
me to do something I've been wanting to do for a while:  enhance mdmfs
so that it can configure tmpfs as well as md+ffs, and update the rc
scripts to make use the the feature.

Attached are diffs to do this (man page updates not in there yet).

mdmfs recognizes two new values for the md-device argument: tmpfs and
auto.  If you request 'tmpfs' you get it, or it fails if tmpfs is not
present in the kernel.  If you request 'auto' it will use tmpfs if it's
present in the kernel and the other options don't include multilabel MAC
(which tmpfs doesn't handle, as near as I can tell).  Other options
which have no meaning with tmpfs (such as setting the number of inodes)
are silently ignored.

The rc scripts are updated to add a new mfs_type knob, which defaults to
"auto".  This in effect automatically updates folks to use tmpfs instead
of md as long as it's present and they aren't using the one option that
forbids it (multilabel MAC).

Thoughts?

-- Ian


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

Index: sys/fs/tmpfs/tmpfs_vfsops.c
===================================================================
--- sys/fs/tmpfs/tmpfs_vfsops.c	(revision 262759)
+++ sys/fs/tmpfs/tmpfs_vfsops.c	(working copy)
@@ -60,6 +60,8 @@ __FBSDID("$FreeBSD$");
 
 #include <fs/tmpfs/tmpfs.h>
 
+FEATURE(tmpfs, "Efficient memory file system");
+
 /*
  * Default permission for root node
  */
Index: sbin/mdmfs/mdmfs.c
===================================================================
--- sbin/mdmfs/mdmfs.c	(revision 262759)
+++ sbin/mdmfs/mdmfs.c	(working copy)
@@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$");
 #include <string.h>
 #include <ctype.h>
 #include <unistd.h>
+#include <sys/sysctl.h>
 
 typedef enum { false, true } bool;
 
@@ -78,7 +79,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,11 +92,11 @@ 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;
 	void *set;
@@ -105,6 +107,7 @@ main(int argc, char **argv)
 	detach = true;
 	softdep = true;
 	autounit = false;
+	mlmac = false;
 	newfs = true;
 	have_mdtype = false;
 	mdtype = MD_SWAP;
@@ -119,6 +122,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 +179,7 @@ main(int argc, char **argv)
 			loudsubs = true;
 			break;
 		case 'l':
+			mlmac = true;
 			argappend(&newfs_arg, "-l");
 			break;
 		case 'M':
@@ -213,7 +218,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 +244,64 @@ 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 on the filesystem.
+	 */
 	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) {
+		if (feature_present("tmpfs") && !mlmac)
+			unitstr = "tmpfs";
+		else
+			unitstr = "md";
+	}
+
+	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 +458,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 +469,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, "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 262759)
+++ 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.subr
===================================================================
--- etc/rc.subr	(revision 262759)
+++ etc/rc.subr	(working copy)
@@ -1474,7 +1474,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
Index: etc/rc.initdiskless
===================================================================
--- etc/rc.initdiskless	(revision 262759)
+++ 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

--=-Cvk3LbT8clLtJ22ceTxC--




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