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

Reply via email to