vnconfig -l: print an error if supplied vn is unknown
[dragonfly.git] / usr.sbin / vnconfig / vnconfig.c
CommitLineData
984263bc
MD
1/*
2 * Copyright (c) 1993 University of Utah.
3 * Copyright (c) 1990, 1993
4 * The Regents of the University of California. All rights reserved.
5 *
6 * This code is derived from software contributed to Berkeley by
7 * the Systems Programming Group of the University of Utah Computer
8 * Science Department.
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 University of
21 * California, Berkeley and its contributors.
22 * 4. Neither the name of the University nor the names of its contributors
23 * may be used to endorse or promote products derived from this software
24 * without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 *
38 * from: Utah $Hdr: vnconfig.c 1.1 93/12/15$
1de703da
MD
39 *
40 * @(#)vnconfig.c 8.1 (Berkeley) 12/15/93
41 * $FreeBSD: src/usr.sbin/vnconfig/vnconfig.c,v 1.13.2.7 2003/06/02 09:10:27 maxim Exp $
daa51328 42 * $DragonFly: src/usr.sbin/vnconfig/vnconfig.c,v 1.15 2008/07/27 22:36:01 thomas Exp $
984263bc
MD
43 */
44
984263bc
MD
45#include <ctype.h>
46#include <err.h>
47#include <errno.h>
48#include <paths.h>
49#include <stdio.h>
50#include <stdlib.h>
51#include <fcntl.h>
52#include <string.h>
53#include <unistd.h>
54#include <sys/param.h>
55#include <sys/ioctl.h>
56#include <sys/linker.h>
57#include <sys/mount.h>
58#include <sys/module.h>
59#include <sys/stat.h>
60#include <sys/vnioctl.h>
38a690d7 61#include <vfs/ufs/ufsmount.h>
984263bc
MD
62
63#define LINESIZE 1024
64#define ZBUFSIZE 32768
65
66struct vndisk {
67 char *dev;
68 char *file;
69 char *autolabel;
70 int flags;
57fec106 71 int64_t size;
984263bc
MD
72 char *oarg;
73} *vndisks;
74
75#define VN_CONFIG 0x01
76#define VN_UNCONFIG 0x02
77#define VN_ENABLE 0x04
78#define VN_DISABLE 0x08
79#define VN_SWAP 0x10
80#define VN_MOUNTRO 0x20
81#define VN_MOUNTRW 0x40
82#define VN_IGNORE 0x80
83#define VN_SET 0x100
84#define VN_RESET 0x200
85#define VN_TRUNCATE 0x400
86#define VN_ZERO 0x800
87
88int nvndisks;
89
90int all = 0;
91int verbose = 0;
92int global = 0;
30c1fde0 93int listopt = 0;
984263bc
MD
94u_long setopt = 0;
95u_long resetopt = 0;
4c8a57a8 96const char *configfile;
984263bc 97
2d8a3be7 98int config(struct vndisk *);
acc9b5f2 99void getoptions(struct vndisk *, const char *);
30c1fde0 100int getinfo(const char *vname);
acc9b5f2 101char *rawdevice(const char *);
2d8a3be7
EN
102void readconfig(int);
103static void usage(void);
57fec106 104static int64_t getsize(const char *arg);
984263bc 105static void do_autolabel(const char *dev, const char *label);
acc9b5f2 106int what_opt(const char *, u_long *);
984263bc
MD
107
108int
cf287f0a 109main(int argc, char *argv[])
984263bc 110{
cf287f0a 111 int i, rv;
984263bc 112 int flags = 0;
57fec106 113 int64_t size = 0;
984263bc
MD
114 char *autolabel = NULL;
115 char *s;
116
117 configfile = _PATH_VNTAB;
30c1fde0 118 while ((i = getopt(argc, argv, "acdef:glr:s:S:TZL:uv")) != -1)
984263bc
MD
119 switch (i) {
120
121 /* all -- use config file */
122 case 'a':
123 all++;
124 break;
125
126 /* configure */
127 case 'c':
128 flags |= VN_CONFIG;
129 flags &= ~VN_UNCONFIG;
130 break;
131
132 /* disable */
133 case 'd':
134 flags |= VN_DISABLE;
135 flags &= ~VN_ENABLE;
136 break;
137
138 /* enable */
139 case 'e':
140 flags |= (VN_ENABLE|VN_CONFIG);
141 flags &= ~(VN_DISABLE|VN_UNCONFIG);
142 break;
143
144 /* alternate config file */
145 case 'f':
146 configfile = optarg;
147 break;
148
149 /* fiddle global options */
150 case 'g':
151 global = 1 - global;
152 break;
153
154 /* reset options */
155 case 'r':
156 for (s = strtok(optarg, ","); s; s = strtok(NULL, ",")) {
157 if (what_opt(s, &resetopt))
158 errx(1, "invalid options '%s'", s);
159 }
160 flags |= VN_RESET;
161 break;
162
30c1fde0
CT
163 case 'l':
164 listopt = 1;
165 break;
166
984263bc
MD
167 /* set options */
168 case 's':
169 for (s = strtok(optarg, ","); s; s = strtok(NULL, ",")) {
170 if (what_opt(s, &setopt))
171 errx(1, "invalid options '%s'", s);
172 }
173 flags |= VN_SET;
174 break;
175
176 /* unconfigure */
177 case 'u':
178 flags |= (VN_DISABLE|VN_UNCONFIG);
179 flags &= ~(VN_ENABLE|VN_CONFIG);
180 break;
181
182 /* verbose */
183 case 'v':
184 verbose++;
185 break;
186
187 case 'S':
188 size = getsize(optarg);
189 flags |= VN_CONFIG;
190 flags &= ~VN_UNCONFIG;
191 break;
192
193 case 'T':
194 flags |= VN_TRUNCATE;
195 break;
196
197 case 'Z':
198 flags |= VN_ZERO;
199 break;
200
201 case 'L':
202 autolabel = optarg;
203 break;
204
205 default:
206 usage();
207 }
208
209 if (modfind("vn") < 0)
210 if (kldload("vn") < 0 || modfind("vn") < 0)
211 warnx( "cannot find or load \"vn\" kernel module");
212
4c8a57a8 213 rv = 0;
30c1fde0
CT
214 if (listopt) {
215 if(argc > optind)
216 while(argc > optind)
217 rv += getinfo( argv[optind++]);
218 else {
219 rv = getinfo( NULL );
220 }
221 exit(rv);
222 }
223
984263bc
MD
224 if (flags == 0)
225 flags = VN_CONFIG;
226 if (all) {
227 readconfig(flags);
228 } else {
229 vndisks = calloc(sizeof(struct vndisk), 1);
230 if (argc < optind + 1)
231 usage();
232 vndisks[0].dev = argv[optind++];
233 vndisks[0].file = argv[optind++]; /* may be NULL */
234 vndisks[0].flags = flags;
235 vndisks[0].size = size;
236 vndisks[0].autolabel = autolabel;
237 if (optind < argc)
238 getoptions(&vndisks[0], argv[optind]);
239 nvndisks = 1;
240 }
241 rv = 0;
242 for (i = 0; i < nvndisks; i++)
243 rv += config(&vndisks[i]);
244 exit(rv);
245}
246
247int
acc9b5f2 248what_opt(const char *str, u_long *p)
984263bc
MD
249{
250 if (!strcmp(str,"reserve")) { *p |= VN_RESERVE; return 0; }
251 if (!strcmp(str,"labels")) { *p |= VN_LABELS; return 0; }
252 if (!strcmp(str,"follow")) { *p |= VN_FOLLOW; return 0; }
253 if (!strcmp(str,"debug")) { *p |= VN_DEBUG; return 0; }
254 if (!strcmp(str,"io")) { *p |= VN_IO; return 0; }
255 if (!strcmp(str,"all")) { *p |= ~0; return 0; }
256 if (!strcmp(str,"none")) { *p |= 0; return 0; }
257 return 1;
258}
259
30c1fde0
CT
260/*
261 *
262 * GETINFO
263 *
264 * Print vnode disk information to stdout for the device at
265 * path 'vname', or all existing 'vn' devices if none is given.
266 * Any 'vn' devices must exist under /dev in order to be queried.
267 *
268 * Todo: correctly use vm_secsize for swap-backed vn's ..
269 */
270
271int
272getinfo( const char *vname )
273{
4c8a57a8
SK
274 int i = 0, vd, printlim = 0;
275 char vnpath[PATH_MAX];
276 const char *tmp;
30c1fde0
CT
277
278 struct vn_user vnu;
279 struct stat sb;
280
281 if (vname == NULL) {
30c1fde0 282 printlim = 1024;
4c8a57a8
SK
283 } else {
284 tmp = vname;
201b3f37 285 while (*tmp != 0) {
30c1fde0
CT
286 if(isdigit(*tmp)){
287 i = atoi(tmp);
288 printlim = i + 1;
289 break;
290 }
291 tmp++;
292 }
906f76fe
SK
293 if (*tmp == '\0')
294 errx(1, "unknown vn device: %s", vname);
30c1fde0
CT
295 }
296
297 snprintf(vnpath, sizeof(vnpath), "/dev/vn%d", i);
298
acc9b5f2 299 vd = open(vnpath, O_RDONLY);
30c1fde0
CT
300 if (vd < 0) {
301 err(1, "open: %s", vnpath);
302 return 1;
303 }
304
4c8a57a8 305 for (; i<printlim; i++) {
30c1fde0
CT
306
307 bzero((void *) &vnpath, sizeof(vnpath));
308 bzero((void *) &sb, sizeof(struct stat));
309 bzero((void *) &vnu, sizeof(struct vn_user));
310
311 vnu.vnu_unit = i;
312
313 snprintf(vnpath, sizeof(vnpath), "/dev/vn%d", vnu.vnu_unit);
314
acc9b5f2 315 if(stat(vnpath, &sb) < 0) {
30c1fde0 316 break;
acc9b5f2 317 }
30c1fde0
CT
318 else {
319 if (ioctl(vd, VNIOCGET, &vnu) == -1) {
320 if (errno != ENXIO) {
2ddea4d5
SK
321 if (*vnu.vnu_file == '\0') {
322 fprintf(stdout,
323 "vn%d: ioctl: can't access regular file\n",
324 vnu.vnu_unit);
325 continue;
326 }
327 else {
328 err(1, "ioctl: %s", vname);
329 close(vd);
330 return 1;
331 }
30c1fde0
CT
332 }
333 }
334
335 fprintf(stdout, "vn%d: ", vnu.vnu_unit);
336
337 if (vnu.vnu_file[0] == 0)
338 fprintf(stdout, "not in use\n");
339 else if ((strcmp(vnu.vnu_file, _VN_USER_SWAP)) == 0)
340 fprintf(stdout,
4c8a57a8 341 "consuming %lld VM pages\n",
30c1fde0
CT
342 vnu.vnu_size);
343 else
344 fprintf(stdout,
0656dd4c 345 "covering %s on %s, inode %ju\n",
30c1fde0
CT
346 vnu.vnu_file,
347 devname(vnu.vnu_dev, S_IFBLK),
0656dd4c 348 (uintmax_t)vnu.vnu_ino);
30c1fde0
CT
349 }
350 }
351 close(vd);
352 return 0;
353}
354
984263bc 355int
cf287f0a 356config(struct vndisk *vnp)
984263bc 357{
66950a15 358 char *dev, *file, *rdev, *oarg;
984263bc 359 FILE *f;
66950a15
HP
360 struct vn_ioctl vnio;
361 int flags, pgsize, rv, status;
984263bc 362 u_long l;
66950a15
HP
363
364 pgsize = getpagesize();
984263bc
MD
365
366 status = rv = 0;
367
368 /*
369 * Prepend "/dev/" to the specified device name, if necessary.
370 * Operate on vnp->dev because it is used later.
371 */
372 if (vnp->dev[0] != '/' && vnp->dev[0] != '.')
71126e33 373 asprintf(&vnp->dev, "%s%s", _PATH_DEV, vnp->dev);
984263bc
MD
374 dev = vnp->dev;
375 file = vnp->file;
376 flags = vnp->flags;
377 oarg = vnp->oarg;
378
379 if (flags & VN_IGNORE)
380 return(0);
381
382 /*
383 * When a regular file has been specified, do any requested setup
384 * of the file. Truncation (also creates the file if necessary),
385 * sizing, and zeroing.
386 */
387
388 if (file && vnp->size != 0 && (flags & VN_CONFIG)) {
389 int fd;
390 struct stat st;
391
392 if (flags & VN_TRUNCATE)
c7daadb1 393 fd = open(file, O_RDWR|O_CREAT|O_TRUNC, 0600);
984263bc
MD
394 else
395 fd = open(file, O_RDWR);
396 if (fd >= 0 && fstat(fd, &st) == 0 && S_ISREG(st.st_mode)) {
57fec106
MD
397 if (st.st_size < vnp->size * pgsize)
398 ftruncate(fd, vnp->size * pgsize);
984263bc 399 if (vnp->size != 0)
57fec106 400 st.st_size = vnp->size * pgsize;
984263bc
MD
401
402 if (flags & VN_ZERO) {
403 char *buf = malloc(ZBUFSIZE);
404 bzero(buf, ZBUFSIZE);
405 while (st.st_size > 0) {
406 int n = (st.st_size > ZBUFSIZE) ?
407 ZBUFSIZE : (int)st.st_size;
408 if (write(fd, buf, n) != n) {
409 ftruncate(fd, 0);
410 printf("Unable to ZERO file %s\n", file);
411 return(0);
412 }
413 st.st_size -= (off_t)n;
414 }
415 }
416 close(fd);
417 } else {
418 printf("Unable to open file %s\n", file);
419 return(0);
420 }
ba2933c8
SW
421 } else if (file == NULL && vnp->size == 0 && (flags & VN_CONFIG)) {
422 warnx("specify regular filename or swap size");
423 return (0);
984263bc
MD
424 }
425
426 rdev = rawdevice(dev);
427 f = fopen(rdev, "rw");
428 if (f == NULL) {
429 warn("%s", dev);
430 return(1);
431 }
432 vnio.vn_file = file;
433 vnio.vn_size = vnp->size; /* non-zero only if swap backed */
434
435 /*
436 * Disable the device
437 */
438 if (flags & VN_DISABLE) {
439 if (flags & (VN_MOUNTRO|VN_MOUNTRW)) {
440 rv = unmount(oarg, 0);
441 if (rv) {
442 status--;
443 if (errno == EBUSY)
444 flags &= ~VN_UNCONFIG;
445 if ((flags & VN_UNCONFIG) == 0)
446 warn("umount");
447 } else if (verbose)
448 printf("%s: unmounted\n", dev);
449 }
450 }
451 /*
452 * Clear (un-configure) the device
453 */
454 if (flags & VN_UNCONFIG) {
455 rv = ioctl(fileno(f), VNIOCDETACH, &vnio);
456 if (rv) {
457 if (errno == ENODEV) {
458 if (verbose)
459 printf("%s: not configured\n", dev);
460 rv = 0;
461 } else {
462 status--;
463 warn("VNIOCDETACH");
464 }
465 } else if (verbose)
466 printf("%s: cleared\n", dev);
467 }
468 /*
469 * Set specified options
470 */
471 if (flags & VN_SET) {
472 l = setopt;
473 if (global)
474 rv = ioctl(fileno(f), VNIOCGSET, &l);
475 else
476 rv = ioctl(fileno(f), VNIOCUSET, &l);
477 if (rv) {
478 status--;
479 warn("VNIO[GU]SET");
480 } else if (verbose)
4c8a57a8 481 printf("%s: flags now=%08lx\n",dev,l);
984263bc
MD
482 }
483 /*
484 * Reset specified options
485 */
486 if (flags & VN_RESET) {
487 l = resetopt;
488 if (global)
489 rv = ioctl(fileno(f), VNIOCGCLEAR, &l);
490 else
491 rv = ioctl(fileno(f), VNIOCUCLEAR, &l);
492 if (rv) {
493 status--;
494 warn("VNIO[GU]CLEAR");
495 } else if (verbose)
4c8a57a8 496 printf("%s: flags now=%08lx\n",dev,l);
984263bc
MD
497 }
498 /*
499 * Configure the device
500 */
501 if (flags & VN_CONFIG) {
502 rv = ioctl(fileno(f), VNIOCATTACH, &vnio);
503 if (rv) {
504 status--;
505 warn("VNIOCATTACH");
506 flags &= ~VN_ENABLE;
507 } else {
508 if (verbose) {
b3f9ca10
HP
509 printf("%s: %s, ", dev, file);
510 if (vnp->size != 0) {
57fec106 511 printf("%lld bytes mapped\n", vnio.vn_size);
b3f9ca10
HP
512 } else {
513 printf("complete file mapped\n");
514 }
984263bc
MD
515 }
516 /*
517 * autolabel
518 */
519 if (vnp->autolabel) {
520 do_autolabel(vnp->dev, vnp->autolabel);
521 }
522 }
523 }
524 /*
525 * Set an option
526 */
527 if (flags & VN_SET) {
528 l = setopt;
529 if (global)
530 rv = ioctl(fileno(f), VNIOCGSET, &l);
531 else
532 rv = ioctl(fileno(f), VNIOCUSET, &l);
533 if (rv) {
534 status--;
535 warn("VNIO[GU]SET");
536 } else if (verbose)
537 printf("%s: flags now=%08lx\n",dev,l);
538 }
539 /*
540 * Reset an option
541 */
542 if (flags & VN_RESET) {
543 l = resetopt;
544 if (global)
545 rv = ioctl(fileno(f), VNIOCGCLEAR, &l);
546 else
547 rv = ioctl(fileno(f), VNIOCUCLEAR, &l);
548 if (rv) {
549 status--;
550 warn("VNIO[GU]CLEAR");
551 } else if (verbose)
552 printf("%s: flags now=%08lx\n",dev,l);
553 }
554
555 /*
556 * Close the device now, as we may want to mount it.
557 */
558 fclose(f);
559
560 /*
561 * Enable special functions on the device
562 */
563 if (flags & VN_ENABLE) {
564 if (flags & VN_SWAP) {
565 rv = swapon(dev);
566 if (rv) {
567 status--;
568 warn("swapon");
569 }
570 else if (verbose)
571 printf("%s: swapping enabled\n", dev);
572 }
573 if (flags & (VN_MOUNTRO|VN_MOUNTRW)) {
574 struct ufs_args args;
575 int mflags;
576
577 args.fspec = dev;
578 mflags = (flags & VN_MOUNTRO) ? MNT_RDONLY : 0;
579 rv = mount("ufs", oarg, mflags, &args);
580 if (rv) {
581 status--;
582 warn("mount");
583 }
584 else if (verbose)
585 printf("%s: mounted on %s\n", dev, oarg);
586 }
587 }
588/* done: */
589 fflush(stdout);
590 return(status < 0);
591}
592
593#define EOL(c) ((c) == '\0' || (c) == '\n')
594#define WHITE(c) ((c) == ' ' || (c) == '\t' || (c) == '\n')
595
596void
cf287f0a 597readconfig(int flags)
984263bc
MD
598{
599 char buf[LINESIZE];
600 FILE *f;
cf287f0a
MD
601 char *cp, *sp;
602 int ix;
984263bc
MD
603 int ax;
604
605 f = fopen(configfile, "r");
606 if (f == NULL)
607 err(1, "%s", configfile);
608 ix = 0; /* number of elements */
609 ax = 0; /* allocated elements */
610 while (fgets(buf, LINESIZE, f) != NULL) {
611 cp = buf;
612 if (*cp == '#')
613 continue;
614 while (!EOL(*cp) && WHITE(*cp))
615 cp++;
616 if (EOL(*cp))
617 continue;
618 sp = cp;
619 while (!EOL(*cp) && !WHITE(*cp))
620 cp++;
621 if (EOL(*cp))
622 continue;
623 *cp++ = '\0';
624
625 if (ix == ax) {
626 ax = ax + 16;
627 vndisks = realloc(vndisks, ax * sizeof(struct vndisk));
628 bzero(&vndisks[ix], (ax - ix) * sizeof(struct vndisk));
629 }
630 vndisks[ix].dev = malloc(cp - sp);
631 strcpy(vndisks[ix].dev, sp);
632 while (!EOL(*cp) && WHITE(*cp))
633 cp++;
634 if (EOL(*cp))
635 continue;
636 sp = cp;
637 while (!EOL(*cp) && !WHITE(*cp))
638 cp++;
639 *cp++ = '\0';
640
641 if (*sp == '%' && strtol(sp + 1, NULL, 0) > 0) {
642 vndisks[ix].size = getsize(sp + 1);
643 } else {
644 vndisks[ix].file = malloc(cp - sp);
645 strcpy(vndisks[ix].file, sp);
646 }
647
648 while (!EOL(*cp) && WHITE(*cp))
649 cp++;
650 vndisks[ix].flags = flags;
651 if (!EOL(*cp)) {
652 sp = cp;
653 while (!EOL(*cp) && !WHITE(*cp))
654 cp++;
655 *cp++ = '\0';
656 getoptions(&vndisks[ix], sp);
657 }
658 nvndisks++;
659 ix++;
660 }
661}
662
663void
acc9b5f2 664getoptions(struct vndisk *vnp, const char *fstr)
984263bc
MD
665{
666 int flags = 0;
acc9b5f2 667 const char *oarg = NULL;
984263bc
MD
668
669 if (strcmp(fstr, "swap") == 0)
670 flags |= VN_SWAP;
671 else if (strncmp(fstr, "mount=", 6) == 0) {
672 flags |= VN_MOUNTRW;
673 oarg = &fstr[6];
674 } else if (strncmp(fstr, "mountrw=", 8) == 0) {
675 flags |= VN_MOUNTRW;
676 oarg = &fstr[8];
677 } else if (strncmp(fstr, "mountro=", 8) == 0) {
678 flags |= VN_MOUNTRO;
679 oarg = &fstr[8];
680 } else if (strcmp(fstr, "ignore") == 0)
681 flags |= VN_IGNORE;
682 vnp->flags |= flags;
683 if (oarg) {
684 vnp->oarg = malloc(strlen(oarg) + 1);
685 strcpy(vnp->oarg, oarg);
686 } else
687 vnp->oarg = NULL;
688}
689
690char *
acc9b5f2 691rawdevice(const char *dev)
984263bc 692{
cf287f0a 693 char *rawbuf, *dp, *ep;
984263bc
MD
694 struct stat sb;
695 int len;
696
697 len = strlen(dev);
698 rawbuf = malloc(len + 2);
699 strcpy(rawbuf, dev);
700 if (stat(rawbuf, &sb) != 0 || !S_ISCHR(sb.st_mode)) {
17b61719 701 dp = strrchr(rawbuf, '/');
984263bc
MD
702 if (dp) {
703 for (ep = &rawbuf[len]; ep > dp; --ep)
704 *(ep+1) = *ep;
705 *++ep = 'r';
706 }
707 }
708 return (rawbuf);
709}
710
711static void
44d05a04 712usage(void)
984263bc 713{
daa51328
TN
714 fprintf(stderr, "%s\n%s\n%s\n%s\n",
715 "usage: vnconfig [-cdeguvTZ] [-s options] [-r options]",
716 " [-S value] special_file [regular_file] [feature]",
717 " vnconfig -a [-cdeguv] [-s options] [-r options] [-f config_file]",
718 " vnconfig -l [special_file ...]");
984263bc
MD
719 exit(1);
720}
721
57fec106 722static int64_t
984263bc
MD
723getsize(const char *arg)
724{
725 char *ptr;
726 int pgsize = getpagesize();
57fec106 727 int64_t size = strtoq(arg, &ptr, 0);
984263bc
MD
728
729 switch(tolower(*ptr)) {
730 case 't':
731 /*
acc9b5f2 732 * GULP! Terabytes. It's actually possible to create
984263bc
MD
733 * a 7.9 TB VN device, though newfs can't handle any single
734 * filesystem larger then 1 TB.
735 */
736 size *= 1024;
737 /* fall through */
738 case 'g':
739 size *= 1024;
740 /* fall through */
741 default:
742 case 'm':
743 size *= 1024;
744 /* fall through */
745 case 'k':
746 size *= 1024;
747 /* fall through */
748 case 'c':
749 break;
750 }
751 size = (size + pgsize - 1) / pgsize;
57fec106 752 return(size);
984263bc
MD
753}
754
755/*
756 * DO_AUTOLABEL
757 *
758 * Automatically label the device. This will wipe any preexisting
759 * label.
760 */
761
762static void
4c8a57a8 763do_autolabel(const char *dev __unused, const char *label __unused)
984263bc
MD
764{
765 /* XXX not yet implemented */
766 fprintf(stderr, "autolabel not yet implemented, sorry\n");
767 exit(1);
768}
769