summaryrefslogtreecommitdiffstats
path: root/libblkid/src/superblocks/drbd.c
diff options
context:
space:
mode:
Diffstat (limited to 'libblkid/src/superblocks/drbd.c')
-rw-r--r--libblkid/src/superblocks/drbd.c147
1 files changed, 80 insertions, 67 deletions
diff --git a/libblkid/src/superblocks/drbd.c b/libblkid/src/superblocks/drbd.c
index f360186..96a2168 100644
--- a/libblkid/src/superblocks/drbd.c
+++ b/libblkid/src/superblocks/drbd.c
@@ -18,18 +18,24 @@
#include "superblocks.h"
+enum {
+ DRBD_VERSION_08,
+ DRBD_VERSION_09,
+};
+
/*
- * drbd/linux/drbd.h
+ * drbd/drbd_int.h
*/
-#define DRBD_MAGIC 0x83740267
+#define BM_BLOCK_SHIFT 12 /* 4k per bit */
+#define BM_BLOCK_SIZE (1<<BM_BLOCK_SHIFT)
/*
* user/drbdmeta.c
* We support v08 and v09
*/
-#define DRBD_MD_MAGIC_08 (DRBD_MAGIC+4)
-#define DRBD_MD_MAGIC_84_UNCLEAN (DRBD_MAGIC+5)
-#define DRBD_MD_MAGIC_09 (DRBD_MAGIC+6)
+#define DRBD_MD_MAGIC_08 "\x83\x74\x02\x6b"
+#define DRBD_MD_MAGIC_84_UNCLEAN "\x83\x74\x02\x6c"
+#define DRBD_MD_MAGIC_09 "\x83\x74\x02\x6d"
/* there is no DRBD_MD_MAGIC_09_UNCLEAN */
/*
@@ -70,9 +76,8 @@ struct md_on_disk_08 {
uint32_t bm_bytes_per_bit;
uint32_t reserved_u32[4];
- /* Unnecessary for libblkid **
- * char reserved[8 * 512 - (8*(UI_SIZE+3)+4*11)];
- */
+ unsigned char padding_start[0];
+ unsigned char padding_end[0] __attribute__((aligned(4096)));
};
/*
@@ -118,32 +123,34 @@ struct meta_data_on_disk_9 {
struct peer_dev_md_on_disk_9 peers[DRBD_PEERS_MAX];
uint64_t history_uuids[HISTORY_UUIDS];
- /* Unnecessary for libblkid **
- * char padding[0] __attribute__((aligned(4096)));
- */
+ unsigned char padding_start[0];
+ unsigned char padding_end[0] __attribute__((aligned(4096)));
} __attribute__((packed));
-static int probe_drbd_84(blkid_probe pr)
+static int is_zero_padded(const unsigned char *padding_start,
+ const unsigned char *padding_end)
{
- struct md_on_disk_08 *md;
- off_t off;
-
- off = pr->size - DRBD_MD_OFFSET;
+ for (; padding_start < padding_end; padding_start++) {
+ if (*padding_start != 0)
+ return 0;
+ }
+ return 1;
+}
- /* Small devices cannot be drbd (?) */
- if (pr->size < 0x10000)
- return 1;
+static int probe_drbd_84(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ const struct md_on_disk_08 *md;
- md = (struct md_on_disk_08 *)
- blkid_probe_get_buffer(pr,
- off,
- sizeof(struct md_on_disk_08));
+ md = blkid_probe_get_sb(pr, mag, struct md_on_disk_08);
if (!md)
return errno ? -errno : 1;
- if (be32_to_cpu(md->magic) != DRBD_MD_MAGIC_08 &&
- be32_to_cpu(md->magic) != DRBD_MD_MAGIC_84_UNCLEAN)
+ if (be32_to_cpu(read_unaligned_member(md, bm_bytes_per_bit)) != BM_BLOCK_SIZE)
+ return 1;
+
+ if (!is_zero_padded(member_ptr(md, padding_start),
+ member_ptr(md, padding_end)))
return 1;
/*
@@ -151,43 +158,27 @@ static int probe_drbd_84(blkid_probe pr)
* notion of uuids (64 bit, see struct above)
*/
blkid_probe_sprintf_uuid(pr,
- (unsigned char *) &md->device_uuid, sizeof(md->device_uuid),
- "%" PRIx64, be64_to_cpu(md->device_uuid));
+ member_ptr(md, device_uuid), sizeof(md->device_uuid),
+ "%" PRIx64, be64_to_cpu(read_unaligned_member(md, device_uuid)));
blkid_probe_set_version(pr, "v08");
- if (blkid_probe_set_magic(pr,
- off + offsetof(struct md_on_disk_08, magic),
- sizeof(md->magic),
- (unsigned char *) &md->magic))
- return 1;
-
return 0;
}
-static int probe_drbd_90(blkid_probe pr)
+static int probe_drbd_90(blkid_probe pr, const struct blkid_idmag *mag)
{
- struct meta_data_on_disk_9 *md;
- off_t off;
-
- off = pr->size - DRBD_MD_OFFSET;
-
- /*
- * Smaller ones are certainly not DRBD9 devices.
- * Recent utils even refuse to generate larger ones,
- * keep this as a sufficient lower bound.
- */
- if (pr->size < 0x10000)
- return 1;
+ const struct meta_data_on_disk_9 *md;
- md = (struct meta_data_on_disk_9 *)
- blkid_probe_get_buffer(pr,
- off,
- sizeof(struct meta_data_on_disk_9));
+ md = blkid_probe_get_sb(pr, mag, struct meta_data_on_disk_9);
if (!md)
return errno ? -errno : 1;
- if (be32_to_cpu(md->magic) != DRBD_MD_MAGIC_09)
+ if (be32_to_cpu(read_unaligned_member(md, bm_bytes_per_bit)) != BM_BLOCK_SIZE)
+ return 1;
+
+ if (!is_zero_padded(member_ptr(md, padding_start),
+ member_ptr(md, padding_end)))
return 1;
/*
@@ -195,30 +186,23 @@ static int probe_drbd_90(blkid_probe pr)
* notion of uuids (64 bit, see struct above)
*/
blkid_probe_sprintf_uuid(pr,
- (unsigned char *) &md->device_uuid, sizeof(md->device_uuid),
- "%" PRIx64, be64_to_cpu(md->device_uuid));
+ member_ptr(md, device_uuid), sizeof(md->device_uuid),
+ "%" PRIx64, be64_to_cpu(read_unaligned_member(md, device_uuid)));
blkid_probe_set_version(pr, "v09");
- if (blkid_probe_set_magic(pr,
- off + offsetof(struct meta_data_on_disk_9, magic),
- sizeof(md->magic),
- (unsigned char *) &md->magic))
- return 1;
-
return 0;
}
-static int probe_drbd(blkid_probe pr,
- const struct blkid_idmag *mag __attribute__((__unused__)))
+static int probe_drbd(blkid_probe pr, const struct blkid_idmag *mag)
{
- int ret;
+ if (mag->hint == DRBD_VERSION_08)
+ return probe_drbd_84(pr, mag);
- ret = probe_drbd_84(pr);
- if (ret <= 0) /* success or fatal (-errno) */
- return ret;
+ if (mag->hint == DRBD_VERSION_09)
+ return probe_drbd_90(pr, mag);
- return probe_drbd_90(pr);
+ return 1;
}
const struct blkid_idinfo drbd_idinfo =
@@ -226,6 +210,35 @@ const struct blkid_idinfo drbd_idinfo =
.name = "drbd",
.usage = BLKID_USAGE_RAID,
.probefunc = probe_drbd,
- .magics = BLKID_NONE_MAGIC
+ /*
+ * Smaller ones are certainly not DRBD9 devices.
+ * Recent utils even refuse to generate larger ones,
+ * keep this as a sufficient lower bound.
+ */
+ .minsz = 0x10000,
+ .magics = {
+ {
+ .magic = DRBD_MD_MAGIC_08,
+ .len = sizeof(DRBD_MD_MAGIC_08) - 1,
+ .hint = DRBD_VERSION_08,
+ .kboff = -(DRBD_MD_OFFSET >> 10),
+ .sboff = offsetof(struct md_on_disk_08, magic),
+ },
+ {
+ .magic = DRBD_MD_MAGIC_84_UNCLEAN,
+ .len = sizeof(DRBD_MD_MAGIC_84_UNCLEAN) - 1,
+ .hint = DRBD_VERSION_08,
+ .kboff = -(DRBD_MD_OFFSET >> 10),
+ .sboff = offsetof(struct md_on_disk_08, magic),
+ },
+ {
+ .magic = DRBD_MD_MAGIC_09,
+ .len = sizeof(DRBD_MD_MAGIC_09) - 1,
+ .hint = DRBD_VERSION_09,
+ .kboff = -(DRBD_MD_OFFSET >> 10),
+ .sboff = offsetof(struct meta_data_on_disk_9, magic),
+ },
+ { NULL }
+ }
};