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