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