lvm2/0018-devices-detect-md-ddf-and-imsm-superblocks.patch
Xiaole He 189dd63981 md: add support for intel vroc raid
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>
2022-10-29 16:38:31 +08:00

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