aboutsummaryrefslogtreecommitdiffstats
path: root/sbin/disklabel/disklabel.c
diff options
context:
space:
mode:
Diffstat (limited to 'sbin/disklabel/disklabel.c')
-rw-r--r--sbin/disklabel/disklabel.c113
1 files changed, 88 insertions, 25 deletions
diff --git a/sbin/disklabel/disklabel.c b/sbin/disklabel/disklabel.c
index f8810370dd6a..4fd3bbdcd58e 100644
--- a/sbin/disklabel/disklabel.c
+++ b/sbin/disklabel/disklabel.c
@@ -88,13 +88,14 @@ static char sccsid[] = "@(#)disklabel.c 5.20 (Berkeley) 2/9/91";
#define RAWPARTITION 'c'
#endif
-#if defined(i386)
+#if defined(__386BSD__)
/* with 386BSD, 'c' maps the portion of the disk given over to 386BSD,
and 'd' maps the entire drive, ignoring any partition tables */
+#define LABELPARTITION ('c' - 'a')
#define RAWPARTITION 'd'
#endif
-#if defined(vax)==0 && defined(i386)==0
+#ifndef RAWPARTITION
#define RAWPARTITION 'a'
#endif
@@ -102,7 +103,7 @@ static char sccsid[] = "@(#)disklabel.c 5.20 (Berkeley) 2/9/91";
#define BBSIZE 8192 /* size of boot area, with label */
#endif
-#if defined(vax) || defined(i386)
+#if defined(vax) || defined(__386BSD__)
#define BOOT /* also have bootstrap in "boot area" */
#define BOOTDIR _PATH_BOOTDIR /* source of boot binaries */
#else
@@ -226,12 +227,14 @@ main(argc, argv)
* partition.
*/
dosdp = readmbr(f);
+#ifdef notdef /* not used (some bootstraps copy wd tables to 0x300) */
{ int mfd; unsigned char params[0x10];
/* sleezy, but we need it fast! */
mfd = open("/dev/mem", 0);
lseek(mfd, 0x300, 0);
read (mfd, params, 0x10);
}
+#endif
#endif
@@ -240,6 +243,19 @@ main(argc, argv)
if (argc != 1)
usage();
lp = readlabel(f);
+ if (lp == NULL) {
+ /*
+ * It's too much trouble to make -e -r work
+ * when there is no on-disk label.
+ *
+ * XXX -e without -r will fail if there is no
+ * on-disk label, but not until the user has
+ * wasted time editing the in-core label.
+ */
+ errno = ESRCH;
+ l_perror("-e flag is not suitable");
+ exit(1);
+ }
error = edit(lp, f);
break;
case NOWRITE: {
@@ -253,6 +269,12 @@ main(argc, argv)
usage();
lp = readlabel(f);
+ if (lp == NULL) {
+ fprintf(stderr,
+ "Ignoring -r and trying to read in-core label\n");
+ rflag = 0;
+ lp = readlabel(f);
+ }
display(stdout, lp);
error = checklabel(lp);
break;
@@ -370,7 +392,7 @@ writelabel(f, boot, lp)
register int i;
int flag;
#ifdef __386BSD__
- off_t lbl_off; struct partition *pp = lp->d_partitions;
+ off_t lbl_off; struct partition *pp = lp->d_partitions + LABELPARTITION;
#endif
lp->d_magic = DISKMAGIC;
@@ -385,7 +407,7 @@ writelabel(f, boot, lp)
* the label to be written is not within partition,
* prompt first. Need to allow this in case operator
* wants to convert the drive for dedicated use.
- * In this case, partition 'a' had better start at 0,
+ * In this case, partition 'c' had better start at 0,
* otherwise we reject the request as meaningless. -wfj
*/
@@ -394,15 +416,15 @@ writelabel(f, boot, lp)
lbl_off = pp->p_offset;
} else {
if (dosdp) {
- char c;
+ int c;
- printf("overwriting disk with DOS partition table? (n):");
+ printf("overwrite DOS partition table? [n]: ");
fflush(stdout);
c = getchar();
- if (c != EOF && c != (int)'\n')
- while (getchar() != (int)'\n')
+ if (c != EOF && c != '\n')
+ while (getchar() != '\n')
;
- if (c == (int)'n')
+ if (c != 'y')
exit(0);
}
lbl_off = 0;
@@ -444,10 +466,23 @@ writelabel(f, boot, lp)
if (lp->d_type != DTYPE_SCSI && lp->d_flags & D_BADSECT) {
daddr_t alt;
- alt = lp->d_ncylinders * lp->d_secpercyl - lp->d_nsectors;
+ /*
+ * XXX this knows too much about bad144 internals
+ */
+#ifdef __386BSD__
+#define BAD144_PART 2 /* XXX scattered magic numbers */
+#define BSD_PART 0 /* XXX should be 2 but bad144.c uses 0 */
+ if (lp->d_partitions[BSD_PART].p_offset != 0)
+ alt = lp->d_partitions[BAD144_PART].p_offset
+ + lp->d_partitions[BAD144_PART].p_size;
+ else
+#endif
+ alt = lp->d_secperunit;
+ alt -= lp->d_nsectors;
for (i = 1; i < 11 && i < lp->d_nsectors; i += 2) {
- (void)lseek(f, (off_t)((alt + i) * lp->d_secsize), L_SET);
- if (write(f, boot, lp->d_secsize) < lp->d_secsize) {
+ lseek(f, (off_t)((alt + i) * lp->d_secsize), L_SET);
+ if (write(f, boot + (LABELSECTOR * lp->d_secsize),
+ lp->d_secsize) < lp->d_secsize) {
int oerrno = errno;
fprintf(stderr, "alternate label %d ", i/2);
errno = oerrno;
@@ -471,7 +506,7 @@ l_perror(s)
case ESRCH:
fprintf(stderr, "No disk label on disk;\n");
fprintf(stderr,
- "use \"disklabel -r\" to install initial label\n");
+ "use flags \"-w -r\" or \"-R -r\" to install initial label\n");
break;
case EINVAL:
@@ -506,7 +541,7 @@ readmbr(f)
{
static struct dos_partition dos_partitions[NDOSPART];
struct dos_partition *dp, *bsdp;
- char mbr[DEV_BSIZE];
+ char mbr[DEV_BSIZE]; /* XXX - DOS_DEV_BSIZE */
int i, npart, nboot, njunk;
(void)lseek(f, (off_t)DOSBBSECTOR, L_SET);
@@ -519,6 +554,10 @@ readmbr(f)
* Don't (yet) know disk geometry (BIOS), use
* partition table to find 386BSD partition, and obtain
* disklabel from there.
+ *
+ * XXX - the checks for a valid partition table are inadequate.
+ * This gets called for floppies, which will never have an mbr
+ * and may have junk that looks like a partition table...
*/
dp = dos_partitions;
npart = njunk = nboot = 0;
@@ -533,6 +572,11 @@ readmbr(f)
}
/* valid partition table? */
+ /*
+ * XXX - ignore `nboot'. Drives other than the first do not need a
+ * boot flag. The first drive doesn't need a boot flag when it is
+ * booted from a multi-boot program.
+ */
if (npart == 0 || njunk) /* 18 Sep 92*/
/* was: if (nboot != 1 || npart == 0 || njunk)*/
return (0);
@@ -579,12 +623,9 @@ readlabel(f)
dkcksum(lp) != 0) {
fprintf(stderr,
"Bad pack magic number (label is damaged, or pack is unlabeled)\n");
- /* lp = (struct disklabel *)(bootarea + LABELOFFSET);
- exit (1); */
- goto tryioctl;
+ return (NULL);
}
} else {
-tryioctl:
lp = &lab;
if (ioctl(f, DIOCGDINFO, lp) < 0)
Perror("ioctl DIOCGDINFO");
@@ -746,7 +787,7 @@ display(f, lp)
(pp->p_offset +
pp->p_size + lp->d_secpercyl - 1) /
lp->d_secpercyl - 1);
- if (pp->p_size % lp->d_secpercyl)
+ if ((pp->p_offset + pp->p_size) % lp->d_secpercyl)
putc('*', f);
fprintf(f, ")\n");
}
@@ -791,10 +832,10 @@ edit(lp, f)
}
printf("re-edit the label? [y]: "); fflush(stdout);
c = getchar();
- if (c != EOF && c != (int)'\n')
- while (getchar() != (int)'\n')
+ if (c != EOF && c != '\n')
+ while (getchar() != '\n')
;
- if (c == (int)'n')
+ if (c == 'n')
break;
}
(void) unlink(tmpfil);
@@ -1169,6 +1210,7 @@ checklabel(lp)
register struct partition *pp;
int i, errors = 0;
char part;
+ unsigned long secper;
if (lp->d_secsize == 0) {
fprintf(stderr, "sector size %d\n", lp->d_secsize);
@@ -1188,10 +1230,31 @@ checklabel(lp)
}
if (lp->d_rpm == 0)
Warning("revolutions/minute %d\n", lp->d_rpm);
+ secper = lp->d_nsectors * lp->d_ntracks;
if (lp->d_secpercyl == 0)
- lp->d_secpercyl = lp->d_nsectors * lp->d_ntracks;
+ lp->d_secpercyl = secper;
+ else if (lp->d_secpercyl != secper) {
+ fprintf(stderr, "sectors/cylinder %lu should be %lu\n",
+ lp->d_secpercyl, secper);
+ errors++;
+ }
+ secper = lp->d_secpercyl * lp->d_ncylinders;
if (lp->d_secperunit == 0)
- lp->d_secperunit = lp->d_secpercyl * lp->d_ncylinders;
+ lp->d_secperunit = secper;
+ else if (lp->d_secperunit != secper) {
+ /*
+ * lp->d_secperunit makes sense as a limit on the disk size
+ * independent of the product. However, bad144 handling at
+ * least requires it to be the same as the product, and the
+ * "whole disk" partition may be used to limit the size.
+ *
+ * XXX It's silly to accept derived quantities as input only
+ * to reject them.
+ */
+ fprintf(stderr, "sectors/unit %lu should be %lu\n",
+ lp->d_secperunit, secper);
+ errors++;
+ }
#ifdef __386BSD__notyet
if (dosdp && dosdp->dp_size && dosdp->dp_typ == DOSPTYP_386BSD
&& lp->d_secperunit > dosdp->dp_start + dosdp->dp_size) {