1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 23 #pragma ident "%Z%%M% %I% %E% SMI" 24 /* from UCB 5.2 9/11/85 */ 25 26 /* 27 * newfs: friendly front end to mkfs 28 * 29 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 30 * Use is subject to license terms. 31 */ 32 33 #include <sys/param.h> 34 #include <sys/types.h> 35 #include <locale.h> 36 #include <sys/stat.h> 37 #include <sys/buf.h> 38 #include <sys/fs/ufs_fs.h> 39 #include <sys/vnode.h> 40 #include <sys/fs/ufs_inode.h> 41 #include <sys/sysmacros.h> 42 43 #include <errno.h> 44 #include <stdio.h> 45 #include <string.h> 46 #include <stdlib.h> 47 #include <stdarg.h> 48 #include <stdio.h> 49 #include <fcntl.h> 50 #include <unistd.h> 51 #include <limits.h> 52 #include <libintl.h> 53 #include <sys/dkio.h> 54 #include <sys/vtoc.h> 55 #include <sys/mkdev.h> 56 #include <sys/efi_partition.h> 57 58 #include <fslib.h> 59 60 static unsigned int number(char *, char *, int, int); 61 static int64_t number64(char *, char *, int, int64_t); 62 static diskaddr_t getdiskbydev(char *); 63 static int yes(void); 64 static int notrand(char *); 65 static void usage(); 66 static diskaddr_t get_device_size(int, char *); 67 static diskaddr_t brute_force_get_device_size(int); 68 static int validate_size(char *disk, diskaddr_t size); 69 static void exenv(void); 70 static struct fs *read_sb(char *); 71 /*PRINTFLIKE1*/ 72 static void fatal(char *fmt, ...); 73 74 #define EPATH "PATH=/usr/sbin:/sbin:" 75 #define CPATH "/sbin" /* an EPATH element */ 76 #define MB (1024 * 1024) 77 #define GBSEC ((1024 * 1024 * 1024) / DEV_BSIZE) /* sectors in a GB */ 78 #define MINFREESEC ((64 * 1024 * 1024) / DEV_BSIZE) /* sectors in 64 MB */ 79 #define MINCPG (16) /* traditional */ 80 #define MAXDEFDENSITY (8 * 1024) /* arbitrary */ 81 #define MINDENSITY (2 * 1024) /* traditional */ 82 #define MIN_MTB_DENSITY (1024 * 1024) 83 #define POWEROF2(num) (((num) & ((num) - 1)) == 0) 84 #define SECTORS_PER_TERABYTE (1LL << 31) 85 /* 86 * The following constant specifies an upper limit for file system size 87 * that is actually a lot bigger than we expect to support with UFS. (Since 88 * it's specified in sectors, the file system size would be 2**44 * 512, 89 * which is 2**53, which is 8192 Terabytes.) However, it's useful 90 * for checking the basic sanity of a size value that is input on the 91 * command line. 92 */ 93 #define FS_SIZE_UPPER_LIMIT 0x100000000000LL 94 95 /* For use with number() */ 96 #define NR_NONE 0 97 #define NR_PERCENT 0x01 98 99 /* 100 * The following two constants set the default block and fragment sizes. 101 * Both constants must be a power of 2 and meet the following constraints: 102 * MINBSIZE <= DESBLKSIZE <= MAXBSIZE 103 * DEV_BSIZE <= DESFRAGSIZE <= DESBLKSIZE 104 * DESBLKSIZE / DESFRAGSIZE <= 8 105 */ 106 #define DESBLKSIZE 8192 107 #define DESFRAGSIZE 1024 108 109 #define dprintf(x) if (debug) printf x 110 111 int debug = 0; /* enable debug output */ 112 static int Nflag; /* run mkfs without writing file system */ 113 static int Tflag; /* set up file system for growth to over 1 TB */ 114 static int verbose; /* show mkfs line before exec */ 115 static int fsize = 0; /* fragment size */ 116 static int fsize_flag = 0; /* fragment size was specified on cmd line */ 117 static int bsize; /* block size */ 118 static int ntracks; /* # tracks/cylinder */ 119 static int ntracks_set = 0; /* true if the user specified ntracks */ 120 static int optim = FS_OPTTIME; /* optimization, t(ime) or s(pace) */ 121 static int nsectors; /* # sectors/track */ 122 static int geom_nsectors; /* # sectors/track as returned by GEOM ioctl */ 123 static int cpg; /* cylinders/cylinder group */ 124 static int cpg_set = 0; /* true if the user specified cpg */ 125 static int minfree = -1; /* free space threshold */ 126 static int rpm; /* revolutions/minute of drive */ 127 static int rpm_set = 0; /* true if the user specified rpm */ 128 static int nrpos = 8; /* # of distinguished rotational positions */ 129 /* 8 is the historical default */ 130 static int nrpos_set = 0; /* true if the user specified nrpos */ 131 static int density = 0; /* number of bytes per inode */ 132 static int apc; /* alternates per cylinder */ 133 static int apc_set = 0; /* true if the user specified apc */ 134 static int rot = -1; /* rotational delay (msecs) */ 135 static int rot_set = 0; /* true if the user specified rot */ 136 static int maxcontig = -1; /* maximum number of contig blocks */ 137 static int text_sb = 0; /* no disk changes; just final sb text dump */ 138 static int binary_sb = 0; /* no disk changes; just final sb binary dump */ 139 static int label_type; /* see types below */ 140 141 /* 142 * The variable use_efi_dflts is an indicator of whether to use EFI logic 143 * or the geometry logic in laying out the filesystem. This is decided 144 * based on the size of the disk and is used only for non-EFI labeled disks. 145 */ 146 static int use_efi_dflts = 0; 147 148 static char device[MAXPATHLEN]; 149 static char cmd[BUFSIZ]; 150 151 extern char *getfullrawname(); /* from libadm */ 152 153 int 154 main(int argc, char *argv[]) 155 { 156 char *special, *name; 157 struct stat64 st; 158 int status; 159 int option; 160 int nsect; 161 struct fs *sbp; /* Pointer to superblock (if present) */ 162 diskaddr_t actual_fssize; 163 diskaddr_t max_possible_fssize; 164 diskaddr_t req_fssize = 0; 165 diskaddr_t fssize = 0; 166 char *req_fssize_str = NULL; /* requested size argument */ 167 168 (void) setlocale(LC_ALL, ""); 169 170 #if !defined(TEXT_DOMAIN) 171 #define TEXT_DOMAIN "SYS_TEST" 172 #endif 173 (void) textdomain(TEXT_DOMAIN); 174 175 opterr = 0; /* We print our own errors, disable getopt's message */ 176 while ((option = getopt(argc, argv, 177 "vNBSs:C:d:t:o:a:b:f:c:m:n:r:i:T")) != EOF) { 178 switch (option) { 179 case 'S': 180 text_sb++; 181 break; 182 case 'B': 183 binary_sb++; 184 break; 185 case 'v': 186 verbose++; 187 break; 188 189 case 'N': 190 Nflag++; 191 break; 192 193 case 's': 194 /* 195 * The maximum file system size is a lot smaller 196 * than FS_SIZE_UPPER_LIMIT, but until we find out 197 * the device size and block size, we don't know 198 * what it is. So save the requested size in a 199 * string so that we can print it out later if we 200 * determine it's too big. 201 */ 202 req_fssize = number64("fssize", optarg, NR_NONE, 203 FS_SIZE_UPPER_LIMIT); 204 if (req_fssize < 1024) 205 fatal(gettext( 206 "%s: fssize must be at least 1024"), 207 optarg); 208 req_fssize_str = strdup(optarg); 209 if (req_fssize_str == NULL) 210 fatal(gettext( 211 "Insufficient memory for string copy.")); 212 break; 213 214 case 'C': 215 maxcontig = number("maxcontig", optarg, NR_NONE, -1); 216 if (maxcontig < 0) 217 fatal(gettext("%s: bad maxcontig"), optarg); 218 break; 219 220 case 'd': 221 rot = number("rotdelay", optarg, NR_NONE, 0); 222 rot_set = 1; 223 if (rot < 0 || rot > 1000) 224 fatal(gettext( 225 "%s: bad rotational delay"), optarg); 226 break; 227 228 case 't': 229 ntracks = number("ntrack", optarg, NR_NONE, 16); 230 ntracks_set = 1; 231 if ((ntracks < 0) || 232 (ntracks > INT_MAX)) 233 fatal(gettext("%s: bad total tracks"), optarg); 234 break; 235 236 case 'o': 237 if (strcmp(optarg, "space") == 0) 238 optim = FS_OPTSPACE; 239 else if (strcmp(optarg, "time") == 0) 240 optim = FS_OPTTIME; 241 else 242 fatal(gettext( 243 "%s: bad optimization preference (options are `space' or `time')"), 244 optarg); 245 break; 246 247 case 'a': 248 apc = number("apc", optarg, NR_NONE, 0); 249 apc_set = 1; 250 if (apc < 0 || apc > 32768) /* see mkfs.c */ 251 fatal(gettext( 252 "%s: bad alternates per cyl"), optarg); 253 break; 254 255 case 'b': 256 bsize = number("bsize", optarg, NR_NONE, DESBLKSIZE); 257 if (bsize < MINBSIZE || bsize > MAXBSIZE) 258 fatal(gettext( 259 "%s: bad block size"), optarg); 260 break; 261 262 case 'f': 263 fsize = number("fragsize", optarg, NR_NONE, 264 DESFRAGSIZE); 265 fsize_flag++; 266 /* xxx ought to test against bsize for upper limit */ 267 if (fsize < DEV_BSIZE) 268 fatal(gettext("%s: bad frag size"), optarg); 269 break; 270 271 case 'c': 272 cpg = number("cpg", optarg, NR_NONE, 16); 273 cpg_set = 1; 274 if (cpg < 1) 275 fatal(gettext("%s: bad cylinders/group"), 276 optarg); 277 break; 278 279 case 'm': 280 minfree = number("minfree", optarg, NR_PERCENT, 10); 281 if (minfree < 0 || minfree > 99) 282 fatal(gettext("%s: bad free space %%"), optarg); 283 break; 284 285 case 'n': 286 nrpos = number("nrpos", optarg, NR_NONE, 8); 287 nrpos_set = 1; 288 if (nrpos <= 0) 289 fatal(gettext( 290 "%s: bad number of rotational positions"), 291 optarg); 292 break; 293 294 case 'r': 295 rpm = number("rpm", optarg, NR_NONE, 3600); 296 rpm_set = 1; 297 if (rpm < 0) 298 fatal(gettext("%s: bad revs/minute"), optarg); 299 break; 300 301 case 'i': 302 /* xxx ought to test against fsize */ 303 density = number("nbpi", optarg, NR_NONE, 2048); 304 if (density < DEV_BSIZE) 305 fatal(gettext("%s: bad bytes per inode"), 306 optarg); 307 break; 308 309 case 'T': 310 Tflag++; 311 break; 312 313 default: 314 usage(); 315 fatal(gettext("-%c: unknown flag"), optopt); 316 } 317 } 318 319 /* At this point, there should only be one argument left: */ 320 /* The raw-special-device itself. If not, print usage message. */ 321 if ((argc - optind) != 1) { 322 usage(); 323 exit(1); 324 } 325 326 name = argv[optind]; 327 328 special = getfullrawname(name); 329 if (special == NULL) { 330 (void) fprintf(stderr, gettext("newfs: malloc failed\n")); 331 exit(1); 332 } 333 334 if (*special == '\0') { 335 if (strchr(name, '/') != NULL) { 336 if (stat64(name, &st) < 0) { 337 (void) fprintf(stderr, 338 gettext("newfs: %s: %s\n"), 339 name, strerror(errno)); 340 exit(2); 341 } 342 fatal(gettext("%s: not a raw disk device"), name); 343 } 344 (void) sprintf(device, "/dev/rdsk/%s", name); 345 if ((special = getfullrawname(device)) == NULL) { 346 (void) fprintf(stderr, 347 gettext("newfs: malloc failed\n")); 348 exit(1); 349 } 350 351 if (*special == '\0') { 352 (void) sprintf(device, "/dev/%s", name); 353 if ((special = getfullrawname(device)) == NULL) { 354 (void) fprintf(stderr, 355 gettext("newfs: malloc failed\n")); 356 exit(1); 357 } 358 if (*special == '\0') 359 fatal(gettext( 360 "%s: not a raw disk device"), name); 361 } 362 } 363 364 /* 365 * getdiskbydev() determines the characteristics of the special 366 * device on which the file system will be built. In the case 367 * of devices with SMI labels (that is, non-EFI labels), the 368 * following characteristics are set (if they were not already 369 * set on the command line, since the command line settings 370 * take precedence): 371 * 372 * nsectors - sectors per track 373 * ntracks - tracks per cylinder 374 * rpm - disk revolutions per minute 375 * 376 * apc is NOT set 377 * 378 * getdiskbydev() also sets the following quantities for all 379 * devices, if not already set: 380 * 381 * bsize - file system block size 382 * maxcontig 383 * label_type (efi, vtoc, or other) 384 * 385 * getdiskbydev() returns the actual size of the device, in 386 * sectors. 387 */ 388 389 actual_fssize = getdiskbydev(special); 390 391 if (req_fssize == 0) { 392 fssize = actual_fssize; 393 } else { 394 /* 395 * If the user specified a size larger than what we've 396 * determined as the actual size of the device, see if the 397 * size specified by the user can be read. If so, use it, 398 * since some devices and volume managers may not support 399 * the vtoc and EFI interfaces we use to determine device 400 * size. 401 */ 402 if (req_fssize > actual_fssize && 403 validate_size(special, req_fssize)) { 404 (void) fprintf(stderr, gettext( 405 "Warning: the requested size of this file system\n" 406 "(%lld sectors) is greater than the size of the\n" 407 "device reported by the driver (%lld sectors).\n" 408 "However, a read of the device at the requested size\n" 409 "does succeed, so the requested size will be used.\n"), 410 req_fssize, actual_fssize); 411 fssize = req_fssize; 412 } else { 413 fssize = MIN(req_fssize, actual_fssize); 414 } 415 } 416 417 if (label_type == LABEL_TYPE_VTOC) { 418 if (!use_efi_dflts) { 419 if (nsectors < 0) 420 fatal(gettext("%s: no default #sectors/track"), 421 special); 422 if (ntracks < 0) 423 fatal(gettext("%s: no default #tracks"), 424 special); 425 } 426 if (rpm < 0) 427 fatal(gettext( 428 "%s: no default revolutions/minute value"), 429 special); 430 if (rpm < 60) { 431 (void) fprintf(stderr, 432 gettext("Warning: setting rpm to 60\n")); 433 rpm = 60; 434 } 435 } 436 if (label_type == LABEL_TYPE_EFI || label_type == LABEL_TYPE_OTHER) { 437 if (ntracks_set) 438 (void) fprintf(stderr, gettext( 439 "Warning: ntracks is obsolete for this device and will be ignored.\n")); 440 if (cpg_set) 441 (void) fprintf(stderr, gettext( 442 "Warning: cylinders/group is obsolete for this device and will be ignored.\n")); 443 if (rpm_set) 444 (void) fprintf(stderr, gettext( 445 "Warning: rpm is obsolete for this device and will be ignored.\n")); 446 if (rot_set) 447 (void) fprintf(stderr, gettext( 448 "Warning: rotational delay is obsolete for this device and" 449 " will be ignored.\n")); 450 if (nrpos_set) 451 (void) fprintf(stderr, gettext( 452 "Warning: number of rotational positions is obsolete for this device and\n" 453 "will be ignored.\n")); 454 if (apc_set) 455 (void) fprintf(stderr, gettext( 456 "Warning: number of alternate sectors per cylinder is obsolete for this\n" 457 "device and will be ignored.\n")); 458 459 /* 460 * We need these for the call to mkfs, even though they are 461 * meaningless. 462 */ 463 rpm = 60; 464 nrpos = 1; 465 apc = 0; 466 rot = -1; 467 468 /* 469 * These values are set to produce a file system with 470 * a cylinder group size of 48MB. For disks with 471 * non-EFI labels, most geometries result in cylinder 472 * groups of around 40 - 50 MB, so we arbitrarily choose 473 * 48MB for disks with EFI labels. mkfs will reduce 474 * cylinders per group even further if necessary. 475 */ 476 477 cpg = 16; 478 nsectors = 128; 479 ntracks = 48; 480 481 /* 482 * mkfs produces peculiar results for file systems 483 * that are smaller than one cylinder so don't allow 484 * them to be created (this check is only made for 485 * disks with EFI labels. Eventually, it should probably 486 * be enforced for all disks.) 487 */ 488 489 if (fssize < nsectors * ntracks) { 490 fatal(gettext( 491 "file system size must be at least %d sectors"), 492 nsectors * ntracks); 493 } 494 } 495 496 if (fssize > INT_MAX) 497 Tflag = 1; 498 499 /* 500 * If the user requested that the file system be set up for 501 * eventual growth to over a terabyte, or if it's already greater 502 * than a terabyte, set the inode density (nbpi) to MIN_MTB_DENSITY 503 * (unless the user has specified a larger nbpi), set the frag size 504 * equal to the block size, and set the cylinders-per-group value 505 * passed to mkfs to -1, which tells mkfs to make cylinder groups 506 * as large as possible. 507 */ 508 if (Tflag) { 509 if (density < MIN_MTB_DENSITY) 510 density = MIN_MTB_DENSITY; 511 fsize = bsize; 512 cpg = -1; /* says make cyl groups as big as possible */ 513 } else { 514 if (fsize == 0) 515 fsize = DESFRAGSIZE; 516 } 517 518 if (!POWEROF2(fsize)) { 519 (void) fprintf(stderr, gettext( 520 "newfs: fragment size must a power of 2, not %d\n"), fsize); 521 fsize = bsize/8; 522 (void) fprintf(stderr, gettext( 523 "newfs: fragsize reset to %ld\n"), fsize); 524 } 525 526 /* 527 * The file system is limited in size by the fragment size. 528 * The number of fragments in the file system must fit into 529 * a signed 32-bit quantity, so the number of sectors in the 530 * file system is INT_MAX * the number of sectors in a frag. 531 */ 532 533 max_possible_fssize = ((uint64_t)fsize)/DEV_BSIZE * INT_MAX; 534 if (fssize > max_possible_fssize) 535 fssize = max_possible_fssize; 536 537 /* 538 * Now fssize is the final size of the file system (in sectors). 539 * If it's less than what the user requested, print a message. 540 */ 541 if (fssize < req_fssize) { 542 (void) fprintf(stderr, gettext( 543 "newfs: requested size of %s disk blocks is too large.\n"), 544 req_fssize_str); 545 (void) fprintf(stderr, gettext( 546 "newfs: Resetting size to %lld\n"), fssize); 547 } 548 549 /* 550 * fssize now equals the size (in sectors) of the file system 551 * that will be created. 552 */ 553 554 /* XXX - following defaults are both here and in mkfs */ 555 if (density <= 0) { 556 if (fssize < GBSEC) 557 density = MINDENSITY; 558 else 559 density = (int)((((longlong_t)fssize + (GBSEC - 1)) / 560 GBSEC) * MINDENSITY); 561 if (density <= 0) 562 density = MINDENSITY; 563 if (density > MAXDEFDENSITY) 564 density = MAXDEFDENSITY; 565 } 566 if (cpg == 0) { 567 /* 568 * maxcpg calculation adapted from mkfs 569 * In the case of disks with EFI labels, cpg has 570 * already been set, so we won't enter this code. 571 */ 572 long maxcpg, maxipg; 573 574 maxipg = roundup(bsize * NBBY / 3, 575 bsize / sizeof (struct inode)); 576 577 nsect = (nsectors == -1) ? geom_nsectors : nsectors; 578 579 maxcpg = (bsize - sizeof (struct cg) - howmany(maxipg, NBBY)) / 580 (sizeof (long) + nrpos * sizeof (short) + 581 nsect / (MAXFRAG * NBBY)); 582 cpg = (fssize / GBSEC) * 32; 583 if (cpg > maxcpg) 584 cpg = maxcpg; 585 if (cpg <= 0) 586 cpg = MINCPG; 587 } 588 if (minfree < 0) { 589 minfree = ((float)MINFREESEC / fssize) * 100; 590 if (minfree > 10) 591 minfree = 10; 592 if (minfree <= 0) 593 minfree = 1; 594 } 595 #ifdef i386 /* Bug 1170182 */ 596 if (ntracks > 32 && (ntracks % 16) != 0) { 597 ntracks -= (ntracks % 16); 598 } 599 #endif 600 /* 601 * Confirmation 602 */ 603 if (isatty(fileno(stdin)) && !Nflag) { 604 /* 605 * If we can read a valid superblock, report the mount 606 * point on which this filesystem was last mounted. 607 */ 608 if (((sbp = read_sb(special)) != 0) && 609 (*sbp->fs_fsmnt != '\0')) { 610 (void) printf(gettext( 611 "newfs: %s last mounted as %s\n"), 612 special, sbp->fs_fsmnt); 613 } 614 (void) printf(gettext( 615 "newfs: construct a new file system %s: (y/n)? "), 616 special); 617 (void) fflush(stdout); 618 if (!yes()) 619 exit(0); 620 } 621 dprintf(("DeBuG newfs : nsect=%d ntrak=%d cpg=%d\n", 622 nsectors, ntracks, cpg)); 623 /* 624 * If alternates-per-cylinder is ever implemented: 625 * need to get apc from dp->d_apc if no -a switch??? 626 */ 627 (void) sprintf(cmd, 628 "mkfs -F ufs %s%s%s%s %lld %d %d %d %d %d %d %d %d %s %d %d %d %d %s", 629 Nflag ? "-o N " : "", binary_sb ? "-o calcbinsb " : "", 630 text_sb ? "-o calcsb " : "", special, 631 fssize, nsectors, ntracks, bsize, fsize, cpg, minfree, rpm/60, 632 density, optim == FS_OPTSPACE ? "s" : "t", apc, rot, nrpos, 633 maxcontig, Tflag ? "y" : "n"); 634 if (verbose) { 635 (void) printf("%s\n", cmd); 636 (void) fflush(stdout); 637 } 638 exenv(); 639 if (status = system(cmd)) 640 exit(status >> 8); 641 if (Nflag) 642 exit(0); 643 (void) sprintf(cmd, "/usr/sbin/fsirand %s", special); 644 if (notrand(special) && (status = system(cmd)) != 0) 645 (void) fprintf(stderr, 646 gettext("%s: failed, status = %d\n"), 647 cmd, status); 648 return (0); 649 } 650 651 static void 652 exenv(void) 653 { 654 char *epath; /* executable file path */ 655 char *cpath; /* current path */ 656 657 if ((cpath = getenv("PATH")) == NULL) { 658 (void) fprintf(stderr, gettext("newfs: no PATH in env\n")); 659 /* 660 * Background: the Bourne shell interpolates "." into 661 * the path where said path starts with a colon, ends 662 * with a colon, or has two adjacent colons. Thus, 663 * the path ":/sbin::/usr/sbin:" is equivalent to 664 * ".:/sbin:.:/usr/sbin:.". Now, we have no cpath, 665 * and epath ends in a colon (to make for easy 666 * catenation in the normal case). By the above, if 667 * we use "", then "." becomes part of path. That's 668 * bad, so use CPATH (which is just a duplicate of some 669 * element in EPATH). No point in opening ourselves 670 * up to a Trojan horse attack when we don't have to.... 671 */ 672 cpath = CPATH; 673 } 674 if ((epath = malloc(strlen(EPATH) + strlen(cpath) + 1)) == NULL) { 675 (void) fprintf(stderr, gettext("newfs: malloc failed\n")); 676 exit(1); 677 } 678 (void) strcpy(epath, EPATH); 679 (void) strcat(epath, cpath); 680 if (putenv(epath) < 0) { 681 (void) fprintf(stderr, gettext("newfs: putenv failed\n")); 682 exit(1); 683 } 684 } 685 686 static int 687 yes(void) 688 { 689 int i, b; 690 691 i = b = getchar(); 692 while (b != '\n' && b != '\0' && b != EOF) 693 b = getchar(); 694 return (i == 'y'); 695 } 696 697 /* 698 * xxx Caller must run fmt through gettext(3) for us, if we ever 699 * xxx go the i18n route.... 700 */ 701 static void 702 fatal(char *fmt, ...) 703 { 704 va_list pvar; 705 706 (void) fprintf(stderr, "newfs: "); 707 va_start(pvar, fmt); 708 (void) vfprintf(stderr, fmt, pvar); 709 va_end(pvar); 710 (void) putc('\n', stderr); 711 exit(10); 712 } 713 714 static diskaddr_t 715 getdiskbydev(char *disk) 716 { 717 struct dk_geom g; 718 struct dk_cinfo ci; 719 diskaddr_t actual_size; 720 int fd; 721 722 if ((fd = open64(disk, 0)) < 0) { 723 perror(disk); 724 exit(1); 725 } 726 727 /* 728 * get_device_size() determines the actual size of the 729 * device, and also the disk's attributes, such as geometry. 730 */ 731 actual_size = get_device_size(fd, disk); 732 733 if (label_type == LABEL_TYPE_VTOC) { 734 if (ioctl(fd, DKIOCGGEOM, &g)) 735 fatal(gettext( 736 "%s: Unable to read Disk geometry"), disk); 737 dprintf(("DeBuG newfs : geom=%ld, CHSLIMIT=%d\n", 738 g.dkg_ncyl * g.dkg_nhead * g.dkg_nsect, CHSLIMIT)); 739 if (((g.dkg_ncyl * g.dkg_nhead * g.dkg_nsect) > CHSLIMIT) && 740 !Tflag) { 741 dprintf(("DeBuG newfs : geom > CHSLIMIT\n")); 742 use_efi_dflts = 1; 743 } 744 /* 745 * Though the nsector that is passed to mkfs is decided here 746 * based on use_efi_dflts, we still need the geometry 747 * based dkg_nsect for the cpg calculation later. 748 */ 749 geom_nsectors = g.dkg_nsect; 750 if (nsectors == 0) 751 nsectors = use_efi_dflts ? -1 : g.dkg_nsect; 752 if (ntracks == 0) 753 ntracks = use_efi_dflts ? -1 : g.dkg_nhead; 754 if (rpm == 0) 755 rpm = ((int)g.dkg_rpm <= 0) ? 3600: g.dkg_rpm; 756 } 757 758 if (bsize == 0) 759 bsize = DESBLKSIZE; 760 /* 761 * Adjust maxcontig by the device's maxtransfer. If maxtransfer 762 * information is not available, default to the min of a MB and 763 * maxphys. 764 */ 765 if (maxcontig == -1 && ioctl(fd, DKIOCINFO, &ci) == 0) { 766 maxcontig = ci.dki_maxtransfer * DEV_BSIZE; 767 if (maxcontig < 0) { 768 int error, gotit, maxphys; 769 gotit = fsgetmaxphys(&maxphys, &error); 770 771 /* 772 * If we cannot get the maxphys value, default 773 * to ufs_maxmaxphys (MB). 774 */ 775 if (gotit) { 776 maxcontig = MIN(maxphys, MB); 777 } else { 778 (void) fprintf(stderr, gettext( 779 "Warning: Could not get system value for maxphys. The value for maxcontig\n" 780 "will default to 1MB.\n")); 781 maxcontig = MB; 782 } 783 } 784 maxcontig /= bsize; 785 } 786 (void) close(fd); 787 return (actual_size); 788 } 789 790 /* 791 * Figure out how big the partition we're dealing with is. 792 */ 793 static diskaddr_t 794 get_device_size(int fd, char *name) 795 { 796 struct vtoc vtoc; 797 dk_gpt_t *efi_vtoc; 798 diskaddr_t slicesize; 799 800 int index = read_vtoc(fd, &vtoc); 801 802 if (index >= 0) { 803 label_type = LABEL_TYPE_VTOC; 804 } else { 805 if (index == VT_ENOTSUP || index == VT_ERROR) { 806 /* it might be an EFI label */ 807 index = efi_alloc_and_read(fd, &efi_vtoc); 808 if (index >= 0) 809 label_type = LABEL_TYPE_EFI; 810 } 811 } 812 813 if (index < 0) { 814 /* 815 * Since both attempts to read the label failed, we're 816 * going to fall back to a brute force approach to 817 * determining the device's size: see how far out we can 818 * perform reads on the device. 819 */ 820 821 slicesize = brute_force_get_device_size(fd); 822 if (slicesize == 0) { 823 switch (index) { 824 case VT_ERROR: 825 (void) fprintf(stderr, gettext( 826 "newfs: %s: %s\n"), name, strerror(errno)); 827 exit(10); 828 /*NOTREACHED*/ 829 case VT_EIO: 830 fatal(gettext( 831 "%s: I/O error accessing VTOC"), name); 832 /*NOTREACHED*/ 833 case VT_EINVAL: 834 fatal(gettext( 835 "%s: Invalid field in VTOC"), name); 836 /*NOTREACHED*/ 837 default: 838 fatal(gettext( 839 "%s: unknown error accessing VTOC"), 840 name); 841 /*NOTREACHED*/ 842 } 843 } else { 844 label_type = LABEL_TYPE_OTHER; 845 } 846 } 847 848 if (label_type == LABEL_TYPE_EFI) { 849 slicesize = efi_vtoc->efi_parts[index].p_size; 850 efi_free(efi_vtoc); 851 } else if (label_type == LABEL_TYPE_VTOC) { 852 /* 853 * In the vtoc struct, p_size is a 32-bit signed quantity. 854 * In the dk_gpt struct (efi's version of the vtoc), p_size 855 * is an unsigned 64-bit quantity. By casting the vtoc's 856 * psize to an unsigned 32-bit quantity, it will be copied 857 * to 'slicesize' (an unsigned 64-bit diskaddr_t) without 858 * sign extension. 859 */ 860 861 slicesize = (uint32_t)vtoc.v_part[index].p_size; 862 } 863 864 return (slicesize); 865 } 866 867 /* 868 * brute_force_get_device_size 869 * 870 * Determine the size of the device by seeing how far we can 871 * read. Doing an llseek( , , SEEK_END) would probably work 872 * in most cases, but we've seen at least one third-party driver 873 * which doesn't correctly support the SEEK_END option when the 874 * the device is greater than a terabyte. 875 */ 876 877 static diskaddr_t 878 brute_force_get_device_size(int fd) 879 { 880 diskaddr_t min_fail = 0; 881 diskaddr_t max_succeed = 0; 882 diskaddr_t cur_db_off; 883 char buf[DEV_BSIZE]; 884 885 /* 886 * First, see if we can read the device at all, just to 887 * eliminate errors that have nothing to do with the 888 * device's size. 889 */ 890 891 if (((llseek(fd, (offset_t)0, SEEK_SET)) == -1) || 892 ((read(fd, buf, DEV_BSIZE)) == -1)) 893 return (0); /* can't determine size */ 894 895 /* 896 * Now, go sequentially through the multiples of 4TB 897 * to find the first read that fails (this isn't strictly 898 * the most efficient way to find the actual size if the 899 * size really could be anything between 0 and 2**64 bytes. 900 * We expect the sizes to be less than 16 TB for some time, 901 * so why do a bunch of reads that are larger than that? 902 * However, this algorithm *will* work for sizes of greater 903 * than 16 TB. We're just not optimizing for those sizes.) 904 */ 905 906 for (cur_db_off = SECTORS_PER_TERABYTE * 4; 907 min_fail == 0 && cur_db_off < FS_SIZE_UPPER_LIMIT; 908 cur_db_off += 4 * SECTORS_PER_TERABYTE) { 909 if (((llseek(fd, (offset_t)(cur_db_off * DEV_BSIZE), 910 SEEK_SET)) == -1) || 911 ((read(fd, buf, DEV_BSIZE)) != DEV_BSIZE)) 912 min_fail = cur_db_off; 913 else 914 max_succeed = cur_db_off; 915 } 916 917 if (min_fail == 0) 918 return (0); 919 920 /* 921 * We now know that the size of the device is less than 922 * min_fail and greater than or equal to max_succeed. Now 923 * keep splitting the difference until the actual size in 924 * sectors in known. We also know that the difference 925 * between max_succeed and min_fail at this time is 926 * 4 * SECTORS_PER_TERABYTE, which is a power of two, which 927 * simplifies the math below. 928 */ 929 930 while (min_fail - max_succeed > 1) { 931 cur_db_off = max_succeed + (min_fail - max_succeed)/2; 932 if (((llseek(fd, (offset_t)(cur_db_off * DEV_BSIZE), 933 SEEK_SET)) == -1) || 934 ((read(fd, buf, DEV_BSIZE)) != DEV_BSIZE)) 935 min_fail = cur_db_off; 936 else 937 max_succeed = cur_db_off; 938 } 939 940 /* the size is the last successfully read sector offset plus one */ 941 return (max_succeed + 1); 942 } 943 944 /* 945 * validate_size 946 * 947 * Return 1 if the device appears to be at least "size" sectors long. 948 * Return 0 if it's shorter or we can't read it. 949 */ 950 951 static int 952 validate_size(char *disk, diskaddr_t size) 953 { 954 char buf[DEV_BSIZE]; 955 int fd, rc; 956 957 if ((fd = open64(disk, O_RDONLY)) < 0) { 958 perror(disk); 959 exit(1); 960 } 961 962 if ((llseek(fd, (offset_t)((size - 1) * DEV_BSIZE), SEEK_SET) == -1) || 963 (read(fd, buf, DEV_BSIZE)) != DEV_BSIZE) 964 rc = 0; 965 else 966 rc = 1; 967 (void) close(fd); 968 return (rc); 969 } 970 971 /* 972 * read_sb(char * rawdev) - Attempt to read the superblock from a raw device 973 * 974 * Returns: 975 * 0 : 976 * Could not read a valid superblock for a variety of reasons. 977 * Since 'newfs' handles any fatal conditions, we're not going 978 * to make any guesses as to why this is failing or what should 979 * be done about it. 980 * 981 * struct fs *: 982 * A pointer to (what we think is) a valid superblock. The 983 * space for the superblock is static (inside the function) 984 * since we will only be reading the values from it. 985 */ 986 987 struct fs * 988 read_sb(char *fsdev) 989 { 990 static struct fs sblock; 991 struct stat64 statb; 992 int dskfd; 993 char *bufp = NULL; 994 int bufsz = 0; 995 996 if (stat64(fsdev, &statb) < 0) 997 return (0); 998 999 if ((dskfd = open64(fsdev, O_RDONLY)) < 0) 1000 return (0); 1001 1002 /* 1003 * We need a buffer whose size is a multiple of DEV_BSIZE in order 1004 * to read from a raw device (which we were probably passed). 1005 */ 1006 bufsz = ((sizeof (sblock) / DEV_BSIZE) + 1) * DEV_BSIZE; 1007 if ((bufp = malloc(bufsz)) == NULL) { 1008 (void) close(dskfd); 1009 return (0); 1010 } 1011 1012 if (llseek(dskfd, (offset_t)SBOFF, SEEK_SET) < 0 || 1013 read(dskfd, bufp, bufsz) < 0) { 1014 (void) close(dskfd); 1015 free(bufp); 1016 return (0); 1017 } 1018 (void) close(dskfd); /* Done with the file */ 1019 1020 (void) memcpy(&sblock, bufp, sizeof (sblock)); 1021 free(bufp); /* Don't need this anymore */ 1022 1023 if (((sblock.fs_magic != FS_MAGIC) && 1024 (sblock.fs_magic != MTB_UFS_MAGIC)) || 1025 sblock.fs_ncg < 1 || sblock.fs_cpg < 1) 1026 return (0); 1027 1028 if (sblock.fs_ncg * sblock.fs_cpg < sblock.fs_ncyl || 1029 (sblock.fs_ncg - 1) * sblock.fs_cpg >= sblock.fs_ncyl) 1030 return (0); 1031 1032 if (sblock.fs_sbsize < 0 || sblock.fs_sbsize > SBSIZE) 1033 return (0); 1034 1035 return (&sblock); 1036 } 1037 1038 /* 1039 * Read the UFS file system on the raw device SPECIAL. If it does not 1040 * appear to be a UFS file system, return non-zero, indicating that 1041 * fsirand should be called (and it will spit out an error message). 1042 * If it is a UFS file system, take a look at the inodes in the first 1043 * cylinder group. If they appear to be randomized (non-zero), return 1044 * zero, which will cause fsirand to not be called. If the inode generation 1045 * counts are all zero, then we must call fsirand, so return non-zero. 1046 */ 1047 1048 #define RANDOMIZED 0 1049 #define NOT_RANDOMIZED 1 1050 1051 static int 1052 notrand(char *special) 1053 { 1054 long fsbuf[SBSIZE / sizeof (long)]; 1055 struct dinode dibuf[MAXBSIZE/sizeof (struct dinode)]; 1056 struct fs *fs; 1057 struct dinode *dip; 1058 offset_t seekaddr; 1059 int bno, inum; 1060 int fd; 1061 1062 fs = (struct fs *)fsbuf; 1063 if ((fd = open64(special, 0)) == -1) 1064 return (NOT_RANDOMIZED); 1065 if (llseek(fd, (offset_t)SBLOCK * DEV_BSIZE, 0) == -1 || 1066 read(fd, (char *)fs, SBSIZE) != SBSIZE || 1067 ((fs->fs_magic != FS_MAGIC) && (fs->fs_magic != MTB_UFS_MAGIC))) { 1068 (void) close(fd); 1069 return (NOT_RANDOMIZED); 1070 } 1071 1072 /* looks like a UFS file system; read the first cylinder group */ 1073 bsize = INOPB(fs) * sizeof (struct dinode); 1074 inum = 0; 1075 while (inum < fs->fs_ipg) { 1076 bno = itod(fs, inum); 1077 seekaddr = (offset_t)fsbtodb(fs, bno) * DEV_BSIZE; 1078 if (llseek(fd, seekaddr, 0) == -1 || 1079 read(fd, (char *)dibuf, bsize) != bsize) { 1080 (void) close(fd); 1081 return (NOT_RANDOMIZED); 1082 } 1083 for (dip = dibuf; dip < &dibuf[INOPB(fs)]; dip++) { 1084 if (dip->di_gen != 0) { 1085 (void) close(fd); 1086 return (RANDOMIZED); 1087 } 1088 inum++; 1089 } 1090 } 1091 (void) close(fd); 1092 return (NOT_RANDOMIZED); 1093 } 1094 1095 static void 1096 usage(void) 1097 { 1098 (void) fprintf(stderr, gettext( 1099 "usage: newfs [ -v ] [ mkfs-options ] raw-special-device\n")); 1100 (void) fprintf(stderr, gettext("where mkfs-options are:\n")); 1101 (void) fprintf(stderr, gettext( 1102 "\t-N do not create file system, just print out parameters\n")); 1103 (void) fprintf(stderr, gettext( 1104 "\t-T configure file system for eventual growth to over a terabyte\n")); 1105 (void) fprintf(stderr, gettext("\t-s file system size (sectors)\n")); 1106 (void) fprintf(stderr, gettext("\t-b block size\n")); 1107 (void) fprintf(stderr, gettext("\t-f frag size\n")); 1108 (void) fprintf(stderr, gettext("\t-t tracks/cylinder\n")); 1109 (void) fprintf(stderr, gettext("\t-c cylinders/group\n")); 1110 (void) fprintf(stderr, gettext("\t-m minimum free space %%\n")); 1111 (void) fprintf(stderr, gettext( 1112 "\t-o optimization preference (`space' or `time')\n")); 1113 (void) fprintf(stderr, gettext("\t-r revolutions/minute\n")); 1114 (void) fprintf(stderr, gettext("\t-i number of bytes per inode\n")); 1115 (void) fprintf(stderr, gettext( 1116 "\t-a number of alternates per cylinder\n")); 1117 (void) fprintf(stderr, gettext("\t-C maxcontig\n")); 1118 (void) fprintf(stderr, gettext("\t-d rotational delay\n")); 1119 (void) fprintf(stderr, gettext( 1120 "\t-n number of rotational positions\n")); 1121 (void) fprintf(stderr, gettext( 1122 "\t-S print a textual version of the calculated superblock to stdout\n")); 1123 (void) fprintf(stderr, gettext( 1124 "\t-B dump a binary version of the calculated superblock to stdout\n")); 1125 } 1126 1127 /* 1128 * Error-detecting version of atoi(3). Adapted from mkfs' number(). 1129 */ 1130 static unsigned int 1131 number(char *param, char *value, int flags, int def_value) 1132 { 1133 char *cs; 1134 int n; 1135 int cut = INT_MAX / 10; /* limit to avoid overflow */ 1136 int minus = 0; 1137 1138 cs = value; 1139 if (*cs == '-') { 1140 minus = 1; 1141 cs += 1; 1142 } 1143 if ((*cs < '0') || (*cs > '9')) { 1144 goto bail_out; 1145 } 1146 n = 0; 1147 while ((*cs >= '0') && (*cs <= '9') && (n <= cut)) { 1148 n = n*10 + *cs++ - '0'; 1149 } 1150 if (minus) 1151 n = -n; 1152 for (;;) { 1153 switch (*cs++) { 1154 case '\0': 1155 return (n); 1156 1157 case '0': case '1': case '2': case '3': case '4': 1158 case '5': case '6': case '7': case '8': case '9': 1159 (void) fprintf(stderr, gettext( 1160 "newfs: value for %s overflowed, using %d\n"), 1161 param, def_value); 1162 return (def_value); 1163 1164 case '%': 1165 if (flags & NR_PERCENT) 1166 break; 1167 /* FALLTHROUGH */ 1168 1169 default: 1170 bail_out: 1171 fatal(gettext("bad numeric arg for %s: \"%s\""), 1172 param, value); 1173 1174 } 1175 } 1176 /* NOTREACHED */ 1177 } 1178 1179 /* 1180 * Error-detecting version of atoi(3). Adapted from mkfs' number(). 1181 */ 1182 static int64_t 1183 number64(char *param, char *value, int flags, int64_t def_value) 1184 { 1185 char *cs; 1186 int64_t n; 1187 int64_t cut = FS_SIZE_UPPER_LIMIT/ 10; /* limit to avoid overflow */ 1188 int minus = 0; 1189 1190 cs = value; 1191 if (*cs == '-') { 1192 minus = 1; 1193 cs += 1; 1194 } 1195 if ((*cs < '0') || (*cs > '9')) { 1196 goto bail_out; 1197 } 1198 n = 0; 1199 while ((*cs >= '0') && (*cs <= '9') && (n <= cut)) { 1200 n = n*10 + *cs++ - '0'; 1201 } 1202 if (minus) 1203 n = -n; 1204 for (;;) { 1205 switch (*cs++) { 1206 case '\0': 1207 return (n); 1208 1209 case '0': case '1': case '2': case '3': case '4': 1210 case '5': case '6': case '7': case '8': case '9': 1211 (void) fprintf(stderr, gettext( 1212 "newfs: value for %s overflowed, using %d\n"), 1213 param, def_value); 1214 return (def_value); 1215 1216 case '%': 1217 if (flags & NR_PERCENT) 1218 break; 1219 /* FALLTHROUGH */ 1220 1221 default: 1222 bail_out: 1223 fatal(gettext("bad numeric arg for %s: \"%s\""), 1224 param, value); 1225 1226 } 1227 } 1228 /* NOTREACHED */ 1229 } 1230