diff --git a/distrib/sets/lists/minix/mi b/distrib/sets/lists/minix/mi index ded48abb50..71814ed0a9 100644 --- a/distrib/sets/lists/minix/mi +++ b/distrib/sets/lists/minix/mi @@ -4713,6 +4713,8 @@ ./usr/man/man8/usermod.8 minix-sys ./usr/man/man8/vbfs.8 minix-sys ./usr/man/man8/vipw.8 minix-sys +./usr/man/man8/vnconfig.8 minix-sys +./usr/man/man8/vndconfig.8 minix-sys ./usr/man/man8/zdump.8 minix-sys ./usr/man/man8/zic.8 minix-sys ./usr/man/man9 minix-sys @@ -4767,6 +4769,8 @@ ./usr/sbin/vfs minix-sys ./usr/sbin/vipw minix-sys ./usr/sbin/vm minix-sys +./usr/sbin/vnconfig minix-sys +./usr/sbin/vndconfig minix-sys ./usr/sbin/vnd minix-sys ./usr/sbin/zic minix-sys ./usr/share minix-sys diff --git a/include/minix/paths.h b/include/minix/paths.h index 65ea4325ba..447c465afa 100644 --- a/include/minix/paths.h +++ b/include/minix/paths.h @@ -17,4 +17,6 @@ #define _PATH_RAMDISK "/dev/ram" +#define _PATH_DRIVERS "/usr/sbin" + #endif /* _MINIX_PATHS_H_ */ diff --git a/releasetools/nbsd_ports b/releasetools/nbsd_ports index fda6c052ca..80b6af0a9e 100644 --- a/releasetools/nbsd_ports +++ b/releasetools/nbsd_ports @@ -269,4 +269,5 @@ 2012/10/17 12:00:00,usr.sbin/unlink 2011/01/04 10:30:21,usr.sbin/user 2009/04/19 00:44:49,usr.sbin/vipw +2013/07/31 12:00:00,usr.sbin/vnconfig 2009/04/22 15:23:10,usr.sbin/zic diff --git a/usr.sbin/Makefile b/usr.sbin/Makefile index 0282e16246..5baeffa2a9 100644 --- a/usr.sbin/Makefile +++ b/usr.sbin/Makefile @@ -12,6 +12,7 @@ SUBDIR= \ rdate \ unlink user \ vipw \ + vnconfig \ zic # LSC MINIX Specific diff --git a/usr.sbin/vnconfig/Makefile b/usr.sbin/vnconfig/Makefile new file mode 100644 index 0000000000..4916628090 --- /dev/null +++ b/usr.sbin/vnconfig/Makefile @@ -0,0 +1,10 @@ +# $NetBSD: Makefile,v 1.8 2013/06/09 22:00:50 jmmv Exp $ + +PROG= vnconfig +MAN= vnconfig.8 +DPADD+= ${LIBUTIL} +LDADD+= -lutil +LINKS+= ${BINDIR}/vnconfig ${BINDIR}/vndconfig +MLINKS+= vnconfig.8 vndconfig.8 + +.include diff --git a/usr.sbin/vnconfig/vnconfig.8 b/usr.sbin/vnconfig/vnconfig.8 new file mode 100644 index 0000000000..5b6ca008d5 --- /dev/null +++ b/usr.sbin/vnconfig/vnconfig.8 @@ -0,0 +1,195 @@ +.\" $NetBSD: vnconfig.8,v 1.39 2013/06/09 18:39:31 christos Exp $ +.\" +.\" Copyright (c) 1997 The NetBSD Foundation, Inc. +.\" All rights reserved. +.\" +.\" This code is derived from software contributed to The NetBSD Foundation +.\" by Jason R. Thorpe. +.\" +.\" 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. +.\" +.\" 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. +.\" +.\" Copyright (c) 1993 University of Utah. +.\" Copyright (c) 1980, 1989, 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" the Systems Programming Group of the University of Utah Computer +.\" Science Department. +.\" +.\" 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. Neither the name of the University 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 REGENTS 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 REGENTS 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. +.\" +.\" @(#)vnconfig.8 8.1 (Berkeley) 6/5/93 +.\" +.Dd June 9, 2013 +.Dt VNDCONFIG 8 +.Os +.Sh NAME +.Nm vndconfig +.Nd configure vnode disks +.Sh SYNOPSIS +.Nm +.Op Fl Scrv +.Ar vnode_disk +.Ar regular_file +.Op Ar geomspec +.Nm +.Fl u +.Op Fl SFv +.Ar vnode_disk +.Nm +.Fl l +.Op Ar vnode_disk +.Sh DESCRIPTION +The +.Nm +command configures vnode pseudo disk devices. +It will associate the vnode disk +.Ar vnode_disk +with the regular file +.Ar regular_file +allowing the latter to be accessed as though it were a disk. +Hence a regular file within the filesystem can be used for swapping +or can contain a filesystem that is mounted in the name space. +The +.Ar vnode_disk +is a special file of raw partition or name of vnode disk like +.Pa vnd0 . +.Pp +Options indicate an action to be performed: +.Bl -tag -width indent +.It Fl c +Configures the device. +If successful, references to +.Ar vnode_disk +will access the contents of +.Ar regular_file . +.Pp +If +.Ar geomspec +is specified, the vnode device will emulate the specified disk geometry. +The format of the +.Ar geomspec +argument is: +.Bd -ragged -offset indent +.Sm off +.Xo Ar secsize Li / Ar nsectors Li / +.Ar ntracks Li / Ar ncylinders Xc +.Sm on +.Ed +.Pp +If geometry is not specified, the driver will choose a default based on 1MB +cylinders. +.Ar secsize +is the number of bytes per sector. +It must be an even multiple of 512. +.Ar nsectors +is the number of sectors per track. +.Ar ntracks +is the number of tracks per cylinder. +.Ar ncylinders +is the number of cylinders in the device. +.It Fl S +Do not start or stop the corresponding device driver instance. +.It Fl F +Force unconfiguration if the device is in use. +Does not imply +.Fl u . +.It Fl l +List the vnd devices and indicate which ones are in use. +If a specific +.Ar vnode_disk +is given, then only that will be described. +.It Fl r +Configure the device as read-only. +.It Fl u +Unconfigures the device. +.It Fl v +Print messages to stdout describing actions taken. +.El +.Pp +If no action option is given, +.Fl c +is assumed. +.Sh FILES +.Bl -tag -width /dev/vnd* -compact +.It Pa /dev/vnd* +.El +.Sh EXAMPLES +.Dl vndconfig vnd0 /tmp/diskimage +or +.Dl vndconfig /dev/vnd0 /tmp/diskimage +.Pp +Configures the vnode disk +.Pa vnd0 . +.Pp +.Dl vndconfig vnd0 /tmp/floppy.img 512/18/2/80 +.Pp +Configures the vnode disk +.Pa vnd0 +emulating the geometry of 512 bytes per sector, 18 sectors per track, +2 tracks per cylinder, and 80 cylinders total. +.Pp +.Dl vndconfig -u vnd0 +.Pp +Unconfigures the +.Pa vnd0 +device. +.Sh NOTES +If +.Ic vnconfig -uF +is used and the device was still in use, the driver instance +will not be shut down, even if +.Fl S +was not given. One may manually shut down +the service later with +.Ic service down +.Ar vndN +where +.Ar N +is the instance number, or simply +leave the driver running for later reuse. +.Sh SEE ALSO +.Xr opendisk 3 , +.Xr mount 8 , +.Xr umount 8 diff --git a/usr.sbin/vnconfig/vnconfig.c b/usr.sbin/vnconfig/vnconfig.c new file mode 100644 index 0000000000..e95f6d2a45 --- /dev/null +++ b/usr.sbin/vnconfig/vnconfig.c @@ -0,0 +1,605 @@ +/* $NetBSD: vnconfig.c,v 1.41 2013/06/09 13:25:40 christos Exp $ */ + +/*- + * Copyright (c) 1997 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe. + * + * 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. + * + * 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. + */ + +/* + * Copyright (c) 1993 University of Utah. + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * the Systems Programming Group of the University of Utah Computer + * Science Department. + * + * 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. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * from: Utah $Hdr: vnconfig.c 1.1 93/12/15$ + * + * @(#)vnconfig.c 8.1 (Berkeley) 12/15/93 + */ + +#include +#include +#include +#ifndef __minix +#include +#include +#include +#include +#else +#include +#endif + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define VND_CONFIG 1 +#define VND_UNCONFIG 2 +#define VND_GET 3 + +static int verbose = 0; +static int readonly = 0; +static int force = 0; +static int compressed = 0; +static char *tabname; +#ifdef __minix +static int service = 1; +#endif + +#ifndef __minix +static void show(int, int); +#else +static void show(const char *, int); +#endif +static int config(char *, char *, char *, int); +static int getgeom(struct vndgeom *, char *); +__dead static void usage(void); + +#ifdef __minix +/* + * Start a driver instance for the given vnd name. The return value indicates + * whether the instance has been started successfully. + */ +static int +start_service(char *dev) +{ + char *p, *endp, cmd[PATH_MAX]; + int n, status; + + p = strrchr(dev, '/'); + if (p == NULL) p = dev; + else p++; + + /* + * There are two alternatives to get the instance number for the + * driver: either we scan the given device name, or we obtain its major + * number. We choose to scan the name, because major numbers are more + * likely to change in the future. + */ + if (strncmp(p, "vnd", 3) != 0) + return 0; + n = strtoul(p + 3, &endp, 10); + if (endp[0]) + return 0; + + if (verbose) + printf("%s: starting driver\n", dev); + + snprintf(cmd, sizeof(cmd), + "%s up %s/vnd -label vnd%u -args instance=%u -dev %s", + _PATH_SERVICE, _PATH_DRIVERS, n, n, dev); + + status = system(cmd); + + if (!WIFEXITED(status)) + return 0; + return !WEXITSTATUS(status); +} + +/* + * Stop the driver instance responsible for the given file descriptor. + * The file descriptor is closed upon return. + */ +static void +stop_service(int fd, char *dev) +{ + char cmd[PATH_MAX]; + struct vnd_user vnu; + int openct, stop = 0; + + /* Only shut down the driver if the device is opened once, by us. */ + if (ioctl(fd, DIOCOPENCT, &openct) == 0 && openct == 1) { + /* We let the driver tell us what instance number it has. */ + if (ioctl(fd, VNDIOCGET, &vnu) == 0) + stop = 1; + } + + /* Close the file descriptor before shutting down the driver! */ + (void) close(fd); + + if (stop) { + if (verbose) + printf("%s: stopping driver\n", dev); + + snprintf(cmd, sizeof(cmd), "%s down vnd%u", _PATH_SERVICE, + vnu.vnu_unit); + + system(cmd); + } +} +#endif + +int +main(int argc, char *argv[]) +{ + int ch, rv, action = VND_CONFIG; + +#ifndef __minix + while ((ch = getopt(argc, argv, "Fcf:lrt:uvz")) != -1) { +#else + /* MINIX3: added -S; no support for -f, -t, -z at this time. */ + while ((ch = getopt(argc, argv, "SFclruv")) != -1) { +#endif + switch (ch) { +#ifdef __minix + case 'S': + service = 0; + break; +#endif + case 'F': + force = 1; + break; + case 'c': + action = VND_CONFIG; + break; + case 'f': +#ifndef __minix + if (setdisktab(optarg) == -1) + usage(); +#endif + break; + case 'l': + action = VND_GET; + break; + case 'r': + readonly = 1; + break; + case 't': + tabname = optarg; + break; + case 'u': + action = VND_UNCONFIG; + break; + case 'v': + verbose = 1; + break; + case 'z': + compressed = 1; + readonly = 1; + break; + default: + case '?': + usage(); + /* NOTREACHED */ + } + } + argc -= optind; + argv += optind; + + if (action == VND_CONFIG) { + if ((argc < 2 || argc > 3) || + (argc == 3 && tabname != NULL)) + usage(); + rv = config(argv[0], argv[1], (argc == 3) ? argv[2] : NULL, + action); + } else if (action == VND_UNCONFIG) { + if (argc != 1 || tabname != NULL) + usage(); + rv = config(argv[0], NULL, NULL, action); + } else { /* VND_GET */ +#ifndef __minix + int n, v; + const char *vn; + char path[64]; +#else + int n; +#endif + + if (argc != 0 && argc != 1) + usage(); + +#ifndef __minix + vn = argc ? argv[0] : "vnd0"; + + v = opendisk(vn, O_RDONLY, path, sizeof(path), 0); + if (v == -1) + err(1, "open: %s", vn); +#endif + + if (argc) +#ifndef __minix + show(v, -1); +#else + show(argv[0], -1); +#endif + else { + DIR *dirp; + struct dirent *dp; +#ifndef __minix + __BITMAP_TYPE(, uint32_t, 65536) bm; + + __BITMAP_ZERO(&bm); +#else + char *endp; +#endif + + if ((dirp = opendir(_PATH_DEV)) == NULL) + err(1, "opendir: %s", _PATH_DEV); + + while ((dp = readdir(dirp)) != NULL) { +#ifndef __minix + if (strncmp(dp->d_name, "rvnd", 4) != 0) + continue; + n = atoi(dp->d_name + 4); + if (__BITMAP_ISSET(n, &bm)) + continue; + __BITMAP_SET(n, &bm); + show(v, n); +#else + if (strncmp(dp->d_name, "vnd", 3) != 0) + continue; + n = strtoul(dp->d_name + 3, &endp, 10); + if (endp[0]) + continue; + show(dp->d_name, n); +#endif + } + + closedir(dirp); + } +#ifndef __minix + close(v); +#endif + rv = 0; + } + return rv; +} + +static void +#ifndef __minix +show(int v, int n) +#else +show(const char *vn, int n) +#endif +{ + struct vnd_user vnu; + char *dev; + struct statvfs *mnt; + int i, nmount; +#ifdef __minix + int v; + char path[PATH_MAX]; + + v = opendisk(vn, O_RDONLY, path, sizeof(path), 0); + if (v == -1) { + if (n == -1) + err(1, "open: %s", vn); + else + printf("vnd%d: not in use\n", n); + return; + } +#endif + + vnu.vnu_unit = n; + if (ioctl(v, VNDIOCGET, &vnu) == -1) + err(1, "VNDIOCGET"); + +#ifdef __minix + close(v); +#endif + + if (vnu.vnu_ino == 0) { + printf("vnd%d: not in use\n", vnu.vnu_unit); + return; + } + + printf("vnd%d: ", vnu.vnu_unit); + + dev = devname(vnu.vnu_dev, S_IFBLK); + if (dev != NULL) + nmount = getmntinfo(&mnt, MNT_NOWAIT); + else { + mnt = NULL; + nmount = 0; + } + + if (mnt != NULL) { + for (i = 0; i < nmount; i++) { + if (strncmp(mnt[i].f_mntfromname, "/dev/", 5) == 0 && + strcmp(mnt[i].f_mntfromname + 5, dev) == 0) + break; + } + if (i < nmount) + printf("%s (%s) ", mnt[i].f_mntonname, + mnt[i].f_mntfromname); + else + printf("%s ", dev); + } + else if (dev != NULL) + printf("%s ", dev); + else + printf("dev %llu,%llu ", + (unsigned long long)major(vnu.vnu_dev), + (unsigned long long)minor(vnu.vnu_dev)); + + printf("inode %llu\n", (unsigned long long)vnu.vnu_ino); +} + +static int +config(char *dev, char *file, char *geom, int action) +{ + struct vnd_ioctl vndio; +#ifndef __minix + struct disklabel *lp; +#else + int stop = 0; +#endif + char rdev[MAXPATHLEN + 1]; + int fd, rv; + +#ifdef __minix + /* + * MINIX does not have the concept of raw devices. As such, the access + * checks that apply to opening block devices, automatically apply here + * as well. Therefore, we must open the device as read-only, or we + * would be unable to un-configure a device that was configured as + * read-only: opening such a device as read-write would fail. + */ + fd = opendisk(dev, O_RDONLY, rdev, sizeof(rdev), 0); + + if (fd < 0 && errno == ENXIO && action == VND_CONFIG && service) { + stop = start_service(rdev); + + fd = opendisk(dev, O_RDONLY, rdev, sizeof(rdev), 0); + } +#else + fd = opendisk(dev, O_RDWR, rdev, sizeof(rdev), 0); +#endif + if (fd < 0) { + warn("%s: opendisk", rdev); + return (1); + } + + memset(&vndio, 0, sizeof(vndio)); +#ifdef __GNUC__ + rv = 0; /* XXX */ +#endif + +#ifndef __minix + vndio.vnd_file = file; +#endif + if (geom != NULL) { + rv = getgeom(&vndio.vnd_geom, geom); +#ifdef __minix + if (rv && stop) + stop_service(fd, rdev); +#endif + if (rv != 0) + errx(1, "invalid geometry: %s", geom); + vndio.vnd_flags = VNDIOF_HASGEOM; +#ifndef __minix + } else if (tabname != NULL) { + lp = getdiskbyname(tabname); + if (lp == NULL) + errx(1, "unknown disk type: %s", tabname); + vndio.vnd_geom.vng_secsize = lp->d_secsize; + vndio.vnd_geom.vng_nsectors = lp->d_nsectors; + vndio.vnd_geom.vng_ntracks = lp->d_ntracks; + vndio.vnd_geom.vng_ncylinders = lp->d_ncylinders; + vndio.vnd_flags = VNDIOF_HASGEOM; +#endif + } + + if (readonly) + vndio.vnd_flags |= VNDIOF_READONLY; + +#ifndef __minix + if (compressed) + vndio.vnd_flags |= VNF_COMP; +#endif + + /* + * Clear (un-configure) the device + */ + if (action == VND_UNCONFIG) { + if (force) + vndio.vnd_flags |= VNDIOF_FORCE; + rv = ioctl(fd, VNDIOCCLR, &vndio); +#ifdef VNDIOOCCLR + if (rv && errno == ENOTTY) + rv = ioctl(fd, VNDIOOCCLR, &vndio); +#endif + if (rv) + warn("%s: VNDIOCCLR", rdev); + else if (verbose) + printf("%s: cleared\n", rdev); +#ifdef __minix + if (!rv && service) + stop = 2; +#endif + } + /* + * Configure the device + */ + if (action == VND_CONFIG) { + int ffd; + + ffd = open(file, readonly ? O_RDONLY : O_RDWR); + if (ffd < 0) + warn("%s", file); + else { +#ifndef __minix + (void) close(ffd); +#else + vndio.vnd_fildes = ffd; +#endif + + rv = ioctl(fd, VNDIOCSET, &vndio); +#ifdef VNDIOOCSET + if (rv && errno == ENOTTY) { + rv = ioctl(fd, VNDIOOCSET, &vndio); + vndio.vnd_size = vndio.vnd_osize; + } +#endif +#ifdef __minix + (void) close(ffd); +#endif + if (rv) + warn("%s: VNDIOCSET", rdev); + else if (verbose) { + printf("%s: %" PRIu64 " bytes on %s", rdev, + vndio.vnd_size, file); + if (vndio.vnd_flags & VNDIOF_HASGEOM) + printf(" using geometry %d/%d/%d/%d", + vndio.vnd_geom.vng_secsize, + vndio.vnd_geom.vng_nsectors, + vndio.vnd_geom.vng_ntracks, + vndio.vnd_geom.vng_ncylinders); + printf("\n"); + } + } +#ifdef __minix + if ((ffd < 0 || rv) && service) + stop++; +#endif + } + +#ifdef __minix + if (stop >= 2) + stop_service(fd, rdev); + else +#endif + (void) close(fd); + fflush(stdout); + return (rv < 0); +} + +static int +getgeom(struct vndgeom *vng, char *cp) +{ + char *secsize, *nsectors, *ntracks, *ncylinders; + +#define GETARG(arg) \ + do { \ + if (cp == NULL || *cp == '\0') \ + return (1); \ + arg = strsep(&cp, "/"); \ + if (arg == NULL) \ + return (1); \ + } while (0) + + GETARG(secsize); + GETARG(nsectors); + GETARG(ntracks); + GETARG(ncylinders); + +#undef GETARG + + /* Too many? */ + if (cp != NULL) + return (1); + +#define CVTARG(str, num) \ + do { \ + num = strtol(str, &cp, 10); \ + if (*cp != '\0') \ + return (1); \ + } while (0) + + CVTARG(secsize, vng->vng_secsize); + CVTARG(nsectors, vng->vng_nsectors); + CVTARG(ntracks, vng->vng_ntracks); + CVTARG(ncylinders, vng->vng_ncylinders); + +#undef CVTARG + + return (0); +} + +static void +usage(void) +{ + + (void)fprintf(stderr, "%s%s", +#ifndef __minix + "usage: vnconfig [-crvz] [-f disktab] [-t typename] vnode_disk" + " regular-file [geomspec]\n", + " vnconfig -u [-Fv] vnode_disk\n" +#else + "usage: vnconfig [-Scrv] vnode_disk regular-file [geomspec]\n", + " vnconfig -u [-SFv] vnode_disk\n" +#endif + " vnconfig -l [vnode_disk]\n"); + exit(1); +}