import mdadm-4.2-rc1_3.el8

This commit is contained in:
CentOS Sources 2021-07-23 12:31:42 +00:00 committed by Andrew Lukoshko
parent 2fb8b48ff8
commit cdf6b7786a
16 changed files with 1535 additions and 5 deletions

View File

@ -0,0 +1,39 @@
From ff904202a4a6232e0f0dfea31a7c4a34ab08f76e Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Wed, 21 Apr 2021 16:50:08 +0200
Subject: [PATCH 01/15] imsm: change wrong size verification
Expectation that size is always rounded is incorrect.
Just confirm that size is smaller to be certain that update is safe.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
super-intel.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/super-intel.c b/super-intel.c
index 876e077..be0313d 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -11823,12 +11823,12 @@ static int imsm_fix_size_mismatch(struct supertype *st, int subarray_index)
if (calc_size == d_size || dev->vol.migr_type == MIGR_GEN_MIGR)
continue;
- /* There is a difference, verify that imsm_dev_size is
- * rounded correctly and push update.
+ /* There is a difference, confirm that imsm_dev_size is
+ * smaller and push update.
*/
- if (d_size != round_size_to_mb(d_size, disc_count)) {
- dprintf("imsm: Size of volume %d is not rounded correctly\n",
- i);
+ if (d_size > calc_size) {
+ pr_err("imsm: dev size of subarray %d is incorrect\n",
+ i);
goto exit;
}
memset(&geo, 0, sizeof(struct geo_params));
--
2.7.5

View File

@ -1,7 +1,7 @@
From 83b3de7795d2a421eb6ae4ab97656a250bb898ea Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Fri, 23 Apr 2021 14:01:30 +0800
Subject: [PATCH 1/2] Fix some building errors
Subject: [PATCH 02/15] Fix some building errors
There are some building errors if treating warning as errors.
Fix them in this patch.

View File

@ -1,7 +1,7 @@
From 0530e2e0d8c9ecb5171e70bc48e1a6566f317378 Mon Sep 17 00:00:00 2001
From: Norbert Szulc <norbert.szulc@intel.com>
Date: Wed, 5 May 2021 13:01:02 +0200
Subject: [PATCH 2/2] Prevent user from using --stop with ambiguous args
Subject: [PATCH 03/15] Prevent user from using --stop with ambiguous args
When both --scan and device name is passed to --stop action,
then is executed only for given device. Scan is ignored.

View File

@ -0,0 +1,327 @@
From 7c798f870900f6f4d4647dd3c88318524d7ccee4 Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Mon, 17 May 2021 16:39:00 +0200
Subject: [PATCH 04/15] imsm: add generic method to resolve "device" links
Each virtual device is linked with parent by "device". This patch adds
possibility to get previous device in sysfs tree.
Depending on device type, there is a different amount of virutal
layers. The best we can do is allow to directly specify how many
"device" links need to be resolved. This approach also allows to get
previous virtual device, which may contain some attributes.
Simplify fd2devname, this function doesn't require new functionality and
shall use generic fd2kname.
For nvme drives represented via nvme-subystem when path to block
device if requested, then return it without translation.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
platform-intel.c | 75 ++++++++++++++++++++++++++++++++++++++------------------
platform-intel.h | 4 +--
super-intel.c | 63 ++++++++++++++++++-----------------------------
3 files changed, 77 insertions(+), 65 deletions(-)
diff --git a/platform-intel.c b/platform-intel.c
index 2da152f..2ed63ed 100644
--- a/platform-intel.c
+++ b/platform-intel.c
@@ -712,28 +712,61 @@ char *get_nvme_multipath_dev_hw_path(const char *dev_path)
return rp;
}
-char *devt_to_devpath(dev_t dev)
+/* Description: Return part or whole realpath for the dev
+ * Parameters:
+ * dev - the device to be quered
+ * dev_level - level of "/device" entries. It allows to caller to access
+ * virtual or physical devices which are on "path" to quered
+ * one.
+ * buf - optional, must be PATH_MAX size. If set, then will be used.
+ */
+char *devt_to_devpath(dev_t dev, int dev_level, char *buf)
{
- char device[46];
- char *rp;
- char *buf;
+ char device[PATH_MAX];
+ char *hw_path;
+ int i;
+ unsigned long device_free_len = sizeof(device) - 1;
+ char dev_str[] = "/device";
+ unsigned long dev_str_len = strlen(dev_str);
+
+ snprintf(device, sizeof(device), "/sys/dev/block/%d:%d", major(dev),
+ minor(dev));
+
+ /* If caller wants block device, return path to it even if it is exposed
+ * via virtual layer.
+ */
+ if (dev_level == 0)
+ return realpath(device, buf);
- sprintf(device, "/sys/dev/block/%d:%d/device", major(dev), minor(dev));
+ device_free_len -= strlen(device);
+ for (i = 0; i < dev_level; i++) {
+ if (device_free_len < dev_str_len)
+ return NULL;
- rp = realpath(device, NULL);
- if (!rp)
- return NULL;
+ strncat(device, dev_str, device_free_len);
- buf = get_nvme_multipath_dev_hw_path(rp);
- if (buf) {
- free(rp);
- return buf;
+ /* Resolve nvme-subsystem abstraction if needed
+ */
+ device_free_len -= dev_str_len;
+ if (i == 0) {
+ char rp[PATH_MAX];
+
+ if (!realpath(device, rp))
+ return NULL;
+ hw_path = get_nvme_multipath_dev_hw_path(rp);
+ if (hw_path) {
+ strcpy(device, hw_path);
+ device_free_len = sizeof(device) -
+ strlen(device) - 1;
+ free(hw_path);
+ }
+ }
}
- return rp;
+ return realpath(device, buf);
}
-char *diskfd_to_devpath(int fd)
+char *diskfd_to_devpath(int fd, int dev_level, char *buf)
{
/* return the device path for a disk, return NULL on error or fd
* refers to a partition
@@ -745,7 +778,7 @@ char *diskfd_to_devpath(int fd)
if (!S_ISBLK(st.st_mode))
return NULL;
- return devt_to_devpath(st.st_rdev);
+ return devt_to_devpath(st.st_rdev, dev_level, buf);
}
int path_attached_to_hba(const char *disk_path, const char *hba_path)
@@ -770,7 +803,7 @@ int path_attached_to_hba(const char *disk_path, const char *hba_path)
int devt_attached_to_hba(dev_t dev, const char *hba_path)
{
- char *disk_path = devt_to_devpath(dev);
+ char *disk_path = devt_to_devpath(dev, 1, NULL);
int rc = path_attached_to_hba(disk_path, hba_path);
if (disk_path)
@@ -781,7 +814,7 @@ int devt_attached_to_hba(dev_t dev, const char *hba_path)
int disk_attached_to_hba(int fd, const char *hba_path)
{
- char *disk_path = diskfd_to_devpath(fd);
+ char *disk_path = diskfd_to_devpath(fd, 1, NULL);
int rc = path_attached_to_hba(disk_path, hba_path);
if (disk_path)
@@ -862,15 +895,9 @@ int imsm_is_nvme_supported(int disk_fd, int verbose)
*/
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))
+ if (!diskfd_to_devpath(disk_fd, 0, ns_path))
return 0;
if (strncmp(ns_path, NVME_SUBSYS_PATH, strlen(NVME_SUBSYS_PATH)) == 0)
diff --git a/platform-intel.h b/platform-intel.h
index 8396a0f..f93add5 100644
--- a/platform-intel.h
+++ b/platform-intel.h
@@ -237,7 +237,7 @@ static inline char *guid_str(char *buf, struct efi_guid guid)
}
char *get_nvme_multipath_dev_hw_path(const char *dev_path);
-char *diskfd_to_devpath(int fd);
+char *diskfd_to_devpath(int fd, int dev_level, char *buf);
__u16 devpath_to_vendor(const char *dev_path);
struct sys_dev *find_driver_devices(const char *bus, const char *driver);
struct sys_dev *find_intel_devices(void);
@@ -245,7 +245,7 @@ const struct imsm_orom *find_imsm_capability(struct sys_dev *hba);
const struct imsm_orom *find_imsm_orom(void);
int disk_attached_to_hba(int fd, const char *hba_path);
int devt_attached_to_hba(dev_t dev, const char *hba_path);
-char *devt_to_devpath(dev_t dev);
+char *devt_to_devpath(dev_t dev, int dev_level, char *buf);
int path_attached_to_hba(const char *disk_path, const char *hba_path);
const char *get_sys_dev_type(enum sys_dev_type);
const struct orom_entry *get_orom_entry_by_device_id(__u16 dev_id);
diff --git a/super-intel.c b/super-intel.c
index 5469912..cff8550 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -694,7 +694,7 @@ static struct sys_dev* find_disk_attached_hba(int fd, const char *devname)
if (fd < 0)
disk_path = (char *) devname;
else
- disk_path = diskfd_to_devpath(fd);
+ disk_path = diskfd_to_devpath(fd, 1, NULL);
if (!disk_path)
return 0;
@@ -2253,7 +2253,7 @@ static int ahci_enumerate_ports(const char *hba_path, int port_count, int host_b
if (sscanf(ent->d_name, "%d:%d", &major, &minor) != 2)
continue;
- path = devt_to_devpath(makedev(major, minor));
+ path = devt_to_devpath(makedev(major, minor), 1, NULL);
if (!path)
continue;
if (!path_attached_to_hba(path, hba_path)) {
@@ -2407,7 +2407,7 @@ static int print_nvme_info(struct sys_dev *hba)
continue;
}
- device_path = diskfd_to_devpath(fd);
+ device_path = diskfd_to_devpath(fd, 1, NULL);
if (!device_path) {
close(fd);
continue;
@@ -4015,28 +4015,13 @@ static int compare_super_imsm(struct supertype *st, struct supertype *tst,
static void fd2devname(int fd, char *name)
{
- struct stat st;
- char path[256];
- char dname[PATH_MAX];
char *nm;
- int rv;
-
- name[0] = '\0';
- if (fstat(fd, &st) != 0)
- return;
- sprintf(path, "/sys/dev/block/%d:%d",
- major(st.st_rdev), minor(st.st_rdev));
- rv = readlink(path, dname, sizeof(dname)-1);
- if (rv <= 0)
+ nm = fd2kname(fd);
+ if (!nm)
return;
- dname[rv] = '\0';
- nm = strrchr(dname, '/');
- if (nm) {
- nm++;
- snprintf(name, MAX_RAID_SERIAL_LEN, "/dev/%s", nm);
- }
+ snprintf(name, MAX_RAID_SERIAL_LEN, "/dev/%s", nm);
}
static int nvme_get_serial(int fd, void *buf, size_t buf_len)
@@ -5941,29 +5926,23 @@ static int add_to_super_imsm(struct supertype *st, mdu_disk_info_t *dk,
free(dd);
abort();
}
+
if (super->hba && ((super->hba->type == SYS_DEV_NVME) ||
(super->hba->type == SYS_DEV_VMD))) {
int i;
- char *devpath = diskfd_to_devpath(fd);
- char controller_path[PATH_MAX];
- char *controller_name;
+ char cntrl_path[PATH_MAX];
+ char *cntrl_name;
+ char pci_dev_path[PATH_MAX];
- if (!devpath) {
- pr_err("failed to get devpath, aborting\n");
+ if (!diskfd_to_devpath(fd, 2, pci_dev_path) ||
+ !diskfd_to_devpath(fd, 1, cntrl_path)) {
+ pr_err("failed to get dev_path, aborting\n");
if (dd->devname)
free(dd->devname);
free(dd);
return 1;
}
- 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)) {
if (dd->devname)
free(dd->devname);
@@ -5971,7 +5950,12 @@ static int add_to_super_imsm(struct supertype *st, mdu_disk_info_t *dk,
return 1;
}
- if (devpath_to_vendor(controller_path) == 0x8086) {
+ cntrl_name = basename(cntrl_path);
+ if (is_multipath_nvme(fd))
+ pr_err("%s controller supports Multi-Path I/O, Intel (R) VROC does not support multipathing\n",
+ cntrl_name);
+
+ if (devpath_to_vendor(pci_dev_path) == 0x8086) {
/*
* If Intel's NVMe drive has serial ended with
* "-A","-B","-1" or "-2" it means that this is "x8"
@@ -6985,7 +6969,7 @@ get_devices(const char *hba_path)
char *path = NULL;
if (sscanf(ent->d_name, "%d:%d", &major, &minor) != 2)
continue;
- path = devt_to_devpath(makedev(major, minor));
+ path = devt_to_devpath(makedev(major, minor), 1, NULL);
if (!path)
continue;
if (!path_attached_to_hba(path, hba_path)) {
@@ -10648,7 +10632,7 @@ int validate_container_imsm(struct mdinfo *info)
struct sys_dev *hba = NULL;
struct sys_dev *intel_devices = find_intel_devices();
char *dev_path = devt_to_devpath(makedev(info->disk.major,
- info->disk.minor));
+ info->disk.minor), 1, NULL);
for (idev = intel_devices; idev; idev = idev->next) {
if (dev_path && strstr(dev_path, idev->path)) {
@@ -10669,7 +10653,8 @@ int validate_container_imsm(struct mdinfo *info)
struct mdinfo *dev;
for (dev = info->next; dev; dev = dev->next) {
- dev_path = devt_to_devpath(makedev(dev->disk.major, dev->disk.minor));
+ dev_path = devt_to_devpath(makedev(dev->disk.major,
+ dev->disk.minor), 1, NULL);
struct sys_dev *hba2 = NULL;
for (idev = intel_devices; idev; idev = idev->next) {
@@ -11181,7 +11166,7 @@ static const char *imsm_get_disk_controller_domain(const char *path)
struct sys_dev* hba;
char *path;
- path = devt_to_devpath(st.st_rdev);
+ path = devt_to_devpath(st.st_rdev, 1, NULL);
if (path == NULL)
return "unknown";
hba = find_disk_attached_hba(-1, path);
--
2.7.5

View File

@ -0,0 +1,157 @@
From fcebeb77b18842876295b1a0dbc22d173a709434 Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Mon, 17 May 2021 16:39:01 +0200
Subject: [PATCH 05/15] imsm: add devpath_to_char method
Add method for reading sysfs attributes and propagate it across IMSM code.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
platform-intel.c | 23 +++++++++++++++++++++++
platform-intel.h | 2 ++
super-intel.c | 33 +++++++++++++++------------------
3 files changed, 40 insertions(+), 18 deletions(-)
diff --git a/platform-intel.c b/platform-intel.c
index 2ed63ed..9401784 100644
--- a/platform-intel.c
+++ b/platform-intel.c
@@ -239,6 +239,29 @@ __u16 devpath_to_vendor(const char *dev_path)
return id;
}
+/* Description: Read text value of dev_path/entry field
+ * Parameters:
+ * dev_path - sysfs path to the device
+ * entry - entry to be read
+ * buf - buffer for read value
+ * len - size of buf
+ * verbose - error logging level
+ */
+int devpath_to_char(const char *dev_path, const char *entry, char *buf, int len,
+ int verbose)
+{
+ char path[PATH_MAX];
+
+ snprintf(path, sizeof(path), "%s/%s", dev_path, entry);
+ if (load_sys(path, buf, len)) {
+ if (verbose)
+ pr_err("Cannot read %s, aborting\n", path);
+ return 1;
+ }
+
+ return 0;
+}
+
struct sys_dev *find_intel_devices(void)
{
struct sys_dev *ahci, *isci, *nvme;
diff --git a/platform-intel.h b/platform-intel.h
index f93add5..45d98cd 100644
--- a/platform-intel.h
+++ b/platform-intel.h
@@ -238,6 +238,8 @@ static inline char *guid_str(char *buf, struct efi_guid guid)
char *get_nvme_multipath_dev_hw_path(const char *dev_path);
char *diskfd_to_devpath(int fd, int dev_level, char *buf);
+int devpath_to_char(const char *dev_path, const char *entry, char *buf,
+ int len, int verbose);
__u16 devpath_to_vendor(const char *dev_path);
struct sys_dev *find_driver_devices(const char *bus, const char *driver);
struct sys_dev *find_intel_devices(void);
diff --git a/super-intel.c b/super-intel.c
index cff8550..c352f50 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -2246,7 +2246,7 @@ static int ahci_enumerate_ports(const char *hba_path, int port_count, int host_b
char vendor[64];
char buf[1024];
int major, minor;
- char *device;
+ char device[PATH_MAX];
char *c;
int port;
int type;
@@ -2262,20 +2262,15 @@ static int ahci_enumerate_ports(const char *hba_path, int port_count, int host_b
continue;
}
- /* retrieve the scsi device type */
- if (asprintf(&device, "/sys/dev/block/%d:%d/device/xxxxxxx", major, minor) < 0) {
+ /* retrieve the scsi device */
+ if (!devt_to_devpath(makedev(major, minor), 1, device)) {
if (verbose > 0)
- pr_err("failed to allocate 'device'\n");
+ pr_err("failed to get device\n");
err = 2;
break;
}
- sprintf(device, "/sys/dev/block/%d:%d/device/type", major, minor);
- if (load_sys(device, buf, sizeof(buf)) != 0) {
- if (verbose > 0)
- pr_err("failed to read device type for %s\n",
- path);
+ if (devpath_to_char(device, "type", buf, sizeof(buf), 0)) {
err = 2;
- free(device);
break;
}
type = strtoul(buf, NULL, 10);
@@ -2284,8 +2279,9 @@ static int ahci_enumerate_ports(const char *hba_path, int port_count, int host_b
if (!(type == 0 || type == 7 || type == 14)) {
vendor[0] = '\0';
model[0] = '\0';
- sprintf(device, "/sys/dev/block/%d:%d/device/vendor", major, minor);
- if (load_sys(device, buf, sizeof(buf)) == 0) {
+
+ if (devpath_to_char(device, "vendor", buf,
+ sizeof(buf), 0) == 0) {
strncpy(vendor, buf, sizeof(vendor));
vendor[sizeof(vendor) - 1] = '\0';
c = (char *) &vendor[sizeof(vendor) - 1];
@@ -2293,8 +2289,9 @@ static int ahci_enumerate_ports(const char *hba_path, int port_count, int host_b
*c-- = '\0';
}
- sprintf(device, "/sys/dev/block/%d:%d/device/model", major, minor);
- if (load_sys(device, buf, sizeof(buf)) == 0) {
+
+ if (devpath_to_char(device, "model", buf,
+ sizeof(buf), 0) == 0) {
strncpy(model, buf, sizeof(model));
model[sizeof(model) - 1] = '\0';
c = (char *) &model[sizeof(model) - 1];
@@ -2319,7 +2316,6 @@ static int ahci_enumerate_ports(const char *hba_path, int port_count, int host_b
}
} else
buf[0] = '\0';
- free(device);
/* chop device path to 'host%d' and calculate the port number */
c = strchr(&path[hba_len], '/');
@@ -4026,7 +4022,7 @@ static void fd2devname(int fd, char *name)
static int nvme_get_serial(int fd, void *buf, size_t buf_len)
{
- char path[60];
+ char path[PATH_MAX];
char *name = fd2kname(fd);
if (!name)
@@ -4035,9 +4031,10 @@ static int nvme_get_serial(int fd, void *buf, size_t buf_len)
if (strncmp(name, "nvme", 4) != 0)
return 1;
- snprintf(path, sizeof(path) - 1, "/sys/block/%s/device/serial", name);
+ if (!diskfd_to_devpath(fd, 1, path))
+ return 1;
- return load_sys(path, buf, buf_len);
+ return devpath_to_char(path, "serial", buf, buf_len, 0);
}
extern int scsi_get_serial(int fd, void *buf, size_t buf_len);
--
2.7.5

View File

@ -0,0 +1,329 @@
From 8662f92d71f1f88589061272606b8b673d31de05 Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Mon, 17 May 2021 16:39:02 +0200
Subject: [PATCH 06/15] imsm: Limit support to the lowest namespace
First namespace existence is not quaranted by NVMe specification.
Instead first the smallest one shall be chosen.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
platform-intel.c | 81 ++++++++++++++++++++++++++----------
platform-intel.h | 2 +-
super-intel.c | 124 +++++++++++++++++++++++++++----------------------------
3 files changed, 123 insertions(+), 84 deletions(-)
diff --git a/platform-intel.c b/platform-intel.c
index 9401784..5a8729e 100644
--- a/platform-intel.c
+++ b/platform-intel.c
@@ -879,36 +879,75 @@ char *vmd_domain_to_controller(struct sys_dev *hba, char *buf)
closedir(dir);
return NULL;
}
-/* Verify that NVMe drive is supported by IMSM
+
+/* Scan over all controller's namespaces and compare nsid value to verify if
+ * current one is supported. The routine doesn't check IMSM capabilities for
+ * namespace. Only one nvme namespace is supported by IMSM.
+ * Paramteres:
+ * fd - open descriptor to the nvme namespace
+ * verbose - error logging level
* Returns:
- * 0 - not supported
- * 1 - supported
+ * 1 - if namespace is supported
+ * 0 - otherwise
*/
-int imsm_is_nvme_supported(int disk_fd, int verbose)
+int imsm_is_nvme_namespace_supported(int fd, int verbose)
{
- char nsid_path[PATH_MAX];
- char buf[PATH_MAX];
- struct stat stb;
+ DIR *dir = NULL;
+ struct dirent *ent;
+ char cntrl_path[PATH_MAX];
+ char ns_path[PATH_MAX];
+ unsigned long long lowest_nsid = ULLONG_MAX;
+ unsigned long long this_nsid;
+ int rv = 0;
- if (disk_fd < 0)
- return 0;
- if (fstat(disk_fd, &stb))
- return 0;
+ if (!diskfd_to_devpath(fd, 1, cntrl_path) ||
+ !diskfd_to_devpath(fd, 0, ns_path)) {
+ if (verbose)
+ pr_err("Cannot get device paths\n");
+ goto abort;
+ }
- snprintf(nsid_path, PATH_MAX-1, "/sys/dev/block/%d:%d/nsid",
- major(stb.st_rdev), minor(stb.st_rdev));
- if (load_sys(nsid_path, buf, sizeof(buf))) {
- pr_err("Cannot read %s, rejecting drive\n", nsid_path);
- return 0;
- }
- if (strtoll(buf, NULL, 10) != 1) {
+ if (devpath_to_ll(ns_path, "nsid", &this_nsid)) {
if (verbose)
- pr_err("Only first namespace is supported by IMSM, aborting\n");
- return 0;
+ pr_err("Cannot read nsid value for %s",
+ basename(ns_path));
+ goto abort;
}
- return 1;
+
+ dir = opendir(cntrl_path);
+ if (!dir)
+ goto abort;
+
+ /* The lowest nvme namespace is supported */
+ for (ent = readdir(dir); ent; ent = readdir(dir)) {
+ unsigned long long curr_nsid;
+ char curr_ns_path[PATH_MAX + 256];
+
+ if (!strstr(ent->d_name, "nvme"))
+ continue;
+
+ snprintf(curr_ns_path, sizeof(curr_ns_path), "%s/%s",
+ cntrl_path, ent->d_name);
+
+ if (devpath_to_ll(curr_ns_path, "nsid", &curr_nsid))
+ goto abort;
+
+ if (lowest_nsid > curr_nsid)
+ lowest_nsid = curr_nsid;
+ }
+
+ if (this_nsid == lowest_nsid)
+ rv = 1;
+ else if (verbose)
+ pr_err("IMSM is supported on the lowest NVMe namespace\n");
+
+abort:
+ if (dir)
+ closedir(dir);
+
+ return rv;
}
/* Verify if multipath is supported by NVMe controller
diff --git a/platform-intel.h b/platform-intel.h
index 45d98cd..6238d23 100644
--- a/platform-intel.h
+++ b/platform-intel.h
@@ -254,6 +254,6 @@ const struct orom_entry *get_orom_entry_by_device_id(__u16 dev_id);
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);
+int imsm_is_nvme_namespace_supported(int disk_fd, int verbose);
char *vmd_domain_to_controller(struct sys_dev *hba, char *buf);
diff --git a/super-intel.c b/super-intel.c
index c352f50..fdcefb6 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -2381,49 +2381,51 @@ 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;
- int fd;
dir = opendir("/sys/block/");
if (!dir)
return 1;
for (ent = readdir(dir); ent; ent = readdir(dir)) {
- if (strstr(ent->d_name, "nvme")) {
- fd = open_dev(ent->d_name);
- if (fd < 0)
- continue;
+ char ns_path[PATH_MAX];
+ char cntrl_path[PATH_MAX];
+ char buf[PATH_MAX];
+ int fd = -1;
- if (!imsm_is_nvme_supported(fd, 0)) {
- if (fd >= 0)
- close(fd);
- continue;
- }
+ if (!strstr(ent->d_name, "nvme"))
+ goto skip;
- device_path = diskfd_to_devpath(fd, 1, NULL);
- if (!device_path) {
- close(fd);
- continue;
- }
+ fd = open_dev(ent->d_name);
+ if (fd < 0)
+ goto skip;
- if (path_attached_to_hba(device_path, hba->path)) {
- fd2devname(fd, buf);
- if (hba->type == SYS_DEV_VMD)
- printf(" NVMe under VMD : %s", buf);
- else if (hba->type == SYS_DEV_NVME)
- printf(" NVMe Device : %s", buf);
- if (!imsm_read_serial(fd, NULL, (__u8 *)buf,
- sizeof(buf)))
- printf(" (%s)\n", buf);
- else
- printf("()\n");
- }
- free(device_path);
+ if (!diskfd_to_devpath(fd, 0, ns_path) ||
+ !diskfd_to_devpath(fd, 1, cntrl_path))
+ goto skip;
+
+ if (!path_attached_to_hba(cntrl_path, hba->path))
+ goto skip;
+
+ if (!imsm_is_nvme_namespace_supported(fd, 0))
+ goto skip;
+
+ fd2devname(fd, buf);
+ if (hba->type == SYS_DEV_VMD)
+ printf(" NVMe under VMD : %s", buf);
+ else if (hba->type == SYS_DEV_NVME)
+ printf(" NVMe Device : %s", buf);
+
+ if (!imsm_read_serial(fd, NULL, (__u8 *)buf,
+ sizeof(buf)))
+ printf(" (%s)\n", buf);
+ else
+ printf("()\n");
+
+skip:
+ if (fd > -1)
close(fd);
- }
}
closedir(dir);
@@ -5933,14 +5935,8 @@ static int add_to_super_imsm(struct supertype *st, mdu_disk_info_t *dk,
if (!diskfd_to_devpath(fd, 2, pci_dev_path) ||
!diskfd_to_devpath(fd, 1, cntrl_path)) {
- pr_err("failed to get dev_path, aborting\n");
- if (dd->devname)
- free(dd->devname);
- free(dd);
- return 1;
- }
+ pr_err("failed to get dev paths, aborting\n");
- if (!imsm_is_nvme_supported(dd->fd, 1)) {
if (dd->devname)
free(dd->devname);
free(dd);
@@ -6665,7 +6661,7 @@ static int validate_geometry_imsm_container(struct supertype *st, int level,
{
int fd;
unsigned long long ldsize;
- struct intel_super *super;
+ struct intel_super *super = NULL;
int rv = 0;
if (level != LEVEL_CONTAINER)
@@ -6680,24 +6676,18 @@ static int validate_geometry_imsm_container(struct supertype *st, int level,
dev, strerror(errno));
return 0;
}
- if (!get_dev_size(fd, dev, &ldsize)) {
- close(fd);
- return 0;
- }
+ if (!get_dev_size(fd, dev, &ldsize))
+ goto exit;
/* capabilities retrieve could be possible
* note that there is no fd for the disks in array.
*/
super = alloc_super();
- if (!super) {
- close(fd);
- return 0;
- }
- if (!get_dev_sector_size(fd, NULL, &super->sector_size)) {
- close(fd);
- free_imsm(super);
- return 0;
- }
+ if (!super)
+ goto exit;
+
+ if (!get_dev_sector_size(fd, NULL, &super->sector_size))
+ goto exit;
rv = find_intel_hba_capability(fd, super, verbose > 0 ? dev : NULL);
if (rv != 0) {
@@ -6708,32 +6698,42 @@ static int validate_geometry_imsm_container(struct supertype *st, int level,
fd, str, super->orom, rv, raiddisks);
#endif
/* no orom/efi or non-intel hba of the disk */
- close(fd);
- free_imsm(super);
- return 0;
+ rv = 0;
+ goto exit;
}
- close(fd);
if (super->orom) {
if (raiddisks > super->orom->tds) {
if (verbose)
pr_err("%d exceeds maximum number of platform supported disks: %d\n",
raiddisks, super->orom->tds);
- free_imsm(super);
- return 0;
+ goto exit;
}
if ((super->orom->attr & IMSM_OROM_ATTR_2TB_DISK) == 0 &&
(ldsize >> 9) >> 32 > 0) {
if (verbose)
pr_err("%s exceeds maximum platform supported size\n", dev);
- free_imsm(super);
- return 0;
+ goto exit;
+ }
+
+ if (super->hba->type == SYS_DEV_VMD ||
+ super->hba->type == SYS_DEV_NVME) {
+ if (!imsm_is_nvme_namespace_supported(fd, 1)) {
+ if (verbose)
+ pr_err("NVMe namespace %s is not supported by IMSM\n",
+ basename(dev));
+ goto exit;
+ }
}
}
*freesize = avail_size_imsm(st, ldsize >> 9, data_offset);
- free_imsm(super);
+ rv = 1;
+exit:
+ if (super)
+ free_imsm(super);
+ close(fd);
- return 1;
+ return rv;
}
static unsigned long long find_size(struct extent *e, int *idx, int num_extents)
--
2.7.5

View File

@ -0,0 +1,107 @@
From 1f5d54a06df01ca3032ca2d29159584cab7d7509 Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Mon, 17 May 2021 16:39:03 +0200
Subject: [PATCH 07/15] Manage: Call validate_geometry when adding drive to
external container
When adding drive to container call validate_geometry to verify whether
drive is supported and can be addded to container.
Remove unused parameters from validate_geometry_imsm_container().
There is no need to pass them.
Don't calculate freesize if it is not mandatory. Make it configurable.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Manage.c | 7 +++++++
super-ddf.c | 9 +++++----
super-intel.c | 19 +++++++------------
3 files changed, 19 insertions(+), 16 deletions(-)
diff --git a/Manage.c b/Manage.c
index 0a5f09b..f789e0c 100644
--- a/Manage.c
+++ b/Manage.c
@@ -992,6 +992,13 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv,
return -1;
}
+ /* Check if metadata handler is able to accept the drive */
+ if (!tst->ss->validate_geometry(tst, LEVEL_CONTAINER, 0, 1, NULL,
+ 0, 0, dv->devname, NULL, 0, 1)) {
+ close(container_fd);
+ return -1;
+ }
+
Kill(dv->devname, NULL, 0, -1, 0);
dfd = dev_open(dv->devname, O_RDWR | O_EXCL|O_DIRECT);
if (tst->ss->add_to_super(tst, &disc, dfd,
diff --git a/super-ddf.c b/super-ddf.c
index 2314762..80a40f8 100644
--- a/super-ddf.c
+++ b/super-ddf.c
@@ -3475,10 +3475,11 @@ validate_geometry_ddf_container(struct supertype *st,
return 0;
}
close(fd);
-
- *freesize = avail_size_ddf(st, ldsize >> 9, INVALID_SECTORS);
- if (*freesize == 0)
- return 0;
+ if (freesize) {
+ *freesize = avail_size_ddf(st, ldsize >> 9, INVALID_SECTORS);
+ if (*freesize == 0)
+ return 0;
+ }
return 1;
}
diff --git a/super-intel.c b/super-intel.c
index fdcefb6..fe45d93 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -6652,8 +6652,7 @@ static int store_super_imsm(struct supertype *st, int fd)
}
static int validate_geometry_imsm_container(struct supertype *st, int level,
- int layout, int raiddisks, int chunk,
- unsigned long long size,
+ int raiddisks,
unsigned long long data_offset,
char *dev,
unsigned long long *freesize,
@@ -6725,8 +6724,8 @@ static int validate_geometry_imsm_container(struct supertype *st, int level,
}
}
}
-
- *freesize = avail_size_imsm(st, ldsize >> 9, data_offset);
+ if (freesize)
+ *freesize = avail_size_imsm(st, ldsize >> 9, data_offset);
rv = 1;
exit:
if (super)
@@ -7586,15 +7585,11 @@ static int validate_geometry_imsm(struct supertype *st, int level, int layout,
* if given unused devices create a container
* if given given devices in a container create a member volume
*/
- if (level == LEVEL_CONTAINER) {
+ if (level == LEVEL_CONTAINER)
/* Must be a fresh device to add to a container */
- return validate_geometry_imsm_container(st, level, layout,
- raiddisks,
- *chunk,
- size, data_offset,
- dev, freesize,
- verbose);
- }
+ return validate_geometry_imsm_container(st, level, raiddisks,
+ data_offset, dev,
+ freesize, verbose);
/*
* Size is given in sectors.
--
2.7.5

View File

@ -0,0 +1,31 @@
From f421731c7e1de6608f8fafb551d199ff5f1d6b97 Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Wed, 2 Jun 2021 09:17:19 +0800
Subject: [PATCH 08/15] mdadm/super1: It needs to specify int32 for
bitmap_offset
For super1.0 bitmap offset is -16. So it needs to use int type for bitmap offset.
Fixes: 1fe2e1007310 (mdadm/bitmap: locate bitmap calcuate bitmap position wrongly)
Signed-off-by: Xiao Ni <xni@redhat.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
super1.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/super1.c b/super1.c
index c05e623..a12a5bc 100644
--- a/super1.c
+++ b/super1.c
@@ -2631,7 +2631,7 @@ static int locate_bitmap1(struct supertype *st, int fd, int node_num)
else
ret = -1;
- offset = __le64_to_cpu(sb->super_offset) + __le32_to_cpu(sb->bitmap_offset);
+ offset = __le64_to_cpu(sb->super_offset) + (int32_t)__le32_to_cpu(sb->bitmap_offset);
if (node_num) {
bms = (bitmap_super_t*)(((char*)sb)+MAX_SB_SIZE);
bm_sectors_per_node = calc_bitmap_size(bms, 4096) >> 9;
--
2.7.5

View File

@ -0,0 +1,48 @@
From dca80fcd5d15c37ecbd82763e6fe4aee8c077bf9 Mon Sep 17 00:00:00 2001
From: Blazej Kucman <blazej.kucman@intel.com>
Date: Tue, 15 Jun 2021 16:45:39 +0200
Subject: [PATCH 09/15] Use dev_open in validate geometry container
Fix regression caused by the patch 1f5d54a06
("Manage: Call validate_geometry when adding drive to external container")
- mdmonitor passes to Manage() routine dev name as min:mjr.
The open() used in validate_geometry_container()
in both ddf and imsm requires path, replace open calls by dev_open,
which allows to use dev path and min:mjr.
Signed-off-by: Blazej Kucman <blazej.kucman@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
super-ddf.c | 2 +-
super-intel.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/super-ddf.c b/super-ddf.c
index 80a40f8..dc8e512 100644
--- a/super-ddf.c
+++ b/super-ddf.c
@@ -3463,7 +3463,7 @@ validate_geometry_ddf_container(struct supertype *st,
if (!dev)
return 1;
- fd = open(dev, O_RDONLY|O_EXCL, 0);
+ fd = dev_open(dev, O_RDONLY|O_EXCL);
if (fd < 0) {
if (verbose)
pr_err("ddf: Cannot open %s: %s\n",
diff --git a/super-intel.c b/super-intel.c
index fe45d93..5356ca5 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -6668,7 +6668,7 @@ static int validate_geometry_imsm_container(struct supertype *st, int level,
if (!dev)
return 1;
- fd = open(dev, O_RDONLY|O_EXCL, 0);
+ fd = dev_open(dev, O_RDONLY|O_EXCL);
if (fd < 0) {
if (verbose > 0)
pr_err("imsm: Cannot open %s: %s\n",
--
2.7.5

View File

@ -0,0 +1,30 @@
From 7d8935cbb0fdb2b776b736bffc00323a04e5f788 Mon Sep 17 00:00:00 2001
From: Oleksandr Shchirskyi <oleksandr.shchirskyi@linux.intel.com>
Date: Fri, 18 Jun 2021 15:53:30 +0200
Subject: [PATCH 10/15] imsm: correct offset for 4k disks in --examine output
"Sector Offset" field in Examine output was always printed in 512
byte sectors. Update it to support 4096 sector size.
Signed-off-by: Oleksandr Shchirskyi <oleksandr.shchirskyi@linux.intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
super-intel.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/super-intel.c b/super-intel.c
index 5356ca5..88636e0 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -1663,7 +1663,7 @@ static void print_imsm_dev(struct intel_super *super,
(unsigned long long)sz * 512 / super->sector_size,
human_size(sz * 512));
printf(" Sector Offset : %llu\n",
- pba_of_lba0(map));
+ pba_of_lba0(map) * 512 / super->sector_size);
printf(" Num Stripes : %llu\n",
num_data_stripes(map));
printf(" Chunk Size : %u KiB",
--
2.7.5

View File

@ -0,0 +1,35 @@
From 8d69bf147ec77447c5d45c17bed7dc017808cc44 Mon Sep 17 00:00:00 2001
From: Oleksandr Shchirskyi <oleksandr.shchirskyi@linux.intel.com>
Date: Fri, 18 Jun 2021 15:53:31 +0200
Subject: [PATCH 11/15] Remove Spare drives line from details for external
metadata
Arrays with external metadata do not have spare disks directly
assigned to volumes; spare disks belong to containers and are
moved to arrays when the array is degraded/reshaping.
Thus, the display of zero spare disks in volume details is
incorrect and can be confusing.
Signed-off-by: Oleksandr Shchirskyi <oleksandr.shchirskyi@linux.intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Detail.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/Detail.c b/Detail.c
index cd26fb0..ad56344 100644
--- a/Detail.c
+++ b/Detail.c
@@ -548,7 +548,8 @@ int Detail(char *dev, struct context *c)
array.working_disks);
if (array.raid_disks) {
printf(" Failed Devices : %d\n", array.failed_disks);
- printf(" Spare Devices : %d\n", array.spare_disks);
+ if (!external)
+ printf(" Spare Devices : %d\n", array.spare_disks);
}
printf("\n");
if (array.level == 5) {
--
2.7.5

View File

@ -0,0 +1,173 @@
From 601ffa784f03cea843b9b732e561ffea0b8c036f Mon Sep 17 00:00:00 2001
From: Oleksandr Shchirskyi <oleksandr.shchirskyi@linux.intel.com>
Date: Fri, 18 Jun 2021 15:53:32 +0200
Subject: [PATCH 12/15] Don't associate spares with other arrays during RAID
Examine
Spares in imsm belong to containers, not volumes, and must go into
a separate container when assembling the RAID.
Remove association spares with other arrays and make Examine print
separate containers for spares.
Auto assemble without config file already works like this. So make
creating a config file and assembling from it consistent with auto
assemble.
With this change, mdadm -Es will add this line to output if spares
are found:
ARRAY metadata=imsm UUID=00000000:00000000:00000000:00000000
Signed-off-by: Oleksandr Shchirskyi <oleksandr.shchirskyi@linux.intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Examine.c | 2 +-
super-intel.c | 74 +++++++++++++++--------------------------------------------
2 files changed, 20 insertions(+), 56 deletions(-)
diff --git a/Examine.c b/Examine.c
index 4381cd5..9574a3c 100644
--- a/Examine.c
+++ b/Examine.c
@@ -166,7 +166,7 @@ int Examine(struct mddev_dev *devlist,
int newline = 0;
ap->st->ss->brief_examine_super(ap->st, c->verbose > 0);
- if (ap->spares)
+ if (ap->spares && !ap->st->ss->external)
newline += printf(" spares=%d", ap->spares);
if (c->verbose > 0) {
newline += printf(" devices");
diff --git a/super-intel.c b/super-intel.c
index 88636e0..aeea137 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -2123,12 +2123,6 @@ static void brief_examine_super_imsm(struct supertype *st, int verbose)
/* We just write a generic IMSM ARRAY entry */
struct mdinfo info;
char nbuf[64];
- struct intel_super *super = st->sb;
-
- if (!super->anchor->num_raid_devs) {
- printf("ARRAY metadata=imsm\n");
- return;
- }
getinfo_super_imsm(st, &info, NULL);
fname_from_uuid(st, &info, nbuf, ':');
@@ -3911,12 +3905,9 @@ static void imsm_copy_dev(struct imsm_dev *dest, struct imsm_dev *src)
static int compare_super_imsm(struct supertype *st, struct supertype *tst,
int verbose)
{
- /*
- * return:
+ /* return:
* 0 same, or first was empty, and second was copied
- * 1 second had wrong number
- * 2 wrong uuid
- * 3 wrong other info
+ * 1 sb are different
*/
struct intel_super *first = st->sb;
struct intel_super *sec = tst->sb;
@@ -3926,31 +3917,30 @@ static int compare_super_imsm(struct supertype *st, struct supertype *tst,
tst->sb = NULL;
return 0;
}
+
/* in platform dependent environment test if the disks
* use the same Intel hba
- * If not on Intel hba at all, allow anything.
+ * if not on Intel hba at all, allow anything.
+ * doesn't check HBAs if num_raid_devs is not set, as it means
+ * it is a free floating spare, and all spares regardless of HBA type
+ * will fall into separate container during the assembly
*/
- if (!check_env("IMSM_NO_PLATFORM") && first->hba && sec->hba) {
+ if (first->hba && sec->hba && first->anchor->num_raid_devs != 0) {
if (first->hba->type != sec->hba->type) {
if (verbose)
pr_err("HBAs of devices do not match %s != %s\n",
get_sys_dev_type(first->hba->type),
get_sys_dev_type(sec->hba->type));
- return 3;
+ return 1;
}
-
if (first->orom != sec->orom) {
if (verbose)
pr_err("HBAs of devices do not match %s != %s\n",
first->hba->pci_id, sec->hba->pci_id);
- return 3;
+ return 1;
}
-
}
- /* if an anchor does not have num_raid_devs set then it is a free
- * floating spare
- */
if (first->anchor->num_raid_devs > 0 &&
sec->anchor->num_raid_devs > 0) {
/* Determine if these disks might ever have been
@@ -3962,7 +3952,7 @@ static int compare_super_imsm(struct supertype *st, struct supertype *tst,
if (memcmp(first->anchor->sig, sec->anchor->sig,
MAX_SIGNATURE_LENGTH) != 0)
- return 3;
+ return 1;
if (first_family == 0)
first_family = first->anchor->family_num;
@@ -3970,43 +3960,17 @@ static int compare_super_imsm(struct supertype *st, struct supertype *tst,
sec_family = sec->anchor->family_num;
if (first_family != sec_family)
- return 3;
+ return 1;
}
- /* if 'first' is a spare promote it to a populated mpb with sec's
- * family number
- */
- if (first->anchor->num_raid_devs == 0 &&
- sec->anchor->num_raid_devs > 0) {
- int i;
- struct intel_dev *dv;
- struct imsm_dev *dev;
-
- /* we need to copy raid device info from sec if an allocation
- * fails here we don't associate the spare
- */
- for (i = 0; i < sec->anchor->num_raid_devs; i++) {
- dv = xmalloc(sizeof(*dv));
- dev = xmalloc(sizeof_imsm_dev(get_imsm_dev(sec, i), 1));
- dv->dev = dev;
- dv->index = i;
- dv->next = first->devlist;
- first->devlist = dv;
- }
- if (i < sec->anchor->num_raid_devs) {
- /* allocation failure */
- free_devlist(first);
- pr_err("imsm: failed to associate spare\n");
- return 3;
- }
- first->anchor->num_raid_devs = sec->anchor->num_raid_devs;
- first->anchor->orig_family_num = sec->anchor->orig_family_num;
- first->anchor->family_num = sec->anchor->family_num;
- memcpy(first->anchor->sig, sec->anchor->sig, MAX_SIGNATURE_LENGTH);
- for (i = 0; i < sec->anchor->num_raid_devs; i++)
- imsm_copy_dev(get_imsm_dev(first, i), get_imsm_dev(sec, i));
- }
+ /* if an anchor does not have num_raid_devs set then it is a free
+ * floating spare. don't assosiate spare with any array, as during assembly
+ * spares shall fall into separate container, from which they can be moved
+ * when necessary
+ */
+ if (first->anchor->num_raid_devs ^ sec->anchor->num_raid_devs)
+ return 1;
return 0;
}
--
2.7.5

View File

@ -0,0 +1,49 @@
From ccd61ebfd97fde43768497c79e3d361b484b1520 Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Tue, 22 Jun 2021 23:15:55 +0800
Subject: [PATCH 13/15] mdadm: Fix building errors
In util.c, there is a building error:
'/md/metadata_version' directive writing 20 bytes into a
region of size between 0 and 255 [-Werror=format-overflow=]
In mapfile.c
It declares the fouth argument as 'int *' in map_update,
but in mdadm.h it's previously declared as an array 'int[4]'
Signed-off-by: Xiao Ni <xni@redhat.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
mapfile.c | 2 +-
util.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/mapfile.c b/mapfile.c
index 8d7acb3..6b2207d 100644
--- a/mapfile.c
+++ b/mapfile.c
@@ -215,7 +215,7 @@ void map_free(struct map_ent *map)
}
int map_update(struct map_ent **mpp, char *devnm, char *metadata,
- int *uuid, char *path)
+ int uuid[4], char *path)
{
struct map_ent *map, *mp;
int rv;
diff --git a/util.c b/util.c
index 5879694..cdf1da2 100644
--- a/util.c
+++ b/util.c
@@ -1543,7 +1543,7 @@ int open_container(int fd)
/* 'fd' is a block device. Find out if it is in use
* by a container, and return an open fd on that container.
*/
- char path[256];
+ char path[288];
char *e;
DIR *dir;
struct dirent *de;
--
2.7.5

View File

@ -0,0 +1,142 @@
From 3a85bf0e417d0977136efbade7c7ea269e24bc21 Mon Sep 17 00:00:00 2001
From: Mateusz Grzonka <mateusz.grzonka@intel.com>
Date: Mon, 28 Jun 2021 14:15:04 +0200
Subject: [PATCH 14/15] imsm: Fix possible memory leaks and refactor freeing
struct dl
Free memory allocated by structs dl and intel_super.
Allow __free_imsm_disk to decide if fd has to be closed and propagate it
across code instead of direct struct dl freeing.
Signed-off-by: Mateusz Grzonka <mateusz.grzonka@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
super-intel.c | 39 +++++++++++++++++++--------------------
1 file changed, 19 insertions(+), 20 deletions(-)
diff --git a/super-intel.c b/super-intel.c
index aeea137..da37625 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -4499,9 +4499,9 @@ load_and_parse_mpb(int fd, struct intel_super *super, char *devname, int keep_fd
return err;
}
-static void __free_imsm_disk(struct dl *d)
+static void __free_imsm_disk(struct dl *d, int close_fd)
{
- if (d->fd >= 0)
+ if (close_fd && d->fd > -1)
close(d->fd);
if (d->devname)
free(d->devname);
@@ -4518,17 +4518,17 @@ static void free_imsm_disks(struct intel_super *super)
while (super->disks) {
d = super->disks;
super->disks = d->next;
- __free_imsm_disk(d);
+ __free_imsm_disk(d, 1);
}
while (super->disk_mgmt_list) {
d = super->disk_mgmt_list;
super->disk_mgmt_list = d->next;
- __free_imsm_disk(d);
+ __free_imsm_disk(d, 1);
}
while (super->missing) {
d = super->missing;
super->missing = d->next;
- __free_imsm_disk(d);
+ __free_imsm_disk(d, 1);
}
}
@@ -5243,10 +5243,13 @@ static int load_super_imsm(struct supertype *st, int fd, char *devname)
free_super_imsm(st);
super = alloc_super();
- if (!get_dev_sector_size(fd, NULL, &super->sector_size))
- return 1;
if (!super)
return 1;
+
+ if (!get_dev_sector_size(fd, NULL, &super->sector_size)) {
+ free_imsm(super);
+ return 1;
+ }
/* Load hba and capabilities if they exist.
* But do not preclude loading metadata in case capabilities or hba are
* non-compliant and ignore_hw_compat is set.
@@ -5884,9 +5887,7 @@ static int add_to_super_imsm(struct supertype *st, mdu_disk_info_t *dk,
rv = imsm_read_serial(fd, devname, dd->serial, MAX_RAID_SERIAL_LEN);
if (rv) {
pr_err("failed to retrieve scsi serial, aborting\n");
- if (dd->devname)
- free(dd->devname);
- free(dd);
+ __free_imsm_disk(dd, 0);
abort();
}
@@ -5900,10 +5901,7 @@ static int add_to_super_imsm(struct supertype *st, mdu_disk_info_t *dk,
if (!diskfd_to_devpath(fd, 2, pci_dev_path) ||
!diskfd_to_devpath(fd, 1, cntrl_path)) {
pr_err("failed to get dev paths, aborting\n");
-
- if (dd->devname)
- free(dd->devname);
- free(dd);
+ __free_imsm_disk(dd, 0);
return 1;
}
@@ -5939,15 +5937,16 @@ static int add_to_super_imsm(struct supertype *st, mdu_disk_info_t *dk,
!imsm_orom_has_tpv_support(super->orom)) {
pr_err("\tPlatform configuration does not support non-Intel NVMe drives.\n"
"\tPlease refer to Intel(R) RSTe/VROC user guide.\n");
- free(dd->devname);
- free(dd);
+ __free_imsm_disk(dd, 0);
return 1;
}
}
get_dev_size(fd, NULL, &size);
- if (!get_dev_sector_size(fd, NULL, &member_sector_size))
+ if (!get_dev_sector_size(fd, NULL, &member_sector_size)) {
+ __free_imsm_disk(dd, 0);
return 1;
+ }
if (super->sector_size == 0) {
/* this a first device, so sector_size is not set yet */
@@ -9260,7 +9259,7 @@ static int remove_disk_super(struct intel_super *super, int major, int minor)
else
super->disks = dl->next;
dl->next = NULL;
- __free_imsm_disk(dl);
+ __free_imsm_disk(dl, 1);
dprintf("removed %x:%x\n", major, minor);
break;
}
@@ -9310,7 +9309,7 @@ static int add_remove_disk_update(struct intel_super *super)
}
}
/* release allocate disk structure */
- __free_imsm_disk(disk_cfg);
+ __free_imsm_disk(disk_cfg, 1);
}
}
return check_degraded;
@@ -10511,7 +10510,7 @@ static void imsm_delete(struct intel_super *super, struct dl **dlp, unsigned ind
struct dl *dl = *dlp;
*dlp = (*dlp)->next;
- __free_imsm_disk(dl);
+ __free_imsm_disk(dl, 1);
}
}
--
2.7.5

View File

@ -0,0 +1,32 @@
From 5b30a34aa4b5ea7a8202314c1d737ec4a481c127 Mon Sep 17 00:00:00 2001
From: Mateusz Grzonka <mateusz.grzonka@intel.com>
Date: Thu, 15 Jul 2021 12:25:23 +0200
Subject: [PATCH 15/15] Add error handling for chunk size in RAID1
Print error if chunk size is set as it is not supported.
Signed-off-by: Mateusz Grzonka <mateusz.grzonka@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Create.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/Create.c b/Create.c
index 18b5e64..f5d57f8 100644
--- a/Create.c
+++ b/Create.c
@@ -254,9 +254,8 @@ int Create(struct supertype *st, char *mddev,
case LEVEL_MULTIPATH:
case LEVEL_CONTAINER:
if (s->chunk) {
- s->chunk = 0;
- if (c->verbose > 0)
- pr_err("chunk size ignored for this level\n");
+ pr_err("specifying chunk size is forbidden for this level\n");
+ return 1;
}
break;
default:
--
2.7.5

View File

@ -2,7 +2,7 @@ Summary: The mdadm program controls Linux md devices (software RAID arrays)
Name: mdadm
Version: 4.2
%define subversion rc1
Release: rc1_2%{?dist}
Release: rc1_3%{?dist}
Source: http://www.kernel.org/pub/linux/utils/raid/mdadm/mdadm-%{version}-%{subversion}.tar.xz
Source1: mdmonitor.init
Source2: raid-check
@ -15,8 +15,21 @@ Source8: mdadm_event.conf
Source9: mdcheck
Source10: mdadm_env.sh
Patch001: 0001-Fix-some-building-errors.patch
Patch002: 0002-Prevent-user-from-using-stop-with-ambiguous-args.patch
Patch001: 0001-imsm-change-wrong-size-verification.patch
Patch002: 0002-Fix-some-building-errors.patch
Patch003: 0003-Prevent-user-from-using-stop-with-ambiguous-args.patch
Patch004: 0004-imsm-add-generic-method-to-resolve-device-links.patch
Patch005: 0005-imsm-add-devpath_to_char-method.patch
Patch006: 0006-imsm-Limit-support-to-the-lowest-namespace.patch
Patch007: 0007-Manage-Call-validate_geometry-when-adding-drive-to-e.patch
Patch008: 0008-mdadm-super1-It-needs-to-specify-int32-for-bitmap_of.patch
Patch009: 0009-Use-dev_open-in-validate-geometry-container.patch
Patch010: 0010-imsm-correct-offset-for-4k-disks-in-examine-output.patch
Patch011: 0011-Remove-Spare-drives-line-from-details-for-external-m.patch
Patch012: 0012-Don-t-associate-spares-with-other-arrays-during-RAID.patch
Patch013: 0013-mdadm-Fix-building-errors.patch
Patch014: 0014-imsm-Fix-possible-memory-leaks-and-refactor-freeing-.patch
Patch015: 0015-Add-error-handling-for-chunk-size-in-RAID1.patch
# RHEL customization patches
Patch200: mdadm-3.3-udev.patch
@ -49,6 +62,20 @@ file can be used to help with some common tasks.
%patch001 -p1 -b .0001
%patch002 -p1 -b .0002
%patch003 -p1 -b .0003
%patch004 -p1 -b .0004
%patch005 -p1 -b .0005
%patch006 -p1 -b .0006
%patch007 -p1 -b .0007
%patch008 -p1 -b .0008
%patch009 -p1 -b .0009
%patch010 -p1 -b .0010
%patch011 -p1 -b .0011
%patch012 -p1 -b .0012
%patch013 -p1 -b .0013
%patch014 -p1 -b .0014
%patch015 -p1 -b .0015
# RHEL customization patches
%patch200 -p1 -b .udev
%patch201 -p1 -b .static
@ -119,6 +146,10 @@ rm -rf %{buildroot}
/usr/lib/mdadm/mdadm_env.sh
%changelog
* Tue Jul 20 2021 Xiao Ni <xni@redhat.com> - 4.2-rc1-3
- Fix super1.0 offset problem and super imsm bugs
- Resolves rhbz#1966712 and rhbz#1975449
* Thu Jun 10 2021 Xiao Ni <xni@redhat.com> - 4.2-rc1-2
- Fix udev rule syntax error
- Resolves rhbz#1945780