Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 14 Jun 2001 09:08:13 +0200
From:      Poul-Henning Kamp <phk@critter.freebsd.dk>
To:        Dima Dorfman <dima@unixfreak.org>
Cc:        hackers@FreeBSD.ORG, dougb@FreeBSD.ORG
Subject:   Re: mount_mfs-like program for md 
Message-ID:  <56539.992502493@critter>
In-Reply-To: Your message of "Tue, 12 Jun 2001 00:39:47 PDT." <20010612073947.51AD73E28@bazooka.unixfreak.org> 

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

Go for it.

In message <20010612073947.51AD73E28@bazooka.unixfreak.org>, Dima Dorfman write
s:
>Hi folks,
>
>Would anybody have a tantrum if a program with a mount_mfs-like
>interface to create an md disk and put a UFS filesystem on it was
>imported into the base system?  This has been suggested in the past,
>and the only real objection was that it shouldn't be named mount_*.
>At this time, I am *not* proposing to name it mount_*.
>
>More specifically, the program exec's mdconfig, disklabel, newfs, and
>mount, in that order, to set up the disk and filesystem.  It supports
>all the options mount_mfs did, passing them to the correct program(s).
>It can theoretically be renamed to mount_<something> to handle
>corresponding /etc/fstab entries; however, I would like to make it
>clear that I am *not* proposing that.
>
>Furthermore, dougb@ says that something similar would have to be used
>in /etc/rc to make filesystems on md disks for, e.g., /tmp, anyway,
>and this just factors out the code into something that can be used
>separately.  So, is there any reason not to do this?  I've attached a
>sharball of the sources.
>
>Regards,
>
>					Dima Dorfman
>					dima@unixfreak.org
>
># This is a shell archive.  Save it in a file, remove anything before
># this line, and then unpack it by entering "sh file".  Note, it may
># create directories; files and directories will be owned by you and
># have default permissions.
>#
># This archive contains:
>#
>#	mdmfs
>#	mdmfs/Makefile
>#	mdmfs/pathnames.h
>#	mdmfs/mdmfs.c
>#	mdmfs/mdmfs.8
>#
>echo c - mdmfs
>mkdir -p mdmfs > /dev/null 2>&1
>echo x - mdmfs/Makefile
>sed 's/^X//' >mdmfs/Makefile << 'END-of-mdmfs/Makefile'
>X# $FreeBSD$
>X
>XPROG=		mdmfs
>XMAN=		mdmfs.8
>XWARNS?=		2
>X
>X.include <bsd.prog.mk>
>END-of-mdmfs/Makefile
>echo x - mdmfs/pathnames.h
>sed 's/^X//' >mdmfs/pathnames.h << 'END-of-mdmfs/pathnames.h'
>X/* $FreeBSD$ */
>X#ifndef	MDMFS_PATHNAMES_H
>X#define	MDMFS_PATHNAMES_H
>X
>X#define	PATH_MDCONFIG	"/sbin/mdconfig"
>X#define	PATH_DISKLABEL	"/sbin/disklabel"
>X#define	PATH_NEWFS	"/sbin/newfs"
>X#define	PATH_MOUNT	"/sbin/mount"
>X
>X#endif	/* !MDMFS_PATHNAMES_H */
>END-of-mdmfs/pathnames.h
>echo x - mdmfs/mdmfs.c
>sed 's/^X//' >mdmfs/mdmfs.c << 'END-of-mdmfs/mdmfs.c'
>X/*
>X * Copyright (c) 2001 Dima Dorfman <dima@unixfreak.org>.
>X * All rights reserved.
>X *
>X * Redistribution and use in source and binary forms, with or without
>X * modification, are permitted provided that the following conditions
>X * are met:
>X * 1. Redistributions of source code must retain the above copyright
>X *    notice, this list of conditions and the following disclaimer.
>X * 2. Redistributions in binary form must reproduce the above copyright
>X *    notice, this list of conditions and the following disclaimer in the
>X *    documentation and/or other materials provided with the distribution.
>X *
>X * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
>X * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
>X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
>X * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
>X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
>X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
>X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
>X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
>X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
>X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
>X * SUCH DAMAGE.
>X */
>X
>X/*
>X * mdmfs (md/MFS) is a wrapper around mdconfig(8), disklabel(8),
>X * newfs(8), and mount(8) that mimics the command line option set of
>X * the deprecated mount_mfs(8).  As the name suggests, it creates an
>X * md(4) disk, labels it, newfs's it, and mounts it.
>X */
>X
>X#ifndef lint
>Xstatic const char rcsid[] =
>X  "$FreeBSD$";
>X#endif /* not lint */
>X
>X#include <sys/param.h>
>X#include <sys/mdioctl.h>
>X#include <sys/stat.h>
>X#include <sys/wait.h>
>X
>X#include <assert.h>
>X#include <err.h>
>X#include <fcntl.h>
>X#include <grp.h>
>X#include <paths.h>
>X#include <pwd.h>
>X#include <stdarg.h>
>X#include <stdio.h>
>X#include <stdlib.h>
>X#include <string.h>
>X#include <unistd.h>
>X
>X#include "pathnames.h"
>X
>X/* XXX variable args in macros is a GCCism! */
>X#define ARGAPPEND(d, s...)	(argappend(d, sizeof(d), " " ##s))
>X#define debugprintf(s...)	if (debug) (void)fprintf(stderr, "DEBUG: " ##s)
>X
>Xtypedef enum { false, true } bool;
>X
>Xstruct mtpt_info {
>X	uid_t		 mi_uid;
>X	bool		 mi_have_uid;
>X	gid_t		 mi_gid;
>X	bool		 mi_have_gid;
>X	mode_t		 mi_mode;
>X	bool		 mi_have_mode;
>X};
>X
>Xbool debug, loudsubs, norun;	/* Global options. */
>Xint unit;			/* The unit we're working with. */
>Xconst char *mdname;		/* Name of memory disk device (e.g., "md"). */
>Xsize_t mdnamelen;		/* Length of mdname. */
>X
>Xint	 main(int, char **);
>Xvoid	 argappend(char *, size_t, const char *, ...);
>Xvoid	 do_disklabel(void);
>Xvoid	 do_mdconfig_attach(const char *, const enum md_types);
>Xvoid	 do_mdconfig_attach_au(const char *, const enum md_types);
>Xvoid	 do_mdconfig_detach(void);
>Xvoid	 do_mount(const char *, const char *);
>Xvoid	 do_mtptsetup(const char *, struct mtpt_info *);
>Xvoid	 do_newfs(const char *);
>Xvoid	 extract_ugid(const char *, struct mtpt_info *);
>Xint	 run(int *, const char *, ...);
>Xvoid	 usage(void);
>X
>Xint
>Xmain(int ac, char **av)
>X{
>X	char mdconfig_arg[MAXPATHLEN], newfs_arg[MAXPATHLEN],
>X	    mount_arg[MAXPATHLEN];
>X	char ch, *mtpoint, *unitstr;
>X	struct mtpt_info mi;
>X	bool nodetach = false, softdep = true, autounit = false;
>X	bool have_mdtype = false;
>X	enum md_types mdtype;
>X
>X	(void)memset(&mi, '\0', sizeof(mi));
>X	(void)memset(mdconfig_arg, '\0', sizeof(mdconfig_arg));
>X	(void)memset(newfs_arg, '\0', sizeof(newfs_arg));
>X	(void)memset(mount_arg, '\0', sizeof(mount_arg));
>X	mdname = MD_NAME;
>X	mdnamelen = strlen(MD_NAME);
>X
>X	while ((ch = getopt(ac, av,
>X	    "a:b:c:Dd:e:F:f:hi:LMm:Nn:O:o:p:Ss:t:w:X")) != -1)
>X		switch (ch) {
>X		case 'a':
>X			ARGAPPEND(newfs_arg, "-a %s", optarg);
>X			break;
>X		case 'b':
>X			ARGAPPEND(newfs_arg, "-b %s", optarg);
>X			break;
>X		case 'c':
>X			ARGAPPEND(newfs_arg, "-c %s", optarg);
>X			break;
>X		case 'D':
>X			nodetach = true;
>X			break;
>X		case 'd':
>X			ARGAPPEND(newfs_arg, "-d %s", optarg);
>X			break;
>X		case 'e':
>X			ARGAPPEND(newfs_arg, "-e %s", optarg);
>X			break;
>X		case 'F':
>X			if (have_mdtype)
>X				usage();
>X			mdtype = MD_VNODE;
>X			have_mdtype = true;
>X			ARGAPPEND(mdconfig_arg, "-f %s", optarg);
>X			break;
>X		case 'f':
>X			ARGAPPEND(newfs_arg, "-f %s", optarg);
>X			break;
>X		case 'h':
>X			usage();
>X			break;
>X		case 'i':
>X			ARGAPPEND(newfs_arg, "-i %s", optarg);
>X			break;
>X		case 'L':
>X			loudsubs = true;
>X			break;
>X		case 'M':
>X			if (have_mdtype)
>X				usage();
>X			mdtype = MD_MALLOC;
>X			have_mdtype = true;
>X			break;
>X		case 'm':
>X			ARGAPPEND(newfs_arg, "-m %s", optarg);
>X			break;
>X		case 'N':
>X			norun = true;
>X			break;
>X		case 'n':
>X			ARGAPPEND(newfs_arg, "-n %s", optarg);
>X			break;
>X		case 'O':
>X			ARGAPPEND(newfs_arg, "-o %s", optarg);
>X			break;
>X		case 'o':
>X			ARGAPPEND(mount_arg, "-o %s", optarg);
>X			break;
>X		case 'p':
>X			if (*optarg >= '0' && *optarg <= '7')
>X				mi.mi_mode = strtol(optarg, NULL, 8);
>X			if ((mi.mi_mode & ~07777) != 0)
>X				usage();
>X			mi.mi_have_mode = true;
>X			break;
>X		case 'S':
>X			softdep = false;
>X			break;
>X		case 's':
>X			ARGAPPEND(mdconfig_arg, "-s %s", optarg);
>X			break;
>X		case 't':
>X			ARGAPPEND(mount_arg, "-t %s", optarg);
>X			break;
>X		case 'w':
>X			extract_ugid(optarg, &mi);
>X			break;
>X		case 'X':
>X			debug = true;
>X			break;
>X		default:
>X			usage();
>X		}
>X	ac -= optind;
>X	av += optind;
>X	if (ac < 2)
>X		usage();
>X	unitstr = av[0];
>X	if (strncmp(unitstr, "/dev/", 5) == 0)
>X		unitstr += 5;
>X	if (strncmp(unitstr, mdname, mdnamelen) == 0)
>X		unitstr += mdnamelen;
>X	if (*unitstr == '\0') {
>X		autounit = true;
>X		unit = -1;
>X	} else {
>X		unit = strtoul(unitstr, NULL, 10);
>X		if ((unsigned)unit == ULONG_MAX)
>X			errx(1, "bad device unit: %s", unitstr);
>X	}
>X	mtpoint = av[1];
>X	if (!have_mdtype)
>X		mdtype = MD_SWAP;
>X
>X	if (softdep)
>X		ARGAPPEND(newfs_arg, "-U");
>X
>X	if (!nodetach && !autounit)
>X		do_mdconfig_detach();
>X	if (autounit)
>X		do_mdconfig_attach_au(mdconfig_arg, mdtype);
>X	else
>X		do_mdconfig_attach(mdconfig_arg, mdtype);
>X	do_disklabel();
>X	do_newfs(newfs_arg);
>X	do_mount(mount_arg, mtpoint);
>X	do_mtptsetup(mtpoint, &mi);
>X
>X	return (0);
>X}
>X
>X/*
>X * Append the formatted string pointed to by 'fmt' to 'dst'.
>X */
>Xvoid
>Xargappend(char *dst, size_t dstlen, const char *fmt, ...)
>X{
>X	va_list ap;
>X	char tb[256];
>X	size_t rv;
>X	
>X	va_start(ap, fmt);
>X	rv = vsnprintf(tb, sizeof(tb), fmt, ap);
>X	va_end(ap);
>X	assert(rv < sizeof(tb));
>X	rv = strlcat(dst, tb, dstlen);
>X	assert(rv < dstlen);
>X}
>X
>Xvoid
>Xdo_disklabel(void)
>X{
>X	int rv;
>X
>X	rv = run(NULL, "%s -r -w %s%d auto", PATH_DISKLABEL, mdname, unit);
>X	if (rv)
>X		errx(1, "disklabel exited with error code %d", rv);
>X}
>X
>Xvoid
>Xdo_mdconfig_attach(const char *args, const enum md_types mdtype)
>X{
>X	int rv;
>X	const char *ta;		/* Type arg. */
>X
>X	switch (mdtype) {
>X	case MD_SWAP:
>X		ta = "-t swap";
>X		break;
>X	case MD_VNODE:
>X		ta = "-t vnode";
>X		break;
>X	case MD_MALLOC:
>X		ta = "-t malloc";
>X		break;
>X	default:
>X		abort();
>X	}
>X	rv = run(NULL, "%s -a %s%s -u %s%d", PATH_MDCONFIG, ta, args,
>X	    mdname, unit);
>X	if (rv)
>X		errx(1, "mdconfig (attach) exited with error code %d", rv);
>X}
>X
>Xvoid
>Xdo_mdconfig_attach_au(const char *args, const enum md_types mdtype)
>X{
>X	int rv, fd;
>X	const char *ta;		/* Type arg. */
>X	char tb[10];
>X	char *linep;
>X	size_t linelen;
>X	FILE *sfd;		/* FILE version of fd. */
>X
>X	switch (mdtype) {
>X	case MD_SWAP:
>X		ta = "-t swap";
>X		break;
>X	case MD_VNODE:
>X		ta = "-t vnode";
>X		break;
>X	case MD_MALLOC:
>X		ta = "-t malloc";
>X		break;
>X	default:
>X		abort();
>X	}
>X	rv = run(&fd, "%s -a %s%s", PATH_MDCONFIG, ta, args);
>X	if (rv)
>X		errx(1, "mdconfig (attach) exited with error code %d", rv);
>X	if (norun) {	/* Since we didn't run, we can't read.  Fake it. */
>X		unit = -1;
>X		return;
>X	}
>X	sfd = fdopen(fd, "r");
>X	if (sfd == NULL)
>X		err(1, "fdopen");
>X	linep = fgetln(sfd, &linelen);
>X	if (linep == NULL && linelen < mdnamelen + 1)
>X		errx(1, "unexpected output from mdconfig (attach)");
>X	if (strncmp(linep, mdname, mdnamelen) == 0)
>X		linep += mdnamelen;
>X	assert(linelen + mdnamelen < sizeof(tb));
>X	strncpy(tb, linep, linelen);
>X	tb[linelen] = '\0';
>X	unit = strtoul(tb, NULL, 10);
>X	if ((unsigned)unit == ULONG_MAX)
>X		errx(1, "unexpected output from mdconfig (attach)");
>X
>X	fclose(sfd);
>X	close(fd);
>X}
>X
>Xvoid
>Xdo_mdconfig_detach(void)
>X{
>X	int rv;
>X
>X	rv = run(NULL, "%s -d -u %s%d", PATH_MDCONFIG, mdname, unit);
>X	if (rv && debug)	/* This is allowed to fail. */
>X		warnx("mdconfig (detach) exited with error code %d (ignored)",
>X		      rv);
>X}
>X
>Xvoid
>Xdo_mount(const char *args, const char *mtpoint)
>X{
>X	int rv;
>X
>X	rv = run(NULL, "%s%s /dev/%s%dc %s", PATH_MOUNT, args,
>X	    mdname, unit, mtpoint);
>X	if (rv)
>X		errx(1, "mount exited with error code %d", rv);
>X}
>X
>Xvoid
>Xdo_mtptsetup(const char *mtpoint, struct mtpt_info *mip)
>X{
>X
>X	if (mip->mi_have_mode) {
>X		debugprintf("changing mode of %s to %o.\n", mtpoint,
>X		    mip->mi_mode);
>X		if (!norun)
>X			if (chmod(mtpoint, mip->mi_mode) == -1)
>X				err(1, "chmod: %s", mtpoint);
>X	}
>X	if (mip->mi_have_uid) {
>X		debugprintf("changing owner (user) or %s to %u.\n", mtpoint,
>X		    mip->mi_uid);
>X		if (!norun)
>X			if (chown(mtpoint, mip->mi_uid, -1) == -1)
>X				err(1, "chown %s to %u (user)", mtpoint,
>X				    mip->mi_uid);
>X	}
>X	if (mip->mi_have_gid) {
>X		debugprintf("changing owner (group) or %s to %u.\n", mtpoint,
>X		    mip->mi_gid);
>X		if (!norun)
>X			if (chown(mtpoint, -1, mip->mi_gid) == -1)
>X				err(1, "chown %s to %u (group)", mtpoint,
>X				    mip->mi_gid);
>X	}
>X}
>X
>Xvoid
>Xdo_newfs(const char *args)
>X{
>X	int rv;
>X
>X	rv = run(NULL, "%s%s /dev/%s%dc", PATH_NEWFS, args, mdname, unit);
>X	if (rv)
>X		errx(1, "newfs exited with error code %d", rv);
>X}
>X
>X/*
>X * 'str' should be a user and group name similar to the last argument
>X * to chown(1); i.e., a user, followed by a colon or period, followed
>X * by a group.  The user and group in 'str' may be either a [ug]id or
>X * a name.  Upon return, the uid and gid fields in 'mip' will contain
>X * the uid and gid of the user and group name in 'str', respectively.
>X *
>X * In other words, this derives a user and group id from a string
>X * formatted like the last argument to chown(1).
>X */
>Xvoid
>Xextract_ugid(const char *str, struct mtpt_info *mip)
>X{
>X	struct passwd *pw;
>X	struct group *gr;
>X	char ug[MAXLOGNAME * 2 + 2];
>X	char *user, *group;
>X	char *p;
>X	uid_t *uid;
>X	gid_t *gid;
>X
>X	uid = &mip->mi_uid;
>X	gid = &mip->mi_gid;
>X	mip->mi_have_uid = mip->mi_have_gid = false;
>X
>X	(void)strlcpy(ug, str, sizeof(ug));
>X	group = ug;
>X	user = strsep(&group, ":.");
>X	if (user == NULL || group == NULL || *user == '\0' || *group == '\0')
>X		usage();
>X
>X	*uid = strtoul(user, &p, 10);
>X	if ((unsigned)*uid == ULONG_MAX)
>X		usage();
>X	if (*p != '\0') {
>X		pw = getpwnam(user);
>X		if (pw == NULL)
>X			errx(1, "invalid user: %s", user);
>X		*uid = pw->pw_uid;
>X		mip->mi_have_uid = true;
>X	}
>X	*gid = strtoul(group, &p, 10);
>X	if ((unsigned)*gid == ULONG_MAX)
>X		usage();
>X	if (*p != '\0') {
>X		gr = getgrnam(group);
>X		if (gr == NULL)
>X			errx(1, "invalid group: %s", group);
>X		*gid = gr->gr_gid;
>X		mip->mi_have_gid = true;
>X	}
>X
>X	assert(mip->mi_have_uid);
>X	assert(mip->mi_have_gid);
>X}
>X
>X/*
>X * Run a process with command name and arguments pointed to by the
>X * formatted string 'cmdline'.  Since system(3) is not used, the first
>X * space-delimited token of 'cmdline' must be the full pathname of the
>X * program to run.  The return value is the return code of the process
>X * spawned.  If 'ofd' is non-NULL, it is set to the standard output of
>X * the program spawned (i.e., you can read from ofd and get the output
>X * of the program).
>X */
>Xint
>Xrun(int *ofd, const char *cmdline, ...)
>X{
>X	va_list ap;
>X	char cmd[MAXPATHLEN], **av, **avp, *p;
>X	int i, pid, status, ac, pfd[2], nfd;
>X	bool dup2dn = true;	/* Dup /dev/null to stdout? */
>X
>X	va_start(ap, cmdline);
>X	(void)vsnprintf(cmd, sizeof(cmd), cmdline, ap);
>X	va_end(ap);
>X
>X	for (ac = 1, p = cmd; (p = strchr(p, ' ')) != NULL; p++)
>X		ac++;		/* 'ac' generation loop. */
>X	av = (char **)malloc(sizeof(*av) * (ac + 1));
>X	if (av == NULL)
>X		err(1, "malloc");
>X	for (p = cmd, avp = av; (*avp = strsep(&p, " ")) != NULL;)
>X		if (**av != '\0')
>X			if (++avp >= &av[ac]) {
>X				*avp = NULL;
>X				break;
>X			}
>X	assert(*av);
>X	if (debug) {
>X		(void)fprintf(stderr, "DEBUG: running:");
>X		/* Should be equivilent to 'cmd' (before strsep, of course). */
>X		for (i = 0; av[i] != NULL; i++)
>X			(void)fprintf(stderr, " %s", av[i]);
>X		(void)fprintf(stderr, "\n");
>X	}
>X	if (ofd != NULL) {
>X		if (pipe(&pfd[0]) == -1)
>X			err(1, "pipe");
>X		*ofd = pfd[0];
>X		dup2dn = false;
>X	}
>X	pid = fork();
>X	switch (pid) {
>X	case 0:
>X		if (norun)
>X			_exit(0);
>X		if (ofd != NULL)
>X			if (dup2(pfd[1], STDOUT_FILENO) < 0)
>X				err(1, "dup2");
>X		if (!loudsubs) {
>X			nfd = open(_PATH_DEVNULL, O_RDWR);
>X			if (nfd < 0)
>X				err(1, "open: %s", _PATH_DEVNULL);
>X			if (dup2(nfd, STDIN_FILENO) < 0)
>X				err(1, "dup2");
>X			if (dup2dn)
>X				if (dup2(nfd, STDOUT_FILENO) < 0)
>X				   err(1, "dup2");
>X			if (dup2(nfd, STDERR_FILENO) < 0)
>X				err(1, "dup2");
>X		}
>X
>X		(void)execv(av[0], av);
>X		warn("exec: %s", av[0]);
>X		_exit(-1);
>X	case -1:
>X		err(1, "fork");
>X	}
>X	while (waitpid(pid, &status, 0) != pid)
>X		;
>X	free(av);
>X	return (WEXITSTATUS(status));
>X}
>X
>Xvoid
>Xusage(void)
>X{
>X
>X	fprintf(stderr,
>X"usage: %s [-DLMNSX] [-a maxcontig] [-b block-size] [-c cylinders]\n"
>X"\t[-d rotdelay] [-e maxbpg] [-F file] [-f frag-size] [-i bytes]\n"
>X"\t[-m percent-free] [-n rotational-positions] [-O optimization]\n"
>X"\t[-o mount-options] [-p permissions] [-s size] [-w user:group]\n"
>X"\tmd-device mount-point\n", getprogname());
>X	exit(1);
>X}
>END-of-mdmfs/mdmfs.c
>echo x - mdmfs/mdmfs.8
>sed 's/^X//' >mdmfs/mdmfs.8 << 'END-of-mdmfs/mdmfs.8'
>X.\"
>X.\" Copyright (c) 2001 Dima Dorfman <dima@unixfreak.org>
>X.\" All rights reserved.
>X.\"
>X.\" Redistribution and use in source and binary forms, with or without
>X.\" modification, are permitted provided that the following conditions
>X.\" are met:
>X.\" 1. Redistributions of source code must retain the above copyright
>X.\"    notice, this list of conditions and the following disclaimer.
>X.\" 2. Redistributions in binary form must reproduce the above copyright
>X.\"    notice, this list of conditions and the following disclaimer in the
>X.\"    documentation and/or other materials provided with the distribution.
>X.\"
>X.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
>X.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
>X.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
>X.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
>X.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
>X.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
>X.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
>X.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
>X.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
>X.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
>X.\" SUCH DAMAGE.
>X.\"
>X.\" $FreeBSD$
>X.\"
>X.Dd May 26, 2001
>X.Dt MDMFS 8
>X.Os
>X.Sh NAME
>X.Nm mdmfs
>X.Nd configure and mount an in-memory filesystem using the
>X.Xr md 4
>Xdriver
>X.Sh SYNOPSIS
>X.Nm
>X.Op Fl DLMNSX
>X.Op Fl a Ar maxcontig
>X.Op Fl b Ar block-size
>X.Op Fl c Ar cylinders
>X.Op Fl d Ar rotdelay
>X.Op Fl e Ar maxbpg
>X.Op Fl F Ar file
>X.Op Fl f Ar frag-size
>X.Op Fl i Ar bytes
>X.Op Fl m Ar percent-free
>X.Op Fl n Ar rotational-positions
>X.Op Fl O Ar optimization
>X.Op Fl o Ar mount-options
>X.Op Fl p Ar permissions
>X.Op Fl s Ar size
>X.Op Fl w Ar user Ns | Ns Ar group
>X.Ar md-device
>X.Ar mount-point
>X.Sh DESCRIPTION
>XThe
>X.Nm
>Xprogram is designed to be a work-alike and look-alike of the deprecated
>X.Xr mount_mfs 8 .
>XThe end result is essentially the same,
>Xbut is accomplished in a completely different way.
>X.Nm
>Xconfigures an
>X.Xr md 4
>Xdisk using
>X.Xr mdconfig 8 ,
>Xlabels it using
>X.Xr disklabel 8 ,
>Xputs a UFS filesystem on it using
>X.Xr newfs 8 ,
>Xand mounts it using
>X.Xr mount 8 .
>XAll the command line options are passed to the appropriate program
>Xat the appropriate stage in order to achieve the desired effect.
>X.Pp
>XBy default,
>X.Nm
>Xcreates a swap-based
>X.Pq Dv MD_SWAP
>Xdisk with soft-updates enabled
>Xand mounts it on
>X.Ar mount-point .
>XIt uses the
>X.Xr md 4
>Xdevice specified by
>X.Ar md-device .
>XIf
>X.Ar md-device
>Xis
>X.Ql md
>X(no unit number),
>Xit will use
>X.Xr md 4 Ns 's
>Xauto-unit feature to automatically select an unused device.
>XUnless otherwise specified with one of the options below,
>Xit uses the default arguments to all the helper programs.
>X.Pp
>XThe following options are available.
>XWhere possible,
>Xthe option letter matches the one used by
>X.Xr mount_mfs 8
>Xfor the same thing.
>X.Bl -tag -width Ds
>X.It Fl a Ar maxcontig
>XSpecify the maximum number of contiguous blocks that will be laid
>Xout before forcing a rotational delay
>X(see the
>X.Fl d
>Xoption).
>X.It Fl b Ar block-size
>XThe block size of the filesystem, in bytes.
>X.It Fl c Ar cylinders
>XThe number of cylinders per cylinder group in the filesystem.
>X.It Fl D
>XIf not using auto-unit,
>Xdon't run
>X.Xr mdconfig 8
>Xto try to detach the unit before attaching it.
>X.It Fl d Ar rotdelay
>XSpecify the mininum time in milliseconds required to initiate another
>Xdisk transfer on the same cylinder.
>XModern disks with read/write-behind achieve higher performance without
>Xthis feature,
>Xso it is best to leave it at 0 milliseconds.
>X.It Fl e Ar maxbpg
>XIndicate the maximum number of blocks any single file can allocate
>Xout of a cylinder group before it is forced to begin allocating
>Xblocks from another cylinder group.
>X.It Fl F Ar file
>XCreate a vnode-backed
>X.Pq Dv MD_VNODE
>Xmemory disk backed by
>X.Ar file .
>X.It Fl f Ar frag-size
>XThe fragment size of the filesystem in bytes.
>X.It Fl i Ar bytes
>XNumber of bytes per inode.
>X.It Fl L
>XShow the output of the helper programs.
>XBy default,
>Xit is sent to
>X.Pa /dev/null .
>X.It Fl M
>XCreate a
>X.Xr malloc 9
>Xbacked disk
>X.Pq Dv MD_MALLOC
>Xinstead of a swap-backed disk.
>X.It Fl m Ar percent-free
>XThe percentage of space reserved for the superuser.
>X.It Fl N
>XDon't actually run the helper programs.
>XThis is most useful in conjunction with
>X.Fl X .
>X.It Fl n Ar rotational-positions
>XThe default number of rotational positions to distinguish.
>X.It Fl O Ar optimization
>XSelect the optimization preference;
>Xvalid choices are
>X.Ar space
>Xand
>X.Ar time ,
>Xwhich will optimize for minimum space fragmentation and
>Xminimum time spent allocating blocks,
>Xrespectively.
>X.It Fl o Ar mount-options
>XSpecify the mount options with which to mount the filesystem.
>XSee
>X.Xr mount 8
>Xfor more information.
>X.It Fl p Ar permissions
>XSet the file (directory) permissions of the mount point
>X.Ar mount-point
>Xto
>X.Ar permissions .
>X.It Fl S
>XDon't enable soft-updates on the filesystem.
>X.It Fl s Ar size
>XSpecify the size of the disk to create.
>XThis only makes sense if
>X.Fl F
>Xis
>X.Em not
>Xspecified.
>XThat is,
>Xthis will work for the default swap-backed
>X.Pq Dv MD_SWAP
>Xdisks,
>Xand the optional
>X.Pq Fl M
>X.Xr malloc 9
>Xbacked disks
>X.Pq Dv MD_MALLOC .
>X.It Fl w Ar user Ns | Ns Ar group
>XSet the owner user and group to
>X.Ar user
>Xand
>X.Ar group ,
>Xrespectively.
>XThe arguments have the same semantics as with
>X.Xr chown 8 ,
>Xbut specifying just a user or just a group is not supported.
>X.El
>X.Pp
>XThe
>X.Fl F
>Xand
>X.Fl s
>Xoptions are passed to
>X.Xr mdconfig 8
>Xas
>X.Fl f
>Xand
>X.Fl s ,
>Xrespectively.
>XThe
>X.Fl a ,
>X.Fl b ,
>X.Fl c ,
>X.Fl d ,
>X.Fl e ,
>X.Fl f ,
>X.Fl i ,
>X.FL m
>Xand
>X.Fl n
>Xoptions are passed to
>X.Xr newfs 8
>Xwith the same letter;
>Xthe
>X.Fl O
>Xoption is passed to
>X.Xr newfs 8
>Xas
>X.Fl o .
>XThe
>X.Fl o
>Xand
>X.Fl t
>Xoptions are passed to
>X.Xr mount 8
>Xwith the same letter.
>XSee the programs that the options are passed to for more information
>Xon their semantics.
>X.Sh EXAMPLES
>XCreate and mount a 32 megabyte swap-backed filesystem on
>X.Pa /tmp :
>X.Pp
>X.Dl mdmfs -s 32m md /tmp
>X.Pp
>XCreate and mount a 16 megabyte malloc-backed filesystem on
>X.Pa /tmp
>Xusing the
>X.Pa /dev/md1
>Xdevice;
>Xfurthermore,
>Xdon't use soft-updates it and mount it
>X.Cm async :
>X.Pp
>X.Dl mdmfs -M -S -o async -s 16m md1 /tmp
>X.Sh AUTHORS
>X.An Dima Dorfman
>X.Aq dima@unixfreak.org
>END-of-mdmfs/mdmfs.8
>exit
>
>
>To Unsubscribe: send mail to majordomo@FreeBSD.org
>with "unsubscribe freebsd-hackers" in the body of the message
>

-- 
Poul-Henning Kamp       | UNIX since Zilog Zeus 3.20
phk@FreeBSD.ORG         | TCP/IP since RFC 956
FreeBSD committer       | BSD since 4.3-tahoe    
Never attribute to malice what can adequately be explained by incompetence.

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




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