#include "kpartx.h" #include #define BSD_LABEL_OFFSET 64 #define BSD_DISKMAGIC (0x82564557UL) /* The disk magic number */ #define XBSD_MAXPARTITIONS 16 #define BSD_FS_UNUSED 0 struct bsd_disklabel { unsigned int d_magic; /* the magic number */ short int d_type; /* drive type */ short int d_subtype; /* controller/d_type specific */ char d_typename[16]; /* type name, e.g. "eagle" */ char d_packname[16]; /* pack identifier */ unsigned int d_secsize; /* # of bytes per sector */ unsigned int d_nsectors; /* # of data sectors per track */ unsigned int d_ntracks; /* # of tracks per cylinder */ unsigned int d_ncylinders; /* # of data cylinders per unit */ unsigned int d_secpercyl; /* # of data sectors per cylinder */ unsigned int d_secperunit; /* # of data sectors per unit */ unsigned short d_sparespertrack;/* # of spare sectors per track */ unsigned short d_sparespercyl; /* # of spare sectors per cylinder */ unsigned int d_acylinders; /* # of alt. cylinders per unit */ unsigned short d_rpm; /* rotational speed */ unsigned short d_interleave; /* hardware sector interleave */ unsigned short d_trackskew; /* sector 0 skew, per track */ unsigned short d_cylskew; /* sector 0 skew, per cylinder */ unsigned int d_headswitch; /* head switch time, usec */ unsigned int d_trkseek; /* track-to-track seek, usec */ unsigned int d_flags; /* generic flags */ unsigned int d_drivedata[5]; /* drive-type specific information */ unsigned int d_spare[5]; /* reserved for future use */ unsigned int d_magic2; /* the magic number (again) */ unsigned short d_checksum; /* xor of data incl. partitions */ /* filesystem and partition information: */ unsigned short d_npartitions; /* number of partitions in following */ unsigned int d_bbsize; /* size of boot area at sn0, bytes */ unsigned int d_sbsize; /* max size of fs superblock, bytes */ struct bsd_partition { /* the partition table */ unsigned int p_size; /* number of sectors in partition */ unsigned int p_offset; /* starting sector */ unsigned int p_fsize; /* filesystem basic fragment size */ unsigned char p_fstype; /* filesystem type, see below */ unsigned char p_frag; /* filesystem fragments per block */ unsigned short p_cpg; /* filesystem cylinders per group */ } d_partitions[XBSD_MAXPARTITIONS];/* actually may be more */ }; int read_bsd_pt(int fd, struct slice all, struct slice *sp, unsigned int ns) { struct bsd_disklabel *l; struct bsd_partition *p; unsigned int offset = all.start, end; int max_partitions; char *bp; unsigned int n = 0, i, j; bp = getblock(fd, offset+1); /* 1 sector suffices */ if (bp == NULL) return -1; l = (struct bsd_disklabel *) bp; if (l->d_magic != BSD_DISKMAGIC) { /* * BSD disklabels can also start 64 bytes offset from the * start of the first sector */ bp = getblock(fd, offset); if (bp == NULL) return -1; l = (struct bsd_disklabel *)(bp + 64); if (l->d_magic != BSD_DISKMAGIC) return -1; } max_partitions = 16; if (l->d_npartitions < max_partitions) max_partitions = l->d_npartitions; for (p = l->d_partitions; p - l->d_partitions < max_partitions; p++) { if (p->p_fstype == BSD_FS_UNUSED) /* nothing */; else if (n < ns) { sp[n].start = p->p_offset; sp[n].size = p->p_size; n++; } else { fprintf(stderr, "bsd_partition: too many slices\n"); break; } } /* * Convention has it that the bsd disklabel will always have * the 'c' partition spanning the entire disk. * So we have to check for contained slices. */ for(i = 0; i < n; i++) { if (sp[i].size == 0) continue; end = sp[i].start + sp[i].size; for(j = 0; j < n; j ++) { if ( i == j ) continue; if (sp[j].size == 0) continue; if (sp[i].start < sp[j].start) { if (end > sp[j].start && end < sp[j].start + sp[j].size) { /* Invalid slice */ fprintf(stderr, "bsd_disklabel: slice %d overlaps with %d\n", i , j); sp[i].size = 0; } } else { if (end <= sp[j].start + sp[j].size) { sp[i].container = j + 1; } } } } return n; }