[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[dm-devel] [PATCH 21/21] [kpartx] Add handling for SUN partition tables



Not that I've come across one of these disks, but it's a nice testbed for
the stacked partition handling. And might even be useful at one point.

Signed-off-by: Hannes Reinecke <hare suse de>
---
 kpartx/Makefile |    4 +-
 kpartx/kpartx.c |    8 +++-
 kpartx/kpartx.h |    1 +
 kpartx/sun.c    |  131 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 140 insertions(+), 4 deletions(-)

diff --git a/kpartx/Makefile b/kpartx/Makefile
index a43f881..ba69550 100644
--- a/kpartx/Makefile
+++ b/kpartx/Makefile
@@ -10,11 +10,11 @@ CFLAGS += -I. -D_LARGEFILE64_SOURCE
 
 ifeq ($(strip $(BUILD)),klibc)
 	OBJS = bsd.o dos.o kpartx.o solaris.o unixware.o gpt.o crc32.o \
-	       lopart.o xstrncpy.o devmapper.o dasd.o mac.o \
+	       lopart.o xstrncpy.o devmapper.o dasd.o mac.o sun.o \
 	       $(MULTIPATHLIB)-$(BUILD).a $(libdm)
 else
 	LDFLAGS = -ldevmapper
-	OBJS = bsd.o dos.o kpartx.o solaris.o unixware.o dasd.o \
+	OBJS = bsd.o dos.o kpartx.o solaris.o unixware.o dasd.o sun.o \
 	       gpt.o mac.o crc32.o lopart.o xstrncpy.o devmapper.o
 endif
 
diff --git a/kpartx/kpartx.c b/kpartx/kpartx.c
index 48169f1..30f23da 100644
--- a/kpartx/kpartx.c
+++ b/kpartx/kpartx.c
@@ -79,6 +79,7 @@ initpts(void)
 	addpts("unixware", read_unixware_pt);
 	addpts("dasd", read_dasd_pt);
 	addpts("mac", read_mac_pt);
+	addpts("sun", read_sun_pt);
 }
 
 static char short_opts[] = "ladgvnp:t:";
