Index: mbrlabel.c =================================================================== RCS file: /cvsroot/src/sbin/mbrlabel/mbrlabel.c,v retrieving revision 1.28 diff -p -u -r1.28 mbrlabel.c --- mbrlabel.c 14 Jul 2012 20:14:17 -0000 1.28 +++ mbrlabel.c 17 Feb 2018 12:06:05 -0000 @@ -116,20 +116,32 @@ getlong(void *p) static int getparts(int sd, u_int32_t off, u_int32_t extoff, int verbose) { - unsigned char buf[DEV_BSIZE]; + unsigned char *buf; struct mbr_partition parts[MBR_PART_COUNT]; struct partition npe; off_t loff; int i, j, unused, changed; + unsigned bsize = label.d_secsize; + + if (bsize < DEV_BSIZE) { + fprintf(stderr,"Invalid sector size %u\n", bsize); + exit(1); + } + + buf = malloc(bsize); + if (buf == NULL) { + perror("malloc I/O buffer"); + exit(1); + } changed = 0; - loff = (off_t)off * DEV_BSIZE; + loff = (off_t)off * bsize; if (lseek(sd, loff, SEEK_SET) != loff) { perror("seek label"); exit(1); } - if (read(sd, buf, sizeof buf) != DEV_BSIZE) { + if (read(sd, buf, bsize) != bsize) { if (off != MBR_BBSECTOR) perror("read label (sector is possibly out of " "range)"); @@ -160,31 +172,50 @@ getparts(int sd, u_int32_t off, u_int32_ "Found %s partition; size %u (%u MB), offset %u\n", fstypenames[npe.p_fstype], npe.p_size, npe.p_size / 2048, npe.p_offset); + for (j = 0; j < label.d_npartitions; j++) { struct partition *lpe; if (j == RAW_PART) continue; lpe = &label.d_partitions[j]; + if (lpe->p_size == npe.p_size && - lpe->p_offset == npe.p_offset -#ifdef notyet - && (lpe->p_fstype == npe.p_fstype || - lpe->p_fstype == FS_UNUSED) */ -#endif - ) { + lpe->p_offset == npe.p_offset) { if (verbose) printf( - " skipping existing %s partition at slot %c.\n", + " skipping existing %s partition at slot %c.\n", fstypenames[lpe->p_fstype], j + 'a'); unused = -2; /* flag as existing */ break; } + if (unused == -1 && lpe->p_size == 0 && lpe->p_fstype == FS_UNUSED) unused = j; } + if (unused == -1) { + for (j = 0; j < label.d_npartitions; j++) { + struct partition *lpe; + + if (j == RAW_PART) + continue; + lpe = &label.d_partitions[j]; + + if ((npe.p_offset >= lpe->p_offset && + npe.p_offset < lpe->p_offset + lpe->p_size) || + (npe.p_offset + npe.p_size - 1 >= lpe->p_offset && + npe.p_offset + npe.p_size - 1 < lpe->p_offset + lpe->p_size)) { + printf( + " skipping overlapping %s partition at slot %c.\n", + fstypenames[lpe->p_fstype], + j + 'a'); + unused = -2; /* flag as existing */ + break; + } + } + } if (unused == -2) continue; /* entry exists, skip... */ if (unused == -1) { @@ -202,23 +233,25 @@ getparts(int sd, u_int32_t off, u_int32_ if (verbose) printf(" adding %s partition to slot %c.\n", fstypenames[npe.p_fstype], unused + 'a'); + + /* + * XXX guess some filesystem parameters, these should be + * scanned from the superblocks + */ switch (npe.p_fstype) { case FS_BSDFFS: case FS_APPLEUFS: - npe.p_size = 16384; /* XXX */ npe.p_fsize = 1024; npe.p_frag = 8; npe.p_cpg = 16; break; -#ifdef __does_not_happen__ case FS_BSDLFS: - npe.p_size = 16384; /* XXX */ npe.p_fsize = 1024; npe.p_frag = 8; - npe.p_sgs = XXX; + npe.p_sgs = 7; break; -#endif } + changed++; label.d_partitions[unused] = npe; } @@ -233,6 +266,8 @@ getparts(int sd, u_int32_t off, u_int32_ extoff ? extoff : poff, verbose); } } + + free(buf); return (changed); }