Home | History | Annotate | Line # | Download | only in vnconfig
vnconfig.c revision 1.36
      1 /*	$NetBSD: vnconfig.c,v 1.36 2008/12/29 03:49:17 christos Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 1997 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Jason R. Thorpe.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  * POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 /*
     33  * Copyright (c) 1990, 1993
     34  *	The Regents of the University of California.  All rights reserved.
     35  *
     36  * This code is derived from software contributed to Berkeley by
     37  * the Systems Programming Group of the University of Utah Computer
     38  * Science Department.
     39  *
     40  * Redistribution and use in source and binary forms, with or without
     41  * modification, are permitted provided that the following conditions
     42  * are met:
     43  * 1. Redistributions of source code must retain the above copyright
     44  *    notice, this list of conditions and the following disclaimer.
     45  * 2. Redistributions in binary form must reproduce the above copyright
     46  *    notice, this list of conditions and the following disclaimer in the
     47  *    documentation and/or other materials provided with the distribution.
     48  * 3. Neither the name of the University nor the names of its contributors
     49  *    may be used to endorse or promote products derived from this software
     50  *    without specific prior written permission.
     51  *
     52  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     53  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     54  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     55  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     56  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     57  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     58  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     59  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     60  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     61  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     62  * SUCH DAMAGE.
     63  *
     64  * from: Utah $Hdr: vnconfig.c 1.1 93/12/15$
     65  *
     66  *	@(#)vnconfig.c	8.1 (Berkeley) 12/15/93
     67  */
     68 
     69 /*
     70  * Copyright (c) 1993 University of Utah.
     71  *
     72  * This code is derived from software contributed to Berkeley by
     73  * the Systems Programming Group of the University of Utah Computer
     74  * Science Department.
     75  *
     76  * Redistribution and use in source and binary forms, with or without
     77  * modification, are permitted provided that the following conditions
     78  * are met:
     79  * 1. Redistributions of source code must retain the above copyright
     80  *    notice, this list of conditions and the following disclaimer.
     81  * 2. Redistributions in binary form must reproduce the above copyright
     82  *    notice, this list of conditions and the following disclaimer in the
     83  *    documentation and/or other materials provided with the distribution.
     84  * 3. All advertising materials mentioning features or use of this software
     85  *    must display the following acknowledgement:
     86  *	This product includes software developed by the University of
     87  *	California, Berkeley and its contributors.
     88  * 4. Neither the name of the University nor the names of its contributors
     89  *    may be used to endorse or promote products derived from this software
     90  *    without specific prior written permission.
     91  *
     92  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     93  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     94  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     95  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     96  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     97  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     98  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     99  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    100  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    101  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    102  * SUCH DAMAGE.
    103  *
    104  * from: Utah $Hdr: vnconfig.c 1.1 93/12/15$
    105  *
    106  *	@(#)vnconfig.c	8.1 (Berkeley) 12/15/93
    107  */
    108 
    109 #include <sys/param.h>
    110 #include <sys/ioctl.h>
    111 #include <sys/mount.h>
    112 #include <sys/buf.h>
    113 #include <sys/disklabel.h>
    114 #include <sys/disk.h>
    115 
    116 #include <dev/vndvar.h>
    117 
    118 #include <disktab.h>
    119 #include <err.h>
    120 #include <errno.h>
    121 #include <fcntl.h>
    122 #include <stdio.h>
    123 #include <stdlib.h>
    124 #include <string.h>
    125 #include <unistd.h>
    126 #include <util.h>
    127 
    128 #define VND_CONFIG	1
    129 #define VND_UNCONFIG	2
    130 #define VND_GET		3
    131 
    132 int	verbose = 0;
    133 int	readonly = 0;
    134 int	force = 0;
    135 int	compressed = 0;
    136 char	*tabname;
    137 
    138 int	config __P((char *, char *, char *, int));
    139 int	getgeom __P((struct vndgeom *, char *));
    140 int	main __P((int, char **));
    141 char   *rawdevice __P((char *));
    142 void	usage __P((void));
    143 
    144 int
    145 main(argc, argv)
    146 	int argc;
    147 	char *argv[];
    148 {
    149 	int ch, rv, action = VND_CONFIG;
    150 
    151 	while ((ch = getopt(argc, argv, "Fcf:lrt:uvz")) != -1) {
    152 		switch (ch) {
    153 		case 'F':
    154 			force = 1;
    155 			break;
    156 		case 'c':
    157 			action = VND_CONFIG;
    158 			break;
    159 		case 'f':
    160 			if (setdisktab(optarg) == -1)
    161 				usage();
    162 			break;
    163 		case 'l':
    164 			action = VND_GET;
    165 			break;
    166 		case 'r':
    167 			readonly = 1;
    168 			break;
    169 		case 't':
    170 			tabname = optarg;
    171 			break;
    172 		case 'u':
    173 			action = VND_UNCONFIG;
    174 			break;
    175 		case 'v':
    176 			verbose = 1;
    177 			break;
    178 		case 'z':
    179 			compressed = 1;
    180 			readonly = 1;
    181 			break;
    182 		default:
    183 		case '?':
    184 			usage();
    185 			/* NOTREACHED */
    186 		}
    187 	}
    188 	argc -= optind;
    189 	argv += optind;
    190 
    191 	if (action == VND_CONFIG) {
    192 		if ((argc < 2 || argc > 3) ||
    193 		    (argc == 3 && tabname != NULL))
    194 			usage();
    195 		rv = config(argv[0], argv[1], (argc == 3) ? argv[2] : NULL,
    196 		    action);
    197 	} else if (action == VND_UNCONFIG) {
    198 		if (argc != 1 || tabname != NULL)
    199 			usage();
    200 		rv = config(argv[0], NULL, NULL, action);
    201 	} else { /* VND_GET */
    202 		char *vn, path[64];
    203 		struct vnd_user vnu;
    204 		int v, n;
    205 
    206 		if (argc != 0 && argc != 1)
    207 			usage();
    208 
    209 		vn = argc ? argv[0] : "vnd0";
    210 
    211 		v = opendisk(vn, O_RDONLY, path, sizeof(path), 0);
    212 		if (v == -1)
    213 			err(1, "open: %s", vn);
    214 
    215 		for (n = 0; ; n++) {
    216 			vnu.vnu_unit = argc ? -1 : n;
    217 			rv = ioctl(v, VNDIOCGET, &vnu);
    218 			if (rv == -1) {
    219 				if (errno == ENXIO)
    220 					break;
    221 				err(1, "VNDIOCGET");
    222 			}
    223 
    224 			if (vnu.vnu_ino == 0)
    225 				printf("vnd%d: not in use\n",
    226 				    vnu.vnu_unit);
    227 			else {
    228 				char *dev;
    229 				struct statvfs *mnt = NULL;
    230 				int i, n;
    231 
    232 				n = 0;	/* XXXGCC -Wuninitialized */
    233 
    234 				printf("vnd%d: ", vnu.vnu_unit);
    235 
    236 				dev = devname(vnu.vnu_dev, S_IFBLK);
    237 				if (dev != NULL)
    238 					n = getmntinfo(&mnt, MNT_NOWAIT);
    239 				else
    240 					mnt = NULL;
    241 				if (mnt != NULL) {
    242 					for (i = 0; i < n; i++) {
    243 						if (strncmp(
    244 						    mnt[i].f_mntfromname,
    245 						    "/dev/", 5) == 0 &&
    246 						    strcmp(
    247 						    mnt[i].f_mntfromname + 5,
    248 						    dev) == 0)
    249 							break;
    250 					}
    251 					if (i < n)
    252 						printf("%s (%s) ",
    253 						    mnt[i].f_mntonname,
    254 						    mnt[i].f_mntfromname);
    255 					else
    256 						printf("%s ", dev);
    257 				}
    258 				else if (dev != NULL)
    259 					printf("%s ", dev);
    260 				else
    261 					printf("dev %llu,%llu ",
    262 					    (unsigned long long)major(vnu.vnu_dev),
    263 					    (unsigned long long)minor(vnu.vnu_dev));
    264 
    265 				printf("inode %llu\n",
    266 				    (unsigned long long)vnu.vnu_ino);
    267 			}
    268 
    269 			if (argc)
    270 				break;
    271 		}
    272 		close(v);
    273 	}
    274 	exit(rv);
    275 }
    276 
    277 int
    278 config(dev, file, geom, action)
    279 	char *dev, *file, *geom;
    280 	int action;
    281 {
    282 	struct vnd_ioctl vndio;
    283 	struct disklabel *lp;
    284 	char rdev[MAXPATHLEN + 1];
    285 	int fd, rv;
    286 
    287 	fd = opendisk(dev, O_RDWR, rdev, sizeof(rdev), 0);
    288 	if (fd < 0) {
    289 		warn("%s: opendisk", rdev);
    290 		return (1);
    291 	}
    292 
    293 	memset(&vndio, 0, sizeof(vndio));
    294 #ifdef __GNUC__
    295 	rv = 0;			/* XXX */
    296 #endif
    297 
    298 	vndio.vnd_file = file;
    299 	if (geom != NULL) {
    300 		rv = getgeom(&vndio.vnd_geom, geom);
    301 		if (rv != 0)
    302 			errx(1, "invalid geometry: %s", geom);
    303 		vndio.vnd_flags = VNDIOF_HASGEOM;
    304 	} else if (tabname != NULL) {
    305 		lp = getdiskbyname(tabname);
    306 		if (lp == NULL)
    307 			errx(1, "unknown disk type: %s", tabname);
    308 		vndio.vnd_geom.vng_secsize = lp->d_secsize;
    309 		vndio.vnd_geom.vng_nsectors = lp->d_nsectors;
    310 		vndio.vnd_geom.vng_ntracks = lp->d_ntracks;
    311 		vndio.vnd_geom.vng_ncylinders = lp->d_ncylinders;
    312 		vndio.vnd_flags = VNDIOF_HASGEOM;
    313 	}
    314 
    315 	if (readonly)
    316 		vndio.vnd_flags |= VNDIOF_READONLY;
    317 
    318 	if (compressed)
    319 		vndio.vnd_flags |= VNF_COMP;
    320 
    321 	/*
    322 	 * Clear (un-configure) the device
    323 	 */
    324 	if (action == VND_UNCONFIG) {
    325 		if (force)
    326 			vndio.vnd_flags |= VNDIOF_FORCE;
    327 		rv = ioctl(fd, VNDIOCCLR, &vndio);
    328 		if (rv)
    329 			warn("%s: VNDIOCCLR", rdev);
    330 		else if (verbose)
    331 			printf("%s: cleared\n", rdev);
    332 	}
    333 	/*
    334 	 * Configure the device
    335 	 */
    336 	if (action == VND_CONFIG) {
    337 		int	ffd;
    338 
    339 		ffd = open(file, readonly ? O_RDONLY : O_RDWR);
    340 		if (ffd < 0)
    341 			warn("%s", file);
    342 		else {
    343 			(void) close(ffd);
    344 
    345 			rv = ioctl(fd, VNDIOCSET, &vndio);
    346 			if (rv)
    347 				warn("%s: VNDIOCSET", rdev);
    348 			else if (verbose) {
    349 				printf("%s: %d bytes on %s", rdev,
    350 				    vndio.vnd_size, file);
    351 				if (vndio.vnd_flags & VNDIOF_HASGEOM)
    352 					printf(" using geometry %d/%d/%d/%d",
    353 					    vndio.vnd_geom.vng_secsize,
    354 					    vndio.vnd_geom.vng_nsectors,
    355 					    vndio.vnd_geom.vng_ntracks,
    356 				    vndio.vnd_geom.vng_ncylinders);
    357 				printf("\n");
    358 			}
    359 		}
    360 	}
    361 
    362 	(void) close(fd);
    363 	fflush(stdout);
    364 	return (rv < 0);
    365 }
    366 
    367 int
    368 getgeom(vng, cp)
    369 	struct vndgeom *vng;
    370 	char *cp;
    371 {
    372 	char *secsize, *nsectors, *ntracks, *ncylinders;
    373 
    374 #define	GETARG(arg) \
    375 	do { \
    376 		if (cp == NULL || *cp == '\0') \
    377 			return (1); \
    378 		arg = strsep(&cp, "/"); \
    379 		if (arg == NULL) \
    380 			return (1); \
    381 	} while (0)
    382 
    383 	GETARG(secsize);
    384 	GETARG(nsectors);
    385 	GETARG(ntracks);
    386 	GETARG(ncylinders);
    387 
    388 #undef GETARG
    389 
    390 	/* Too many? */
    391 	if (cp != NULL)
    392 		return (1);
    393 
    394 #define	CVTARG(str, num) \
    395 	do { \
    396 		num = strtol(str, &cp, 10); \
    397 		if (*cp != '\0') \
    398 			return (1); \
    399 	} while (0)
    400 
    401 	CVTARG(secsize, vng->vng_secsize);
    402 	CVTARG(nsectors, vng->vng_nsectors);
    403 	CVTARG(ntracks, vng->vng_ntracks);
    404 	CVTARG(ncylinders, vng->vng_ncylinders);
    405 
    406 #undef CVTARG
    407 
    408 	return (0);
    409 }
    410 
    411 void
    412 usage()
    413 {
    414 
    415 	(void)fprintf(stderr, "%s%s",
    416 	    "usage: vnconfig [-crvz] [-f disktab] [-t typename] vnode_disk"
    417 		" regular-file [geomspec]\n",
    418 	    "       vnconfig -u [-Fv] vnode_disk\n"
    419 	    "       vnconfig -l [vnode_disk]\n");
    420 	exit(1);
    421 }
    422