]> err.no Git - util-linux/commitdiff
blkid: improve ddf detection
authorKarel Zak <kzak@redhat.com>
Thu, 22 Jan 2009 00:15:02 +0000 (01:15 +0100)
committerKarel Zak <kzak@redhat.com>
Wed, 11 Feb 2009 22:35:23 +0000 (23:35 +0100)
Signed-off-by: Karel Zak <kzak@redhat.com>
libs/blkid/src/probers/ddf_raid.c

index 1e82281fad53b985283029bef3b6347fc960f253..41d6e12352105c036783eae0cfc8436c6737aa35 100644 (file)
 #include "blkidP.h"
 
 /* http://www.snia.org/standards/home */
-#define DDF_HEADER                     0xDE11DE11
 #define DDF_GUID_LENGTH                        24
 #define DDF_REV_LENGTH                 8
 
 struct ddf_header {
-       uint32_t        signature;
+       uint8_t         signature[4];
        uint32_t        crc;
        uint8_t         guid[DDF_GUID_LENGTH];
        uint8_t         ddf_rev[DDF_REV_LENGTH];
-};
+} __attribute__((packed));
 
 static int probe_ddf(blkid_probe pr, const struct blkid_idmag *mag)
 {
-       uint64_t off;
-       struct ddf_header *ddf;
+       int hdrs[] = { 1, 257 };
+       int i;
+       struct ddf_header *ddf = NULL;
+       char version[DDF_REV_LENGTH + 1];
 
-       if (pr->size < 0x10000)
+       if (pr->size < 0x30000)
                return -1;
 
-       off = ((pr->size / 0x200) - 1) * 0x200;
-       ddf = (struct ddf_header *)
-                       blkid_probe_get_buffer(pr,
+       for (i = 0; i < ARRAY_SIZE(hdrs); i++) {
+               uint64_t off = ((pr->size / 0x200) - hdrs[i]) * 0x200;
+
+               ddf = (struct ddf_header *) blkid_probe_get_buffer(pr,
                                        off,
                                        sizeof(struct ddf_header));
+               if (!ddf)
+                       return -1;
+
+               if (memcmp(ddf->signature, "\x11\xde\x11\xde", 4) == 0 ||
+                   memcmp(ddf->signature, "\xde\x11\xde\x11", 4) == 0)
+                       break;
+               ddf = NULL;
+       }
+
        if (!ddf)
                return -1;
-       if (ddf->signature != cpu_to_be32(DDF_HEADER))
-               return -1;
-       if (blkid_probe_sprintf_uuid(pr, ddf->guid,
-                               sizeof(ddf->guid), "%s", ddf->guid) != 0)
-               return -1;
-       if (blkid_probe_set_version(pr, (char *) ddf->ddf_rev) != 0)
+
+       blkid_probe_strncpy_uuid(pr, ddf->guid, sizeof(ddf->guid));
+
+       memcpy(version, ddf->ddf_rev, sizeof(ddf->ddf_rev));
+       *(version + sizeof(ddf->ddf_rev)) = '\0';
+
+       if (blkid_probe_set_version(pr, version) != 0)
                return -1;
        return 0;
 }