Print this page
10120 smatch indenting fixes for usr/src/cmd
Reviewed by: Gergő Doma <domag02@gmail.com>
Portions contributed by: Joyce McIntosh <joyce.mcintosh@nexenta.com>
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/fmthard/fmthard.c
+++ new/usr/src/cmd/fmthard/fmthard.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
22 22 /* All Rights Reserved */
23 23
24 24
25 25 /*
26 26 *
↓ open down ↓ |
26 lines elided |
↑ open up ↑ |
27 27 * Portions of this source code were provided by International
28 28 * Computers Limited (ICL) under a development agreement with AT&T.
29 29 */
30 30
31 31 /*
32 32 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
33 33 * Use is subject to license terms.
34 34 */
35 35
36 36 /*
37 + * Copyright (c) 2018, Joyent, Inc.
38 + */
39 +/*
37 40 * Sun Microsystems version of fmthard:
38 41 *
39 42 * Supports the following arguments:
40 43 *
41 44 * -i Writes VTOC to stdout, rather than disk
42 45 * -q Quick check: exit code 0 if VTOC ok
43 46 * -d <data> Incremental changes to the VTOC
44 47 * -n <vname> Change volume name to <vname>
45 48 * -s <file> Read VTOC information from <file>, or stdin ("-")
46 49 * -u <state> Reboot after writing VTOC, according to <state>:
47 50 * boot: AD_BOOT (standard reboot)
48 51 * firm: AD_IBOOT (interactive reboot)
49 52 *
50 53 * Note that fmthard cannot write a VTOC on an unlabeled disk.
51 54 * You must use format or SunInstall for this purpose.
52 55 * (NOTE: the above restriction only applies on Sparc systems).
53 56 *
54 57 * The primary motivation for fmthard is to duplicate the
55 58 * partitioning from disk to disk:
56 59 *
57 60 * prtvtoc /dev/rdsk/c0t0d0s2 | fmthard -s - /dev/rdsk/c0t1d0s2
58 61 */
59 62
60 63 #include <stdio.h>
61 64 #include <fcntl.h>
62 65 #include <errno.h>
63 66 #include <string.h>
64 67 #include <stdlib.h>
65 68 #include <unistd.h>
66 69 #include <sys/types.h>
67 70 #include <sys/param.h>
68 71 #include <sys/int_limits.h>
69 72 #include <sys/stat.h>
70 73 #include <sys/uadmin.h>
71 74 #include <sys/open.h>
72 75 #include <sys/vtoc.h>
73 76 #include <sys/dkio.h>
74 77 #include <sys/isa_defs.h>
75 78 #include <sys/efi_partition.h>
76 79
77 80 #if defined(_SUNOS_VTOC_16)
78 81 #include <sys/dklabel.h>
79 82 #endif
80 83
81 84 #include <sys/sysmacros.h>
82 85
83 86 #ifndef SECSIZE
84 87 #define SECSIZE DEV_BSIZE
85 88 #endif /* SECSIZE */
86 89
87 90 /*
88 91 * Internal functions.
89 92 */
90 93 extern int main(int, char **);
91 94 static void display(struct dk_geom *, struct extvtoc *, char *);
92 95 static void display64(struct dk_gpt *, char *);
93 96 static void insert(char *, struct extvtoc *);
94 97 static void insert64(char *, struct dk_gpt *);
95 98 static void load(FILE *, struct dk_geom *, struct extvtoc *);
96 99 static void load64(FILE *, int fd, struct dk_gpt **);
97 100 static void usage(void);
98 101 static void validate(struct dk_geom *, struct extvtoc *);
99 102 static void validate64(struct dk_gpt *);
100 103 static int vread(int, struct extvtoc *, char *);
101 104 static void vread64(int, struct dk_gpt **, char *);
102 105 static void vwrite(int, struct extvtoc *, char *);
103 106 static void vwrite64(int, struct dk_gpt *, char *);
104 107
105 108 /*
106 109 * Static variables.
107 110 */
108 111 static char *delta; /* Incremental update */
109 112 static short eflag; /* force write of an EFI label */
110 113 static short iflag; /* Prints VTOC w/o updating */
111 114 static short qflag; /* Check for a formatted disk */
112 115 static short uflag; /* Exit to firmware after writing */
113 116 /* new vtoc and reboot. Used during */
114 117 /* installation of core floppies */
115 118 static diskaddr_t lastlba = 0; /* last LBA on 64-bit VTOC */
116 119
117 120 #if defined(sparc)
118 121 static char *uboot = "boot";
119 122
120 123 #elif defined(i386)
121 124 /* use installgrub(1M) to install boot blocks */
122 125 static char *uboot = "";
123 126 #else
124 127 #error No platform defined.
125 128 #endif /* various platform-specific definitions */
126 129
127 130 static char *ufirm = "firm";
128 131 static int sectsiz;
129 132 #if defined(_SUNOS_VTOC_16)
130 133 static struct extvtoc disk_vtoc;
131 134 #endif /* defined(_SUNOS_VTOC_16) */
132 135
133 136 int
134 137 main(int argc, char **argv)
135 138 {
136 139 int fd;
137 140 int c;
138 141 char *dfile;
139 142 char *vname;
140 143 struct stat statbuf;
141 144 #if defined(_SUNOS_VTOC_8)
142 145 struct extvtoc disk_vtoc;
143 146 #endif /* defined(_SUNOS_VTOC_8) */
144 147 struct dk_gpt *disk_efi;
145 148 struct dk_geom disk_geom;
146 149 struct dk_minfo minfo;
147 150 int n;
148 151
149 152
150 153 disk_efi = NULL;
151 154 dfile = NULL;
152 155 vname = NULL;
153 156 #if defined(sparc)
154 157 while ((c = getopt(argc, argv, "ed:u:in:qs:")) != EOF)
155 158
156 159 #elif defined(i386)
157 160 while ((c = getopt(argc, argv, "ed:u:in:qb:p:s:")) != EOF)
158 161
159 162 #else
160 163 #error No platform defined.
161 164 #endif
162 165 switch (c) {
163 166 #if defined(i386)
164 167 case 'p':
165 168 case 'b':
166 169 (void) fprintf(stderr,
167 170 "fmthard: -p and -b no longer supported."
168 171 " Use installgrub(1M) to install boot blocks\n");
169 172 break;
170 173 #endif /* defined(i386) */
171 174
172 175 case 'd':
173 176 delta = optarg;
174 177 break;
175 178 case 'e':
176 179 ++eflag;
177 180 break;
178 181 case 'i':
179 182 ++iflag;
180 183 break;
181 184 case 'n':
182 185 vname = optarg;
183 186 break;
184 187 case 'q':
185 188 ++qflag;
186 189 break;
187 190 case 's':
188 191 dfile = optarg;
189 192 break;
190 193 case 'u':
191 194 if (strcmp(uboot, optarg) == 0)
192 195 ++uflag;
193 196 else if (strcmp(ufirm, optarg) == 0)
194 197 uflag = 2;
195 198
196 199 break;
197 200 default:
198 201 usage();
199 202 }
200 203
201 204
202 205 if (argc - optind != 1)
203 206 usage();
204 207
205 208 if (stat(argv[optind], (struct stat *)&statbuf) == -1) {
206 209 (void) fprintf(stderr,
207 210 "fmthard: Cannot stat device %s\n",
208 211 argv[optind]);
209 212 exit(1);
210 213 }
211 214
212 215 if ((statbuf.st_mode & S_IFMT) != S_IFCHR) {
213 216 (void) fprintf(stderr,
214 217 "fmthard: %s must be a raw device.\n",
215 218 argv[optind]);
216 219 exit(1);
217 220 }
218 221
219 222 if ((fd = open(argv[optind], O_RDWR|O_NDELAY)) < 0) {
220 223 (void) fprintf(stderr, "fmthard: Cannot open device %s - %s\n",
221 224 argv[optind], strerror(errno));
222 225 exit(1);
223 226 }
224 227
225 228 if (ioctl(fd, DKIOCGMEDIAINFO, &minfo) == 0) {
226 229 sectsiz = minfo.dki_lbsize;
227 230 }
228 231
229 232 if (sectsiz == 0) {
230 233 sectsiz = SECSIZE;
231 234 }
232 235
233 236 /*
234 237 * Get the geometry information for this disk from the driver
235 238 */
236 239 if (!eflag && ioctl(fd, DKIOCGGEOM, &disk_geom)) {
237 240 #ifdef DEBUG
238 241 perror("DKIOCGGEOM failed");
239 242 #endif /* DEBUG */
240 243 if (errno == ENOTSUP) {
241 244 /* disk has EFI labels */
242 245 eflag++;
243 246 } else {
244 247 (void) fprintf(stderr,
245 248 "%s: Cannot get disk geometry\n", argv[optind]);
246 249 (void) close(fd);
247 250 exit(1);
248 251 }
249 252 }
250 253
251 254 /*
252 255 * Read the vtoc on the disk
253 256 */
254 257 if (!eflag) {
255 258 if (vread(fd, &disk_vtoc, argv[optind]) == 1)
256 259 eflag++;
257 260 }
258 261 if (eflag && ((dfile == NULL) || qflag)) {
259 262 vread64(fd, &disk_efi, argv[optind]);
260 263 }
261 264
262 265 /*
263 266 * Quick check for valid disk: 0 if ok, 1 if not
264 267 */
265 268 if (qflag) {
266 269 (void) close(fd);
267 270 if (!eflag) {
268 271 exit(disk_vtoc.v_sanity == VTOC_SANE ? 0 : 1);
269 272 } else {
270 273 exit(disk_efi->efi_version <= EFI_VERSION102 ? 0 : 1);
271 274 }
272 275 }
273 276
274 277 /*
275 278 * Incremental changes to the VTOC
276 279 */
277 280 if (delta) {
278 281 if (!eflag) {
279 282 insert(delta, &disk_vtoc);
280 283 validate(&disk_geom, &disk_vtoc);
281 284 vwrite(fd, &disk_vtoc, argv[optind]);
282 285 } else {
283 286 insert64(delta, disk_efi);
284 287 validate64(disk_efi);
285 288 vwrite64(fd, disk_efi, argv[optind]);
286 289 }
287 290 (void) close(fd);
288 291 exit(0);
289 292 }
290 293
291 294 if (!dfile && !vname)
292 295 usage();
293 296
294 297 /*
295 298 * Read new VTOC from stdin or data file
296 299 */
297 300 if (dfile) {
298 301 if (strcmp(dfile, "-") == 0) {
299 302 if (!eflag)
300 303 load(stdin, &disk_geom, &disk_vtoc);
301 304 else
302 305 load64(stdin, fd, &disk_efi);
303 306 } else {
304 307 FILE *fp;
305 308 if ((fp = fopen(dfile, "r")) == NULL) {
306 309 (void) fprintf(stderr, "Cannot open file %s\n",
307 310 dfile);
308 311 (void) close(fd);
309 312 exit(1);
310 313 }
311 314 if (!eflag)
312 315 load(fp, &disk_geom, &disk_vtoc);
313 316 else
314 317 load64(fp, fd, &disk_efi);
315 318 (void) fclose(fp);
316 319 }
317 320 }
318 321
319 322 /*
320 323 * Print the modified VTOC, rather than updating the disk
321 324 */
322 325 if (iflag) {
323 326 if (!eflag)
324 327 display(&disk_geom, &disk_vtoc, argv[optind]);
325 328 else
326 329 display64(disk_efi, argv[optind]);
327 330 (void) close(fd);
328 331 exit(0);
329 332 }
330 333
331 334 if (vname) {
332 335 n = MIN(strlen(vname) + 1, LEN_DKL_VVOL);
333 336 if (!eflag) {
334 337 (void) memcpy(disk_vtoc.v_volume, vname, n);
335 338 } else {
336 339 for (c = 0; c < disk_efi->efi_nparts; c++) {
337 340 if (disk_efi->efi_parts[c].p_tag ==
338 341 V_RESERVED) {
339 342 (void) memcpy(&disk_efi->efi_parts[c].p_name,
340 343 vname, n);
341 344 }
342 345 }
343 346 }
344 347
345 348 }
346 349 /*
347 350 * Write the new VTOC on the disk
348 351 */
349 352 if (!eflag) {
350 353 validate(&disk_geom, &disk_vtoc);
351 354 vwrite(fd, &disk_vtoc, argv[optind]);
352 355 } else {
353 356 validate64(disk_efi);
354 357 vwrite64(fd, disk_efi, argv[optind]);
355 358 }
356 359
357 360 /*
358 361 * Shut system down after writing a new vtoc to disk
359 362 * This is used during installation of core floppies.
360 363 */
361 364 if (uflag == 1)
362 365 (void) uadmin(A_REBOOT, AD_BOOT, 0);
363 366 else if (uflag == 2)
364 367 (void) uadmin(A_REBOOT, AD_IBOOT, 0);
365 368
366 369 (void) printf("fmthard: New volume table of contents now in place.\n");
367 370
368 371 return (0);
369 372 }
370 373
371 374
372 375
373 376 /*
374 377 * display ()
375 378 *
376 379 * display contents of VTOC without writing it to disk
377 380 */
378 381 static void
379 382 display(struct dk_geom *geom, struct extvtoc *vtoc, char *device)
380 383 {
381 384 int i;
382 385 int c;
383 386
384 387 /*
385 388 * Print out the VTOC
386 389 */
387 390 (void) printf("* %s default partition map\n", device);
388 391 if (*vtoc->v_volume) {
389 392 (void) printf("* Volume Name: ");
390 393 for (i = 0; i < LEN_DKL_VVOL; i++) {
391 394 if ((c = vtoc->v_volume[i]) == 0)
392 395 break;
393 396 (void) printf("%c", c);
394 397 }
395 398 (void) printf("\n");
396 399 }
397 400 (void) printf("*\n");
398 401 (void) printf("* Dimensions:\n");
399 402 (void) printf("* %d bytes/sector\n", sectsiz);
400 403 (void) printf("* %d sectors/track\n", geom->dkg_nsect);
401 404 (void) printf("* %d tracks/cylinder\n", geom->dkg_nhead);
402 405 (void) printf("* %d cylinders\n", geom->dkg_pcyl);
403 406 (void) printf("* %d accessible cylinders\n", geom->dkg_ncyl);
404 407 (void) printf("*\n");
405 408 (void) printf("* Flags:\n");
406 409 (void) printf("* 1: unmountable\n");
407 410 (void) printf("* 10: read-only\n");
408 411 (void) printf("*\n");
409 412 (void) printf(
410 413 "\n* Partition Tag Flag First Sector Sector Count\n");
411 414 for (i = 0; i < V_NUMPAR; i++) {
412 415 if (vtoc->v_part[i].p_size > 0)
413 416 (void) printf(
414 417 " %d %d 0%x %llu %llu\n",
415 418 i, vtoc->v_part[i].p_tag,
416 419 vtoc->v_part[i].p_flag,
417 420 vtoc->v_part[i].p_start,
418 421 vtoc->v_part[i].p_size);
419 422 }
420 423 exit(0);
421 424 }
422 425
423 426 /*
424 427 * display64 ()
425 428 *
426 429 * display64 contents of EFI partition without writing it to disk
427 430 */
428 431 static void
429 432 display64(struct dk_gpt *efi, char *device)
430 433 {
431 434 int i;
432 435
433 436 /*
434 437 * Print out the VTOC
435 438 */
436 439 (void) printf("* %s default partition map\n", device);
437 440 (void) printf("*\n");
438 441 (void) printf("* Dimensions:\n");
439 442 (void) printf("* %d bytes/sector\n", efi->efi_lbasize);
440 443 (void) printf("* N/A sectors/track\n");
441 444 (void) printf("* N/A tracks/cylinder\n");
442 445 (void) printf("* N/A cylinders\n");
443 446 (void) printf("* N/A accessible cylinders\n");
444 447 (void) printf("*\n");
445 448 (void) printf("* Flags:\n");
446 449 (void) printf("* 1: unmountable\n");
447 450 (void) printf("* 10: read-only\n");
448 451 (void) printf("*\n");
449 452 (void) printf(
450 453 "\n* Partition Tag Flag First Sector Sector Count\n");
451 454 for (i = 0; i < efi->efi_nparts; i++) {
452 455 if (efi->efi_parts[i].p_size > 0)
453 456 (void) printf(
454 457 " %d %d 0%x %8lld %8lld\n",
455 458 i, efi->efi_parts[i].p_tag,
456 459 efi->efi_parts[i].p_flag,
457 460 efi->efi_parts[i].p_start,
458 461 efi->efi_parts[i].p_size);
459 462 }
460 463 exit(0);
461 464 }
462 465
463 466
464 467 /*
465 468 * insert()
466 469 *
467 470 * Insert a change into the VTOC.
468 471 */
469 472 static void
470 473 insert(char *data, struct extvtoc *vtoc)
471 474 {
472 475 int part;
473 476 int tag;
474 477 uint_t flag;
475 478 diskaddr_t start;
476 479 uint64_t size;
477 480
478 481 if (sscanf(data, "%d:%d:%x:%llu:%llu",
479 482 &part, &tag, &flag, &start, &size) != 5) {
480 483 (void) fprintf(stderr, "Delta syntax error on \"%s\"\n", data);
481 484 exit(1);
482 485 }
483 486 if (part >= V_NUMPAR) {
484 487 (void) fprintf(stderr,
485 488 "Error in data \"%s\": No such partition %x\n",
486 489 data, part);
487 490 exit(1);
488 491 }
489 492 vtoc->v_part[part].p_tag = (ushort_t)tag;
490 493 vtoc->v_part[part].p_flag = (ushort_t)flag;
491 494 vtoc->v_part[part].p_start = start;
492 495 vtoc->v_part[part].p_size = size;
493 496 }
494 497
495 498 /*
496 499 * insert64()
497 500 *
498 501 * Insert a change into the VTOC.
499 502 */
500 503 static void
501 504 insert64(char *data, struct dk_gpt *efi)
502 505 {
503 506 int part;
504 507 int tag;
505 508 uint_t flag;
506 509 diskaddr_t start;
507 510 diskaddr_t size;
508 511
509 512 if (sscanf(data, "%d:%d:%x:%lld:%lld",
510 513 &part, &tag, &flag, &start, &size) != 5) {
511 514 (void) fprintf(stderr, "Delta syntax error on \"%s\"\n", data);
512 515 exit(1);
513 516 }
514 517 if (part >= efi->efi_nparts) {
515 518 (void) fprintf(stderr,
516 519 "Error in data \"%s\": No such partition %x\n",
517 520 data, part);
518 521 exit(1);
519 522 }
520 523 efi->efi_parts[part].p_tag = (ushort_t)tag;
521 524 efi->efi_parts[part].p_flag = (ushort_t)flag;
522 525 efi->efi_parts[part].p_start = start;
523 526 efi->efi_parts[part].p_size = size;
524 527 }
525 528
526 529 /*
527 530 * load()
528 531 *
529 532 * Load VTOC information from a datafile.
530 533 */
531 534 static void
532 535 load(FILE *fp, struct dk_geom *geom, struct extvtoc *vtoc)
533 536 {
534 537 int part;
535 538 int tag;
536 539 uint_t flag;
537 540 diskaddr_t start;
538 541 uint64_t size;
539 542 char line[256];
540 543 int i;
541 544 uint64_t nblks;
542 545 uint64_t fullsz;
543 546
544 547 for (i = 0; i < V_NUMPAR; ++i) {
545 548 vtoc->v_part[i].p_tag = 0;
546 549 vtoc->v_part[i].p_flag = V_UNMNT;
547 550 vtoc->v_part[i].p_start = 0;
548 551 vtoc->v_part[i].p_size = 0;
549 552 }
550 553 /*
551 554 * initialize partition 2, by convention it corresponds to whole
552 555 * disk. It will be overwritten, if specified in the input datafile
553 556 */
554 557 fullsz = (uint64_t)geom->dkg_ncyl * geom->dkg_nsect * geom->dkg_nhead;
555 558 vtoc->v_part[2].p_tag = V_BACKUP;
556 559 vtoc->v_part[2].p_flag = V_UNMNT;
557 560 vtoc->v_part[2].p_start = 0;
558 561 vtoc->v_part[2].p_size = fullsz;
559 562
560 563 nblks = geom->dkg_nsect * geom->dkg_nhead;
561 564
562 565 while (fgets(line, sizeof (line) - 1, fp)) {
563 566 if (line[0] == '\0' || line[0] == '\n' || line[0] == '*')
564 567 continue;
565 568 line[strlen(line) - 1] = '\0';
566 569 if (sscanf(line, "%d %d %x %llu %llu",
567 570 &part, &tag, &flag, &start, &size) != 5) {
568 571 (void) fprintf(stderr, "Syntax error: \"%s\"\n",
569 572 line);
570 573 exit(1);
571 574 }
572 575 if (part >= V_NUMPAR) {
573 576 (void) fprintf(stderr,
574 577 "No such partition %x: \"%s\"\n",
575 578 part, line);
576 579 exit(1);
577 580 }
578 581 if (!eflag && ((start % nblks) != 0 || (size % nblks) != 0)) {
579 582 (void) fprintf(stderr,
580 583 "Partition %d not aligned on cylinder boundary: \"%s\"\n",
581 584 part, line);
582 585 exit(1);
583 586 }
584 587 vtoc->v_part[part].p_tag = (ushort_t)tag;
585 588 vtoc->v_part[part].p_flag = (ushort_t)flag;
586 589 vtoc->v_part[part].p_start = start;
587 590 vtoc->v_part[part].p_size = size;
588 591 }
589 592 for (part = 0; part < V_NUMPAR; part++) {
590 593 vtoc->timestamp[part] = (time_t)0;
591 594 }
592 595 }
593 596
594 597 /*
595 598 * load64()
596 599 *
597 600 * Load VTOC information from a datafile.
598 601 */
599 602 static void
600 603 load64(FILE *fp, int fd, struct dk_gpt **efi)
601 604 {
602 605 int part;
603 606 int tag;
604 607 uint_t flag;
605 608 diskaddr_t start;
606 609 diskaddr_t size;
607 610 int nlines = 0;
608 611 char line[256];
609 612 int i;
610 613 uint_t max_part = 0;
611 614 char **mem = NULL;
612 615
613 616 while (fgets(line, sizeof (line) - 1, fp)) {
614 617 if (line[0] == '\0' || line[0] == '\n' || line[0] == '*')
615 618 continue;
616 619 line[strlen(line) - 1] = '\0';
617 620 if (sscanf(line, "%d %d %x %lld %lld",
618 621 &part, &tag, &flag, &start, &size) != 5) {
619 622 (void) fprintf(stderr, "Syntax error: \"%s\"\n",
620 623 line);
621 624 exit(1);
622 625 }
623 626 mem = realloc(mem, sizeof (*mem) * (nlines + 1));
624 627 if (mem == NULL) {
625 628 (void) fprintf(stderr, "realloc failed\n");
626 629 exit(1);
627 630 }
628 631 mem[nlines] = strdup(line);
629 632 if (mem[nlines] == NULL) {
630 633 (void) fprintf(stderr, "strdup failed\n");
631 634 exit(1);
632 635 }
633 636 nlines++;
634 637 if (part > max_part)
635 638 max_part = part;
636 639 }
637 640 max_part++;
638 641
639 642 if ((i = efi_alloc_and_init(fd, max_part, efi)) < 0) {
640 643 (void) fprintf(stderr,
641 644 "efi_alloc_and_init failed: %d\n", i);
642 645 exit(1);
643 646 }
644 647 for (i = 0; i < (*efi)->efi_nparts; ++i) {
645 648 (*efi)->efi_parts[i].p_tag = V_UNASSIGNED;
646 649 (*efi)->efi_parts[i].p_flag = V_UNMNT;
647 650 (*efi)->efi_parts[i].p_start = 0;
648 651 (*efi)->efi_parts[i].p_size = 0;
649 652 }
650 653 lastlba = (*efi)->efi_last_u_lba;
651 654
652 655 for (i = 0; i < nlines; i++) {
653 656 if (sscanf(mem[i], "%d %d %x %lld %lld",
654 657 &part, &tag, &flag, &start, &size) != 5) {
655 658 (void) fprintf(stderr, "Syntax error: \"%s\"\n",
656 659 line);
657 660 exit(1);
658 661 }
659 662 free(mem[i]);
660 663 if (part >= (*efi)->efi_nparts) {
661 664 (void) fprintf(stderr,
662 665 "No such partition %x: \"%s\"\n",
663 666 part, line);
664 667 exit(1);
665 668 }
666 669 (*efi)->efi_parts[part].p_tag = (ushort_t)tag;
667 670 (*efi)->efi_parts[part].p_flag = (ushort_t)flag;
668 671 (*efi)->efi_parts[part].p_start = start;
669 672 (*efi)->efi_parts[part].p_size = size;
670 673 }
671 674 (*efi)->efi_nparts = max_part;
672 675 free(mem);
673 676 }
674 677
675 678
676 679 static void
677 680 usage()
678 681 {
679 682 #if defined(sparc)
680 683 (void) fprintf(stderr,
681 684 "Usage: fmthard [ -i ] [ -n volumename ] [ -s datafile ] [ -d arguments] \
682 685 raw-device\n");
683 686
684 687 #elif defined(i386)
685 688 (void) fprintf(stderr,
686 689 "Usage: fmthard [ -i ] [ -S ] [-I geom_file] \
687 690 -n volumename | -s datafile [ -d arguments] raw-device\n");
688 691
689 692 #else
690 693 #error No platform defined.
691 694 #endif
692 695 exit(2);
693 696 }
694 697
695 698 /*
696 699 * validate()
697 700 *
698 701 * Validate the new VTOC.
699 702 */
700 703 static void
701 704 validate(struct dk_geom *geom, struct extvtoc *vtoc)
702 705 {
703 706 int i;
704 707 int j;
705 708 uint64_t fullsz;
706 709 diskaddr_t endsect;
707 710 diskaddr_t istart;
708 711 diskaddr_t jstart;
709 712 uint64_t isize;
710 713 uint64_t jsize;
711 714 uint64_t nblks;
712 715
713 716 nblks = geom->dkg_nsect * geom->dkg_nhead;
714 717
715 718 fullsz = (uint64_t)geom->dkg_ncyl * geom->dkg_nsect * geom->dkg_nhead;
716 719
717 720 #if defined(_SUNOS_VTOC_16)
718 721 /* make the vtoc look sane - ha ha */
719 722 vtoc->v_version = V_VERSION;
720 723 vtoc->v_sanity = VTOC_SANE;
721 724 vtoc->v_nparts = V_NUMPAR;
722 725 if (vtoc->v_sectorsz == 0)
723 726 vtoc->v_sectorsz = sectsiz;
724 727 #endif /* defined(_SUNOS_VTOC_16) */
725 728
726 729 for (i = 0; i < V_NUMPAR; i++) {
727 730 if (vtoc->v_part[i].p_tag == V_BACKUP) {
728 731 if (vtoc->v_part[i].p_size != fullsz) {
729 732 (void) fprintf(stderr, "\
730 733 fmthard: Partition %d specifies the full disk and is not equal\n\
731 734 full size of disk. The full disk capacity is %llu sectors.\n", i, fullsz);
732 735 #if defined(sparc)
↓ open down ↓ |
686 lines elided |
↑ open up ↑ |
733 736 exit(1);
734 737 #endif
735 738 }
736 739 }
737 740 if (vtoc->v_part[i].p_size == 0)
738 741 continue; /* Undefined partition */
739 742 if ((vtoc->v_part[i].p_start % nblks) ||
740 743 (vtoc->v_part[i].p_size % nblks)) {
741 744 (void) fprintf(stderr, "\
742 745 fmthard: Partition %d not aligned on cylinder boundary \n", i);
743 - exit(1);
746 + exit(1);
744 747 }
745 748 if (vtoc->v_part[i].p_start > fullsz ||
746 749 vtoc->v_part[i].p_start +
747 750 vtoc->v_part[i].p_size > fullsz) {
748 751 (void) fprintf(stderr, "\
749 752 fmthard: Partition %d specified as %llu sectors starting at %llu\n\
750 753 \tdoes not fit. The full disk contains %llu sectors.\n",
751 754 i, vtoc->v_part[i].p_size,
752 755 vtoc->v_part[i].p_start, fullsz);
753 756 #if defined(sparc)
754 757 exit(1);
755 758 #endif
756 759 }
757 760
758 761 if (vtoc->v_part[i].p_tag != V_BACKUP &&
759 762 vtoc->v_part[i].p_size != fullsz) {
760 763 for (j = 0; j < V_NUMPAR; j++) {
761 764 if (vtoc->v_part[j].p_tag == V_BACKUP)
762 765 continue;
763 766 if (vtoc->v_part[j].p_size == fullsz)
764 767 continue;
765 768 isize = vtoc->v_part[i].p_size;
766 769 jsize = vtoc->v_part[j].p_size;
767 770 istart = vtoc->v_part[i].p_start;
768 771 jstart = vtoc->v_part[j].p_start;
769 772 if ((i != j) &&
770 773 (isize != 0) && (jsize != 0)) {
771 774 endsect = jstart + jsize -1;
772 775 if ((jstart <= istart) &&
773 776 (istart <= endsect)) {
774 777 (void) fprintf(stderr, "\
775 778 fmthard: Partition %d overlaps partition %d. Overlap is allowed\n\
776 779 \tonly on partition on the full disk partition).\n",
777 780 i, j);
778 781 #if defined(sparc)
779 782 exit(1);
780 783 #endif
781 784 }
782 785 }
783 786 }
784 787 }
785 788 }
786 789 }
787 790
788 791 /*
789 792 * validate64()
790 793 *
791 794 * Validate the new VTOC.
792 795 */
793 796 static void
794 797 validate64(struct dk_gpt *efi)
795 798 {
796 799 int i;
797 800 int j;
798 801 int resv_part = 0;
799 802 diskaddr_t endsect;
800 803 diskaddr_t fullsz;
801 804 diskaddr_t istart;
802 805 diskaddr_t jstart;
803 806 diskaddr_t isize;
804 807 diskaddr_t jsize;
805 808
806 809 fullsz = lastlba + 1;
807 810
808 811 for (i = 0; i < efi->efi_nparts; i++) {
809 812 if (efi->efi_parts[i].p_size == 0)
810 813 continue; /* Undefined partition */
811 814 if (efi->efi_parts[i].p_tag == V_RESERVED)
812 815 resv_part++;
813 816 if (efi->efi_parts[i].p_start > fullsz ||
814 817 efi->efi_parts[i].p_start +
815 818 efi->efi_parts[i].p_size > fullsz) {
816 819 (void) fprintf(stderr, "\
817 820 fmthard: Partition %d specified as %lld sectors starting at %lld\n\
818 821 \tdoes not fit. The full disk contains %lld sectors.\n",
819 822 i, efi->efi_parts[i].p_size,
820 823 efi->efi_parts[i].p_start, fullsz);
821 824 exit(1);
822 825 }
823 826
824 827 if (efi->efi_parts[i].p_tag != V_BACKUP &&
825 828 efi->efi_parts[i].p_size != fullsz) {
826 829 for (j = 0; j < efi->efi_nparts; j++) {
827 830 if (efi->efi_parts[j].p_size == fullsz)
828 831 continue;
829 832 isize = efi->efi_parts[i].p_size;
830 833 jsize = efi->efi_parts[j].p_size;
831 834 istart = efi->efi_parts[i].p_start;
832 835 jstart = efi->efi_parts[j].p_start;
833 836 if ((i != j) &&
834 837 (isize != 0) && (jsize != 0)) {
835 838 endsect = jstart + jsize - 1;
836 839 if ((jstart <= istart) &&
837 840 (istart <= endsect)) {
838 841 (void) fprintf(stderr, "\
839 842 fmthard: Partition %d overlaps partition %d. Overlap is allowed\n\
840 843 \tonly on partition on the full disk partition).\n",
841 844 i, j);
842 845 #if defined(sparc)
843 846 exit(1);
844 847 #endif
845 848 }
846 849 }
847 850 }
848 851 }
849 852 }
850 853 if (resv_part != 1) {
851 854 (void) fprintf(stderr,
852 855 "expected one reserved partition, but found %d\n",
853 856 resv_part);
854 857 exit(1);
855 858 }
856 859 }
857 860
858 861
859 862 /*
860 863 * Read the VTOC
861 864 */
862 865 int
863 866 vread(int fd, struct extvtoc *vtoc, char *devname)
864 867 {
865 868 int i;
866 869
867 870 if ((i = read_extvtoc(fd, vtoc)) < 0) {
868 871 if (i == VT_ENOTSUP) {
869 872 return (1);
870 873 }
871 874 if (i == VT_EINVAL) {
872 875 (void) fprintf(stderr, "%s: Invalid VTOC\n",
873 876 devname);
874 877 } else {
875 878 (void) fprintf(stderr, "%s: Cannot read VTOC\n",
876 879 devname);
877 880 }
878 881 exit(1);
879 882 }
880 883 return (0);
881 884 }
882 885
883 886 void
884 887 vread64(int fd, struct dk_gpt **efi_hdr, char *devname)
885 888 {
886 889 int i;
887 890
888 891 if ((i = efi_alloc_and_read(fd, efi_hdr)) < 0) {
889 892 if (i == VT_EINVAL)
890 893 (void) fprintf(stderr,
891 894 "%s: this disk must be labeled first\n",
892 895 devname);
893 896 else
894 897 (void) fprintf(stderr,
895 898 "%s: read_efi failed %d\n",
896 899 devname, i);
897 900 exit(1);
898 901 }
899 902 lastlba = (*efi_hdr)->efi_last_u_lba;
900 903 }
901 904
902 905 /*
903 906 * Write the VTOC
904 907 */
905 908 void
906 909 vwrite(int fd, struct extvtoc *vtoc, char *devname)
907 910 {
908 911 int i;
909 912
910 913 if ((i = write_extvtoc(fd, vtoc)) != 0) {
911 914 if (i == VT_EINVAL) {
912 915 (void) fprintf(stderr,
913 916 "%s: invalid entry exists in vtoc\n",
914 917 devname);
915 918 } else {
916 919 (void) fprintf(stderr, "%s: Cannot write VTOC\n",
917 920 devname);
918 921 }
919 922 exit(1);
920 923 }
921 924 }
922 925
923 926 /*
924 927 * Write the VTOC
925 928 */
926 929 void
927 930 vwrite64(int fd, struct dk_gpt *efi, char *devname)
928 931 {
929 932 int i;
930 933
931 934 if ((i = efi_write(fd, efi)) != 0) {
932 935 if (i == VT_EINVAL) {
933 936 (void) fprintf(stderr,
934 937 "%s: invalid entry exists in vtoc\n",
935 938 devname);
936 939 } else {
937 940 (void) fprintf(stderr, "%s: Cannot write EFI\n",
938 941 devname);
939 942 }
940 943 exit(1);
941 944 }
942 945 }
↓ open down ↓ |
189 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX