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