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>