Deleted Added
full compact
49c49
< "$FreeBSD: head/sbin/bsdlabel/bsdlabel.c 68044 2000-10-31 07:07:39Z jkh $";
---
> "$FreeBSD: head/sbin/bsdlabel/bsdlabel.c 73034 2001-02-25 16:47:44Z jwd $";
82a83,91
> /* FIX! These are too low, but are traditional */
> #define DEFAULT_NEWFS_BLOCK 8192U
> #define DEFAULT_NEWFS_FRAG 1024U
> #define DEFAULT_NEWFS_CPG 16U
>
> #define BIG_NEWFS_BLOCK 16384U
> #define BIG_NEWFS_FRAG 4096U
> #define BIG_NEWFS_CPG 64U
>
120a130,137
> /* partition 'c' is the full disk and is special */
> #define FULL_DISK_PART 2
> #define MAX_PART ('z')
> #define MAX_NUM_PARTS (1 + MAX_PART - 'a')
> char part_size_type[MAX_NUM_PARTS];
> char part_offset_type[MAX_NUM_PARTS];
> int part_set[MAX_NUM_PARTS];
>
135a153
> int disable_write; /* set to disable writing to disk label */
139c157
< #define OPTIONS "BNRWb:ders:w"
---
> #define OPTIONS "BNRWb:denrs:w"
141c159
< #define OPTIONS "BNRWb:ers:w"
---
> #define OPTIONS "BNRWb:enrs:w"
173a192,194
> case 'n':
> disable_write = 1;
> break;
400,420c421,446
< setbootflag(lp);
< lp->d_magic = DISKMAGIC;
< lp->d_magic2 = DISKMAGIC;
< lp->d_checksum = 0;
< lp->d_checksum = dkcksum(lp);
< if (rflag) {
< /*
< * First set the kernel disk label,
< * then write a label to the raw disk.
< * If the SDINFO ioctl fails because it is unimplemented,
< * keep going; otherwise, the kernel consistency checks
< * may prevent us from changing the current (in-core)
< * label.
< */
< if (ioctl(f, DIOCSDINFO, lp) < 0 &&
< errno != ENODEV && errno != ENOTTY) {
< l_perror("ioctl DIOCSDINFO");
< return (1);
< }
< (void)lseek(f, (off_t)0, SEEK_SET);
<
---
> if (disable_write) {
> Warning("write to disk label supressed - label was as follows:");
> display(stdout, lp);
> return (0);
> } else {
> setbootflag(lp);
> lp->d_magic = DISKMAGIC;
> lp->d_magic2 = DISKMAGIC;
> lp->d_checksum = 0;
> lp->d_checksum = dkcksum(lp);
> if (rflag) {
> /*
> * First set the kernel disk label,
> * then write a label to the raw disk.
> * If the SDINFO ioctl fails because it is unimplemented,
> * keep going; otherwise, the kernel consistency checks
> * may prevent us from changing the current (in-core)
> * label.
> */
> if (ioctl(f, DIOCSDINFO, lp) < 0 &&
> errno != ENODEV && errno != ENOTTY) {
> l_perror("ioctl DIOCSDINFO");
> return (1);
> }
> (void)lseek(f, (off_t)0, SEEK_SET);
>
422,427c448,453
< /*
< * Generate the bootblock checksum for the SRM console.
< */
< for (p = (u_long *)boot, i = 0, sum = 0; i < 63; i++)
< sum += p[i];
< p[63] = sum;
---
> /*
> * Generate the bootblock checksum for the SRM console.
> */
> for (p = (u_long *)boot, i = 0, sum = 0; i < 63; i++)
> sum += p[i];
> p[63] = sum;
429,440c455,466
<
< /*
< * write enable label sector before write (if necessary),
< * disable after writing.
< */
< flag = 1;
< if (ioctl(f, DIOCWLABEL, &flag) < 0)
< warn("ioctl DIOCWLABEL");
< if (write(f, boot, lp->d_bbsize) != lp->d_bbsize) {
< warn("write");
< return (1);
< }
---
>
> /*
> * write enable label sector before write (if necessary),
> * disable after writing.
> */
> flag = 1;
> if (ioctl(f, DIOCWLABEL, &flag) < 0)
> warn("ioctl DIOCWLABEL");
> if (write(f, boot, lp->d_bbsize) != lp->d_bbsize) {
> warn("write");
> return (1);
> }
442,448c468,474
< /*
< * Output the remainder of the disklabel
< */
< if (bootbuf && write(f, bootbuf, bootsize) != bootsize) {
< warn("write");
< return(1);
< }
---
> /*
> * Output the remainder of the disklabel
> */
> if (bootbuf && write(f, bootbuf, bootsize) != bootsize) {
> warn("write");
> return(1);
> }
450,455c476,481
< flag = 0;
< (void) ioctl(f, DIOCWLABEL, &flag);
< } else if (ioctl(f, DIOCWDINFO, lp) < 0) {
< l_perror("ioctl DIOCWDINFO");
< return (1);
< }
---
> flag = 0;
> (void) ioctl(f, DIOCWLABEL, &flag);
> } else if (ioctl(f, DIOCWDINFO, lp) < 0) {
> l_perror("ioctl DIOCWDINFO");
> return (1);
> }
457,465c483,492
< if (lp->d_type == DTYPE_SMD && lp->d_flags & D_BADSECT) {
< daddr_t alt;
<
< alt = lp->d_ncylinders * lp->d_secpercyl - lp->d_nsectors;
< for (i = 1; i < 11 && i < lp->d_nsectors; i += 2) {
< (void)lseek(f, (off_t)((alt + i) * lp->d_secsize),
< SEEK_SET);
< if (write(f, boot, lp->d_secsize) < lp->d_secsize)
< warn("alternate label %d write", i/2);
---
> if (lp->d_type == DTYPE_SMD && lp->d_flags & D_BADSECT) {
> daddr_t alt;
>
> alt = lp->d_ncylinders * lp->d_secpercyl - lp->d_nsectors;
> for (i = 1; i < 11 && i < lp->d_nsectors; i += 2) {
> (void)lseek(f, (off_t)((alt + i) * lp->d_secsize),
> SEEK_SET);
> if (write(f, boot, lp->d_secsize) < lp->d_secsize)
> warn("alternate label %d write", i/2);
> }
467d493
< }
468a495
> }
935a963,964
> int i;
> unsigned int part;
1140,1143c1169,1172
< if ('a' <= *cp && *cp <= 'z' && cp[1] == '\0') {
< unsigned part = *cp - 'a';
<
< if (part > lp->d_npartitions) {
---
> /* the ':' was removed above */
> if ('a' <= *cp && *cp <= MAX_PART && cp[1] == '\0') {
> part = *cp - 'a';
> if (part >= lp->d_npartitions) {
1145c1174,1175
< "line %d: bad partition name\n", lineno);
---
> "line %d: partition name out of range a-%c: %s\n",
> lineno, 'a' + lp->d_npartitions - 1, cp);
1149a1180
> part_set[part] = 1;
1162,1164c1193,1210
<
< NXTNUM(v);
< if (v < 0) {
---
> /* retain 1 character following number */
> #define NXTWORD(w,n) { \
> if (tp == NULL) { \
> fprintf(stderr, "line %d: too few numeric fields\n", lineno); \
> errors++; \
> break; \
> } else { \
> char *tmp; \
> cp = tp, tp = word(cp); \
> if (tp == NULL) \
> tp = cp; \
> (n) = strtol(cp,&tmp,10); \
> if (tmp) (w) = *tmp; \
> } \
> }
> v = 0;
> NXTWORD(part_size_type[part],v);
> if (v < 0 || (v == 0 && part_size_type[part] != '*')) {
1169c1215,1216
< } else
---
> break;
> } else {
1171,1196d1217
< NXTNUM(v);
< if (v < 0) {
< fprintf(stderr,
< "line %d: %s: bad partition offset\n",
< lineno, cp);
< errors++;
< } else
< pp->p_offset = v;
< cp = tp, tp = word(cp);
< cpp = fstypenames;
< for (; cpp < &fstypenames[FSMAXTYPES]; cpp++)
< if ((s = *cpp) && streq(s, cp)) {
< pp->p_fstype = cpp - fstypenames;
< goto gottype;
< }
< if (isdigit(*cp))
< v = atoi(cp);
< else
< v = FSMAXTYPES;
< if ((unsigned)v >= FSMAXTYPES) {
< fprintf(stderr, "line %d: %s %s\n", lineno,
< "Warning, unknown filesystem type", cp);
< v = FS_UNUSED;
< }
< pp->p_fstype = v;
< gottype:
1198,1202c1219,1227
< switch (pp->p_fstype) {
<
< case FS_UNUSED: /* XXX */
< NXTNUM(pp->p_fsize);
< if (pp->p_fsize == 0)
---
> v = 0;
> NXTWORD(part_offset_type[part],v);
> if (v < 0 || (v == 0 &&
> part_offset_type[part] != '*' &&
> part_offset_type[part] != '\0')) {
> fprintf(stderr,
> "line %d: %s: bad partition offset\n",
> lineno, cp);
> errors++;
1204,1206c1229,1270
< NXTNUM(v);
< pp->p_frag = v / pp->p_fsize;
< break;
---
> } else {
> pp->p_offset = v;
> cp = tp, tp = word(cp);
> cpp = fstypenames;
> for (; cpp < &fstypenames[FSMAXTYPES]; cpp++)
> if ((s = *cpp) && streq(s, cp)) {
> pp->p_fstype = cpp -
> fstypenames;
> goto gottype;
> }
> if (isdigit(*cp))
> v = atoi(cp);
> else
> v = FSMAXTYPES;
> if ((unsigned)v >= FSMAXTYPES) {
> fprintf(stderr,
> "line %d: Warning, unknown "
> "filesystem type %s\n",
> lineno, cp);
> v = FS_UNUSED;
> }
> pp->p_fstype = v;
> gottype:;
> /*
> * Note: NXTNUM will break us out of the
> * switch only!
> */
> switch (pp->p_fstype) {
> case FS_UNUSED:
> /*
> * allow us to accept defaults for
> * fsize/frag/cpg
> */
> if (tp) {
> NXTNUM(pp->p_fsize);
> if (pp->p_fsize == 0)
> break;
> NXTNUM(v);
> pp->p_frag = v / pp->p_fsize;
> }
> /* else default to 0's */
> break;
1208,1215c1272,1302
< case FS_BSDFFS:
< NXTNUM(pp->p_fsize);
< if (pp->p_fsize == 0)
< break;
< NXTNUM(v);
< pp->p_frag = v / pp->p_fsize;
< NXTNUM(pp->p_cpg);
< break;
---
> /* These happen to be the same */
> case FS_BSDFFS:
> case FS_BSDLFS:
> if (tp) {
> NXTNUM(pp->p_fsize);
> if (pp->p_fsize == 0)
> break;
> NXTNUM(v);
> pp->p_frag = v / pp->p_fsize;
> NXTNUM(pp->p_cpg);
> } else {
> /*
> * FIX! poor attempt at
> * adaptive
> */
> /* 1 GB */
> if (pp->p_size < 1*1024*1024*1024/lp->d_secsize) {
> /* FIX! These are too low, but are traditional */
> pp->p_fsize = DEFAULT_NEWFS_BLOCK;
> pp->p_frag = (unsigned char) DEFAULT_NEWFS_FRAG;
> pp->p_cpg = DEFAULT_NEWFS_CPG;
> } else {
> pp->p_fsize = BIG_NEWFS_BLOCK;
> pp->p_frag = (unsigned char) BIG_NEWFS_FRAG;
> pp->p_cpg = BIG_NEWFS_CPG;
> }
> }
> break;
> default:
> break;
> }
1217,1227c1304,1310
< case FS_BSDLFS:
< NXTNUM(pp->p_fsize);
< if (pp->p_fsize == 0)
< break;
< NXTNUM(v);
< pp->p_frag = v / pp->p_fsize;
< NXTNUM(pp->p_cpg);
< break;
<
< default:
< break;
---
> /*
> * note: we may not have
> * gotten all the entries for
> * the fs though if we didn't,
> * errors will be set.
> */
> }
1234,1235c1317
< next:
< ;
---
> next:;
1251a1334,1338
> unsigned long total_size,total_percent,current_offset;
> int seen_default_offset;
> int hog_part;
> int j;
> struct partition *pp2;
1287a1375,1380
>
> /* first allocate space to the partitions, then offsets */
> total_size = 0; /* in sectors */
> total_percent = 0; /* in percent */
> hog_part = -1;
> /* find all fixed partitions */
1288a1382,1482
> pp = &lp->d_partitions[i];
> if (part_set[i]) {
> if (part_size_type[i] == '*') {
> /* partition 2 ('c') is special */
> if (i == FULL_DISK_PART) {
> pp->p_size = lp->d_secperunit;
> } else {
> if (hog_part != -1)
> Warning("Too many '*' partitions (%c and %c)",
> hog_part + 'a',i + 'a');
> else
> hog_part = i;
> }
> } else {
> char *type;
> unsigned long size;
>
> size = pp->p_size;
> switch (part_size_type[i]) {
> case '%':
> total_percent += size;
> break;
> case 'k':
> case 'K':
> size *= 1024UL;
> break;
> case 'm':
> case 'M':
> size *= ((unsigned long) 1024*1024);
> break;
> case 'g':
> case 'G':
> size *= ((unsigned long) 1024*1024*1024);
> break;
> case '\0':
> break;
> default:
> Warning("unknown size specifier '%c' (K/M/G are valid)",part_size_type[i]);
> break;
> }
> /* don't count %'s yet */
> if (part_size_type[i] != '%') {
> /*
> * for all not in sectors, convert to
> * sectors
> */
> if (part_size_type[i] != '\0') {
> if (size % lp->d_secsize != 0)
> Warning("partition %c not an integer number of sectors",
> i + 'a');
> size /= lp->d_secsize;
> pp->p_size = size;
> }
> /* else already in sectors */
> /* partition 2 ('c') is special */
> if (i != FULL_DISK_PART)
> total_size += size;
> }
> }
> }
> }
> /* handle % partitions - note %'s don't need to add up to 100! */
> if (total_percent != 0) {
> long free_space = lp->d_secperunit - total_size;
> if (total_percent > 100) {
> fprintf(stderr,"total percentage %d is greater than 100\n",
> total_percent);
> errors++;
> }
>
> if (free_space > 0) {
> for (i = 0; i < lp->d_npartitions; i++) {
> pp = &lp->d_partitions[i];
> if (part_set[i] && part_size_type[i] == '%') {
> unsigned long old_size = pp->p_size;
> /* careful of overflows! and integer roundoff */
> pp->p_size = ((double)pp->p_size/100) * free_space;
> total_size += pp->p_size;
>
> /* FIX we can lose a sector or so due to roundoff per
> partition. A more complex algorithm could avoid that */
> }
> }
> } else {
> fprintf(stderr,
> "%ld sectors available to give to '*' and '%' partitions\n",
> free_space);
> errors++;
> /* fix? set all % partitions to size 0? */
> }
> }
> /* give anything remaining to the hog partition */
> if (hog_part != -1) {
> lp->d_partitions[hog_part].p_size = lp->d_secperunit - total_size;
> total_size = lp->d_secperunit;
> }
>
> /* Now set the offsets for each partition */
> current_offset = 0; /* in sectors */
> seen_default_offset = 0;
> for (i = 0; i < lp->d_npartitions; i++) {
1290a1485,1524
> if (part_set[i]) {
> if (part_offset_type[i] == '*') {
> /* partition 2 ('c') is special */
> if (i == FULL_DISK_PART) {
> pp->p_offset = 0;
> } else {
> pp->p_offset = current_offset;
> seen_default_offset = 1;
> }
> } else {
> /* allow them to be out of order for old-style tables */
> /* partition 2 ('c') is special */
> if (pp->p_offset < current_offset &&
> seen_default_offset && i != FULL_DISK_PART) {
> fprintf(stderr,
> "Offset %ld for partition %c overlaps previous partition which ends at %ld\n",
> pp->p_offset,i+'a',current_offset);
> fprintf(stderr,
> "Labels with any *'s for offset must be in ascending order by sector\n");
> errors++;
> } else if (pp->p_offset != current_offset &&
> i != FULL_DISK_PART && seen_default_offset) {
> /*
> * this may give unneeded warnings if
> * partitions are out-of-order
> */
> Warning(
> "Offset %ld for partition %c doesn't match expected value %ld",
> pp->p_offset, i + 'a', current_offset);
> }
> }
> /* partition 2 ('c') is special */
> if (i != FULL_DISK_PART)
> current_offset = pp->p_offset + pp->p_size;
> }
> }
>
> for (i = 0; i < lp->d_npartitions; i++) {
> part = 'a' + i;
> pp = &lp->d_partitions[i];
1312a1547,1578
> if (i == FULL_DISK_PART)
> {
> if (pp->p_fstype != FS_UNUSED)
> Warning("partition %c is not marked as unused!",part);
> if (pp->p_offset != 0)
> Warning("partition %c doesn't start at 0!",part);
> if (pp->p_size != lp->d_secperunit)
> Warning("partition %c doesn't cover the whole unit!",part);
>
> if ((pp->p_fstype != FS_UNUSED) || (pp->p_offset != 0) ||
> (pp->p_size != lp->d_secperunit)) {
> Warning("An incorrect partition %c may cause problems for "
> "standard system utilities",part);
> }
> }
>
> /* check for overlaps */
> /* this will check for all possible overlaps once and only once */
> for (j = 0; j < i; j++) {
> /* partition 2 ('c') is special */
> if (j != FULL_DISK_PART && i != FULL_DISK_PART &&
> part_set[i] && part_set[j]) {
> pp2 = &lp->d_partitions[j];
> if (pp2->p_offset < pp->p_offset + pp->p_size &&
> (pp2->p_offset + pp2->p_size > pp->p_offset ||
> pp2->p_offset >= pp->p_offset)) {
> fprintf(stderr,"partitions %c and %c overlap!\n",
> j + 'a', i + 'a');
> errors++;
> }
> }
> }
1355,1359c1621,1625
< if (ioctl(f, DIOCGDINFO, &lab) < 0) {
< warn("ioctl DIOCGDINFO");
< close(f);
< return (NULL);
< }
---
> if (ioctl(f, DIOCGDINFO, &lab) < 0) {
> warn("ioctl DIOCGDINFO");
> close(f);
> return (NULL);
> }
1430c1696
< " disklabel -w [-r] disk type [ packid ]",
---
> " disklabel -w [-r] [-n] disk type [ packid ]",
1432c1698
< " disklabel -e [-r] disk",
---
> " disklabel -e [-r] [-n] disk",
1434c1700
< " disklabel -R [-r] disk protofile",
---
> " disklabel -R [-r] [-n] disk protofile",
1437c1703
< " disklabel -B [ -b boot1 [ -s boot2 ] ] disk [ type ]",
---
> " disklabel -B [-n] [ -b boot1 [ -s boot2 ] ] disk [ type ]",
1439c1705
< " disklabel -w -B [ -b boot1 [ -s boot2 ] ] disk type [ packid ]",
---
> " disklabel -w -B [-n] [ -b boot1 [ -s boot2 ] ] disk type [ packid ]",
1441c1707
< " disklabel -R -B [ -b boot1 [ -s boot2 ] ] disk protofile [ type ]",
---
> " disklabel -R -B [-n] [ -b boot1 [ -s boot2 ] ] disk protofile [ type ]",
1444c1710
< " disklabel -B [ -b bootprog ] disk [ type ]",
---
> " disklabel -B [-n] [ -b bootprog ] disk [ type ]",
1446c1712
< " disklabel -w -B [ -b bootprog ] disk type [ packid ]",
---
> " disklabel -w -B [-n] [ -b bootprog ] disk type [ packid ]",
1448c1714
< " disklabel -R -B [ -b bootprog ] disk protofile [ type ]",
---
> " disklabel -R -B [-n] [ -b bootprog ] disk protofile [ type ]",
1456c1722
< " disklabel -w [-r] disk type [ packid ]",
---
> " disklabel -w [-r] [-n] disk type [ packid ]",
1458c1724
< " disklabel -e [-r] disk",
---
> " disklabel -e [-r] [-n] disk",
1460c1726
< " disklabel -R [-r] disk protofile",
---
> " disklabel -R [-r] [-n] disk protofile",