mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-05 09:14:03 +00:00
Allow for easier configuration when using disklabel. A sample
being: # size offset fstype [fsize bsize bps/cpg] a: 400M 0 4.2BSD 4096 16384 75 # (Cyl. 0 - 812*) b: 1G * swap c: * * unused e: 204800 * 4.2BSD f: 5g * 4.2BSD g: * * 4.2BSD These patches are the original work of Randell Jesup, and I believe Matt Dillon, with additional work by Warner Losh. Please let me know if I've left someone out. Incorporated into this is the fix for PR bin/22727. This patchset still has style issues and a possible problem on large disks. However, it was a agreed to get these committed before performing major surgery on them. PR: bin/22727 Submitted by: Randell Jesup <rjesup@wgate.com>
This commit is contained in:
parent
a10f496636
commit
3233afaec7
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=73034
@ -48,15 +48,18 @@
|
||||
.Nm
|
||||
.Fl w
|
||||
.Op Fl r
|
||||
.Op Fl n
|
||||
.Ar disk Ar disktype/auto
|
||||
.Oo Ar packid Oc
|
||||
.Nm
|
||||
.Fl e
|
||||
.Op Fl r
|
||||
.Op Fl n
|
||||
.Ar disk
|
||||
.Nm
|
||||
.Fl R
|
||||
.Op Fl r
|
||||
.Op Fl n
|
||||
.Ar disk Ar protofile
|
||||
.Nm
|
||||
.Op Fl NW
|
||||
@ -73,6 +76,7 @@
|
||||
.Nm
|
||||
.Fl w
|
||||
.Fl B
|
||||
.Op Fl n
|
||||
.Oo
|
||||
.Fl b Ar boot1
|
||||
.Fl s Ar boot2
|
||||
@ -82,6 +86,7 @@
|
||||
.Nm
|
||||
.Fl R
|
||||
.Fl B
|
||||
.Op Fl n
|
||||
.Oo
|
||||
.Fl b Ar boot1
|
||||
.Fl s Ar boot2
|
||||
@ -170,12 +175,14 @@ To write a standard label, use the form
|
||||
.Nm
|
||||
.Fl w
|
||||
.Op Fl r
|
||||
.Op Fl n
|
||||
.Ar disk Ar disktype/auto
|
||||
.Oo Ar packid Oc
|
||||
.Pp
|
||||
.Nm
|
||||
.Fl w
|
||||
.Op Fl r
|
||||
.Op Fl n
|
||||
.Ar disk
|
||||
auto
|
||||
.Pp
|
||||
@ -188,7 +195,14 @@ different disks of the same physical type are to have different partitions, it
|
||||
will be necessary to have separate disktab entries describing each, or to edit
|
||||
the label after installation as described below. The optional argument is a
|
||||
pack identification string, up to 16 characters long. The pack id must be
|
||||
quoted if it contains blanks. If the
|
||||
quoted if it contains blanks.
|
||||
.Pp
|
||||
If the
|
||||
.Fl n
|
||||
flag is given, no data will be written to the device, and instead the
|
||||
disklabel that would have been written will be printed to stdout.
|
||||
.Pp
|
||||
If the
|
||||
.Fl r
|
||||
flag is given, the disk sectors containing the label and bootstrap
|
||||
will be written directly.
|
||||
@ -220,6 +234,9 @@ disk is the only supported operation, and the
|
||||
itself must be provided as the canonical name, i.e. not as a full
|
||||
path name.
|
||||
.Pp
|
||||
For most harddisks, a label based on percentages for most partitions (and
|
||||
one partition with a size of '*') will produce a reasonable configuration.
|
||||
.Pp
|
||||
PC-based systems have special requirements in order for the BIOS to properly
|
||||
recognize a
|
||||
.Fx
|
||||
@ -244,6 +261,7 @@ To edit an existing disk label, use the form
|
||||
.Nm
|
||||
.Fl e
|
||||
.Op Fl r
|
||||
.Op Fl n
|
||||
.Ar disk
|
||||
.Pp
|
||||
This command reads the label from the in-core kernel copy, or directly from the
|
||||
@ -257,7 +275,11 @@ environment variable,
|
||||
is used. When the editor terminates, the label file is used to rewrite the disk
|
||||
label. Existing bootstrap code is unchanged regardless of whether
|
||||
.Fl r
|
||||
was specified.
|
||||
was specified. If
|
||||
.Fl n
|
||||
is specified, no data will be written to the device, and instead the
|
||||
disklabel that would have been written will be printed to stdout. This is
|
||||
useful to see how a partitioning scheme will work out for a specific disk.
|
||||
.Ss Restoring a disk label from a file
|
||||
.Pp
|
||||
To restore a disk label from a file, use the form
|
||||
@ -265,6 +287,7 @@ To restore a disk label from a file, use the form
|
||||
.Nm
|
||||
.Fl R
|
||||
.Op Fl r
|
||||
.Op Fl n
|
||||
.Ar disk Ar protofile
|
||||
.Pp
|
||||
.Nm
|
||||
@ -277,6 +300,11 @@ clobbered if
|
||||
.Fl r
|
||||
is specified and will be unaffected otherwise. See the boot options below for a
|
||||
method of restoring the label and writing the bootstrap at the same time.
|
||||
If
|
||||
.Fl n
|
||||
is used, no data will be written to the device, and instead the
|
||||
disklabel that would have been written will be printed to stdout. This is
|
||||
useful to see how a partitioning scheme will work out for a specific disk.
|
||||
.Ss Enabling and disabling writing to the disk label area
|
||||
.Pp
|
||||
By default, it is not possible to write to the disk label area at the beginning
|
||||
@ -331,6 +359,7 @@ This command is typically run on a slice such as
|
||||
.Nm
|
||||
.Fl w
|
||||
.Fl B
|
||||
.Op Fl n
|
||||
.Oo
|
||||
.Fl b Ar boot1
|
||||
.Fl s Ar boot2
|
||||
@ -345,10 +374,15 @@ In addition to writing a new volume label, it also installs the bootstrap.
|
||||
If run on a base disk this command will create a
|
||||
.Dq dangerously-dedicated
|
||||
label. This command is normally run on a slice rather than a base disk.
|
||||
If
|
||||
.Fl n
|
||||
is used, no data will be written to the device, and instead the
|
||||
disklabel that would have been written will be printed to stdout.
|
||||
.Pp
|
||||
.Nm
|
||||
.Fl R
|
||||
.Fl B
|
||||
.Op Fl n
|
||||
.Oo
|
||||
.Fl b Ar boot1
|
||||
.Fl s Ar boot2
|
||||
@ -367,7 +401,10 @@ label. This command is normally run on a slice rather than a base disk.
|
||||
The bootstrap commands always access the disk directly, so it is not necessary
|
||||
to specify the
|
||||
.Fl r
|
||||
flag.
|
||||
flag. If
|
||||
.Fl n
|
||||
is used, no data will be written to the device, and instead the
|
||||
disklabel that would have been written will be printed to stdout.
|
||||
.Pp
|
||||
The bootstrap code is comprised of two boot programs. Specify the name of the
|
||||
boot programs to be installed in one of these ways:
|
||||
@ -548,21 +585,63 @@ By convention, partition
|
||||
.Nm c
|
||||
is reserved to describe the entire disk.
|
||||
.It size
|
||||
is the size of the partition in sectors.
|
||||
is the size of the partition in sectors,
|
||||
.Nm K
|
||||
(kilobytes - 1024),
|
||||
.Nm M
|
||||
(megabytes - 1024*1024),
|
||||
.Nm G
|
||||
(gigabytes - 1024*1024*1024),
|
||||
.Nm %
|
||||
(percentage of free space AFTER removing any fixed-size partitions other
|
||||
than partition
|
||||
.Nm c
|
||||
), or * (all remaining free space AFTER fixed-size and percentage
|
||||
partitions). For partition
|
||||
.Nm c ,
|
||||
a size of * indicates the entire disk. Lowercase versions of K, M, and G
|
||||
are allowed.
|
||||
Size and type should be specifed without any spaces between them.
|
||||
.Pp
|
||||
Example: 2097152, 1g, 1024m and 1048576k are all the same size
|
||||
(assuming 512-byte sectors).
|
||||
.It offset
|
||||
is the offset of the start of the partition from the beginning of the drive.
|
||||
is the offset of the start of the partition from the beginning of the
|
||||
drive in sectors, or * to have
|
||||
.Nm
|
||||
calculate the correct offset to use (the end of the previous partition plus
|
||||
one, ignoring partition
|
||||
.Nm c .
|
||||
For partition
|
||||
.Nm c ,
|
||||
* will be interpreted as an offset of 0.
|
||||
.It fstype
|
||||
describes the purpose of the partition. The example shows most normal usages.
|
||||
For UFS file systems, use type 4.2BSD. See
|
||||
For UFS file systems, use type
|
||||
.Nm 4.2BSD .
|
||||
Other common types are
|
||||
.Nm unused
|
||||
and
|
||||
.Nm swap .
|
||||
See
|
||||
.Pa /usr/include/sys/disklabel.h
|
||||
for a complete list.
|
||||
.It fsize
|
||||
For file systems only, the fragment size.
|
||||
For
|
||||
.Nm 4.2BSD
|
||||
and LFS file systems only, the fragment size. Defaults to 8192 for
|
||||
partitions smaller than 1 GB, 16384 for partitions 1GB or larger.
|
||||
.It bsize
|
||||
For file systems only, the block size.
|
||||
For
|
||||
.Nm 4.2BSD
|
||||
and LFS file systems only, the block size. Defaults to 1024 for
|
||||
partitions smaller than 1 GB, 4096 for partitions 1GB or larger.
|
||||
.It bps/cpg
|
||||
For UFS file systems, the number of cylinders in a cylinder group. For LFS file
|
||||
systems, the segment shift value.
|
||||
For
|
||||
.Nm 4.2BSD
|
||||
file systems, the number of cylinders in a cylinder group. For LFS file
|
||||
systems, the segment shift value. Defaults to 16 for
|
||||
partitions smaller than 1 GB, 64 for partitions 1GB or larger.
|
||||
.El
|
||||
.Pp
|
||||
The remainder of the line is a comment and shows the cylinder allocations based
|
||||
@ -611,6 +690,13 @@ Read the on-disk label for
|
||||
edit it and reinstall in-core as well as on-disk. Existing bootstrap code is
|
||||
unaffected.
|
||||
.Pp
|
||||
.Dl disklabel -e -r -n da0s1
|
||||
.Pp
|
||||
Read the on-disk label for
|
||||
.Pa da0s1 ,
|
||||
edit it, and display what the new label would be (in sectors). It does
|
||||
NOT install the new label either in-core or on-disk.
|
||||
.Pp
|
||||
.Dl disklabel -r -w da0s1 auto
|
||||
.Pp
|
||||
Try to auto-detect the required information from
|
||||
@ -626,6 +712,15 @@ from information in
|
||||
.Pa savedlabel .
|
||||
Existing bootstrap code is unaffected.
|
||||
.Pp
|
||||
.Dl disklabel -R -n da0s1 label_layout
|
||||
.Pp
|
||||
Display what the label would be for
|
||||
.Pa da0s1
|
||||
using the partition layout in
|
||||
.Pa label_layout .
|
||||
This is useful for determining how much space would be alloted for various
|
||||
partitions with a labelling scheme using %-based or * partition sizes.
|
||||
.Pp
|
||||
.Dl disklabel -B da0s1
|
||||
.Pp
|
||||
Install a new bootstrap on
|
||||
@ -661,6 +756,40 @@ initialize the slice, then edit it to your needs. The
|
||||
.Pa dd
|
||||
commands are optional, but may be necessary for some BIOSes to properly
|
||||
recognize the disk.
|
||||
.Pp
|
||||
This is an example disklabel that uses some of the new partition size types
|
||||
such as %, M, G, and *, which could be used as a source file for
|
||||
.Pp
|
||||
.Dl disklabel -R ad0s1c new_label_file
|
||||
.Bd -literal -offset 4n
|
||||
# /dev/ad0s1c:
|
||||
type: ESDI
|
||||
disk: ad0s1
|
||||
label:
|
||||
flags:
|
||||
bytes/sector: 512
|
||||
sectors/track: 63
|
||||
tracks/cylinder: 16
|
||||
sectors/cylinder: 1008
|
||||
cylinders: 40633
|
||||
sectors/unit: 40959009
|
||||
rpm: 3600
|
||||
interleave: 1
|
||||
trackskew: 0
|
||||
cylinderskew: 0
|
||||
headswitch: 0 # milliseconds
|
||||
track-to-track seek: 0 # milliseconds
|
||||
drivedata: 0
|
||||
|
||||
8 partitions:
|
||||
# size offset fstype [fsize bsize bps/cpg]
|
||||
a: 400M 0 4.2BSD 4096 16384 75 # (Cyl. 0 - 812*)
|
||||
b: 1G * swap
|
||||
c: * * unused
|
||||
e: 204800 * 4.2BSD
|
||||
f: 5g * 4.2BSD
|
||||
g: * * 4.2BSD
|
||||
.Ed
|
||||
.Sh SEE ALSO
|
||||
.Xr disklabel 5 ,
|
||||
.Xr disktab 5 ,
|
||||
@ -723,5 +852,9 @@ concern if the disk is fully dedicated, so that the BSD disklabel
|
||||
starts at absolute block 0 on the disk.
|
||||
.Pp
|
||||
.Nm
|
||||
does not perform adequate error checking. No warning is given if partitions
|
||||
overlap, nor if space remains unused.
|
||||
does not perform all possible error checking. Warning *is* given if partitions
|
||||
overlap; if an absolute offset doesn't match the expected offset; if the
|
||||
.Nm c
|
||||
partition doesn't start at 0 or doesn't cover the entire slice; if a
|
||||
partition runs past the end of the device; and a number of other errors; but
|
||||
no warning is given if space remains unused.
|
||||
|
@ -80,6 +80,15 @@ static const char rcsid[] =
|
||||
#define BBSIZE 8192 /* size of boot area, with label */
|
||||
#endif
|
||||
|
||||
/* 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
|
||||
|
||||
#ifdef tahoe
|
||||
#define NUMBOOT 0
|
||||
#else
|
||||
@ -118,6 +127,14 @@ char namebuf[BBSIZE], *np = namebuf;
|
||||
struct disklabel lab;
|
||||
char bootarea[BBSIZE];
|
||||
|
||||
/* 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];
|
||||
|
||||
#if NUMBOOT > 0
|
||||
int installboot; /* non-zero if we should install a boot program */
|
||||
char *bootbuf; /* pointer to buffer with remainder of boot prog */
|
||||
@ -133,12 +150,13 @@ enum {
|
||||
} op = UNSPEC;
|
||||
|
||||
int rflag;
|
||||
int disable_write; /* set to disable writing to disk label */
|
||||
|
||||
#ifdef DEBUG
|
||||
int debug;
|
||||
#define OPTIONS "BNRWb:ders:w"
|
||||
#define OPTIONS "BNRWb:denrs:w"
|
||||
#else
|
||||
#define OPTIONS "BNRWb:ers:w"
|
||||
#define OPTIONS "BNRWb:enrs:w"
|
||||
#endif
|
||||
|
||||
int
|
||||
@ -171,6 +189,9 @@ main(argc, argv)
|
||||
usage();
|
||||
op = NOWRITE;
|
||||
break;
|
||||
case 'n':
|
||||
disable_write = 1;
|
||||
break;
|
||||
case 'R':
|
||||
if (op != UNSPEC)
|
||||
usage();
|
||||
@ -397,75 +418,81 @@ writelabel(f, boot, lp)
|
||||
register int i;
|
||||
#endif
|
||||
|
||||
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);
|
||||
|
||||
#ifdef __alpha__
|
||||
/*
|
||||
* 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;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 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");
|
||||
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
#if NUMBOOT > 0
|
||||
/*
|
||||
* Output the remainder of the disklabel
|
||||
*/
|
||||
if (bootbuf && write(f, bootbuf, bootsize) != bootsize) {
|
||||
warn("write");
|
||||
return(1);
|
||||
}
|
||||
#endif
|
||||
flag = 0;
|
||||
(void) ioctl(f, DIOCWLABEL, &flag);
|
||||
} else if (ioctl(f, DIOCWDINFO, lp) < 0) {
|
||||
l_perror("ioctl DIOCWDINFO");
|
||||
return (1);
|
||||
}
|
||||
#if NUMBOOT > 0
|
||||
/*
|
||||
* Output the remainder of the disklabel
|
||||
*/
|
||||
if (bootbuf && write(f, bootbuf, bootsize) != bootsize) {
|
||||
warn("write");
|
||||
return(1);
|
||||
}
|
||||
#endif
|
||||
flag = 0;
|
||||
(void) ioctl(f, DIOCWLABEL, &flag);
|
||||
} else if (ioctl(f, DIOCWDINFO, lp) < 0) {
|
||||
l_perror("ioctl DIOCWDINFO");
|
||||
return (1);
|
||||
}
|
||||
#ifdef vax
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -933,6 +960,8 @@ getasciilabel(f, lp)
|
||||
{
|
||||
register char **cpp, *cp;
|
||||
register struct partition *pp;
|
||||
int i;
|
||||
unsigned int part;
|
||||
char *tp, *s, line[BUFSIZ];
|
||||
int v, lineno = 0, errors = 0;
|
||||
|
||||
@ -1137,16 +1166,18 @@ getasciilabel(f, lp)
|
||||
lp->d_trkseek = v;
|
||||
continue;
|
||||
}
|
||||
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) {
|
||||
fprintf(stderr,
|
||||
"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);
|
||||
errors++;
|
||||
continue;
|
||||
}
|
||||
pp = &lp->d_partitions[part];
|
||||
part_set[part] = 1;
|
||||
#define NXTNUM(n) { \
|
||||
if (tp == NULL) { \
|
||||
fprintf(stderr, "line %d: too few numeric fields\n", lineno); \
|
||||
@ -1159,80 +1190,131 @@ getasciilabel(f, lp)
|
||||
(n) = atoi(cp); \
|
||||
} \
|
||||
}
|
||||
|
||||
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] != '*')) {
|
||||
fprintf(stderr,
|
||||
"line %d: %s: bad partition size\n",
|
||||
lineno, cp);
|
||||
errors++;
|
||||
} else
|
||||
break;
|
||||
} else {
|
||||
pp->p_size = v;
|
||||
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;
|
||||
|
||||
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++;
|
||||
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;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/*
|
||||
* note: we may not have
|
||||
* gotten all the entries for
|
||||
* the fs though if we didn't,
|
||||
* errors will be set.
|
||||
*/
|
||||
}
|
||||
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:
|
||||
|
||||
switch (pp->p_fstype) {
|
||||
|
||||
case FS_UNUSED: /* XXX */
|
||||
NXTNUM(pp->p_fsize);
|
||||
if (pp->p_fsize == 0)
|
||||
break;
|
||||
NXTNUM(v);
|
||||
pp->p_frag = v / pp->p_fsize;
|
||||
break;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
fprintf(stderr, "line %d: %s: Unknown disklabel field\n",
|
||||
lineno, cp);
|
||||
errors++;
|
||||
next:
|
||||
;
|
||||
next:;
|
||||
}
|
||||
errors += checklabel(lp);
|
||||
return (errors == 0);
|
||||
@ -1249,6 +1331,11 @@ checklabel(lp)
|
||||
register struct partition *pp;
|
||||
int i, errors = 0;
|
||||
char part;
|
||||
unsigned long total_size,total_percent,current_offset;
|
||||
int seen_default_offset;
|
||||
int hog_part;
|
||||
int j;
|
||||
struct partition *pp2;
|
||||
|
||||
if (lp->d_secsize == 0) {
|
||||
fprintf(stderr, "sector size 0\n");
|
||||
@ -1285,6 +1372,153 @@ checklabel(lp)
|
||||
if (lp->d_npartitions > MAXPARTITIONS)
|
||||
Warning("number of partitions (%lu) > MAXPARTITIONS (%d)",
|
||||
(u_long)lp->d_npartitions, MAXPARTITIONS);
|
||||
|
||||
/* 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 */
|
||||
for (i = 0; i < lp->d_npartitions; i++) {
|
||||
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++) {
|
||||
part = 'a' + i;
|
||||
pp = &lp->d_partitions[i];
|
||||
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];
|
||||
@ -1310,6 +1544,38 @@ checklabel(lp)
|
||||
part);
|
||||
errors++;
|
||||
}
|
||||
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++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (; i < MAXPARTITIONS; i++) {
|
||||
part = 'a' + i;
|
||||
@ -1352,11 +1618,11 @@ getvirginlabel(void)
|
||||
* fallback to the old get-disdk-info ioctl.
|
||||
*/
|
||||
if (ioctl(f, DIOCGDVIRGIN, &lab) < 0) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
close(f);
|
||||
lab.d_boot0 = NULL;
|
||||
@ -1427,25 +1693,25 @@ usage()
|
||||
fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
|
||||
"usage: disklabel [-r] disk",
|
||||
"\t\t(to read label)",
|
||||
" disklabel -w [-r] disk type [ packid ]",
|
||||
" disklabel -w [-r] [-n] disk type [ packid ]",
|
||||
"\t\t(to write label with existing boot program)",
|
||||
" disklabel -e [-r] disk",
|
||||
" disklabel -e [-r] [-n] disk",
|
||||
"\t\t(to edit label)",
|
||||
" disklabel -R [-r] disk protofile",
|
||||
" disklabel -R [-r] [-n] disk protofile",
|
||||
"\t\t(to restore label with existing boot program)",
|
||||
#if NUMBOOT > 1
|
||||
" disklabel -B [ -b boot1 [ -s boot2 ] ] disk [ type ]",
|
||||
" disklabel -B [-n] [ -b boot1 [ -s boot2 ] ] disk [ type ]",
|
||||
"\t\t(to install boot program with existing label)",
|
||||
" disklabel -w -B [ -b boot1 [ -s boot2 ] ] disk type [ packid ]",
|
||||
" disklabel -w -B [-n] [ -b boot1 [ -s boot2 ] ] disk type [ packid ]",
|
||||
"\t\t(to write label and boot program)",
|
||||
" disklabel -R -B [ -b boot1 [ -s boot2 ] ] disk protofile [ type ]",
|
||||
" disklabel -R -B [-n] [ -b boot1 [ -s boot2 ] ] disk protofile [ type ]",
|
||||
"\t\t(to restore label and boot program)",
|
||||
#else
|
||||
" disklabel -B [ -b bootprog ] disk [ type ]",
|
||||
" disklabel -B [-n] [ -b bootprog ] disk [ type ]",
|
||||
"\t\t(to install boot program with existing on-disk label)",
|
||||
" disklabel -w -B [ -b bootprog ] disk type [ packid ]",
|
||||
" disklabel -w -B [-n] [ -b bootprog ] disk type [ packid ]",
|
||||
"\t\t(to write label and install boot program)",
|
||||
" disklabel -R -B [ -b bootprog ] disk protofile [ type ]",
|
||||
" disklabel -R -B [-n] [ -b bootprog ] disk protofile [ type ]",
|
||||
"\t\t(to restore label and install boot program)",
|
||||
#endif
|
||||
" disklabel [-NW] disk",
|
||||
@ -1453,11 +1719,11 @@ usage()
|
||||
#else
|
||||
fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
|
||||
"usage: disklabel [-r] disk", "(to read label)",
|
||||
" disklabel -w [-r] disk type [ packid ]",
|
||||
" disklabel -w [-r] [-n] disk type [ packid ]",
|
||||
"\t\t(to write label)",
|
||||
" disklabel -e [-r] disk",
|
||||
" disklabel -e [-r] [-n] disk",
|
||||
"\t\t(to edit label)",
|
||||
" disklabel -R [-r] disk protofile",
|
||||
" disklabel -R [-r] [-n] disk protofile",
|
||||
"\t\t(to restore label)",
|
||||
" disklabel [-NW] disk",
|
||||
"\t\t(to write disable/enable label)");
|
||||
|
@ -48,15 +48,18 @@
|
||||
.Nm
|
||||
.Fl w
|
||||
.Op Fl r
|
||||
.Op Fl n
|
||||
.Ar disk Ar disktype/auto
|
||||
.Oo Ar packid Oc
|
||||
.Nm
|
||||
.Fl e
|
||||
.Op Fl r
|
||||
.Op Fl n
|
||||
.Ar disk
|
||||
.Nm
|
||||
.Fl R
|
||||
.Op Fl r
|
||||
.Op Fl n
|
||||
.Ar disk Ar protofile
|
||||
.Nm
|
||||
.Op Fl NW
|
||||
@ -73,6 +76,7 @@
|
||||
.Nm
|
||||
.Fl w
|
||||
.Fl B
|
||||
.Op Fl n
|
||||
.Oo
|
||||
.Fl b Ar boot1
|
||||
.Fl s Ar boot2
|
||||
@ -82,6 +86,7 @@
|
||||
.Nm
|
||||
.Fl R
|
||||
.Fl B
|
||||
.Op Fl n
|
||||
.Oo
|
||||
.Fl b Ar boot1
|
||||
.Fl s Ar boot2
|
||||
@ -170,12 +175,14 @@ To write a standard label, use the form
|
||||
.Nm
|
||||
.Fl w
|
||||
.Op Fl r
|
||||
.Op Fl n
|
||||
.Ar disk Ar disktype/auto
|
||||
.Oo Ar packid Oc
|
||||
.Pp
|
||||
.Nm
|
||||
.Fl w
|
||||
.Op Fl r
|
||||
.Op Fl n
|
||||
.Ar disk
|
||||
auto
|
||||
.Pp
|
||||
@ -188,7 +195,14 @@ different disks of the same physical type are to have different partitions, it
|
||||
will be necessary to have separate disktab entries describing each, or to edit
|
||||
the label after installation as described below. The optional argument is a
|
||||
pack identification string, up to 16 characters long. The pack id must be
|
||||
quoted if it contains blanks. If the
|
||||
quoted if it contains blanks.
|
||||
.Pp
|
||||
If the
|
||||
.Fl n
|
||||
flag is given, no data will be written to the device, and instead the
|
||||
disklabel that would have been written will be printed to stdout.
|
||||
.Pp
|
||||
If the
|
||||
.Fl r
|
||||
flag is given, the disk sectors containing the label and bootstrap
|
||||
will be written directly.
|
||||
@ -220,6 +234,9 @@ disk is the only supported operation, and the
|
||||
itself must be provided as the canonical name, i.e. not as a full
|
||||
path name.
|
||||
.Pp
|
||||
For most harddisks, a label based on percentages for most partitions (and
|
||||
one partition with a size of '*') will produce a reasonable configuration.
|
||||
.Pp
|
||||
PC-based systems have special requirements in order for the BIOS to properly
|
||||
recognize a
|
||||
.Fx
|
||||
@ -244,6 +261,7 @@ To edit an existing disk label, use the form
|
||||
.Nm
|
||||
.Fl e
|
||||
.Op Fl r
|
||||
.Op Fl n
|
||||
.Ar disk
|
||||
.Pp
|
||||
This command reads the label from the in-core kernel copy, or directly from the
|
||||
@ -257,7 +275,11 @@ environment variable,
|
||||
is used. When the editor terminates, the label file is used to rewrite the disk
|
||||
label. Existing bootstrap code is unchanged regardless of whether
|
||||
.Fl r
|
||||
was specified.
|
||||
was specified. If
|
||||
.Fl n
|
||||
is specified, no data will be written to the device, and instead the
|
||||
disklabel that would have been written will be printed to stdout. This is
|
||||
useful to see how a partitioning scheme will work out for a specific disk.
|
||||
.Ss Restoring a disk label from a file
|
||||
.Pp
|
||||
To restore a disk label from a file, use the form
|
||||
@ -265,6 +287,7 @@ To restore a disk label from a file, use the form
|
||||
.Nm
|
||||
.Fl R
|
||||
.Op Fl r
|
||||
.Op Fl n
|
||||
.Ar disk Ar protofile
|
||||
.Pp
|
||||
.Nm
|
||||
@ -277,6 +300,11 @@ clobbered if
|
||||
.Fl r
|
||||
is specified and will be unaffected otherwise. See the boot options below for a
|
||||
method of restoring the label and writing the bootstrap at the same time.
|
||||
If
|
||||
.Fl n
|
||||
is used, no data will be written to the device, and instead the
|
||||
disklabel that would have been written will be printed to stdout. This is
|
||||
useful to see how a partitioning scheme will work out for a specific disk.
|
||||
.Ss Enabling and disabling writing to the disk label area
|
||||
.Pp
|
||||
By default, it is not possible to write to the disk label area at the beginning
|
||||
@ -331,6 +359,7 @@ This command is typically run on a slice such as
|
||||
.Nm
|
||||
.Fl w
|
||||
.Fl B
|
||||
.Op Fl n
|
||||
.Oo
|
||||
.Fl b Ar boot1
|
||||
.Fl s Ar boot2
|
||||
@ -345,10 +374,15 @@ In addition to writing a new volume label, it also installs the bootstrap.
|
||||
If run on a base disk this command will create a
|
||||
.Dq dangerously-dedicated
|
||||
label. This command is normally run on a slice rather than a base disk.
|
||||
If
|
||||
.Fl n
|
||||
is used, no data will be written to the device, and instead the
|
||||
disklabel that would have been written will be printed to stdout.
|
||||
.Pp
|
||||
.Nm
|
||||
.Fl R
|
||||
.Fl B
|
||||
.Op Fl n
|
||||
.Oo
|
||||
.Fl b Ar boot1
|
||||
.Fl s Ar boot2
|
||||
@ -367,7 +401,10 @@ label. This command is normally run on a slice rather than a base disk.
|
||||
The bootstrap commands always access the disk directly, so it is not necessary
|
||||
to specify the
|
||||
.Fl r
|
||||
flag.
|
||||
flag. If
|
||||
.Fl n
|
||||
is used, no data will be written to the device, and instead the
|
||||
disklabel that would have been written will be printed to stdout.
|
||||
.Pp
|
||||
The bootstrap code is comprised of two boot programs. Specify the name of the
|
||||
boot programs to be installed in one of these ways:
|
||||
@ -548,21 +585,63 @@ By convention, partition
|
||||
.Nm c
|
||||
is reserved to describe the entire disk.
|
||||
.It size
|
||||
is the size of the partition in sectors.
|
||||
is the size of the partition in sectors,
|
||||
.Nm K
|
||||
(kilobytes - 1024),
|
||||
.Nm M
|
||||
(megabytes - 1024*1024),
|
||||
.Nm G
|
||||
(gigabytes - 1024*1024*1024),
|
||||
.Nm %
|
||||
(percentage of free space AFTER removing any fixed-size partitions other
|
||||
than partition
|
||||
.Nm c
|
||||
), or * (all remaining free space AFTER fixed-size and percentage
|
||||
partitions). For partition
|
||||
.Nm c ,
|
||||
a size of * indicates the entire disk. Lowercase versions of K, M, and G
|
||||
are allowed.
|
||||
Size and type should be specifed without any spaces between them.
|
||||
.Pp
|
||||
Example: 2097152, 1g, 1024m and 1048576k are all the same size
|
||||
(assuming 512-byte sectors).
|
||||
.It offset
|
||||
is the offset of the start of the partition from the beginning of the drive.
|
||||
is the offset of the start of the partition from the beginning of the
|
||||
drive in sectors, or * to have
|
||||
.Nm
|
||||
calculate the correct offset to use (the end of the previous partition plus
|
||||
one, ignoring partition
|
||||
.Nm c .
|
||||
For partition
|
||||
.Nm c ,
|
||||
* will be interpreted as an offset of 0.
|
||||
.It fstype
|
||||
describes the purpose of the partition. The example shows most normal usages.
|
||||
For UFS file systems, use type 4.2BSD. See
|
||||
For UFS file systems, use type
|
||||
.Nm 4.2BSD .
|
||||
Other common types are
|
||||
.Nm unused
|
||||
and
|
||||
.Nm swap .
|
||||
See
|
||||
.Pa /usr/include/sys/disklabel.h
|
||||
for a complete list.
|
||||
.It fsize
|
||||
For file systems only, the fragment size.
|
||||
For
|
||||
.Nm 4.2BSD
|
||||
and LFS file systems only, the fragment size. Defaults to 8192 for
|
||||
partitions smaller than 1 GB, 16384 for partitions 1GB or larger.
|
||||
.It bsize
|
||||
For file systems only, the block size.
|
||||
For
|
||||
.Nm 4.2BSD
|
||||
and LFS file systems only, the block size. Defaults to 1024 for
|
||||
partitions smaller than 1 GB, 4096 for partitions 1GB or larger.
|
||||
.It bps/cpg
|
||||
For UFS file systems, the number of cylinders in a cylinder group. For LFS file
|
||||
systems, the segment shift value.
|
||||
For
|
||||
.Nm 4.2BSD
|
||||
file systems, the number of cylinders in a cylinder group. For LFS file
|
||||
systems, the segment shift value. Defaults to 16 for
|
||||
partitions smaller than 1 GB, 64 for partitions 1GB or larger.
|
||||
.El
|
||||
.Pp
|
||||
The remainder of the line is a comment and shows the cylinder allocations based
|
||||
@ -611,6 +690,13 @@ Read the on-disk label for
|
||||
edit it and reinstall in-core as well as on-disk. Existing bootstrap code is
|
||||
unaffected.
|
||||
.Pp
|
||||
.Dl disklabel -e -r -n da0s1
|
||||
.Pp
|
||||
Read the on-disk label for
|
||||
.Pa da0s1 ,
|
||||
edit it, and display what the new label would be (in sectors). It does
|
||||
NOT install the new label either in-core or on-disk.
|
||||
.Pp
|
||||
.Dl disklabel -r -w da0s1 auto
|
||||
.Pp
|
||||
Try to auto-detect the required information from
|
||||
@ -626,6 +712,15 @@ from information in
|
||||
.Pa savedlabel .
|
||||
Existing bootstrap code is unaffected.
|
||||
.Pp
|
||||
.Dl disklabel -R -n da0s1 label_layout
|
||||
.Pp
|
||||
Display what the label would be for
|
||||
.Pa da0s1
|
||||
using the partition layout in
|
||||
.Pa label_layout .
|
||||
This is useful for determining how much space would be alloted for various
|
||||
partitions with a labelling scheme using %-based or * partition sizes.
|
||||
.Pp
|
||||
.Dl disklabel -B da0s1
|
||||
.Pp
|
||||
Install a new bootstrap on
|
||||
@ -661,6 +756,40 @@ initialize the slice, then edit it to your needs. The
|
||||
.Pa dd
|
||||
commands are optional, but may be necessary for some BIOSes to properly
|
||||
recognize the disk.
|
||||
.Pp
|
||||
This is an example disklabel that uses some of the new partition size types
|
||||
such as %, M, G, and *, which could be used as a source file for
|
||||
.Pp
|
||||
.Dl disklabel -R ad0s1c new_label_file
|
||||
.Bd -literal -offset 4n
|
||||
# /dev/ad0s1c:
|
||||
type: ESDI
|
||||
disk: ad0s1
|
||||
label:
|
||||
flags:
|
||||
bytes/sector: 512
|
||||
sectors/track: 63
|
||||
tracks/cylinder: 16
|
||||
sectors/cylinder: 1008
|
||||
cylinders: 40633
|
||||
sectors/unit: 40959009
|
||||
rpm: 3600
|
||||
interleave: 1
|
||||
trackskew: 0
|
||||
cylinderskew: 0
|
||||
headswitch: 0 # milliseconds
|
||||
track-to-track seek: 0 # milliseconds
|
||||
drivedata: 0
|
||||
|
||||
8 partitions:
|
||||
# size offset fstype [fsize bsize bps/cpg]
|
||||
a: 400M 0 4.2BSD 4096 16384 75 # (Cyl. 0 - 812*)
|
||||
b: 1G * swap
|
||||
c: * * unused
|
||||
e: 204800 * 4.2BSD
|
||||
f: 5g * 4.2BSD
|
||||
g: * * 4.2BSD
|
||||
.Ed
|
||||
.Sh SEE ALSO
|
||||
.Xr disklabel 5 ,
|
||||
.Xr disktab 5 ,
|
||||
@ -723,5 +852,9 @@ concern if the disk is fully dedicated, so that the BSD disklabel
|
||||
starts at absolute block 0 on the disk.
|
||||
.Pp
|
||||
.Nm
|
||||
does not perform adequate error checking. No warning is given if partitions
|
||||
overlap, nor if space remains unused.
|
||||
does not perform all possible error checking. Warning *is* given if partitions
|
||||
overlap; if an absolute offset doesn't match the expected offset; if the
|
||||
.Nm c
|
||||
partition doesn't start at 0 or doesn't cover the entire slice; if a
|
||||
partition runs past the end of the device; and a number of other errors; but
|
||||
no warning is given if space remains unused.
|
||||
|
@ -80,6 +80,15 @@ static const char rcsid[] =
|
||||
#define BBSIZE 8192 /* size of boot area, with label */
|
||||
#endif
|
||||
|
||||
/* 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
|
||||
|
||||
#ifdef tahoe
|
||||
#define NUMBOOT 0
|
||||
#else
|
||||
@ -118,6 +127,14 @@ char namebuf[BBSIZE], *np = namebuf;
|
||||
struct disklabel lab;
|
||||
char bootarea[BBSIZE];
|
||||
|
||||
/* 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];
|
||||
|
||||
#if NUMBOOT > 0
|
||||
int installboot; /* non-zero if we should install a boot program */
|
||||
char *bootbuf; /* pointer to buffer with remainder of boot prog */
|
||||
@ -133,12 +150,13 @@ enum {
|
||||
} op = UNSPEC;
|
||||
|
||||
int rflag;
|
||||
int disable_write; /* set to disable writing to disk label */
|
||||
|
||||
#ifdef DEBUG
|
||||
int debug;
|
||||
#define OPTIONS "BNRWb:ders:w"
|
||||
#define OPTIONS "BNRWb:denrs:w"
|
||||
#else
|
||||
#define OPTIONS "BNRWb:ers:w"
|
||||
#define OPTIONS "BNRWb:enrs:w"
|
||||
#endif
|
||||
|
||||
int
|
||||
@ -171,6 +189,9 @@ main(argc, argv)
|
||||
usage();
|
||||
op = NOWRITE;
|
||||
break;
|
||||
case 'n':
|
||||
disable_write = 1;
|
||||
break;
|
||||
case 'R':
|
||||
if (op != UNSPEC)
|
||||
usage();
|
||||
@ -397,75 +418,81 @@ writelabel(f, boot, lp)
|
||||
register int i;
|
||||
#endif
|
||||
|
||||
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);
|
||||
|
||||
#ifdef __alpha__
|
||||
/*
|
||||
* 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;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 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");
|
||||
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
#if NUMBOOT > 0
|
||||
/*
|
||||
* Output the remainder of the disklabel
|
||||
*/
|
||||
if (bootbuf && write(f, bootbuf, bootsize) != bootsize) {
|
||||
warn("write");
|
||||
return(1);
|
||||
}
|
||||
#endif
|
||||
flag = 0;
|
||||
(void) ioctl(f, DIOCWLABEL, &flag);
|
||||
} else if (ioctl(f, DIOCWDINFO, lp) < 0) {
|
||||
l_perror("ioctl DIOCWDINFO");
|
||||
return (1);
|
||||
}
|
||||
#if NUMBOOT > 0
|
||||
/*
|
||||
* Output the remainder of the disklabel
|
||||
*/
|
||||
if (bootbuf && write(f, bootbuf, bootsize) != bootsize) {
|
||||
warn("write");
|
||||
return(1);
|
||||
}
|
||||
#endif
|
||||
flag = 0;
|
||||
(void) ioctl(f, DIOCWLABEL, &flag);
|
||||
} else if (ioctl(f, DIOCWDINFO, lp) < 0) {
|
||||
l_perror("ioctl DIOCWDINFO");
|
||||
return (1);
|
||||
}
|
||||
#ifdef vax
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -933,6 +960,8 @@ getasciilabel(f, lp)
|
||||
{
|
||||
register char **cpp, *cp;
|
||||
register struct partition *pp;
|
||||
int i;
|
||||
unsigned int part;
|
||||
char *tp, *s, line[BUFSIZ];
|
||||
int v, lineno = 0, errors = 0;
|
||||
|
||||
@ -1137,16 +1166,18 @@ getasciilabel(f, lp)
|
||||
lp->d_trkseek = v;
|
||||
continue;
|
||||
}
|
||||
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) {
|
||||
fprintf(stderr,
|
||||
"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);
|
||||
errors++;
|
||||
continue;
|
||||
}
|
||||
pp = &lp->d_partitions[part];
|
||||
part_set[part] = 1;
|
||||
#define NXTNUM(n) { \
|
||||
if (tp == NULL) { \
|
||||
fprintf(stderr, "line %d: too few numeric fields\n", lineno); \
|
||||
@ -1159,80 +1190,131 @@ getasciilabel(f, lp)
|
||||
(n) = atoi(cp); \
|
||||
} \
|
||||
}
|
||||
|
||||
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] != '*')) {
|
||||
fprintf(stderr,
|
||||
"line %d: %s: bad partition size\n",
|
||||
lineno, cp);
|
||||
errors++;
|
||||
} else
|
||||
break;
|
||||
} else {
|
||||
pp->p_size = v;
|
||||
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;
|
||||
|
||||
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++;
|
||||
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;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/*
|
||||
* note: we may not have
|
||||
* gotten all the entries for
|
||||
* the fs though if we didn't,
|
||||
* errors will be set.
|
||||
*/
|
||||
}
|
||||
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:
|
||||
|
||||
switch (pp->p_fstype) {
|
||||
|
||||
case FS_UNUSED: /* XXX */
|
||||
NXTNUM(pp->p_fsize);
|
||||
if (pp->p_fsize == 0)
|
||||
break;
|
||||
NXTNUM(v);
|
||||
pp->p_frag = v / pp->p_fsize;
|
||||
break;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
fprintf(stderr, "line %d: %s: Unknown disklabel field\n",
|
||||
lineno, cp);
|
||||
errors++;
|
||||
next:
|
||||
;
|
||||
next:;
|
||||
}
|
||||
errors += checklabel(lp);
|
||||
return (errors == 0);
|
||||
@ -1249,6 +1331,11 @@ checklabel(lp)
|
||||
register struct partition *pp;
|
||||
int i, errors = 0;
|
||||
char part;
|
||||
unsigned long total_size,total_percent,current_offset;
|
||||
int seen_default_offset;
|
||||
int hog_part;
|
||||
int j;
|
||||
struct partition *pp2;
|
||||
|
||||
if (lp->d_secsize == 0) {
|
||||
fprintf(stderr, "sector size 0\n");
|
||||
@ -1285,6 +1372,153 @@ checklabel(lp)
|
||||
if (lp->d_npartitions > MAXPARTITIONS)
|
||||
Warning("number of partitions (%lu) > MAXPARTITIONS (%d)",
|
||||
(u_long)lp->d_npartitions, MAXPARTITIONS);
|
||||
|
||||
/* 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 */
|
||||
for (i = 0; i < lp->d_npartitions; i++) {
|
||||
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++) {
|
||||
part = 'a' + i;
|
||||
pp = &lp->d_partitions[i];
|
||||
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];
|
||||
@ -1310,6 +1544,38 @@ checklabel(lp)
|
||||
part);
|
||||
errors++;
|
||||
}
|
||||
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++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (; i < MAXPARTITIONS; i++) {
|
||||
part = 'a' + i;
|
||||
@ -1352,11 +1618,11 @@ getvirginlabel(void)
|
||||
* fallback to the old get-disdk-info ioctl.
|
||||
*/
|
||||
if (ioctl(f, DIOCGDVIRGIN, &lab) < 0) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
close(f);
|
||||
lab.d_boot0 = NULL;
|
||||
@ -1427,25 +1693,25 @@ usage()
|
||||
fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
|
||||
"usage: disklabel [-r] disk",
|
||||
"\t\t(to read label)",
|
||||
" disklabel -w [-r] disk type [ packid ]",
|
||||
" disklabel -w [-r] [-n] disk type [ packid ]",
|
||||
"\t\t(to write label with existing boot program)",
|
||||
" disklabel -e [-r] disk",
|
||||
" disklabel -e [-r] [-n] disk",
|
||||
"\t\t(to edit label)",
|
||||
" disklabel -R [-r] disk protofile",
|
||||
" disklabel -R [-r] [-n] disk protofile",
|
||||
"\t\t(to restore label with existing boot program)",
|
||||
#if NUMBOOT > 1
|
||||
" disklabel -B [ -b boot1 [ -s boot2 ] ] disk [ type ]",
|
||||
" disklabel -B [-n] [ -b boot1 [ -s boot2 ] ] disk [ type ]",
|
||||
"\t\t(to install boot program with existing label)",
|
||||
" disklabel -w -B [ -b boot1 [ -s boot2 ] ] disk type [ packid ]",
|
||||
" disklabel -w -B [-n] [ -b boot1 [ -s boot2 ] ] disk type [ packid ]",
|
||||
"\t\t(to write label and boot program)",
|
||||
" disklabel -R -B [ -b boot1 [ -s boot2 ] ] disk protofile [ type ]",
|
||||
" disklabel -R -B [-n] [ -b boot1 [ -s boot2 ] ] disk protofile [ type ]",
|
||||
"\t\t(to restore label and boot program)",
|
||||
#else
|
||||
" disklabel -B [ -b bootprog ] disk [ type ]",
|
||||
" disklabel -B [-n] [ -b bootprog ] disk [ type ]",
|
||||
"\t\t(to install boot program with existing on-disk label)",
|
||||
" disklabel -w -B [ -b bootprog ] disk type [ packid ]",
|
||||
" disklabel -w -B [-n] [ -b bootprog ] disk type [ packid ]",
|
||||
"\t\t(to write label and install boot program)",
|
||||
" disklabel -R -B [ -b bootprog ] disk protofile [ type ]",
|
||||
" disklabel -R -B [-n] [ -b bootprog ] disk protofile [ type ]",
|
||||
"\t\t(to restore label and install boot program)",
|
||||
#endif
|
||||
" disklabel [-NW] disk",
|
||||
@ -1453,11 +1719,11 @@ usage()
|
||||
#else
|
||||
fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
|
||||
"usage: disklabel [-r] disk", "(to read label)",
|
||||
" disklabel -w [-r] disk type [ packid ]",
|
||||
" disklabel -w [-r] [-n] disk type [ packid ]",
|
||||
"\t\t(to write label)",
|
||||
" disklabel -e [-r] disk",
|
||||
" disklabel -e [-r] [-n] disk",
|
||||
"\t\t(to edit label)",
|
||||
" disklabel -R [-r] disk protofile",
|
||||
" disklabel -R [-r] [-n] disk protofile",
|
||||
"\t\t(to restore label)",
|
||||
" disklabel [-NW] disk",
|
||||
"\t\t(to write disable/enable label)");
|
||||
|
Loading…
Reference in New Issue
Block a user