forked from pool/mdadm
Accepting request 893159 from home:colyli:branches:Base:System
- Grow: be careful of corrupt dev_roles list (bsc#1181619) 0117-Grow-be-careful-of-corrupt-dev_roles-list.patch - imsm: nvme multipath support (bsc#1175758) 0116-imsm-nvme-multipath-support.patch OBS-URL: https://build.opensuse.org/request/show/893159 OBS-URL: https://build.opensuse.org/package/show/Base:System/mdadm?expand=0&rev=197
This commit is contained in:
parent
ec91862c51
commit
38bab7da8c
232
0116-imsm-nvme-multipath-support.patch
Normal file
232
0116-imsm-nvme-multipath-support.patch
Normal 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
|
||||
|
166
0117-Grow-be-careful-of-corrupt-dev_roles-list.patch
Normal file
166
0117-Grow-be-careful-of-corrupt-dev_roles-list.patch
Normal 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
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user