[lvm-devel] [PATCH] dev-type: add support for checking sgi/sun partition table

Liuhua Wang lwang at suse.com
Wed Mar 30 05:54:41 UTC 2016


The code is based on libfdisk and pass my tests.
---
 lib/device/dev-type.c | 73 ++++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 61 insertions(+), 12 deletions(-)

diff --git a/lib/device/dev-type.c b/lib/device/dev-type.c
index e1243bd..c45738f 100644
--- a/lib/device/dev-type.c
+++ b/lib/device/dev-type.c
@@ -265,11 +265,13 @@ int major_is_scsi_device(struct dev_types *dt, int major)
 	return (dt->dev_type_array[major].flags & PARTITION_SCSI_DEVICE) ? 1 : 0;
 }
 
+
+#define DEFAULT_SECTOR_SIZE 512
 /* See linux/genhd.h and fs/partitions/msdos */
+/* For msdos/gpt */
 #define PART_MAGIC 0xAA55
 #define PART_MAGIC_OFFSET UINT64_C(0x1FE)
 #define PART_OFFSET UINT64_C(0x1BE)
-
 struct partition {
 	uint8_t boot_ind;
 	uint8_t head;
@@ -283,6 +285,42 @@ struct partition {
 	uint32_t nr_sects;
 } __attribute__((packed));
 
+typedef struct {
+	uint8_t skip[PART_OFFSET];
+	struct partition part[4];
+	uint16_t magic;
+} __attribute__((packed)) msdos_disklabel; /* sizeof() == SECTOR_SIZE */
+
+/*For sun*/
+/* See util-linux/include/pt-sun.h */
+#define SUN_SKIP UINT64_C(0x1BC)
+#define SUN_LABEL_MAGIC 0xDABE
+#define SUN_MAX_PARTITIONS  8
+typedef struct {
+	uint8_t skip[SUN_SKIP];
+	struct sun_partition {
+		uint32_t start_cylinder;
+		uint32_t num_sectors;
+	} __attribute__((packed)) partitions[8];
+	uint16_t magic;
+} __attribute__((packed)) sun_disklabel;
+
+/*For sgi*/
+/* See util-linux/include/pt-sgi.h */
+#define SGI_SKIP UINIT64_C(0x134)
+#define SGI_LABEL_MAGIC 0x0BE5A941 
+#define SGI_MAX_PARTITIONS  16
+typedef struct {
+	uint32_t magic;
+	uint8_t skip[SGI_SKIP];
+	struct sgi_partition {
+		uint32_t num_blocks;
+		uint32_t first_block;
+		uint32_t type;
+	} __attribute__((packed)) partitions[16];
+} __attribute__((packed)) sgi_disklabel;
+
+
 static int _is_partitionable(struct dev_types *dt, struct device *dev)
 {
 	int parts = major_max_partitions(dt, MAJOR(dev->dev));
@@ -303,29 +341,40 @@ static int _is_partitionable(struct dev_types *dt, struct device *dev)
 static int _has_partition_table(struct device *dev)
 {
 	int ret = 0;
+	char buf[DEFAULT_SECTOR_SIZE];
 	unsigned p;
-	struct {
-		uint8_t skip[PART_OFFSET];
-		struct partition part[4];
-		uint16_t magic;
-	} __attribute__((packed)) buf; /* sizeof() == SECTOR_SIZE */
+	msdos_disklabel *msl;
+	sun_disklabel *sunl;
+	sgi_disklabel *sgil;
 
 	if (!dev_read(dev, UINT64_C(0), sizeof(buf), &buf))
 		return_0;
 
-	/* FIXME Check for other types of partition table too */
-
-	/* Check for msdos partition table */
-	if (buf.magic == xlate16(PART_MAGIC)) {
+	/* Currently it supports for msdos/gpt/sgi/sun partition table */
+	if ((msl = (msdos_disklabel *)buf) && msl.magic == xlate16(PART_MAGIC)) {
 		for (p = 0; p < 4; ++p) {
 			/* Table is invalid if boot indicator not 0 or 0x80 */
-			if (buf.part[p].boot_ind & 0x7f) {
+			if (msl->part[p].boot_ind & 0x7f) {
 				ret = 0;
 				break;
 			}
 			/* Must have at least one non-empty partition */
-			if (buf.part[p].nr_sects)
+			if (msl->part[p].nr_sects)
+				ret = 1;
+		}
+	} else if ((sgi = (sgi_disklabel *)buf) && xlate32(sgi->magic) == SGI_LABEL_MAGIC) {
+		for (i = 0;i < SGI_MAX_PARTITIONS;i++) {
+			if (xlate32(sgi->partitions[i].num_blocks)) {
 				ret = 1;
+				break;
+			}
+		}
+	} else if ((sun = (sun_disklabel *)buf) && xlate16(sun->magic) == SUN_LABEL_MAGIC) {
+		for (i = 0;i < SUN_MAX_PARTITIONS;i++) {
+			if (sun->partitions[i].num_sectors) {
+				ret = 1;
+				break;
+			}
 		}
 	}
 
-- 
1.8.4.5




More information about the lvm-devel mailing list