Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package mdadm for openSUSE:Factory checked in at 2021-05-20 19:23:16 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/mdadm (Old) and /work/SRC/openSUSE:Factory/.mdadm.new.2988 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "mdadm" Thu May 20 19:23:16 2021 rev:128 rq:893458 version:4.1 Changes: -------- --- /work/SRC/openSUSE:Factory/mdadm/mdadm.changes 2021-03-29 18:21:06.114220741 +0200 +++ /work/SRC/openSUSE:Factory/.mdadm.new.2988/mdadm.changes 2021-05-20 19:23:31.782325456 +0200 @@ -1,0 +2,12 @@ +Fri May 14 14:40:40 UTC 2021 - Coly Li <[email protected]> + +- 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 <[email protected]> + +- imsm: nvme multipath support (bsc#1175758) + 0116-imsm-nvme-multipath-support.patch + +------------------------------------------------------------------- New: ---- 0116-imsm-nvme-multipath-support.patch 0117-Grow-be-careful-of-corrupt-dev_roles-list.patch ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ mdadm.spec ++++++ --- /var/tmp/diff_new_pack.HQToLw/_old 2021-05-20 19:23:33.334318890 +0200 +++ /var/tmp/diff_new_pack.HQToLw/_new 2021-05-20 19:23:33.338318873 +0200 @@ -152,6 +152,8 @@ 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 @@ %patch113 -p1 %patch114 -p1 %patch115 -p1 +%patch116 -p1 +%patch117 -p1 %patch1001 -p1 %patch1002 -p1 %patch1003 -p1 ++++++ 0116-imsm-nvme-multipath-support.patch ++++++ >From d835518b6b5381da773e1ce1ae10614239017ecf Mon Sep 17 00:00:00 2001 From: Blazej Kucman <[email protected]> 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 <[email protected]> Signed-off-by: Blazej Kucman <[email protected]> Signed-off-by: Mariusz Tkaczyk <[email protected]> Signed-off-by: Jes Sorensen <[email protected]> Signed-off-by: Coly Li <[email protected]> --- 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 ++++++ 0117-Grow-be-careful-of-corrupt-dev_roles-list.patch ++++++ >From 8818d4e7fe7cda900d5c00014b05cdde058bdd29 Mon Sep 17 00:00:00 2001 From: NeilBrown <[email protected]> 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 <[email protected]> Signed-off-by: Jes Sorensen <[email protected]> --- 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