@@ -374,6 +375,9 @@ main(int argc, char **argv){
 			d = c;
 			while (c) {
 				for (j = 0; j < n; j++) {
+					unsigned long start;
+					int k = slices[j].container - 1;
+
 					if (slices[j].size == 0)
 						continue;
 					if (slices[j].minor > 0)
@@ -382,11 +386,11 @@ main(int argc, char **argv){
 						continue;
 					slices[j].minor = m++;
 
+					start = slices[j].start - slices[k].start;
 					printf("%s%s%d : 0 %lu /dev/dm-%d %lu\n",
 					       mapname, delim, j+1,
 					       (unsigned long) slices[j].size,
-					       slices[j].minor,
-					       (unsigned long) slices[j].start);
+					       slices[k].minor, start);
 					c--;
 				}
 				/* Terminate loop if nothing more to resolve */
diff --git a/kpartx/kpartx.h b/kpartx/kpartx.h
index b49c543..9b3aeca 100644
--- a/kpartx/kpartx.h
+++ b/kpartx/kpartx.h
@@ -36,6 +36,7 @@ extern ptreader read_unixware_pt;
 extern ptreader read_gpt_pt;
 extern ptreader read_dasd_pt;
 extern ptreader read_mac_pt;
+extern ptreader read_sun_pt;
 
 char *getblock(int fd, unsigned int secnr);
 
diff --git a/kpartx/sun.c b/kpartx/sun.c
new file mode 100644
index 0000000..3d88b21
--- /dev/null
+++ b/kpartx/sun.c
@@ -0,0 +1,131 @@
+/*
+ * Lifted from util-linux' partx sun.c
+ *
+ * Copyrights of the original file apply
+ * Copyright (c) 2007 Hannes Reinecke
+ */
+#include "kpartx.h"
+#include "byteorder.h"
+#include <stdio.h>
+#include <sys/types.h>
+#include <time.h>		/* time_t */
+
+#define SUN_DISK_MAGIC		0xDABE	/* Disk magic number */
+#define SUN_DISK_MAXPARTITIONS	8
+
+struct __attribute__ ((packed)) sun_raw_part {
+	u_int32_t	start_cylinder; /* where the part starts... */
+	u_int32_t	num_sectors;	/* ...and it's length */
+};
+
+struct __attribute__ ((packed)) sun_part_info {
+	u_int8_t	spare1;
+	u_int8_t	id;		/* Partition type */
+	u_int8_t	spare2;
+	u_int8_t	flags;		/* Partition flags */
+};
+
+struct __attribute__ ((packed)) sun_disk_label {
+	char		info[128];	/* Informative text string */
+	u_int8_t	spare0[14];
+	struct sun_part_info infos[SUN_DISK_MAXPARTITIONS];
+	u_int8_t	spare1[246];	/* Boot information etc. */
+	u_int16_t	rspeed;		/* Disk rotational speed */
+	u_int16_t	pcylcount;	/* Physical cylinder count */
+	u_int16_t	sparecyl;	/* extra sects per cylinder */
+	u_int8_t	spare2[4];	/* More magic... */
+	u_int16_t	ilfact;		/* Interleave factor */
+	u_int16_t	ncyl;		/* Data cylinder count */
+	u_int16_t	nacyl;		/* Alt. cylinder count */
+	u_int16_t	ntrks;		/* Tracks per cylinder */
+	u_int16_t	nsect;		/* Sectors per track */
+	u_int8_t	spare3[4];	/* Even more magic... */
+	struct sun_raw_part partitions[SUN_DISK_MAXPARTITIONS];
+	u_int16_t	magic;		/* Magic number */
+	u_int16_t	csum;		/* Label xor'd checksum */
+};
+
+/* Checksum Verification */
+static int
+sun_verify_checksum (struct sun_disk_label *label)
+{
+	u_int16_t *ush = ((u_int16_t *)(label + 1)) - 1;
+	u_int16_t csum = 0;
+
+	while (ush >= (u_int16_t *)label)
+		csum ^= *ush--;
+
+	return !csum;
+}
+
+int
+read_sun_pt(int fd, struct slice all, struct slice *sp, int ns) {
+	struct sun_disk_label *l;
+	struct sun_raw_part *s;
+	unsigned int offset = all.start, end;
+	int i, j, n;
+	char *bp;
+
+	bp = getblock(fd, offset);
+	if (bp == NULL)
+		return -1;
+
+	l = (struct sun_disk_label *) bp;
+	if(be16_to_cpu(l->magic) != SUN_DISK_MAGIC)
+		return -1;
+
+	if (!sun_verify_checksum(l)) {
+		fprintf(stderr, "Corrupted Sun disk label\n");
+		return -1;
+	}
+
+	for(i=0, n=0; i<SUN_DISK_MAXPARTITIONS; i++) {
+		s = &l->partitions[i];
+
+		if (s->num_sectors == 0)
+			continue;
+		if (n < ns) {
+			sp[n].start = offset +
+				be32_to_cpu(s->start_cylinder) * be16_to_cpu(l->nsect) * be16_to_cpu(l->ntrks);
+			sp[n].size = be32_to_cpu(s->num_sectors);
+			n++;
+		} else {
+			fprintf(stderr,
+				"sun_disklabel: too many slices\n");
+			break;
+		}
+	}
+	/*
+	 * Convention has it that the SUN disklabel will always have
+	 * the 'c' partition spanning the entire disk.
+	 * So we have to check for contained slices.
+	 */
+	for(i = 0; i < SUN_DISK_MAXPARTITIONS; i++) {
+		if (sp[i].size == 0)
+			continue;
+
+		end = sp[i].start + sp[i].size;
+		for(j = 0; j < SUN_DISK_MAXPARTITIONS; 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,
+						"sun_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;
+}
+
-- 
1.4.3.4


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]