]> err.no Git - util-linux/commitdiff
libblkid: improbe DDF detection
authorKarel Zak <kzak@redhat.com>
Tue, 18 May 2010 14:09:58 +0000 (16:09 +0200)
committerKarel Zak <kzak@redhat.com>
Tue, 18 May 2010 14:09:58 +0000 (16:09 +0200)
Signed-off-by: Karel Zak <kzak@redhat.com>
shlibs/blkid/src/superblocks/ddf_raid.c
tests/expected/blkid/low-probe-ddf-raid
tests/ts/blkid/images-fs/ddf-raid.img.bz2

index a48735d2a358e4f5d39772cec28069c40a8b8c17..c0ba3351721a4fc1ed7bf1462affba303bfe4bea 100644 (file)
 /* http://www.snia.org/standards/home */
 #define DDF_GUID_LENGTH                        24
 #define DDF_REV_LENGTH                 8
+#define DDF_MAGIC                      0xDE11DE11
+
 
 struct ddf_header {
-       uint8_t         signature[4];
+       uint32_t        signature;
        uint32_t        crc;
        uint8_t         guid[DDF_GUID_LENGTH];
-       uint8_t         ddf_rev[DDF_REV_LENGTH];
+       char            ddf_rev[8];     /* 01.02.00 */
+       uint32_t        seq;            /* starts at '1' */
+       uint32_t        timestamp;
+       uint8_t         openflag;
+       uint8_t         foreignflag;
+       uint8_t         enforcegroups;
+       uint8_t         pad0;           /* 0xff */
+       uint8_t         pad1[12];       /* 12 * 0xff */
+       /* 64 bytes so far */
+       uint8_t         header_ext[32]; /* reserved: fill with 0xff */
+       uint64_t        primary_lba;
+       uint64_t        secondary_lba;
+       uint8_t         type;
+       uint8_t         pad2[3];        /* 0xff */
+       uint32_t        workspace_len;  /* sectors for vendor space -
+                                        * at least 32768(sectors) */
+       uint64_t        workspace_lba;
+       uint16_t        max_pd_entries; /* one of 15, 63, 255, 1023, 4095 */
+       uint16_t        max_vd_entries; /* 2^(4,6,8,10,12)-1 : i.e. as above */
+       uint16_t        max_partitions; /* i.e. max num of configuration
+                                          record entries per disk */
+       uint16_t        config_record_len; /* 1 +ROUNDUP(max_primary_element_entries
+                                          *12/512) */
+       uint16_t        max_primary_element_entries; /* 16, 64, 256, 1024, or 4096 */
+       uint8_t         pad3[54];       /* 0xff */
+       /* 192 bytes so far */
+       uint32_t        controller_section_offset;
+       uint32_t        controller_section_length;
+       uint32_t        phys_section_offset;
+       uint32_t        phys_section_length;
+       uint32_t        virt_section_offset;
+       uint32_t        virt_section_length;
+       uint32_t        config_section_offset;
+       uint32_t        config_section_length;
+       uint32_t        data_section_offset;
+       uint32_t        data_section_length;
+       uint32_t        bbm_section_offset;
+       uint32_t        bbm_section_length;
+       uint32_t        diag_space_offset;
+       uint32_t        diag_space_length;
+       uint32_t        vendor_offset;
+       uint32_t        vendor_length;
+       /* 256 bytes so far */
+       uint8_t         pad4[256];      /* 0xff */
 } __attribute__((packed));
 
 static int probe_ddf(blkid_probe pr, const struct blkid_idmag *mag)
@@ -32,7 +77,7 @@ static int probe_ddf(blkid_probe pr, const struct blkid_idmag *mag)
        int i;
        struct ddf_header *ddf = NULL;
        char version[DDF_REV_LENGTH + 1];
-       uint64_t off;
+       uint64_t off, lba;
 
        if (pr->size < 0x30000)
                return -1;
@@ -46,8 +91,8 @@ static int probe_ddf(blkid_probe pr, const struct blkid_idmag *mag)
                if (!ddf)
                        return -1;
 
-               if (memcmp(ddf->signature, "\x11\xde\x11\xde", 4) == 0 ||
-                   memcmp(ddf->signature, "\xde\x11\xde\x11", 4) == 0)
+               if (ddf->signature == cpu_to_be32(DDF_MAGIC) ||
+                   ddf->signature == cpu_to_le32(DDF_MAGIC))
                        break;
                ddf = NULL;
        }
@@ -55,6 +100,20 @@ static int probe_ddf(blkid_probe pr, const struct blkid_idmag *mag)
        if (!ddf)
                return -1;
 
+       lba = ddf->signature == cpu_to_be32(DDF_MAGIC) ?
+                       be64_to_cpu(ddf->primary_lba) :
+                       le64_to_cpu(ddf->primary_lba);
+
+       if (lba > 0) {
+               /* check primary header */
+               unsigned char *buf;
+
+               buf = blkid_probe_get_buffer(pr,
+                                       lba << 9, sizeof(ddf->signature));
+               if (!buf || memcmp(buf, &ddf->signature, 4))
+                       return -1;
+       }
+
        blkid_probe_strncpy_uuid(pr, ddf->guid, sizeof(ddf->guid));
 
        memcpy(version, ddf->ddf_rev, sizeof(ddf->ddf_rev));
@@ -64,7 +123,7 @@ static int probe_ddf(blkid_probe pr, const struct blkid_idmag *mag)
                return -1;
        if (blkid_probe_set_magic(pr, off,
                        sizeof(ddf->signature),
-                       (unsigned char *) ddf->signature))
+                       (unsigned char *) &ddf->signature))
                return -1;
        return 0;
 }
index 08329501353fffade05fe72ff1c593c40bcf0895..7956dcd0d7be7c7ac2a8aa7f1fc440b05b3fabe3 100644 (file)
@@ -1,5 +1,5 @@
 ID_FS_TYPE=ddf_raid_member
 ID_FS_USAGE=raid
-ID_FS_UUID=8Z_I__B_8Z_I_e_I_q_I____
-ID_FS_UUID_ENC=8Z\xb0I\x95\x10B\x028Z\xb0I\xc8e\xb0I\xb8q\xb0I\xff\xff\xff\xff
-ID_FS_VERSION=02.00.00
+ID_FS_UUID=Linux-MDޭ__
+ID_FS_UUID_ENC=Linux-MDޭ\xbe\xef
+ID_FS_VERSION=01.02.00
index c8f0c8ac527302fbedbd7367befad3b5ca234479..b09349337852a9e5f5b704b36c8d8c1481e0274a 100644 (file)
Binary files a/tests/ts/blkid/images-fs/ddf-raid.img.bz2 and b/tests/ts/blkid/images-fs/ddf-raid.img.bz2 differ