Subject: mounting by wedge name
To: None <tech-userlevel@netbsd.org>
From: Jeff Rizzo <riz@tastylime.net>
List: tech-userlevel
Date: 12/22/2007 18:55:57
This is a multi-part message in MIME format.
--------------060004070909080100020402
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
I've been working on various things lately to improve the state of
wedges and wedge-related things - one of the (valid) complaints is that
there is no way to 'nail down' wedge configuration currently. With the
attached patch, however, one can specify the wedge's *name* to mount
from. With the current DKWEDGE_AUTODISCOVER options, the name is set
according to the underlying disk-labelling method:
DKWEDGE_METHOD_GPT: copied from the user-supplied label if it exists,
the partition GUID if not
DKWEDGE_METHOD_BSDLABEL: set to the BSD disklabel partition name (e.g.
"wd0a", "sd1g")
DKWEDGE_METHOD_MBR: set to a bsd-style partition name beginning with the
'e' partition - up to 4 per disk (e.g., "wd0e" through "wd0h")
This is sufficient to ensure you're mounting the partition you
*intended* to mount. Currently, the kernel requires manual intervention
if it tries to configure two wedges with the name wname.
Wedges-by-name are specified by wedge:<wedgename>, following some prior
art in the kernel from David Young. With the attached patch, I can use
this line in my fstab:
wedge:b57b54a4-ad31-11dc-93e5-000c29746425 /foo ffs rw 1 2
to mount "/foo":
netbsd# mount /foo
netbsd# df -h /foo
Filesystem Size Used Avail %Cap Mounted on
/dev/dk4 7.9G 2.0K 7.5G 0% /foo
netbsd#
or, I can do it on the command line:
netbsd# mount wedge:b57b54a4-ad31-11dc-93e5-000c29746425 /mnt
netbsd# df -h /mnt
Filesystem Size Used Avail %Cap Mounted on
/dev/dk4 7.9G 2.0K 7.5G 0% /mnt
This is primarily a proof of concept; assuming this meets with people's
general approval, there's a lot of tools left to convert (including most
of the mount_* commands - I've only done ffs and lfs so far) - but I
wanted to get some feedback before doing any more work on it.
Is this a good approach? How bad is my code? :)
Known issues:
- with this patch, wedge:/foo does not refer to an nfs mount. :)
- wedge names are specified as uint8_t [] (Unicode UTF-8), but this
patch treats them as char []. What's the proper way to deal with utf-8?
- I wasn't sure the best way to handle the string returned by
getwedgebyname() - suggestions?
What have I missed? Suggestions gratefully accepted.
Thanks!
+j
--------------060004070909080100020402
Content-Type: text/plain; x-mac-type="0"; x-mac-creator="0";
name="mountbyname.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="mountbyname.diff"
Index: lib/libutil/Makefile
===================================================================
RCS file: /cvsroot/src/lib/libutil/Makefile,v
retrieving revision 1.56
diff -u -r1.56 Makefile
--- lib/libutil/Makefile 25 Sep 2007 01:13:56 -0000 1.56
+++ lib/libutil/Makefile 23 Dec 2007 00:54:25 -0000
@@ -9,7 +9,7 @@
LIB= util
CPPFLAGS+=-DLIBC_SCCS
SRCS= efun.c getbootfile.c getlabelsector.c getmaxpartitions.c \
- getmntopts.c getrawpartition.c \
+ getmntopts.c getrawpartition.c getwedgebyname.c \
disklabel_dkcksum.c disklabel_scan.c \
if_media.c \
login.c loginx.c login_cap.c login_tty.c logout.c logoutx.c \
@@ -21,7 +21,7 @@
MAN= efun.3 getbootfile.3 getlabelsector.3 getmaxpartitions.3 \
getmntopts.3 \
- getrawpartition.3 \
+ getrawpartition.3 getwedgebyname.3 \
login.3 login_cap.3 loginx.3 \
disklabel_dkcksum.3 disklabel_scan.3 \
opendisk.3 openpty.3 parsedate.3 pidfile.3 pidlock.3 \
Index: lib/libutil/getwedgebyname.3
===================================================================
RCS file: lib/libutil/getwedgebyname.3
diff -N lib/libutil/getwedgebyname.3
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ lib/libutil/getwedgebyname.3 23 Dec 2007 00:54:26 -0000
@@ -0,0 +1,63 @@
+.\" $NetBSD$
+.\"
+.\" Copyright (c) 2007 The NetBSD Foundation, Inc.
+.\" All rights reserved.
+.\"
+.\" This code is derived from software contributed to The NetBSD Foundation
+.\" by Jeffrey C. Rizzo
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the NetBSD
+.\" Foundation, Inc. and its contributors.
+.\" 4. Neither the name of The NetBSD Foundation nor the names of its
+.\" contributors may be used to endorse or promote products derived
+.\" from this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.Dd December 22, 2007
+.Dt GETWEDGEBYNAME 3
+.Os
+.Sh NAME
+.Nm getwedgebyname
+.Nd get the device name of a named wedge
+.Sh LIBRARY
+.Lb libutil
+.Sh SYNOPSIS
+.In util.h
+.Ft char *
+.Fo getwedgebyname
+.Fa "const char *wname"
+.Fc
+.Sh DESCRIPTION
+.Fn getwedgebyname
+returns the device name of the wedge named
+.Va wname ,
+or NULL if the name was not found or an error occurred.
+The caller is expected to
+.Fn free
+the returned pointer.
+.Sh HISTORY
+The
+.Nm
+function call appeared in
+.Nx 5.0 .
Index: lib/libutil/getwedgebyname.c
===================================================================
RCS file: lib/libutil/getwedgebyname.c
diff -N lib/libutil/getwedgebyname.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ lib/libutil/getwedgebyname.c 23 Dec 2007 00:54:26 -0000
@@ -0,0 +1,119 @@
+/* $NetBSD$ */
+
+/*-
+ * Copyright (c) 2007 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jeffrey C. Rizzo
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/ioctl.h>
+#include <sys/sysctl.h>
+#include <sys/dkio.h>
+#include <sys/device.h>
+#include <sys/disk.h>
+
+#include <err.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <util.h>
+
+static int findwedge(const char *, const char *);
+char *getwedgebyname(const char *);
+
+static int
+findwedge(const char *diskname, const char *wname)
+{
+ int fd;
+ struct dkwedge_info dkw;
+ static char dvname_store[MAXPATHLEN]; /* for opendisk(3) */
+
+ fd = opendisk(diskname, O_RDONLY, dvname_store,
+ sizeof(dvname_store), 0);
+
+ if (fd == -1) {
+ warn("%s", diskname);
+ return 0;
+ }
+
+ if (ioctl(fd, DIOCGWEDGEINFO, &dkw) == -1) {
+ close(fd);
+ return 0;
+ }
+
+ close(fd);
+ if (strcmp((char *)dkw.dkw_wname, wname) == 0) /* XXX */
+ return 1;
+ else
+ return 0;
+}
+
+char *
+getwedgebyname(const char *wname)
+{
+ size_t bufsize;
+ char *disknames, *disk, *lastp;
+ char *wedge;
+
+ if (sysctlbyname("hw.disknames", NULL, &bufsize, NULL, 0) == -1) {
+ warn("%s: could not get buffer size", __func__);
+ return NULL;
+ }
+
+ bufsize += 200; /* arbitrary wiggle room */
+
+ if ((disknames = (char *)malloc(bufsize)) == NULL) {
+ warn("Could not allocate buffer");
+ return NULL;
+ }
+
+ if (sysctlbyname("hw.disknames", disknames, &bufsize, NULL,
+ 0) == -1) {
+ warn("Could not get names");
+ return NULL;
+ }
+
+ for (disk = strtok_r(disknames, " ", &lastp);
+ disk != NULL;
+ disk = strtok_r(NULL, " ", &lastp))
+ if (findwedge(disk, wname)) {
+ wedge = (char *)malloc(strlen(disk));
+ strcpy(wedge, disk);
+ free(disknames);
+ return wedge;
+ }
+ return NULL;
+}
Index: include/util.h
===================================================================
RCS file: /cvsroot/src/include/util.h,v
retrieving revision 1.49
diff -u -r1.49 util.h
--- include/util.h 14 Dec 2007 16:36:19 -0000 1.49
+++ include/util.h 23 Dec 2007 00:54:26 -0000
@@ -72,6 +72,7 @@
int getlabelsector(void);
int getmaxpartitions(void);
int getrawpartition(void);
+char * getwedgebyname(const char *);
void login(const struct utmp *);
void loginx(const struct utmpx *);
int login_tty(int);
Index: sbin/mount/Makefile
===================================================================
RCS file: /cvsroot/src/sbin/mount/Makefile,v
retrieving revision 1.29
diff -u -r1.29 Makefile
--- sbin/mount/Makefile 19 Aug 2004 23:02:27 -0000 1.29
+++ sbin/mount/Makefile 23 Dec 2007 00:54:26 -0000
@@ -6,5 +6,6 @@
PROG= mount
MAN= mount.8
SRCS= mount.c vfslist.c
+LDADD+= -lutil
.include <bsd.prog.mk>
Index: sbin/mount/mount.c
===================================================================
RCS file: /cvsroot/src/sbin/mount/mount.c,v
retrieving revision 1.84
diff -u -r1.84 mount.c
--- sbin/mount/mount.c 17 Jul 2007 23:56:01 -0000 1.84
+++ sbin/mount/mount.c 23 Dec 2007 00:54:26 -0000
@@ -56,12 +56,15 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <util.h>
#define MOUNTNAMES
#include <fcntl.h>
#include <sys/disk.h>
#include <sys/disklabel.h>
+#include <sys/dkio.h>
#include <sys/ioctl.h>
+#include <sys/sysctl.h>
#include "pathnames.h"
#include "vfslist.h"
@@ -81,7 +84,6 @@
static void prmount(struct statvfs *);
static void usage(void);
-
/* Map from mount otions to printable formats. */
static const struct opt {
int o_opt;
@@ -92,6 +94,7 @@
};
static char ffs_fstype[] = "ffs";
+char dvname_store[MAXPATHLEN]; /* for opendisk(3) */
int
main(int argc, char *argv[])
@@ -105,6 +108,7 @@
const char *mountopts, *fstypename;
char canonical_path_buf[MAXPATHLEN];
char *canonical_path;
+ char *special, specbuf[MAXPATHLEN];
/* started as "mount" */
all = forceall = init_flags = 0;
@@ -275,21 +279,38 @@
break;
case 2:
/*
+ * Handle the wedge case first. XXX yes, this means
+ * NFS mounts from machines named "wedge" will no
+ * longer work correctly
+ */
+ if (strncmp("wedge:", argv[0], strlen("wedge:")) == 0) {
+ special = getwedgebyname(argv[0] +
+ strlen("wedge:"));
+ if (special == NULL)
+ errx(1, "%s: unknown wedge name",
+ argv[0] + strlen("wedge:"));
+ snprintf(specbuf, MAXPATHLEN, "/dev/%s", special);
+ free(special);
+ special = specbuf;
+ } else
+ special = argv[0];
+
+ /*
* If -t flag has not been specified, and spec contains either
* a ':' or a '@' then assume that an NFS filesystem is being
* specified ala Sun.
*/
if (vfslist == NULL) {
- if (strpbrk(argv[0], ":@") != NULL)
+ if (strpbrk(special, ":@") != NULL)
vfstype = "nfs";
else {
- vfstype = getfslab(argv[0]);
+ vfstype = getfslab(special);
if (vfstype == NULL)
vfstype = ffs_fstype;
}
}
rval = mountfs(vfstype,
- argv[0], argv[1], init_flags, options, NULL, 0, NULL, 0);
+ special, argv[1], init_flags, options, NULL, 0, NULL, 0);
break;
default:
usage();
Index: sbin/mount_ffs/mount_ffs.c
===================================================================
RCS file: /cvsroot/src/sbin/mount_ffs/mount_ffs.c,v
retrieving revision 1.22
diff -u -r1.22 mount_ffs.c
--- sbin/mount_ffs/mount_ffs.c 16 Jul 2007 17:06:53 -0000 1.22
+++ sbin/mount_ffs/mount_ffs.c 23 Dec 2007 00:54:26 -0000
@@ -54,6 +54,7 @@
#include <string.h>
#include <unistd.h>
+#include <util.h>
#include <mntopts.h>
@@ -88,6 +89,7 @@
struct ufs_args args;
int ch, mntflags;
char fs_name[MAXPATHLEN], canon_dev[MAXPATHLEN];
+ char *dn, dnbuf[MAXPATHLEN];
const char *errcause;
mntoptparse_t mp;
@@ -111,10 +113,21 @@
if (argc != 2)
ffs_usage();
- if (realpath(argv[0], canon_dev) == NULL) /* Check device path */
- err(1, "realpath %s", argv[0]);
- if (strncmp(argv[0], canon_dev, MAXPATHLEN)) {
- warnx("\"%s\" is a relative path.", argv[0]);
+ if (strncmp("wedge:", argv[0], strlen("wedge:")) == 0) {
+ dn = getwedgebyname(argv[0] + strlen("wedge:"));
+ if (dn == NULL)
+ err(1, "No wedge named %s",
+ argv[0] + strlen("wedge:"));
+ snprintf(dnbuf, MAXPATHLEN, "/dev/%s", dn);
+ free(dn);
+ dn = dnbuf;
+ } else {
+ dn = argv[0];
+ }
+ if (realpath(dn, canon_dev) == NULL) /* Check device path */
+ err(1, "realpath %s", dn);
+ if (strncmp(dn, canon_dev, MAXPATHLEN)) {
+ warnx("\"%s\" is a relative path.", dn);
warnx("using \"%s\" instead.", canon_dev);
}
args.fspec = canon_dev;
Index: sbin/mount_lfs/mount_lfs.c
===================================================================
RCS file: /cvsroot/src/sbin/mount_lfs/mount_lfs.c,v
retrieving revision 1.31
diff -u -r1.31 mount_lfs.c
--- sbin/mount_lfs/mount_lfs.c 17 Jul 2007 12:39:24 -0000 1.31
+++ sbin/mount_lfs/mount_lfs.c 23 Dec 2007 00:54:26 -0000
@@ -55,6 +55,7 @@
#include <string.h>
#include <unistd.h>
#include <paths.h>
+#include <util.h>
#include <signal.h>
@@ -92,6 +93,7 @@
struct ufs_args args;
int ch, mntflags, noclean, mntsize, oldflags, i;
char fs_name[MAXPATHLEN], canon_dev[MAXPATHLEN];
+ char *dn, dnbuf[MAXPATHLEN];
char *options;
mntoptparse_t mp;
@@ -138,10 +140,21 @@
if (argc != 2)
usage();
- if (realpath(argv[0], canon_dev) == NULL) /* Check device path */
- err(1, "realpath %s", argv[0]);
- if (strncmp(argv[0], canon_dev, MAXPATHLEN)) {
- warnx("\"%s\" is a relative path.", argv[0]);
+ if (strncmp("wedge:", argv[0], strlen("wedge:")) == 0) {
+ dn = getwedgebyname(argv[0] + strlen("wedge:"));
+ if (dn == NULL)
+ err(1, "No wedge named %s",
+ argv[0] + strlen("wedge:"));
+ snprintf(dnbuf, MAXPATHLEN, "/dev/%s", dn);
+ free(dn);
+ dn = dnbuf;
+ } else {
+ dn = argv[0];
+ }
+ if (realpath(dn, canon_dev) == NULL) /* Check device path */
+ err(1, "realpath %s", dn);
+ if (strncmp(dn, canon_dev, MAXPATHLEN)) {
+ warnx("\"%s\" is a relative path.", dn);
warnx("using \"%s\" instead.", canon_dev);
}
args.fspec = canon_dev;
--------------060004070909080100020402--