summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarel Zak <kzak@redhat.com>2008-09-09 12:16:14 +0200
committerKarel Zak <kzak@redhat.com>2009-02-11 23:21:44 +0100
commit8ccb81be32fd33a3f711cb361ac35e833cf5949f (patch)
tree9525641027b3f76c103273ccaf35eb5e0bec6e61
parentd515672161a519655737d015db57137aa08e72e1 (diff)
downloadutil-linux-old-8ccb81be32fd33a3f711cb361ac35e833cf5949f.tar.gz
blkid: add Linux RAID
Signed-off-by: Karel Zak <kzak@redhat.com>
-rw-r--r--libs/blkid/src/probe.c3
-rw-r--r--libs/blkid/src/probers/Makefile.am3
-rw-r--r--libs/blkid/src/probers/linux_raid.c165
-rw-r--r--libs/blkid/src/probers/probers.h1
4 files changed, 170 insertions, 2 deletions
diff --git a/libs/blkid/src/probe.c b/libs/blkid/src/probe.c
index 4fc3b83e..8f1b8ffd 100644
--- a/libs/blkid/src/probe.c
+++ b/libs/blkid/src/probe.c
@@ -46,7 +46,8 @@ static const struct blkid_idinfo *idinfos[] =
&nvraid_idinfo,
&pdcraid_idinfo,
&silraid_idinfo,
- &viaraid_idinfo
+ &viaraid_idinfo,
+ &linuxraid_idinfo
};
#ifndef ARRAY_SIZE
diff --git a/libs/blkid/src/probers/Makefile.am b/libs/blkid/src/probers/Makefile.am
index 5a5bf7e5..9331636c 100644
--- a/libs/blkid/src/probers/Makefile.am
+++ b/libs/blkid/src/probers/Makefile.am
@@ -15,6 +15,7 @@ libprobers_a_SOURCES = probers.h \
nvidia_raid.c \
promise_raid.c \
silicon_raid.c \
- via_raid.c
+ via_raid.c \
+ linux_raid.c
all-local: $(lib_LIBRARIES)
diff --git a/libs/blkid/src/probers/linux_raid.c b/libs/blkid/src/probers/linux_raid.c
new file mode 100644
index 00000000..41be8b76
--- /dev/null
+++ b/libs/blkid/src/probers/linux_raid.c
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
+ * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+#include <stdint.h>
+
+#include "blkidP.h"
+
+struct mdp0_super_block {
+ uint32_t md_magic;
+ uint32_t major_version;
+ uint32_t minor_version;
+ uint32_t patch_version;
+ uint32_t gvalid_words;
+ uint32_t set_uuid0;
+ uint32_t ctime;
+ uint32_t level;
+ uint32_t size;
+ uint32_t nr_disks;
+ uint32_t raid_disks;
+ uint32_t md_minor;
+ uint32_t not_persistent;
+ uint32_t set_uuid1;
+ uint32_t set_uuid2;
+ uint32_t set_uuid3;
+};
+
+struct mdp1_super_block {
+ uint32_t magic;
+ uint32_t major_version;
+ uint32_t feature_map;
+ uint32_t pad0;
+ uint8_t set_uuid[16];
+ uint8_t set_name[32];
+};
+
+#define MD_RESERVED_BYTES 0x10000
+#define MD_SB_MAGIC 0xa92b4efc
+
+static int probe_raid0(blkid_probe pr, off_t off)
+{
+ struct mdp0_super_block *mdp0;
+ union {
+ uint32_t ints[4];
+ uint8_t bytes[16];
+ } uuid;
+
+ if (pr->size < 0x10000)
+ return -1;
+ mdp0 = (struct mdp0_super_block *)
+ blkid_probe_get_buffer(pr, off, 0x800);
+ if (!mdp0)
+ return -1;
+
+ memset(uuid.ints, 0, sizeof(uuid.ints));
+
+ if (le32_to_cpu(mdp0->md_magic) == MD_SB_MAGIC) {
+ uuid.ints[0] = swab32(mdp0->set_uuid0);
+ if (le32_to_cpu(mdp0->minor_version >= 90)) {
+ uuid.ints[1] = swab32(mdp0->set_uuid1);
+ uuid.ints[2] = swab32(mdp0->set_uuid2);
+ uuid.ints[3] = swab32(mdp0->set_uuid3);
+ }
+ if (blkid_probe_sprintf_version(pr, "%u.%u.%u",
+ le32_to_cpu(mdp0->major_version),
+ le32_to_cpu(mdp0->minor_version),
+ le32_to_cpu(mdp0->patch_version)) != 0)
+ return -1;
+
+ } else if (be32_to_cpu(mdp0->md_magic) == MD_SB_MAGIC) {
+ uuid.ints[0] = mdp0->set_uuid0;
+ if (be32_to_cpu(mdp0->minor_version >= 90)) {
+ uuid.ints[1] = mdp0->set_uuid1;
+ uuid.ints[2] = mdp0->set_uuid2;
+ uuid.ints[3] = mdp0->set_uuid3;
+ }
+ if (blkid_probe_sprintf_version(pr, "%u.%u.%u",
+ be32_to_cpu(mdp0->major_version),
+ be32_to_cpu(mdp0->minor_version),
+ be32_to_cpu(mdp0->patch_version)) != 0)
+ return -1;
+ } else
+ return -1;
+
+ if (blkid_probe_set_uuid(pr, (unsigned char *) uuid.bytes) != 0)
+ return -1;
+
+ return 0;
+}
+
+static int probe_raid1(blkid_probe pr, off_t off)
+{
+ struct mdp1_super_block *mdp1;
+
+ mdp1 = (struct mdp1_super_block *)
+ blkid_probe_get_buffer(pr, off, 0x800);
+ if (!mdp1)
+ return -1;
+ if (le32_to_cpu(mdp1->magic) != MD_SB_MAGIC)
+ return -1;
+ if (le32_to_cpu(mdp1->major_version) != 1)
+ return -1;
+ if (blkid_probe_set_uuid(pr, (unsigned char *) mdp1->set_uuid) != 0)
+ return -1;
+ if (blkid_probe_set_label(pr, mdp1->set_name, sizeof(mdp1->set_name)) != 0)
+ return -1;
+
+ return 0;
+}
+
+int probe_raid(blkid_probe pr, const struct blkid_idmag *mag)
+{
+ const char *ver = NULL;
+ uint64_t sboff;
+
+ /* version 0 at the end of the device */
+ sboff = (pr->size & ~(MD_RESERVED_BYTES - 1)) - MD_RESERVED_BYTES;
+ if (probe_raid0(pr, sboff) == 0)
+ return 0;
+
+ /* version 1.0 at the end of the device */
+ sboff = (pr->size & ~(0x1000 - 1)) - 0x2000;
+ if (probe_raid1(pr, sboff) == 0)
+ ver = "1.0";
+
+ /* version 1.1 at the start of the device */
+ else if (probe_raid1(pr, 0) == 0)
+ ver = "1.1";
+
+ /* version 1.2 at 4k offset from the start */
+ else if (probe_raid1(pr, 0x1000) == 0)
+ ver = "1.2";
+
+ if (ver) {
+ blkid_probe_set_version(pr, ver);
+ return 0;
+ }
+ return -1;
+}
+
+
+const struct blkid_idinfo linuxraid_idinfo = {
+ .name = "linux_raid_member",
+ .usage = BLKID_USAGE_RAID,
+ .probefunc = probe_raid
+};
+
+
diff --git a/libs/blkid/src/probers/probers.h b/libs/blkid/src/probers/probers.h
index e5313364..83012b93 100644
--- a/libs/blkid/src/probers/probers.h
+++ b/libs/blkid/src/probers/probers.h
@@ -27,5 +27,6 @@ extern const struct blkid_idinfo nvraid_idinfo;
extern const struct blkid_idinfo pdcraid_idinfo;
extern const struct blkid_idinfo silraid_idinfo;
extern const struct blkid_idinfo viaraid_idinfo;
+extern const struct blkid_idinfo linuxraid_idinfo;
#endif /* _BLKID_PROBE_H */