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>
This commit is contained in:
Xiaole He 2022-10-29 16:38:31 +08:00
parent 986a963ea3
commit 189dd63981
6 changed files with 474 additions and 1 deletions

View File

@ -0,0 +1,159 @@
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

View File

@ -0,0 +1,220 @@
From 452573975d0f804d255be14edee38e7fc1e69b1a Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Thu, 19 Sep 2019 12:17:36 -0500
Subject: [PATCH 19/22] devices: simplify md superblock checking code
---
lib/device/dev-md.c | 135 +++++++++++++++++++-------------------------
1 file changed, 58 insertions(+), 77 deletions(-)
diff --git a/lib/device/dev-md.c b/lib/device/dev-md.c
index 13a3c16..23ce41a 100644
--- a/lib/device/dev-md.c
+++ b/lib/device/dev-md.c
@@ -75,7 +75,7 @@ struct ddf_header {
char padding[472];
};
-static int _dev_has_ddf_magic(struct device *dev, uint64_t devsize_sectors)
+static int _dev_has_ddf_magic(struct device *dev, uint64_t devsize_sectors, uint64_t *sb_offset)
{
struct ddf_header hdr;
uint32_t crc, our_crc;
@@ -99,8 +99,7 @@ static int _dev_has_ddf_magic(struct device *dev, uint64_t devsize_sectors)
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));
+ *sb_offset = off;
return 1;
} else {
log_debug_devs("Found md ddf magic at %llu wrong crc %x disk %x %s",
@@ -123,8 +122,7 @@ static int _dev_has_ddf_magic(struct device *dev, uint64_t devsize_sectors)
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));
+ *sb_offset = off;
return 1;
} else {
log_debug_devs("Found md ddf magic at %llu wrong crc %x disk %x %s",
@@ -136,46 +134,6 @@ static int _dev_has_ddf_magic(struct device *dev, uint64_t devsize_sectors)
return 0;
}
-/*
- * Calculate the position of the superblock.
- * It is always aligned to a 4K boundary and
- * depending on minor_version, it can be:
- * 0: At least 8K, but less than 12K, from end of device
- * 1: At start of device
- * 2: 4K from start of device.
- */
-typedef enum {
- MD_MINOR_VERSION_MIN,
- MD_MINOR_V0 = MD_MINOR_VERSION_MIN,
- MD_MINOR_V1,
- MD_MINOR_V2,
- MD_MINOR_VERSION_MAX = MD_MINOR_V2
-} md_minor_version_t;
-
-static uint64_t _v1_sb_offset(uint64_t size, md_minor_version_t minor_version)
-{
- uint64_t sb_offset;
-
- switch(minor_version) {
- case MD_MINOR_V0:
- sb_offset = (size - 8 * 2) & ~(4 * 2 - 1ULL);
- break;
- case MD_MINOR_V1:
- sb_offset = 0;
- break;
- case MD_MINOR_V2:
- sb_offset = 4 * 2;
- break;
- default:
- log_warn(INTERNAL_ERROR "WARNING: Unknown minor version %d.",
- minor_version);
- return 0;
- }
- sb_offset <<= SECTOR_SHIFT;
-
- return sb_offset;
-}
-
/*
* _udev_dev_is_md_component() only works if
* external_device_info_source="udev"
@@ -218,7 +176,6 @@ static int _udev_dev_is_md_component(struct device *dev)
*/
static int _native_dev_is_md_component(struct device *dev, uint64_t *offset_found, int full)
{
- md_minor_version_t minor;
uint64_t size, sb_offset;
int ret;
@@ -234,9 +191,9 @@ static int _native_dev_is_md_component(struct device *dev, uint64_t *offset_foun
return 0;
/*
- * Old md versions locate the magic number at the end of the device.
- * Those checks can't be satisfied with the initial bcache data, and
- * would require an extra read i/o at the end of every device. Issuing
+ * Some md versions locate the magic number at the end of the device.
+ * Those checks can't be satisfied with the initial scan data, and
+ * require an extra read i/o at the end of every device. Issuing
* an extra read to every device in every command, just to check for
* the old md format is a bad tradeoff.
*
@@ -247,54 +204,78 @@ static int _native_dev_is_md_component(struct device *dev, uint64_t *offset_foun
* and set it for commands that could possibly write to an md dev
* (pvcreate/vgcreate/vgextend).
*/
- if (!full) {
- sb_offset = 0;
- if (_dev_has_md_magic(dev, sb_offset)) {
- log_debug_devs("Found md magic number at offset 0 of %s.", dev_name(dev));
- ret = 1;
- goto out;
- }
- sb_offset = 8 << SECTOR_SHIFT;
- if (_dev_has_md_magic(dev, sb_offset)) {
- log_debug_devs("Found md magic number at offset %d of %s.", (int)sb_offset, dev_name(dev));
- ret = 1;
- goto out;
- }
+ /*
+ * md superblock version 1.1 at offset 0 from start
+ */
+
+ if (_dev_has_md_magic(dev, 0)) {
+ log_debug_devs("Found md magic number at offset 0 of %s.", dev_name(dev));
+ ret = 1;
+ goto out;
+ }
+
+ /*
+ * md superblock version 1.2 at offset 4KB from start
+ */
+ if (_dev_has_md_magic(dev, 4096)) {
+ log_debug_devs("Found md magic number at offset 4096 of %s.", dev_name(dev));
+ ret = 1;
+ goto out;
+ }
+
+ if (!full) {
ret = 0;
goto out;
}
- /* Version 0.90.0 */
- /* superblock at 64KB from end of device */
+ /*
+ * Handle superblocks at the end of the device.
+ */
+
+ /*
+ * md superblock version 0 at 64KB from end of device
+ * (after end is aligned to 64KB)
+ */
+
sb_offset = MD_NEW_SIZE_SECTORS(size) << SECTOR_SHIFT;
+
if (_dev_has_md_magic(dev, sb_offset)) {
+ log_debug_devs("Found md magic number at offset %llu of %s.", (unsigned long long)sb_offset, dev_name(dev));
ret = 1;
goto out;
}
- minor = MD_MINOR_VERSION_MIN;
+ /*
+ * md superblock version 1.0 at 8KB from end of device
+ */
- /* Version 1, try v1.0 -> v1.2 */
+ sb_offset = ((size - 8 * 2) & ~(4 * 2 - 1ULL)) << SECTOR_SHIFT;
- 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;
- goto out;
- }
- } while (++minor <= MD_MINOR_VERSION_MAX);
+ if (_dev_has_md_magic(dev, sb_offset)) {
+ log_debug_devs("Found md magic number at offset %llu of %s.", (unsigned long long)sb_offset, dev_name(dev));
+ ret = 1;
+ goto out;
+ }
+
+ /*
+ * md imsm superblock 1K from end of device
+ */
- /* superblock 1K from end of device */
if (_dev_has_imsm_magic(dev, size)) {
+ log_debug_devs("Found md imsm magic number at offset %llu of %s.", (unsigned long long)sb_offset, dev_name(dev));
+ sb_offset = 1024;
ret = 1;
goto out;
}
- /* superblock 512 bytes from end, or 128KB from end */
- if (_dev_has_ddf_magic(dev, size)) {
+ /*
+ * md ddf superblock 512 bytes from end, or 128KB from end
+ */
+
+ if (_dev_has_ddf_magic(dev, size, &sb_offset)) {
+ log_debug_devs("Found md ddf magic number at offset %llu of %s.", (unsigned long long)sb_offset, dev_name(dev));
ret = 1;
goto out;
}
--
2.27.0

View File

@ -0,0 +1,25 @@
From ecc646cea8b36d7256447311cfb7187c06600d41 Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabelac@redhat.com>
Date: Fri, 28 Aug 2020 18:58:55 +0200
Subject: [PATCH 20/22] gcc: calc size in compile time
---
lib/device/dev-md.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/device/dev-md.c b/lib/device/dev-md.c
index 23ce41a..8fe7fc3 100644
--- a/lib/device/dev-md.c
+++ b/lib/device/dev-md.c
@@ -50,7 +50,7 @@ static int _dev_has_md_magic(struct device *dev, uint64_t sb_offset)
}
#define IMSM_SIGNATURE "Intel Raid ISM Cfg Sig. "
-#define IMSM_SIG_LEN (strlen(IMSM_SIGNATURE))
+#define IMSM_SIG_LEN (sizeof(IMSM_SIGNATURE) - 1)
static int _dev_has_imsm_magic(struct device *dev, uint64_t devsize_sectors)
{
--
2.27.0

View File

@ -0,0 +1,36 @@
From ce343148c06c394971fec2ca53f15c60b87a8cf8 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Thu, 18 Feb 2021 11:42:32 -0600
Subject: [PATCH 21/22] fix check for md raid imsm signature on 4k devices
On devices with 4k logical block size, the imsm signature
is located 8k from the end of the device, not 1k as is
the case for devices with 512 LBS.
---
lib/device/dev-md.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/lib/device/dev-md.c b/lib/device/dev-md.c
index 8fe7fc3..9f211a8 100644
--- a/lib/device/dev-md.c
+++ b/lib/device/dev-md.c
@@ -56,6 +56,16 @@ 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;
+ unsigned int physical_block_size = 0;
+ unsigned int logical_block_size = 0;
+
+ if (!dev_get_direct_block_sizes(dev, &physical_block_size, &logical_block_size))
+ return_0;
+
+ if (logical_block_size == 4096)
+ off = (devsize_sectors * 512) - 8192;
+ else
+ off = (devsize_sectors * 512) - 1024;
if (!dev_read_bytes(dev, off, IMSM_SIG_LEN, imsm_signature))
return_0;
--
2.27.0

View File

@ -0,0 +1,25 @@
From 60fcc3cfedd9ee1557e981f557511d0ee87ff45e Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabelac@redhat.com>
Date: Fri, 23 Apr 2021 17:27:44 +0200
Subject: [PATCH 22/22] clang: remove unused assignment
---
lib/device/dev-md.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/device/dev-md.c b/lib/device/dev-md.c
index 9f211a8..9598039 100644
--- a/lib/device/dev-md.c
+++ b/lib/device/dev-md.c
@@ -55,7 +55,7 @@ static int _dev_has_md_magic(struct device *dev, uint64_t sb_offset)
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;
+ uint64_t off;
unsigned int physical_block_size = 0;
unsigned int logical_block_size = 0;
--
2.27.0

View File

@ -43,7 +43,7 @@
Name: lvm2
Version: 2.03.09
Release: 12
Release: 13
Epoch: 8
Summary: Tools for logical volume management
License: GPLv2+ and LGPLv2.1 and BSD
@ -66,6 +66,11 @@ Patch14: 0014-unit-test-modify-for-systems-with-PGSIZE-of-64K.patch
Patch15: 0015-13-dm-disk.rules-check-DM_NAME-before-create-symlink.patch
Patch16: 0016-dev_name-determine-whether-the-dev-aliases-linked-li.patch
Patch17: 0017-lvm-code-reduce-cyclomatic-complexity.patch
Patch18: 0018-devices-detect-md-ddf-and-imsm-superblocks.patch
Patch19: 0019-devices-simplify-md-superblock-checking-code.patch
Patch20: 0020-gcc-calc-size-in-compile-time.patch
Patch21: 0021-fix-check-for-md-raid-imsm-signature-on-4k-devices.patch
Patch22: 0022-clang-remove-unused-assignment.patch
BuildRequires: gcc
BuildRequires: gcc-c++
@ -491,6 +496,9 @@ fi
%changelog
* Sat Oct 29 2022 Xiaole He <hexiaole@kylinos.cn> - 8:2.03.09-13
- backport patches:18-22 for supporting intel vroc raid(virtual raid on cpu)
* Sun Jan 30 2022 Zhiqiang Liu <liuzhiqiang26@huawei.com> - 8.2.03.09-12
- lvm: code reduce cyclomatic complexity