Subject: Re: mounting by wedge name
To: None <tech-userlevel@netbsd.org>
From: Christos Zoulas <christos@astron.com>
List: tech-userlevel
Date: 12/23/2007 18:54:56
In article <476DCE3D.7060402@tastylime.net>,
Jeff Rizzo <riz@tastylime.net> wrote:
>-=-=-=-=-=-
>
>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!
>+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;
>+ }
KNF is indent by tab. I am also not sure if this belongs in libutil.
Specially if it uses warn(3). Library functions should not print errors.
>+
>+ bufsize += 200; /* arbitrary wiggle room */
>+
>+ if ((disknames = (char *)malloc(bufsize)) == NULL) {
>+ warn("Could not allocate buffer");
>+ return NULL;
>+ }
No cast for malloc.
>+
>+ 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));
No cast for malloc; +1 for NUL.
>+ strcpy(wedge, disk);
>+ free(disknames);
>+ return wedge;
>+ }
>+ return NULL;
>+}
> 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];
>+
The above code can be factored out into a function since it is used
in 3 places. Don't use strlen("wedge:"), use (sizeof("wedge:") - 1).
Perhaps put that in a define:
#define PREFIX "wedge:"
#define PREFIX_LEN (sizeof(PREFIX) - 1)
I am not sure this is the right way to do things, since I will not be able
to mount from a host called "wedge" :) Perhaps a better syntax is to use
[wedgename].
christos