Backport patches for supporting intel vroc raid device. Commit 23774f997ea077f2cbe8a32bd8bccdd7f4560cca (devices: detect md ddf and imsm superblocks) Commit 00c9a788cc617e5e40746dee2e17287d61ee5c81 (devices: simplify md superblock checking code) Commit 7880896f0dbe730e7b47aa8040544434813eacc4 (gcc: calc size in compile time) Commit 12667e9897ad54f5723463b4c864c8259ba0be2a (fix check for md raid imsm signature on 4k devices) Commit 6a099707c433f0b3f2644c52f7773751832693a4 (clang: remove unused assignment) Otherwise, create vg on a intel vroc raid will produce below error: /* command begin */ $ pvcreate /dev/md0 $ vgcreate testvg /dev/md0 Cannot use device /dev/md0 with duplicates. /* command end */ Signed-off-by: Xiaole He <hexiaole@kylinos.cn>
160 lines
4.3 KiB
Diff
160 lines
4.3 KiB
Diff
From a957fa33e99bfb7da4eee4a4c0ab95ee61928b73 Mon Sep 17 00:00:00 2001
|
|
From: David Teigland <teigland@redhat.com>
|
|
Date: Thu, 19 Sep 2019 11:33:59 -0500
|
|
Subject: [PATCH 18/22] devices: detect md ddf and imsm superblocks
|
|
|
|
---
|
|
lib/device/dev-md.c | 105 +++++++++++++++++++++++++++++++++++++++++++-
|
|
1 file changed, 104 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/lib/device/dev-md.c b/lib/device/dev-md.c
|
|
index 9d0a363..13a3c16 100644
|
|
--- a/lib/device/dev-md.c
|
|
+++ b/lib/device/dev-md.c
|
|
@@ -16,6 +16,7 @@
|
|
#include "lib/misc/lib.h"
|
|
#include "lib/device/dev-type.h"
|
|
#include "lib/mm/xlate.h"
|
|
+#include "lib/misc/crc.h"
|
|
#ifdef UDEV_SYNC_SUPPORT
|
|
#include <libudev.h> /* for MD detection using udev db records */
|
|
#include "lib/device/dev-ext-udev-constants.h"
|
|
@@ -48,6 +49,93 @@ static int _dev_has_md_magic(struct device *dev, uint64_t sb_offset)
|
|
return 0;
|
|
}
|
|
|
|
+#define IMSM_SIGNATURE "Intel Raid ISM Cfg Sig. "
|
|
+#define IMSM_SIG_LEN (strlen(IMSM_SIGNATURE))
|
|
+
|
|
+static int _dev_has_imsm_magic(struct device *dev, uint64_t devsize_sectors)
|
|
+{
|
|
+ char imsm_signature[IMSM_SIG_LEN];
|
|
+ uint64_t off = (devsize_sectors * 512) - 1024;
|
|
+
|
|
+ if (!dev_read_bytes(dev, off, IMSM_SIG_LEN, imsm_signature))
|
|
+ return_0;
|
|
+
|
|
+ if (!memcmp(imsm_signature, IMSM_SIGNATURE, IMSM_SIG_LEN))
|
|
+ return 1;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+#define DDF_MAGIC 0xDE11DE11
|
|
+struct ddf_header {
|
|
+ uint32_t magic;
|
|
+ uint32_t crc;
|
|
+ char guid[24];
|
|
+ char revision[8];
|
|
+ char padding[472];
|
|
+};
|
|
+
|
|
+static int _dev_has_ddf_magic(struct device *dev, uint64_t devsize_sectors)
|
|
+{
|
|
+ struct ddf_header hdr;
|
|
+ uint32_t crc, our_crc;
|
|
+ uint64_t off;
|
|
+ uint64_t devsize_bytes = devsize_sectors * 512;
|
|
+
|
|
+ if (devsize_bytes < 0x30000)
|
|
+ return 0;
|
|
+
|
|
+ /* 512 bytes before the end of device (from libblkid) */
|
|
+ off = ((devsize_bytes / 0x200) - 1) * 0x200;
|
|
+
|
|
+ if (!dev_read_bytes(dev, off, 512, &hdr))
|
|
+ return_0;
|
|
+
|
|
+ if ((hdr.magic == cpu_to_be32(DDF_MAGIC)) ||
|
|
+ (hdr.magic == cpu_to_le32(DDF_MAGIC))) {
|
|
+ crc = hdr.crc;
|
|
+ hdr.crc = 0xffffffff;
|
|
+ our_crc = calc_crc(0, (const uint8_t *)&hdr, 512);
|
|
+
|
|
+ if ((cpu_to_be32(our_crc) == crc) ||
|
|
+ (cpu_to_le32(our_crc) == crc)) {
|
|
+ log_debug_devs("Found md ddf magic at %llu crc %x %s",
|
|
+ (unsigned long long)off, crc, dev_name(dev));
|
|
+ return 1;
|
|
+ } else {
|
|
+ log_debug_devs("Found md ddf magic at %llu wrong crc %x disk %x %s",
|
|
+ (unsigned long long)off, our_crc, crc, dev_name(dev));
|
|
+ return 0;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /* 128KB before the end of device (from libblkid) */
|
|
+ off = ((devsize_bytes / 0x200) - 257) * 0x200;
|
|
+
|
|
+ if (!dev_read_bytes(dev, off, 512, &hdr))
|
|
+ return_0;
|
|
+
|
|
+ if ((hdr.magic == cpu_to_be32(DDF_MAGIC)) ||
|
|
+ (hdr.magic == cpu_to_le32(DDF_MAGIC))) {
|
|
+ crc = hdr.crc;
|
|
+ hdr.crc = 0xffffffff;
|
|
+ our_crc = calc_crc(0, (const uint8_t *)&hdr, 512);
|
|
+
|
|
+ if ((cpu_to_be32(our_crc) == crc) ||
|
|
+ (cpu_to_le32(our_crc) == crc)) {
|
|
+ log_debug_devs("Found md ddf magic at %llu crc %x %s",
|
|
+ (unsigned long long)off, crc, dev_name(dev));
|
|
+ return 1;
|
|
+ } else {
|
|
+ log_debug_devs("Found md ddf magic at %llu wrong crc %x disk %x %s",
|
|
+ (unsigned long long)off, our_crc, crc, dev_name(dev));
|
|
+ return 0;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
/*
|
|
* Calculate the position of the superblock.
|
|
* It is always aligned to a 4K boundary and
|
|
@@ -178,8 +266,8 @@ static int _native_dev_is_md_component(struct device *dev, uint64_t *offset_foun
|
|
goto out;
|
|
}
|
|
|
|
- /* Check if it is an md component device. */
|
|
/* Version 0.90.0 */
|
|
+ /* superblock at 64KB from end of device */
|
|
sb_offset = MD_NEW_SIZE_SECTORS(size) << SECTOR_SHIFT;
|
|
if (_dev_has_md_magic(dev, sb_offset)) {
|
|
ret = 1;
|
|
@@ -187,8 +275,11 @@ static int _native_dev_is_md_component(struct device *dev, uint64_t *offset_foun
|
|
}
|
|
|
|
minor = MD_MINOR_VERSION_MIN;
|
|
+
|
|
/* Version 1, try v1.0 -> v1.2 */
|
|
+
|
|
do {
|
|
+ /* superblock at start or 4K from start */
|
|
sb_offset = _v1_sb_offset(size, minor);
|
|
if (_dev_has_md_magic(dev, sb_offset)) {
|
|
ret = 1;
|
|
@@ -196,6 +287,18 @@ static int _native_dev_is_md_component(struct device *dev, uint64_t *offset_foun
|
|
}
|
|
} while (++minor <= MD_MINOR_VERSION_MAX);
|
|
|
|
+ /* superblock 1K from end of device */
|
|
+ if (_dev_has_imsm_magic(dev, size)) {
|
|
+ ret = 1;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ /* superblock 512 bytes from end, or 128KB from end */
|
|
+ if (_dev_has_ddf_magic(dev, size)) {
|
|
+ ret = 1;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
ret = 0;
|
|
out:
|
|
if (ret && offset_found)
|
|
--
|
|
2.27.0
|
|
|