diff options
author | 2008-06-25 15:26:43 +0000 | |
---|---|---|
committer | 2008-06-25 15:26:43 +0000 | |
commit | d173b22155d7cd2cb69fd36efaeb8d3d1a086ecc (patch) | |
tree | d7bd372e839e0391286d873d258dfea636556be4 | |
parent | handle sparc64 seperately; ok miod (diff) | |
download | wireguard-openbsd-d173b22155d7cd2cb69fd36efaeb8d3d1a086ecc.tar.xz wireguard-openbsd-d173b22155d7cd2cb69fd36efaeb8d3d1a086ecc.zip |
allow to install and boot the OpenBSD A6 partition and disklabel in an
extended DOS partition. the concept of extended partitions is very
simple, it is just another mbr at the partition offset (well, the
standard "EBR" is a linked list with a few limitations, but this diff
works with both variants).
this diff has been in the snapshots for a while.
with input from weingart@ and krw@
ok deraadt@
-rw-r--r-- | sbin/disklabel/disklabel.c | 78 | ||||
-rw-r--r-- | sys/arch/amd64/stand/installboot/installboot.c | 83 | ||||
-rw-r--r-- | sys/arch/amd64/stand/libsa/biosdev.c | 99 | ||||
-rw-r--r-- | sys/arch/i386/stand/installboot/installboot.c | 83 | ||||
-rw-r--r-- | sys/arch/i386/stand/libsa/biosdev.c | 99 | ||||
-rw-r--r-- | sys/kern/subr_disk.c | 22 |
6 files changed, 344 insertions, 120 deletions
diff --git a/sbin/disklabel/disklabel.c b/sbin/disklabel/disklabel.c index 3352bff5c00..21782ce453d 100644 --- a/sbin/disklabel/disklabel.c +++ b/sbin/disklabel/disklabel.c @@ -1,4 +1,4 @@ -/* $OpenBSD: disklabel.c,v 1.128 2008/06/04 01:27:54 deraadt Exp $ */ +/* $OpenBSD: disklabel.c,v 1.129 2008/06/25 15:26:43 reyk Exp $ */ /* * Copyright (c) 1987, 1993 @@ -39,7 +39,7 @@ static const char copyright[] = #endif /* not lint */ #ifndef lint -static const char rcsid[] = "$OpenBSD: disklabel.c,v 1.128 2008/06/04 01:27:54 deraadt Exp $"; +static const char rcsid[] = "$OpenBSD: disklabel.c,v 1.129 2008/06/25 15:26:43 reyk Exp $"; #endif /* not lint */ #include <sys/param.h> @@ -113,6 +113,7 @@ int donothing; #ifdef DOSLABEL struct dos_partition *dosdp; /* DOS partition, if found */ +struct dos_partition *findopenbsd(int, off_t, struct dos_partition **, int *); struct dos_partition *readmbr(int); #endif @@ -525,23 +526,25 @@ l_perror(char *s) } #ifdef DOSLABEL -/* - * Fetch DOS partition table from disk. - */ struct dos_partition * -readmbr(int f) +findopenbsd(int f, off_t mbroff, struct dos_partition **first, int *n) { static int mbr[DEV_BSIZE / sizeof(int)]; - struct dos_partition *dp; + struct dos_partition *dp, *p; u_int16_t signature; + u_int32_t start = 0; int part; + /* Limit the number of recursions */ + if (!(*n)--) + return (NULL); + /* * This must be done this way due to alignment restrictions * in for example mips processors. */ dp = (struct dos_partition *)mbr; - if (lseek(f, (off_t)DOSBBSECTOR * DEV_BSIZE, SEEK_SET) < 0 || + if (lseek(f, (off_t)mbroff * DEV_BSIZE, SEEK_SET) < 0 || read(f, mbr, sizeof(mbr)) != sizeof(mbr)) return (NULL); signature = *((u_char *)mbr + DOSMBR_SIGNATURE_OFF) | @@ -549,39 +552,72 @@ readmbr(int f) bcopy((char *)mbr+DOSPARTOFF, (char *)mbr, sizeof(*dp) * NDOSPART); /* + * If there is no signature and no OpenBSD partition this is probably + * not an MBR. + */ + if (signature != DOSMBR_SIGNATURE) + return (NULL); + + /* * Don't (yet) know disk geometry, use partition table to find OpenBSD * partition, and obtain disklabel from there. */ /* Check if table is valid. */ for (part = 0; part < NDOSPART; part++) { if ((dp[part].dp_flag & ~0x80) != 0) - return (0); + return (NULL); } /* Find OpenBSD partition. */ for (part = 0; part < NDOSPART; part++) { - if (letoh32(dp[part].dp_size) && dp[part].dp_typ == DOSPTYP_OPENBSD) { + if (!letoh32(dp[part].dp_size)) + continue; + if (first && *first == NULL) + *first = &dp[part]; + switch (dp[part].dp_typ) { + case DOSPTYP_OPENBSD: fprintf(stderr, "# Inside MBR partition %d: " "type %02X start %u size %u\n", part, dp[part].dp_typ, letoh32(dp[part].dp_start), letoh32(dp[part].dp_size)); return (&dp[part]); + case DOSPTYP_EXTENDL: + fprintf(stderr, "# Extended partition %d: " + "type %02X start %u size %u\n", + part, dp[part].dp_typ, + letoh32(dp[part].dp_start), letoh32(dp[part].dp_size)); + start = letoh32(dp[part].dp_start); + p = findopenbsd(f, start, NULL, n); + if (p != NULL) { + p->dp_start = + htole32(letoh32(p->dp_start) + start); + return (p); + } + break; } } - /* - * If there is no signature and no OpenBSD partition this is probably - * not an MBR. - */ - if (signature != DOSMBR_SIGNATURE) - return (NULL); + return (NULL); +} + +/* + * Fetch DOS partition table from disk. + */ +struct dos_partition * +readmbr(int f) +{ + struct dos_partition *dp, *first; + int part, n = 8; + + dp = findopenbsd(f, DOSBBSECTOR, &first, &n); + if (dp != NULL) + return (dp); /* If no OpenBSD partition, find first used partition. */ - for (part = 0; part < NDOSPART; part++) { - if (letoh32(dp[part].dp_size)) { - warnx("warning, DOS partition table with no valid OpenBSD partition"); - return (&dp[part]); - } + if (first != NULL) { + warnx("warning, DOS partition table with no valid OpenBSD partition"); + return (first); } + /* Table appears to be empty. */ return (NULL); } diff --git a/sys/arch/amd64/stand/installboot/installboot.c b/sys/arch/amd64/stand/installboot/installboot.c index 85bc9bf0399..88f134a0094 100644 --- a/sys/arch/amd64/stand/installboot/installboot.c +++ b/sys/arch/amd64/stand/installboot/installboot.c @@ -1,4 +1,4 @@ -/* $OpenBSD: installboot.c,v 1.8 2008/01/24 12:09:53 krw Exp $ */ +/* $OpenBSD: installboot.c,v 1.9 2008/06/25 15:26:44 reyk Exp $ */ /* $NetBSD: installboot.c,v 1.5 1995/11/17 23:23:50 gwr Exp $ */ /* @@ -98,6 +98,7 @@ static void devread(int, void *, daddr_t, size_t, char *); static void sym_set_value(struct sym_data *, char *, u_int32_t); static void pbr_set_symbols(char *, char *, struct sym_data *); static void usage(void); +static long findopenbsd(int, struct disklabel *, off_t, int *); static void usage(void) @@ -120,9 +121,9 @@ main(int argc, char *argv[]) long protosize; struct stat sb; struct disklabel dl; - struct dos_mbr mbr; - struct dos_partition *dp; off_t startoff = 0; + long start = 0; + int n = 8; while ((c = getopt(argc, argv, "vn")) != -1) { switch (c) { @@ -200,29 +201,11 @@ main(int argc, char *argv[]) if (dl.d_type != 0 && dl.d_type != DTYPE_FLOPPY && dl.d_type != DTYPE_VND) { - if (lseek(devfd, (off_t)DOSBBSECTOR, SEEK_SET) < 0 || - read(devfd, &mbr, sizeof(mbr)) != sizeof(mbr)) - err(4, "can't read master boot record"); - - if (mbr.dmbr_sign != DOSMBR_SIGNATURE) - errx(1, "broken MBR"); - /* Find OpenBSD partition. */ - for (dp = mbr.dmbr_parts; dp < &mbr.dmbr_parts[NDOSPART]; - dp++) { - if (dp->dp_size && dp->dp_typ == DOSPTYP_OPENBSD) { - startoff = (off_t)dp->dp_start * dl.d_secsize; - fprintf(stderr, "using MBR partition %ld: " - "type %d (0x%02x) offset %d (0x%x)\n", - (long)(dp - mbr.dmbr_parts), - dp->dp_typ, dp->dp_typ, - dp->dp_start, dp->dp_start); - break; - } - } - /* Don't check for old part number, that is ;-p */ - if (dp >= &mbr.dmbr_parts[NDOSPART]) - errx(1, "no OpenBSD partition"); + start = findopenbsd(devfd, &dl, (off_t)DOSBBSECTOR, &n); + if (start == -1) + errx(1, "no OpenBSD partition"); + startoff = (off_t)start * dl.d_secsize; } if (!nowrite) { @@ -236,6 +219,56 @@ main(int argc, char *argv[]) return 0; } +long +findopenbsd(int devfd, struct disklabel *dl, off_t mbroff, int *n) +{ + struct dos_mbr mbr; + struct dos_partition *dp; + off_t startoff; + long start; + + /* Limit the number of recursions */ + if (!(*n)--) + return (-1); + + if (lseek(devfd, mbroff, SEEK_SET) < 0 || + read(devfd, &mbr, sizeof(mbr)) != sizeof(mbr)) + err(4, "can't read master boot record"); + + if (mbr.dmbr_sign != DOSMBR_SIGNATURE) + errx(1, "broken MBR"); + + for (dp = mbr.dmbr_parts; dp < &mbr.dmbr_parts[NDOSPART]; + dp++) { + if (!dp->dp_size) + continue; + startoff = (off_t)dp->dp_start * dl->d_secsize; + if (dp->dp_typ == DOSPTYP_OPENBSD) { + fprintf(stderr, "using MBR partition %ld: " + "type %d (0x%02x) offset %d (0x%x)\n", + (long)(dp - mbr.dmbr_parts), + dp->dp_typ, dp->dp_typ, + dp->dp_start, dp->dp_start); + break; + } else if (dp->dp_typ == DOSPTYP_EXTEND || + dp->dp_typ == DOSPTYP_EXTENDL) { + fprintf(stderr, "extended partition %ld: " + "type %d (0x%02x) offset %d (0x%x)\n", + (long)(dp - mbr.dmbr_parts), + dp->dp_typ, dp->dp_typ, + dp->dp_start, dp->dp_start); + start = findopenbsd(devfd, dl, startoff, n); + if (start != -1) + return (dp->dp_start + start); + } + } + /* Don't check for old part number, that is ;-p */ + if (dp >= &mbr.dmbr_parts[NDOSPART]) + return (-1); + + return (dp->dp_start); +} + /* * Load the prototype boot sector (biosboot) into memory. */ diff --git a/sys/arch/amd64/stand/libsa/biosdev.c b/sys/arch/amd64/stand/libsa/biosdev.c index 696acf81d24..0e4439c8296 100644 --- a/sys/arch/amd64/stand/libsa/biosdev.c +++ b/sys/arch/amd64/stand/libsa/biosdev.c @@ -1,4 +1,4 @@ -/* $OpenBSD: biosdev.c,v 1.4 2007/04/04 14:36:05 jmc Exp $ */ +/* $OpenBSD: biosdev.c,v 1.5 2008/06/25 15:26:44 reyk Exp $ */ /* * Copyright (c) 1996 Michael Shalayeff @@ -45,6 +45,9 @@ static int biosdisk_errno(u_int); static int CHS_rw (int, int, int, int, int, int, void *); static int EDD_rw (int, int, u_int64_t, u_int32_t, void *); +static daddr_t findopenbsd(bios_diskinfo_t *, daddr_t, daddr_t *, + const char **, int *); + extern int debug; int bios_bootdev; int bios_cddev = -1; /* Set by srt0 if coming from CD */ @@ -335,13 +338,76 @@ biosd_io(int rw, bios_diskinfo_t *bd, daddr_t off, int nsect, void *buf) /* * Try to read the bsd label on the given BIOS device */ +static daddr_t +findopenbsd(bios_diskinfo_t *bd, daddr_t off, daddr_t *roff, const char **err, + int *n) +{ + int error, i; + struct dos_mbr mbr; + struct dos_partition *dp; + + /* Limit the number of recursions */ + if (!(*n)--) { + *err = "too many extended partitions"; + return (0); + } + + /* Read MBR */ + error = biosd_io(F_READ, bd, off, 1, &mbr); + if (error) { + *err = biosdisk_err(error); + return (0); + } + + /* check mbr signature */ + if (mbr.dmbr_sign != DOSMBR_SIGNATURE) { + *err = "bad MBR signature\n"; + return (0); + } + + /* Search for OpenBSD partition */ + for (off = 0, i = 0; off == 0 && i < NDOSPART; i++) { + dp = &mbr.dmbr_parts[i]; +#ifdef BIOS_DEBUG + if (debug) + printf("found partition %u: " + "type %u (0x%x) offset %u (0x%x)\n", + (int)(dp - mbr.dmbr_parts), + dp->dp_typ, dp->dp_typ, + dp->dp_start, dp->dp_start); +#endif + if (dp->dp_typ == DOSPTYP_OPENBSD) + off = dp->dp_start; + else if (dp->dp_typ == DOSPTYP_EXTEND || + dp->dp_typ == DOSPTYP_EXTENDL) { + off = findopenbsd(bd, dp->dp_start, roff, err, n); + if (off != 0) + *roff = dp->dp_start; + } + } + +#ifdef BIOS_DEBUG + if (debug) + printf("using offset %u\n", off); +#endif + + if (off == 0) { + if (*err == NULL) + *err = "no OpenBSD partition\n"; + return (0); + } + + return (off); +} + const char * bios_getdisklabel(bios_diskinfo_t *bd, struct disklabel *label) { - daddr_t off = LABELSECTOR; + daddr_t off = 0, roff = 0; char *buf; - struct dos_mbr mbr; - int error, i; + const char *err = NULL; + int error; + int n = 8; /* Sanity check */ if(bd->bios_heads == 0 || bd->bios_sectors == 0) @@ -349,23 +415,14 @@ bios_getdisklabel(bios_diskinfo_t *bd, struct disklabel *label) /* MBR is a harddisk thing */ if (bd->bios_number & 0x80) { - /* Read MBR */ - error = biosd_io(F_READ, bd, DOSBBSECTOR, 1, &mbr); - if (error) - return(biosdisk_err(error)); - - /* check mbr signature */ - if (mbr.dmbr_sign != DOSMBR_SIGNATURE) - return("bad MBR signature\n"); - - /* Search for OpenBSD partition */ - for (off = 0, i = 0; off == 0 && i < NDOSPART; i++) - if (mbr.dmbr_parts[i].dp_typ == DOSPTYP_OPENBSD) - off = mbr.dmbr_parts[i].dp_start + LABELSECTOR; - if (off == 0) - return("no OpenBSD partition\n"); - } else - off = LABELSECTOR; + off = findopenbsd(bd, DOSBBSECTOR, &roff, &err, &n); + if (off == 0) { + if (err != NULL) + return (err); + return "no OpenBSD partition\n"; + } + } + off = LABELSECTOR + off + roff; /* Load BSD disklabel */ buf = alloca(DEV_BSIZE); diff --git a/sys/arch/i386/stand/installboot/installboot.c b/sys/arch/i386/stand/installboot/installboot.c index d8c7a7daa3a..d0a450147a1 100644 --- a/sys/arch/i386/stand/installboot/installboot.c +++ b/sys/arch/i386/stand/installboot/installboot.c @@ -1,4 +1,4 @@ -/* $OpenBSD: installboot.c,v 1.51 2008/01/24 12:09:54 krw Exp $ */ +/* $OpenBSD: installboot.c,v 1.52 2008/06/25 15:26:44 reyk Exp $ */ /* $NetBSD: installboot.c,v 1.5 1995/11/17 23:23:50 gwr Exp $ */ /* @@ -94,6 +94,7 @@ static void devread(int, void *, daddr_t, size_t, char *); static void sym_set_value(struct sym_data *, char *, u_int32_t); static void pbr_set_symbols(char *, char *, struct sym_data *); static void usage(void); +static long findopenbsd(int, struct disklabel *, off_t, int *); static void usage(void) @@ -116,9 +117,9 @@ main(int argc, char *argv[]) long protosize; struct stat sb; struct disklabel dl; - struct dos_mbr mbr; - struct dos_partition *dp; off_t startoff = 0; + long start = 0; + int n = 8; while ((c = getopt(argc, argv, "vn")) != -1) { switch (c) { @@ -196,29 +197,11 @@ main(int argc, char *argv[]) if (dl.d_type != 0 && dl.d_type != DTYPE_FLOPPY && dl.d_type != DTYPE_VND) { - if (lseek(devfd, (off_t)DOSBBSECTOR, SEEK_SET) < 0 || - read(devfd, &mbr, sizeof(mbr)) != sizeof(mbr)) - err(4, "can't read master boot record"); - - if (mbr.dmbr_sign != DOSMBR_SIGNATURE) - errx(1, "broken MBR"); - /* Find OpenBSD partition. */ - for (dp = mbr.dmbr_parts; dp < &mbr.dmbr_parts[NDOSPART]; - dp++) { - if (dp->dp_size && dp->dp_typ == DOSPTYP_OPENBSD) { - startoff = (off_t)dp->dp_start * dl.d_secsize; - fprintf(stderr, "using MBR partition %ld: " - "type %d (0x%02x) offset %d (0x%x)\n", - (long)(dp - mbr.dmbr_parts), - dp->dp_typ, dp->dp_typ, - dp->dp_start, dp->dp_start); - break; - } - } - /* Don't check for old part number, that is ;-p */ - if (dp >= &mbr.dmbr_parts[NDOSPART]) - errx(1, "no OpenBSD partition"); + start = findopenbsd(devfd, &dl, (off_t)DOSBBSECTOR, &n); + if (start == -1) + errx(1, "no OpenBSD partition"); + startoff = (off_t)start * dl.d_secsize; } if (!nowrite) { @@ -232,6 +215,56 @@ main(int argc, char *argv[]) return 0; } +long +findopenbsd(int devfd, struct disklabel *dl, off_t mbroff, int *n) +{ + struct dos_mbr mbr; + struct dos_partition *dp; + off_t startoff; + long start; + + /* Limit the number of recursions */ + if (!(*n)--) + return (-1); + + if (lseek(devfd, mbroff, SEEK_SET) < 0 || + read(devfd, &mbr, sizeof(mbr)) != sizeof(mbr)) + err(4, "can't read master boot record"); + + if (mbr.dmbr_sign != DOSMBR_SIGNATURE) + errx(1, "broken MBR"); + + for (dp = mbr.dmbr_parts; dp < &mbr.dmbr_parts[NDOSPART]; + dp++) { + if (!dp->dp_size) + continue; + startoff = (off_t)dp->dp_start * dl->d_secsize; + if (dp->dp_typ == DOSPTYP_OPENBSD) { + fprintf(stderr, "using MBR partition %ld: " + "type %d (0x%02x) offset %d (0x%x)\n", + (long)(dp - mbr.dmbr_parts), + dp->dp_typ, dp->dp_typ, + dp->dp_start, dp->dp_start); + break; + } else if (dp->dp_typ == DOSPTYP_EXTEND || + dp->dp_typ == DOSPTYP_EXTENDL) { + fprintf(stderr, "extended partition %ld: " + "type %d (0x%02x) offset %d (0x%x)\n", + (long)(dp - mbr.dmbr_parts), + dp->dp_typ, dp->dp_typ, + dp->dp_start, dp->dp_start); + start = findopenbsd(devfd, dl, startoff, n); + if (start != -1) + return (dp->dp_start + start); + } + } + /* Don't check for old part number, that is ;-p */ + if (dp >= &mbr.dmbr_parts[NDOSPART]) + return (-1); + + return (dp->dp_start); +} + /* * Load the prototype boot sector (biosboot) into memory. */ diff --git a/sys/arch/i386/stand/libsa/biosdev.c b/sys/arch/i386/stand/libsa/biosdev.c index 4d6348a8c72..9603fcb8ddd 100644 --- a/sys/arch/i386/stand/libsa/biosdev.c +++ b/sys/arch/i386/stand/libsa/biosdev.c @@ -1,4 +1,4 @@ -/* $OpenBSD: biosdev.c,v 1.72 2007/05/27 00:57:17 tom Exp $ */ +/* $OpenBSD: biosdev.c,v 1.73 2008/06/25 15:26:44 reyk Exp $ */ /* * Copyright (c) 1996 Michael Shalayeff @@ -46,6 +46,9 @@ static int biosdisk_errno(u_int); static int CHS_rw (int, int, int, int, int, int, void *); static int EDD_rw (int, int, u_int64_t, u_int32_t, void *); +static daddr_t findopenbsd(bios_diskinfo_t *, daddr_t, daddr_t *, + const char **, int *); + extern int debug; int bios_bootdev; int bios_cddev = -1; /* Set by srt0 if coming from CD */ @@ -338,13 +341,76 @@ biosd_io(int rw, bios_diskinfo_t *bd, daddr_t off, int nsect, void *buf) /* * Try to read the bsd label on the given BIOS device */ +static daddr_t +findopenbsd(bios_diskinfo_t *bd, daddr_t off, daddr_t *roff, const char **err, + int *n) +{ + int error, i; + struct dos_mbr mbr; + struct dos_partition *dp; + + /* Limit the number of recursions */ + if (!(*n)--) { + *err = "too many extended partitions"; + return (0); + } + + /* Read MBR */ + error = biosd_io(F_READ, bd, off, 1, &mbr); + if (error) { + *err = biosdisk_err(error); + return (0); + } + + /* check mbr signature */ + if (mbr.dmbr_sign != DOSMBR_SIGNATURE) { + *err = "bad MBR signature\n"; + return (0); + } + + /* Search for OpenBSD partition */ + for (off = 0, i = 0; off == 0 && i < NDOSPART; i++) { + dp = &mbr.dmbr_parts[i]; +#ifdef BIOS_DEBUG + if (debug) + printf("found partition %u: " + "type %u (0x%x) offset %u (0x%x)\n", + (int)(dp - mbr.dmbr_parts), + dp->dp_typ, dp->dp_typ, + dp->dp_start, dp->dp_start); +#endif + if (dp->dp_typ == DOSPTYP_OPENBSD) + off = dp->dp_start; + else if (dp->dp_typ == DOSPTYP_EXTEND || + dp->dp_typ == DOSPTYP_EXTENDL) { + off = findopenbsd(bd, dp->dp_start, roff, err, n); + if (off != 0) + *roff = dp->dp_start; + } + } + +#ifdef BIOS_DEBUG + if (debug) + printf("using offset %u\n", off); +#endif + + if (off == 0) { + if (*err == NULL) + *err = "no OpenBSD partition\n"; + return (0); + } + + return (off); +} + const char * bios_getdisklabel(bios_diskinfo_t *bd, struct disklabel *label) { - daddr_t off = LABELSECTOR; + daddr_t off = 0, roff = 0; char *buf; - struct dos_mbr mbr; - int error, i; + const char *err = NULL; + int error; + int n = 8; /* Sanity check */ if (bd->bios_heads == 0 || bd->bios_sectors == 0) @@ -352,23 +418,14 @@ bios_getdisklabel(bios_diskinfo_t *bd, struct disklabel *label) /* MBR is a harddisk thing */ if (bd->bios_number & 0x80) { - /* Read MBR */ - error = biosd_io(F_READ, bd, DOSBBSECTOR, 1, &mbr); - if (error) - return (biosdisk_err(error)); - - /* check mbr signature */ - if (mbr.dmbr_sign != DOSMBR_SIGNATURE) - return "bad MBR signature\n"; - - /* Search for OpenBSD partition */ - for (off = 0, i = 0; off == 0 && i < NDOSPART; i++) - if (mbr.dmbr_parts[i].dp_typ == DOSPTYP_OPENBSD) - off = mbr.dmbr_parts[i].dp_start + LABELSECTOR; - if (off == 0) - return "no OpenBSD partition\n"; - } else - off = LABELSECTOR; + off = findopenbsd(bd, DOSBBSECTOR, &roff, &err, &n); + if (off == 0) { + if (err != NULL) + return (err); + return "no OpenBSD partition\n"; + } + } + off = LABELSECTOR + off + roff; /* Load BSD disklabel */ buf = alloca(DEV_BSIZE); diff --git a/sys/kern/subr_disk.c b/sys/kern/subr_disk.c index e3d80ae69ff..186ff615e10 100644 --- a/sys/kern/subr_disk.c +++ b/sys/kern/subr_disk.c @@ -1,4 +1,4 @@ -/* $OpenBSD: subr_disk.c,v 1.78 2008/06/12 06:58:39 deraadt Exp $ */ +/* $OpenBSD: subr_disk.c,v 1.79 2008/06/25 15:26:43 reyk Exp $ */ /* $NetBSD: subr_disk.c,v 1.17 1996/03/16 23:17:08 christos Exp $ */ /* @@ -409,7 +409,7 @@ readdoslabel(struct buf *bp, void (*strat)(struct buf *), bcopy(bp->b_data + DOSPARTOFF, dp, sizeof(dp)); - if (ourpart == -1 && part_blkno == DOSBBSECTOR) { + if (ourpart == -1) { /* Search for our MBR partition */ for (dp2=dp, i=0; i < NDOSPART && ourpart == -1; i++, dp2++) @@ -454,11 +454,6 @@ donot: continue; if (letoh32(dp2->dp_size) == 0) continue; - if (letoh32(dp2->dp_start)) - DL_SETPOFFSET(pp, - letoh32(dp2->dp_start) + part_blkno); - - DL_SETPSIZE(pp, letoh32(dp2->dp_size)); switch (dp2->dp_typ) { case DOSPTYP_UNUSED: @@ -499,6 +494,19 @@ donot: n++; break; } + + /* + * There is no need to set the offset/size when + * wandering; it would also invalidate the + * disklabel checksum. + */ + if (wander) + continue; + + if (letoh32(dp2->dp_start)) + DL_SETPOFFSET(pp, + letoh32(dp2->dp_start) + part_blkno); + DL_SETPSIZE(pp, letoh32(dp2->dp_size)); } } lp->d_npartitions = MAXPARTITIONS; |