Accepting request 893458 from Base:System

OBS-URL: https://build.opensuse.org/request/show/893458
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/mdadm?expand=0&rev=128
This commit is contained in:
Dominique Leuenberger 2021-05-20 17:23:16 +00:00 committed by Git OBS Bridge
commit 387d61e7e1
4 changed files with 414 additions and 0 deletions

View File

@ -0,0 +1,232 @@
From d835518b6b5381da773e1ce1ae10614239017ecf Mon Sep 17 00:00:00 2001
From: Blazej Kucman <blazej.kucman@intel.com>
Date: Fri, 12 Mar 2021 10:30:16 +0100
Subject: [PATCH] imsm: nvme multipath support
Patch-mainline: mdadm-4.1+
Git-commit: d835518b6b5381da773e1ce1ae10614239017ecf
References: bsc#1175758
Add support for nvme devices which are represented
via nvme-subsystem.
Print warning when multi-path disk is added to RAID.
Signed-off-by: Oleksandr Shchirskyi <oleksandr.shchirskyi@intel.com>
Signed-off-by: Blazej Kucman <blazej.kucman@intel.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
Signed-off-by: Coly Li <colyli@suse.de>
---
platform-intel.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++-
platform-intel.h | 2 ++
super-intel.c | 38 ++++++++++++++---------
3 files changed, 104 insertions(+), 15 deletions(-)
diff --git a/platform-intel.c b/platform-intel.c
index f1f6d4c..0e1ec3d 100644
--- a/platform-intel.c
+++ b/platform-intel.c
@@ -30,6 +30,8 @@
#include <sys/stat.h>
#include <limits.h>
+#define NVME_SUBSYS_PATH "/sys/devices/virtual/nvme-subsystem/"
+
static int devpath_to_ll(const char *dev_path, const char *entry,
unsigned long long *val);
@@ -668,12 +670,63 @@ const struct imsm_orom *find_imsm_capability(struct sys_dev *hba)
return NULL;
}
+/* Check whether the nvme device is represented by nvme subsytem,
+ * if yes virtual path should be changed to hardware device path,
+ * to allow IMSM capabilities detection.
+ * Returns:
+ * hardware path to device - if the device is represented via
+ * nvme virtual subsytem
+ * NULL - if the device is not represented via nvme virtual subsytem
+ */
+char *get_nvme_multipath_dev_hw_path(const char *dev_path)
+{
+ DIR *dir;
+ struct dirent *ent;
+ char *rp = NULL;
+
+ if (strncmp(dev_path, NVME_SUBSYS_PATH, strlen(NVME_SUBSYS_PATH)) != 0)
+ return NULL;
+
+ dir = opendir(dev_path);
+ if (!dir)
+ return NULL;
+
+ for (ent = readdir(dir); ent; ent = readdir(dir)) {
+ char buf[strlen(dev_path) + strlen(ent->d_name) + 1];
+
+ /* Check if dir is a controller, ignore namespaces*/
+ if (!(strncmp(ent->d_name, "nvme", 4) == 0) ||
+ (strrchr(ent->d_name, 'n') != &ent->d_name[0]))
+ continue;
+
+ sprintf(buf, "%s/%s", dev_path, ent->d_name);
+ rp = realpath(buf, NULL);
+ break;
+ }
+
+ closedir(dir);
+ return rp;
+}
+
char *devt_to_devpath(dev_t dev)
{
char device[46];
+ char *rp;
+ char *buf;
sprintf(device, "/sys/dev/block/%d:%d/device", major(dev), minor(dev));
- return realpath(device, NULL);
+
+ rp = realpath(device, NULL);
+ if (!rp)
+ return NULL;
+
+ buf = get_nvme_multipath_dev_hw_path(rp);
+ if (buf) {
+ free(rp);
+ return buf;
+ }
+
+ return rp;
}
char *diskfd_to_devpath(int fd)
@@ -797,3 +850,27 @@ int imsm_is_nvme_supported(int disk_fd, int verbose)
}
return 1;
}
+
+/* Verify if multipath is supported by NVMe controller
+ * Returns:
+ * 0 - not supported
+ * 1 - supported
+ */
+int is_multipath_nvme(int disk_fd)
+{
+ char path_buf[PATH_MAX];
+ char ns_path[PATH_MAX];
+ char *kname = fd2kname(disk_fd);
+
+ if (!kname)
+ return 0;
+ sprintf(path_buf, "/sys/block/%s", kname);
+
+ if (!realpath(path_buf, ns_path))
+ return 0;
+
+ if (strncmp(ns_path, NVME_SUBSYS_PATH, strlen(NVME_SUBSYS_PATH)) == 0)
+ return 1;
+
+ return 0;
+}
diff --git a/platform-intel.h b/platform-intel.h
index 7371478..8396a0f 100644
--- a/platform-intel.h
+++ b/platform-intel.h
@@ -236,6 +236,7 @@ static inline char *guid_str(char *buf, struct efi_guid guid)
return buf;
}
+char *get_nvme_multipath_dev_hw_path(const char *dev_path);
char *diskfd_to_devpath(int fd);
__u16 devpath_to_vendor(const char *dev_path);
struct sys_dev *find_driver_devices(const char *bus, const char *driver);
@@ -252,4 +253,5 @@ const struct imsm_orom *get_orom_by_device_id(__u16 device_id);
struct sys_dev *device_by_id(__u16 device_id);
struct sys_dev *device_by_id_and_path(__u16 device_id, const char *path);
int imsm_is_nvme_supported(int disk_fd, int verbose);
+int is_multipath_nvme(int disk_fd);
char *vmd_domain_to_controller(struct sys_dev *hba, char *buf);
diff --git a/super-intel.c b/super-intel.c
index 2bfcad1..6617dd6 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -2386,9 +2386,9 @@ static int ahci_enumerate_ports(const char *hba_path, int port_count, int host_b
static int print_nvme_info(struct sys_dev *hba)
{
char buf[1024];
+ char *device_path;
struct dirent *ent;
DIR *dir;
- char *rp;
int fd;
dir = opendir("/sys/block/");
@@ -2397,19 +2397,23 @@ static int print_nvme_info(struct sys_dev *hba)
for (ent = readdir(dir); ent; ent = readdir(dir)) {
if (strstr(ent->d_name, "nvme")) {
- sprintf(buf, "/sys/block/%s", ent->d_name);
- rp = realpath(buf, NULL);
- if (!rp)
+ fd = open_dev(ent->d_name);
+ if (fd < 0)
continue;
- if (path_attached_to_hba(rp, hba->path)) {
- fd = open_dev(ent->d_name);
- if (!imsm_is_nvme_supported(fd, 0)) {
- if (fd >= 0)
- close(fd);
- free(rp);
- continue;
- }
+ if (!imsm_is_nvme_supported(fd, 0)) {
+ if (fd >= 0)
+ close(fd);
+ continue;
+ }
+
+ device_path = diskfd_to_devpath(fd);
+ if (!device_path) {
+ close(fd);
+ continue;
+ }
+
+ if (path_attached_to_hba(device_path, hba->path)) {
fd2devname(fd, buf);
if (hba->type == SYS_DEV_VMD)
printf(" NVMe under VMD : %s", buf);
@@ -2420,9 +2424,9 @@ static int print_nvme_info(struct sys_dev *hba)
printf(" (%s)\n", buf);
else
printf("()\n");
- close(fd);
}
- free(rp);
+ free(device_path);
+ close(fd);
}
}
@@ -5938,6 +5942,7 @@ static int add_to_super_imsm(struct supertype *st, mdu_disk_info_t *dk,
int i;
char *devpath = diskfd_to_devpath(fd);
char controller_path[PATH_MAX];
+ char *controller_name;
if (!devpath) {
pr_err("failed to get devpath, aborting\n");
@@ -5948,6 +5953,11 @@ static int add_to_super_imsm(struct supertype *st, mdu_disk_info_t *dk,
}
snprintf(controller_path, PATH_MAX-1, "%s/device", devpath);
+
+ controller_name = basename(devpath);
+ if (is_multipath_nvme(fd))
+ pr_err("%s controller supports Multi-Path I/O, Intel (R) VROC does not support multipathing\n", controller_name);
+
free(devpath);
if (!imsm_is_nvme_supported(dd->fd, 1)) {
--
2.26.2

View File

@ -0,0 +1,166 @@
From 8818d4e7fe7cda900d5c00014b05cdde058bdd29 Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.de>
Date: Fri, 26 Feb 2021 12:02:36 +1100
Subject: [PATCH] Grow: be careful of corrupt dev_roles list
Git-commit: 8818d4e7fe7cda900d5c00014b05cdde058bdd29
Patch-mainline: mdadm-4.1+
References: bsc#1181619
I've seen a case where the dev_roles list of a linear array
was corrupt. ->max_dev was > 128 and > raid_disks, and the
extra slots were '0', not 0xFFFE or 0xFFFF.
This caused problems when a 128th device was added.
So:
1/ make Grow_Add_device more robust so that if numbers
look wrong, it fails-safe.
2/ make examine_super1() report details if the dev_roles
array is corrupt.
Signed-off-by: NeilBrown <neilb@suse.de>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Grow.c | 15 ++++++++++++---
super1.c | 48 ++++++++++++++++++++++++++++++++++++++----------
2 files changed, 50 insertions(+), 13 deletions(-)
diff --git a/Grow.c b/Grow.c
index 5c2512f..cec8388 100644
--- a/Grow.c
+++ b/Grow.c
@@ -197,7 +197,12 @@ int Grow_Add_device(char *devname, int fd, char *newdev)
info.disk.minor = minor(rdev);
info.disk.raid_disk = d;
info.disk.state = (1 << MD_DISK_SYNC) | (1 << MD_DISK_ACTIVE);
- st->ss->update_super(st, &info, "linear-grow-new", newdev, 0, 0, NULL);
+ if (st->ss->update_super(st, &info, "linear-grow-new", newdev,
+ 0, 0, NULL) != 0) {
+ pr_err("Preparing new metadata failed on %s\n", newdev);
+ close(nfd);
+ return 1;
+ }
if (st->ss->store_super(st, nfd)) {
pr_err("Cannot store new superblock on %s\n", newdev);
@@ -250,8 +255,12 @@ int Grow_Add_device(char *devname, int fd, char *newdev)
info.array.active_disks = nd+1;
info.array.working_disks = nd+1;
- st->ss->update_super(st, &info, "linear-grow-update", dv,
- 0, 0, NULL);
+ if (st->ss->update_super(st, &info, "linear-grow-update", dv,
+ 0, 0, NULL) != 0) {
+ pr_err("Updating metadata failed on %s\n", dv);
+ close(fd2);
+ return 1;
+ }
if (st->ss->store_super(st, fd2)) {
pr_err("Cannot store new superblock on %s\n", dv);
diff --git a/super1.c b/super1.c
index b5b379b..7bee026 100644
--- a/super1.c
+++ b/super1.c
@@ -330,6 +330,7 @@ static void examine_super1(struct supertype *st, char *homehost)
int layout;
unsigned long long sb_offset;
struct mdinfo info;
+ int inconsistent = 0;
printf(" Magic : %08x\n", __le32_to_cpu(sb->magic));
printf(" Version : 1");
@@ -576,14 +577,16 @@ static void examine_super1(struct supertype *st, char *homehost)
if (role == d)
cnt++;
}
- if (cnt == 2)
+ if (cnt == 2 && __le32_to_cpu(sb->level) > 0)
printf("R");
else if (cnt == 1)
printf("A");
else if (cnt == 0)
printf(".");
- else
+ else {
printf("?");
+ inconsistent = 1;
+ }
}
#if 0
/* This is confusing too */
@@ -598,6 +601,21 @@ static void examine_super1(struct supertype *st, char *homehost)
#endif
printf(" ('A' == active, '.' == missing, 'R' == replacing)");
printf("\n");
+ for (d = 0; d < __le32_to_cpu(sb->max_dev); d++) {
+ unsigned int r = __le16_to_cpu(sb->dev_roles[d]);
+ if (r <= MD_DISK_ROLE_MAX &&
+ r > __le32_to_cpu(sb->raid_disks) + delta_extra)
+ inconsistent = 1;
+ }
+ if (inconsistent) {
+ printf("WARNING Array state is inconsistent - each number should appear only once\n");
+ for (d = 0; d < __le32_to_cpu(sb->max_dev); d++)
+ if (__le16_to_cpu(sb->dev_roles[d]) >= MD_DISK_ROLE_FAULTY)
+ printf(" %d:-", d);
+ else
+ printf(" %d:%d", d, __le16_to_cpu(sb->dev_roles[d]));
+ printf("\n");
+ }
}
static void brief_examine_super1(struct supertype *st, int verbose)
@@ -1264,19 +1282,25 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
rv = 1;
}
} else if (strcmp(update, "linear-grow-new") == 0) {
- unsigned int i;
+ int i;
int fd;
- unsigned int max = __le32_to_cpu(sb->max_dev);
+ int max = __le32_to_cpu(sb->max_dev);
+
+ if (max > MAX_DEVS)
+ return -2;
for (i = 0; i < max; i++)
if (__le16_to_cpu(sb->dev_roles[i]) >=
MD_DISK_ROLE_FAULTY)
break;
+ if (i != info->disk.number)
+ return -2;
sb->dev_number = __cpu_to_le32(i);
- info->disk.number = i;
- if (i >= max) {
+
+ if (i == max)
sb->max_dev = __cpu_to_le32(max+1);
- }
+ if (i > max)
+ return -2;
random_uuid(sb->device_uuid);
@@ -1302,10 +1326,14 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
}
} else if (strcmp(update, "linear-grow-update") == 0) {
int max = __le32_to_cpu(sb->max_dev);
- sb->raid_disks = __cpu_to_le32(info->array.raid_disks);
- if (info->array.raid_disks > max) {
+ int i = info->disk.number;
+ if (max > MAX_DEVS || i > MAX_DEVS)
+ return -2;
+ if (i > max)
+ return -2;
+ if (i == max)
sb->max_dev = __cpu_to_le32(max+1);
- }
+ sb->raid_disks = __cpu_to_le32(info->array.raid_disks);
sb->dev_roles[info->disk.number] =
__cpu_to_le16(info->disk.raid_disk);
} else if (strcmp(update, "resync") == 0) {
--
2.26.2

View File

@ -1,3 +1,15 @@
-------------------------------------------------------------------
Fri May 14 14:40:40 UTC 2021 - Coly Li <colyli@suse.com>
- Grow: be careful of corrupt dev_roles list (bsc#1181619)
0117-Grow-be-careful-of-corrupt-dev_roles-list.patch
-------------------------------------------------------------------
Fri May 14 12:17:31 UTC 2021 - Coly Li <colyli@suse.com>
- imsm: nvme multipath support (bsc#1175758)
0116-imsm-nvme-multipath-support.patch
-------------------------------------------------------------------
Wed Mar 17 02:35:00 UTC 2021 - Heming Zhao <heming.zhao@suse.com>

View File

@ -152,6 +152,8 @@ Patch112: 0112-Incremental-Remove-redundant-spare-movement-logic.patch
Patch113: 0113-Dump-get-stat-from-a-wrong-metadata-file-when-restor.patch
Patch114: 0114-super1-fix-Floating-point-exception.patch
Patch115: 0115-super1.c-avoid-useless-sync-when-bitmap-switches-fro.patch
Patch116: 0116-imsm-nvme-multipath-support.patch
Patch117: 0117-Grow-be-careful-of-corrupt-dev_roles-list.patch
Patch1001: 1001-display-timeout-status.patch
Patch1002: 1002-OnCalendar-format-fix-of-mdcheck_start-timer.patch
Patch1003: 1003-mdadm-treat-the-Dell-softraid-array-as-local-array.patch
@ -274,6 +276,8 @@ mdadm is a program that can be used to control Linux md devices.
%patch113 -p1
%patch114 -p1
%patch115 -p1
%patch116 -p1
%patch117 -p1
%patch1001 -p1
%patch1002 -p1
%patch1003 -p1