Update to latest upstream

For issue RHEL-40729, patch 0142 fixes it.
For issue RHEL-31448, patch 0125 fixes it.

Resolves: RHEL-31448,RHEL-40729,RHEL-52059

Signed-off-by: Xiao Ni <xni@redhat.com>
This commit is contained in:
Xiao Ni 2024-10-19 04:44:44 -04:00
parent 2e3a947954
commit f1b7707f26
128 changed files with 11982 additions and 4 deletions

View File

@ -0,0 +1,193 @@
From 3f90be087fa62c0c7ed76c2ac26752f0ac3a89e7 Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Tue, 7 May 2024 17:35:09 +0200
Subject: [PATCH 067/201] mdadm: Change main repository to Github
Now github will be used for tracking mdadm, adjust README.md.
Daily routines will be automated on Github, there is not need to
decribe them.
Adjust release process, it must be published to both repositories.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
MAINTAINERS.md | 41 ++++++++----------------
README.md | 86 ++++++++++++++++++++++++++++----------------------
2 files changed, 61 insertions(+), 66 deletions(-)
diff --git a/MAINTAINERS.md b/MAINTAINERS.md
index 9c79ba87..e5b635f0 100644
--- a/MAINTAINERS.md
+++ b/MAINTAINERS.md
@@ -1,44 +1,29 @@
# Maintainer tools
-Useful tools used in daily routines:
+Useful tools for mdadm maintenance:
- [checkpatch](https://docs.kernel.org/dev-tools/checkpatch.html)
- [kup](https://korg.docs.kernel.org/kup.html)
- [Auto-publishing](https://korg.docs.kernel.org/kup.html#auto-publishing-with-git-archive-signer)
- [b4](https://b4.docs.kernel.org/en/latest/)
-# Checklist before applying patch
-
-We don't have CI testing yet, so all those steps must be performed manually:
-- Style check with [checkpatch](https://docs.kernel.org/dev-tools/checkpatch.html):
-
- This is the current code style follows. We are not strict to all rules. It must be run
- by **checkpatch --no-tree**, see README.md.
-
-- [Commit style](https://www.kernel.org/doc/html/v4.10/process/submitting-patches.html):
-
- It doesn't need to be followed as strictly as is in kernel but changes should be logically
- separated. Submitter should care at least to mention "It is used in next patches" if unused
- externs/files are added in patch. We love: *Reported-by:*, *Suggested-by:*, *Fixes:* tags.
-
-- Compilation, ideally on various gcc versions.
-- Mdadm test suite execution.
-- Consider requesting new tests from submitter, especially for new functionalities.
-- Ensure that maintainer *sign-off* is added, before pushing.
-
# Making a release
Assuming that maintainer is certain that release is safe, following steps must be done:
-- Update versions strings in release commit, please refer to previous releases for examples.
+- Make and push release commit:
+ - Update versions strings, refer to previous releases for examples.
+ - Update CHANGELOG.md.
+
+- Create GPG signed tag and push it to both remotes. Use same format as was used previously,
+ prefixed by **mdadm-**, e.g. **mdadm-3.1.2**, **mdadm-4.1**.
-- Create GPG signed tag and push it to repo. Use same format as was used previously, prefixed by
- **mdadm-**, e.g. **mdadm-3.1.2**, **mdadm-4.1**.
+- Run kernel.org
+ [Auto-publishing](https://korg.docs.kernel.org/kup.html#auto-publishing-with-git-archive-signer):
-- [Auto-publishing](https://korg.docs.kernel.org/kup.html#auto-publishing-with-git-archive-signer):
+ Adopt script to our release tag model. When ready, push signed note to kernel.org repository. If
+ it is done correctly, then *(sig)* is added to the package automatically generated by
+ kernel.org automation. There is no need to upload archive manually.
- Adopt script to our release tag model. When ready, push signed note to repository. If it is done
- correctly, then *(sig)* is added to the package automatically generated by kernel.org automation.
- There is no need to upload archive manually.
+- Add release entry on Github.
-- Update CHANGELOG.md.
- Write "ANNOUNCE" mail to linux-raid@kernel.org to notify community.
diff --git a/README.md b/README.md
index 64f2ecec..486c8929 100644
--- a/README.md
+++ b/README.md
@@ -20,58 +20,68 @@
**IMPORTANT:** DDF is in **maintenance only** mode. There is no active development around it.
Please do not use it in new solutions.
-# How to Contribute
-
- **mdadm** is hosted on [kernel.org](https://kernel.org/). You can access repository
-[here](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git).
+# Questions and Support
+
+This Github site is **not** right place to ask if your are looking for:
+- support from Linux Raid Community;
+- support with kernel issues;
+
+This is the place where development of mdadm application is done. Please, do not use for
+looking for support. You should always ask on [Mailing List](https://lore.kernel.org/linux-raid/).
+
+Please use issues if you have confirmation that issue you are experiencing is related to mdadm
+components:
+- mdadm;
+- mdmon;
+- raid6check;
+- swap_super;
+- test_stripe;
+- systemd services ( see systemd/);
+- udev rules;
+- manual pages (including md.man)
+
+For example:
+- mdadm issues (e.g segfaults, memory leaks, crashes, bad communication with MD driver);
+- feature requests for mdadm;
+- suggestions or minor fixes requested (e.g. better error messages);
+
+Generally, if you are not sure it is better to ask on
+[Mailing List](https://lore.kernel.org/linux-raid/) first.
-It is maintained similarly to kernel, using *mailing list*. Patches must be send through email.
-Please familiarize with general kernel
-[submitting patches](https://www.kernel.org/doc/html/v4.17/process/submitting-patches.html)
-documentation. Formatting, tags and commit message guidelines applies to **mdadm**.
+# How to Contribute
-## Sending patches step-by-step
+Effective immediately [Github](https://github.com/md-raid-utilities/mdadm) is the primary
+location for **mdadm**. Use pull request to contribute.
-To maximize change of patches being taken, follow this instruction when submitting:
+It was originally hosted on [kernel.org](https://kernel.org/). You can access the old repository
+[here](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git).
-1. Create possibly logically separated commits and generate patches:
+Patches sent through Mailing list are accepted but Github is preferred. Sent then to ML only
+if you cannot use Github. Please add "mdadm:" to the subject to allow automation to create Github
+Pull Request and run checks.
- Use ``git format-patch --cover-letter --signoff -v <nr>`` to create patches:
- * ``--cover-letter`` can be skipped if it is only one patch;
- * ``--signoff`` adds sign-off tag;
- * ``-v <nr>`` indicates review revision number, sender should increment it before resending.
+**NOTE:** Maintainers may ask you to send RFC to mailing list if the proposed code requires
+consultation with kernel developers.
-2. Check style of every patch with kernel
- [checkpatch](https://docs.kernel.org/dev-tools/checkpatch.html) script:
+Kernel coding style is used. Please familiarize with general kernel
+[submitting patches](https://www.kernel.org/doc/html/v4.17/process/submitting-patches.html)
+documentation. Formatting, tags and commit message guidelines applies to **mdadm**.
- It is important to keep same coding style that is why in **mdadm**
- [kernel coding style](https://www.kernel.org/doc/html/v4.10/process/coding-style.html)
- is preferred. ``checkpath --no-tree <patch_file>`` can be used to verify patches.
- Following checkpatch issues can be ignored:
- - New typedefs.
- - comparing with *True/False*.
- - kernel *MAINTAINERS* file warning.
- - *extern* keyword in headers.
+[Checkpatch](https://docs.kernel.org/dev-tools/checkpatch.html) script is run on
+every patch in pull request so be sure that your commits are not generating
+issues. There are some excludes, so the best is to follow github checkpatch action result.
-3. Send patches using ``git send-mail --to=linux-raid@vger.kernel.org <cover-letter> <patch1> <patch2> (...)``
+Pull Request are closed by `Rebase and Merge` option, so it requires to keep every commit
+meaningful. Kernel style requires that. The review changes must be pushed with **push --force**
+to the chosen branch, then Pull Request will be automatically updated.
-# Maintainers
+# Maintainers of mdadm repository on kernel.org
-It is good practice to add **mdadm maintainers** to recipients for patches:
+If there are differences between github and kernel.org, please contact kernel.org mdadm maintainers:
- Jes Sorensen <jes@trained-monkey.org>;
- Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>;
-Adding **MD maintainers** could be reasonable, especially if patches may affect MD driver:
-
-- Song Liu <song@kernel.org>;
-- Yu Kuai <yukuai3@huawei.com>;
-
-# Reviewers
-
-**mdadm** utility is not part of kernel tree, so there is no certificated *Reviewers* list. Everyone
-can comment on mailing list, last decision (and merging) belongs to maintainers.
-
# Minimal supported kernel version
We do not support kernel versions below **v3.10**. Please be aware that maintainers may remove
--
2.41.0

View File

@ -0,0 +1,267 @@
From 95673c7d83c8ac7f2aeb91a34ead2971ba30e96e Mon Sep 17 00:00:00 2001
From: Nigel Croxon <ncroxon@redhat.com>
Date: Mon, 20 May 2024 09:36:50 -0400
Subject: [PATCH 070/201] add checking of return status on fstat calls
There are a few places we don't check the return status when
calling fstat for success. Clean up the calls by adding a
check before continuing.
Signed-off-by: Nigel Croxon <ncroxon@redhat.com>
---
Assemble.c | 41 +++++++++++++++++++++++------------------
Dump.c | 11 +++++++++--
Grow.c | 12 ++++++++----
config.c | 3 ++-
mdstat.c | 3 ++-
super-ddf.c | 8 ++++++--
super-intel.c | 8 ++++++--
7 files changed, 56 insertions(+), 30 deletions(-)
diff --git a/Assemble.c b/Assemble.c
index 83dced19..58dc2c5e 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -652,7 +652,9 @@ static int load_devices(struct devs *devices, char *devmap,
/* prepare useful information in info structures */
struct stat stb2;
int err;
- fstat(mdfd, &stb2);
+
+ if (fstat(mdfd, &stb2) != 0)
+ goto error;
if (c->update == UOPT_UUID && !ident->uuid_set)
random_uuid((__u8 *)ident->uuid);
@@ -675,13 +677,10 @@ static int load_devices(struct devs *devices, char *devmap,
devname);
if (dfd >= 0)
close(dfd);
- close(mdfd);
- free(devices);
- free(devmap);
tst->ss->free_super(tst);
free(tst);
*stp = st;
- return -1;
+ goto error;
}
tst->ss->getinfo_super(tst, content, devmap + devcnt * content->array.raid_disks);
@@ -715,12 +714,9 @@ static int load_devices(struct devs *devices, char *devmap,
map_num(update_options, c->update), tst->ss->name);
tst->ss->free_super(tst);
free(tst);
- close(mdfd);
close(dfd);
- free(devices);
- free(devmap);
*stp = st;
- return -1;
+ goto error;
}
if (c->update == UOPT_UUID &&
!ident->uuid_set) {
@@ -751,18 +747,23 @@ static int load_devices(struct devs *devices, char *devmap,
devname);
if (dfd >= 0)
close(dfd);
- close(mdfd);
- free(devices);
- free(devmap);
tst->ss->free_super(tst);
free(tst);
*stp = st;
- return -1;
+ goto error;
}
tst->ss->getinfo_super(tst, content, devmap + devcnt * content->array.raid_disks);
}
- fstat(dfd, &stb);
+ if (fstat(dfd, &stb) != 0) {
+ close(dfd);
+ free(devices);
+ free(devmap);
+ tst->ss->free_super(tst);
+ free(tst);
+ *stp = st;
+ return -1;
+ }
close(dfd);
if (c->verbose > 0)
@@ -842,12 +843,9 @@ static int load_devices(struct devs *devices, char *devmap,
inargv ? "the list" :
"the\n DEVICE list in mdadm.conf"
);
- close(mdfd);
- free(devices);
- free(devmap);
free(best);
*stp = st;
- return -1;
+ goto error;
}
if (best[i] == -1 || (devices[best[i]].i.events
< devices[devcnt].i.events))
@@ -863,6 +861,13 @@ static int load_devices(struct devs *devices, char *devmap,
*bestp = best;
*stp = st;
return devcnt;
+
+error:
+ close(mdfd);
+ free(devices);
+ free(devmap);
+ return -1;
+
}
static int force_array(struct mdinfo *content,
diff --git a/Dump.c b/Dump.c
index 736bcb60..81b94940 100644
--- a/Dump.c
+++ b/Dump.c
@@ -37,6 +37,7 @@ int Dump_metadata(char *dev, char *dir, struct context *c,
unsigned long long size;
DIR *dirp;
struct dirent *de;
+ int ret = 0;
if (stat(dir, &stb) != 0 ||
(S_IFMT & stb.st_mode) != S_IFDIR) {
@@ -112,9 +113,15 @@ int Dump_metadata(char *dev, char *dir, struct context *c,
}
if (c->verbose >= 0)
printf("%s saved as %s.\n", dev, fname);
- fstat(fd, &dstb);
- close(fd);
+
close(fl);
+ ret = fstat(fd, &dstb);
+ close(fd);
+ if (ret) {
+ unlink(fname);
+ free(fname);
+ return 1;
+ }
if ((dstb.st_mode & S_IFMT) != S_IFBLK) {
/* Not a block device, so cannot create links */
free(fname);
diff --git a/Grow.c b/Grow.c
index 1923c27c..963792d0 100644
--- a/Grow.c
+++ b/Grow.c
@@ -1223,13 +1223,14 @@ int reshape_open_backup_file(char *backup_file,
* way this will not notice, but it is better than
* nothing.
*/
- fstat(*fdlist, &stb);
+ if (fstat(*fdlist, &stb) != 0)
+ goto error;
dev = stb.st_dev;
- fstat(fd, &stb);
+ if (fstat(fd, &stb) != 0)
+ goto error;
if (stb.st_rdev == dev) {
pr_err("backup file must NOT be on the array being reshaped.\n");
- close(*fdlist);
- return 0;
+ goto error;
}
memset(buf, 0, 512);
@@ -1255,6 +1256,9 @@ int reshape_open_backup_file(char *backup_file,
}
return 1;
+error:
+ close(*fdlist);
+ return 0;
}
unsigned long compute_backup_blocks(int nchunk, int ochunk,
diff --git a/config.c b/config.c
index b46d71cb..612e700d 100644
--- a/config.c
+++ b/config.c
@@ -949,7 +949,8 @@ void conf_file_or_dir(FILE *f)
struct dirent *dp;
struct fname *list = NULL;
- fstat(fileno(f), &st);
+ if (fstat(fileno(f), &st) != 0)
+ return;
if (S_ISREG(st.st_mode))
conf_file(f);
else if (!S_ISDIR(st.st_mode))
diff --git a/mdstat.c b/mdstat.c
index 2fd792c5..e233f094 100644
--- a/mdstat.c
+++ b/mdstat.c
@@ -348,7 +348,8 @@ void mdstat_wait_fd(int fd, const sigset_t *sigmask)
if (fd >= 0) {
struct stat stb;
- fstat(fd, &stb);
+ if (fstat(fd, &stb) != 0)
+ return;
if ((stb.st_mode & S_IFMT) == S_IFREG)
/* Must be a /proc or /sys fd, so expect
* POLLPRI
diff --git a/super-ddf.c b/super-ddf.c
index 21426c75..311001c1 100644
--- a/super-ddf.c
+++ b/super-ddf.c
@@ -1053,7 +1053,10 @@ static int load_ddf_local(int fd, struct ddf_super *super,
0);
dl->devname = devname ? xstrdup(devname) : NULL;
- fstat(fd, &stb);
+ if (fstat(fd, &stb) != 0) {
+ free(dl);
+ return 1;
+ }
dl->major = major(stb.st_rdev);
dl->minor = minor(stb.st_rdev);
dl->next = super->dlist;
@@ -2786,7 +2789,8 @@ static int add_to_super_ddf(struct supertype *st,
/* This is device numbered dk->number. We need to create
* a phys_disk entry and a more detailed disk_data entry.
*/
- fstat(fd, &stb);
+ if (fstat(fd, &stb) != 0)
+ return 1;
n = find_unused_pde(ddf);
if (n == DDF_NOTFOUND) {
pr_err("No free slot in array, cannot add disk\n");
diff --git a/super-intel.c b/super-intel.c
index 2b8b6fda..4d257371 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -4239,7 +4239,10 @@ load_imsm_disk(int fd, struct intel_super *super, char *devname, int keep_fd)
dl = xcalloc(1, sizeof(*dl));
- fstat(fd, &stb);
+ if (fstat(fd, &stb) != 0) {
+ free(dl);
+ return 1;
+ }
dl->major = major(stb.st_rdev);
dl->minor = minor(stb.st_rdev);
dl->next = super->disks;
@@ -5981,7 +5984,8 @@ static int add_to_super_imsm(struct supertype *st, mdu_disk_info_t *dk,
if (super->current_vol >= 0)
return add_to_super_imsm_volume(st, dk, fd, devname);
- fstat(fd, &stb);
+ if (fstat(fd, &stb) != 0)
+ return 1;
dd = xcalloc(sizeof(*dd), 1);
dd->major = major(stb.st_rdev);
dd->minor = minor(stb.st_rdev);
--
2.41.0

View File

@ -0,0 +1,28 @@
From c7790592bb7d050a990a9accb50de8f584879169 Mon Sep 17 00:00:00 2001
From: Blazej Kucman <blazej.kucman@intel.com>
Date: Wed, 22 May 2024 11:13:17 +0200
Subject: [PATCH 071/201] super-intel: fix typo in error msg
Fix typo in encryption policy error msg.
Signed-off-by: Blazej Kucman <blazej.kucman@intel.com>
---
super-intel.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/super-intel.c b/super-intel.c
index 4d257371..95856322 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -11328,7 +11328,7 @@ check_policy:
return MDADM_STATUS_SUCCESS;
fd2devname(disk_fd, devname);
- pr_vrb("Encryption status \"%s\" detected for disk %s, but \"%s\" status was detected eariler.\n",
+ pr_vrb("Encryption status \"%s\" detected for disk %s, but \"%s\" status was detected earlier.\n",
encryption_state, devname, expected_policy->value);
pr_vrb("Disks with different encryption status cannot be used.\n");
return MDADM_STATUS_ERROR;
--
2.41.0

View File

@ -0,0 +1,45 @@
From 49145d4f574b21a6c0612ce691f255732cb91832 Mon Sep 17 00:00:00 2001
From: Nigel Croxon <ncroxon@redhat.com>
Date: Wed, 22 May 2024 16:05:25 -0400
Subject: [PATCH 072/201] mdadm: super-intel remove dead code
Execution cannot reach this statement: "while (devlist) { dv = de...".
Local variable "err" is assigned only once, to a constant value,
making it effectively constant throughout its scope.
Remove dead code.
Signed-off-by: Nigel Croxon <ncroxon@redhat.com>
---
super-intel.c | 9 ---------
1 file changed, 9 deletions(-)
diff --git a/super-intel.c b/super-intel.c
index 95856322..d1b737c7 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -7046,7 +7046,6 @@ get_devices(const char *hba_path)
struct md_list *dv;
struct dirent *ent;
DIR *dir;
- int err = 0;
#if DEBUG_LOOP
devlist = get_loop_devices();
@@ -7088,14 +7087,6 @@ get_devices(const char *hba_path)
dv->next = devlist;
devlist = dv;
}
- if (err) {
- while(devlist) {
- dv = devlist;
- devlist = devlist->next;
- free(dv->devname);
- free(dv);
- }
- }
closedir(dir);
return devlist;
}
--
2.41.0

View File

@ -0,0 +1,55 @@
From 5c30864146412fcdfdcfddcdd94c5c449d9ddbed Mon Sep 17 00:00:00 2001
From: Nigel Croxon <ncroxon@redhat.com>
Date: Wed, 22 May 2024 16:53:22 -0400
Subject: [PATCH 073/201] mdadm: super-intel fix bad shift
In the expression "1 << i", left shifting by more than 31 bits has undefined behavior.
The shift amount, "i", is as much as 63. The operand has type "int" (32 bits) and will
be shifted as an "int". The fix is to change to a 64 bit int.
Signed-off-by: Nigel Croxon <ncroxon@redhat.com>
---
super-intel.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/super-intel.c b/super-intel.c
index d1b737c7..0287a618 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -2343,7 +2343,8 @@ void print_encryption_information(int disk_fd, enum sys_dev_type hba_type)
get_encryption_status_string(information.status));
}
-static int ahci_enumerate_ports(struct sys_dev *hba, int port_count, int host_base, int verbose)
+static int ahci_enumerate_ports(struct sys_dev *hba, unsigned long port_count, int host_base,
+ int verbose)
{
/* dump an unsorted list of devices attached to AHCI Intel storage
* controller, as well as non-connected ports
@@ -2357,7 +2358,7 @@ static int ahci_enumerate_ports(struct sys_dev *hba, int port_count, int host_ba
if (port_count > (int)sizeof(port_mask) * 8) {
if (verbose > 0)
- pr_err("port_count %d out of range\n", port_count);
+ pr_err("port_count %ld out of range\n", port_count);
return 2;
}
@@ -2499,11 +2500,11 @@ static int ahci_enumerate_ports(struct sys_dev *hba, int port_count, int host_ba
if (dir)
closedir(dir);
if (err == 0) {
- int i;
+ unsigned long i;
for (i = 0; i < port_count; i++)
- if (port_mask & (1 << i))
- printf(" Port%d : - no device attached -\n", i);
+ if (port_mask & (1L << i))
+ printf(" Port%ld : - no device attached -\n", i);
}
return err;
--
2.41.0

View File

@ -0,0 +1,438 @@
From 50b100768a115526f5029113af957658ef76b383 Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Fri, 29 Mar 2024 15:21:54 +0100
Subject: [PATCH 074/201] mdadm: deprecate bitmap custom file
This option has been deprecated in kernel by Christoph in commit
0ae1c9d38426 ("md: deprecate bitmap file support"). Do the same in
mdadm.
With this change, user must acknowledge it, it is not
skippable. The implementation of custom bitmap file looks like it's
abandoned. It cannot be done by Incremental so it is not respected by
any udev based system and it seems to not be recorded by metadata.
User must assemble such volume manually.
Tests for bitmap custom file are removed because now they will not
pass because interaction with user is mandatory.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
mdadm.8.in | 34 +++++++++----------
mdadm.c | 70 +++++++++++++++++++++++++++-------------
tests/05r1-bitmapfile | 49 ----------------------------
tests/05r1-grow-external | 33 -------------------
tests/05r1-n3-bitmapfile | 53 ------------------------------
tests/05r5-bitmapfile | 49 ----------------------------
tests/05r6-bitmapfile | 49 ----------------------------
7 files changed, 62 insertions(+), 275 deletions(-)
delete mode 100644 tests/05r1-bitmapfile
delete mode 100644 tests/05r1-grow-external
delete mode 100644 tests/05r1-n3-bitmapfile
delete mode 100644 tests/05r5-bitmapfile
delete mode 100644 tests/05r6-bitmapfile
diff --git a/mdadm.8.in b/mdadm.8.in
index 9ba66825..aa0c5403 100644
--- a/mdadm.8.in
+++ b/mdadm.8.in
@@ -727,29 +727,25 @@ same as
.TP
.BR \-b ", " \-\-bitmap=
-Specify a file to store a write-intent bitmap in. The file should not
-exist unless
-.B \-\-force
-is also given. The same file should be provided
-when assembling the array. If the word
-.B "internal"
-is given, then the bitmap is stored with the metadata on the array,
-and so is replicated on all devices. If the word
-.B "none"
-is given with
-.B \-\-grow
-mode, then any bitmap that is present is removed. If the word
-.B "clustered"
-is given, the array is created for a clustered environment. One bitmap
-is created for each node as defined by the
+Specify how to store a write-intent bitmap. Following values are supported:
+
+.B internal
+- the bitmap is stored with the metadata on the array and so is replicated on all devices.
+
+.B clustered
+- the array is created for a clustered environment. One bitmap is created for each node as defined
+by the
.B \-\-nodes
parameter and are stored internally.
-To help catch typing errors, the filename must contain at least one
-slash ('/') if it is a real file (not 'internal' or 'none').
+.B none
+- create array with no bitmap or remove any present bitmap (grow mode).
-Note: external bitmaps are only known to work on ext2 and ext3.
-Storing bitmap files on other filesystems may result in serious problems.
+Setting bitmap for file is deprecated and should not be used. The file should not exist unless
+.B \-\-force
+is also given. The same file should be provided when assembling the array. The file name must
+contain at least one slash ('/'). Bitmap files are only known to work on ext2 and ext3. Storing
+bitmap files on other filesystems may result in serious problems.
When creating an array on devices which are 100G or larger,
.I mdadm
diff --git a/mdadm.c b/mdadm.c
index d18619db..0b99fad4 100644
--- a/mdadm.c
+++ b/mdadm.c
@@ -29,6 +29,51 @@
#include "md_p.h"
#include <ctype.h>
+/**
+ * set_bitmap_value() - set bitmap value.
+ * @s: Shape.
+ * @c: Context.
+ * @val: value to set.
+ *
+ * Validate and set bitmap. Context is needed for setting nodes for clustered bitmap.
+ */
+static mdadm_status_t set_bitmap_value(struct shape *s, struct context *c, char *val)
+{
+ if (s->bitmap_file) {
+ pr_err("--bitmap cannot be set twice. Second value: \"%s\".\n", val);
+ return MDADM_STATUS_ERROR;
+ }
+
+ if (strcmp(val, "internal") == 0 || strcmp(optarg, STR_COMMON_NONE) == 0) {
+ s->bitmap_file = val;
+ return MDADM_STATUS_SUCCESS;
+ }
+
+ if (strcmp(val, "clustered") == 0) {
+ s->bitmap_file = val;
+ /* Set the default number of cluster nodes
+ * to 4 if not already set by user
+ */
+ if (c->nodes < 1)
+ c->nodes = 4;
+ return MDADM_STATUS_SUCCESS;
+ }
+
+ if (strchr(val, '/')) {
+ pr_info("Custom write-intent bitmap file option is deprecated.\n");
+ if (ask("Do you want to continue? (y/n)")) {
+ s->bitmap_file = val;
+ return MDADM_STATUS_SUCCESS;
+ }
+
+ return MDADM_STATUS_ERROR;
+ }
+
+ pr_err("--bitmap value must contain a '/' or be 'internal', 'clustered' or 'none'\n");
+ pr_err("Current value is \"%s\"", val);
+ return MDADM_STATUS_ERROR;
+}
+
static int scan_assemble(struct supertype *ss,
struct context *c,
struct mddev_ident *ident);
@@ -1094,30 +1139,9 @@ int main(int argc, char *argv[])
case O(CREATE,Bitmap): /* here we create the bitmap */
case O(GROW,'b'):
case O(GROW,Bitmap):
- if (s.bitmap_file) {
- pr_err("bitmap cannot be set twice. Second value: %s.\n", optarg);
+ if (set_bitmap_value(&s, &c, optarg))
exit(2);
- }
- if (strcmp(optarg, "internal") == 0 ||
- strcmp(optarg, STR_COMMON_NONE) == 0 ||
- strchr(optarg, '/') != NULL) {
- s.bitmap_file = optarg;
- continue;
- }
- if (strcmp(optarg, "clustered") == 0) {
- s.bitmap_file = optarg;
- /* Set the default number of cluster nodes
- * to 4 if not already set by user
- */
- if (c.nodes < 1)
- c.nodes = 4;
- continue;
- }
- /* probable typo */
- pr_err("bitmap file must contain a '/', or be 'internal', or be 'clustered', or 'none'\n"
- " not '%s'\n", optarg);
- exit(2);
-
+ continue;
case O(GROW,BitmapChunk):
case O(BUILD,BitmapChunk):
case O(CREATE,BitmapChunk): /* bitmap chunksize */
diff --git a/tests/05r1-bitmapfile b/tests/05r1-bitmapfile
deleted file mode 100644
index f384f0ea..00000000
--- a/tests/05r1-bitmapfile
+++ /dev/null
@@ -1,49 +0,0 @@
-
-#
-# create a raid1 with a bitmap file
-#
-bmf=$targetdir/bitmap
-rm -f $bmf
-mdadm --create --run $md0 --level=1 -n2 --delay=1 --bitmap $bmf $dev1 $dev2
-check wait
-testdev $md0 1 $mdsize1a 64
-mdadm -S $md0
-
-mdadm --assemble $md0 --bitmap=$bmf $dev1 $dev2
-testdev $md0 1 $mdsize1a 64
-dirty1=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
-sleep 4
-dirty2=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
-
-if [ $dirty1 -lt 400 -o $dirty2 -ne 0 ]
-then echo >&2 "ERROR bad 'dirty' counts: $dirty1 and $dirty2"
- exit 1
-fi
-mdadm $md0 -f $dev1
-testdev $md0 1 $mdsize1a 64
-sleep 4
-dirty3=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
-if [ $dirty3 -lt 400 ]
-then
- echo >&2 "ERROR dirty count $dirty3 is too small"
- exit 2
-fi
-
-mdadm -S $md0
-
-mdadm --assemble -R $md0 --bitmap=$bmf $dev2
-dirty4=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
-mdadm --zero $dev1 # force --add, not --re-add
-mdadm $md0 --add $dev1
-#it is too fast# check recovery
-
-check wait
-sleep 4
-dirty5=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
-
-if [ $dirty4 -lt 400 -o $dirty5 -ne 0 ]
-then echo echo >&2 "ERROR bad 'dirty' counts at end: $dirty4 $dirty5"
- exit 1
-fi
-
-mdadm -S $md0
diff --git a/tests/05r1-grow-external b/tests/05r1-grow-external
deleted file mode 100644
index 69da3e90..00000000
--- a/tests/05r1-grow-external
+++ /dev/null
@@ -1,33 +0,0 @@
-
-#
-# create a raid1 array, add an external bitmap
-#
-mdadm --create --run $md0 -l 1 -n 2 $dev1 $dev2
-check wait
-testdev $md0 1 $mdsize1a 64
-
-bmf=$targetdir/bm
-rm -f $bmf
-#mdadm -E $dev1
-mdadm --grow $md0 --bitmap=$bmf --delay=1 || { mdadm -X $bmf ; exit 1; }
-dirty1=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
-sleep 4
-dirty2=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
-
-testdev $md0 1 $mdsize1a 64
-dirty3=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
-sleep 4
-dirty4=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
-
-#echo $dirty1 $dirty2 $dirty3 $dirty4
-if [ $dirty2 -ne 0 -o $dirty4 -ne 0 -o $dirty3 -lt 400 ]
-then
- echo bad dirty counts
- exit 1
-fi
-
-# now to remove the bitmap
-check bitmap
-mdadm --grow $md0 --bitmap=none
-check nobitmap
-mdadm -S $md0
diff --git a/tests/05r1-n3-bitmapfile b/tests/05r1-n3-bitmapfile
deleted file mode 100644
index f1c3f1ee..00000000
--- a/tests/05r1-n3-bitmapfile
+++ /dev/null
@@ -1,53 +0,0 @@
-
-#
-# create a raid1 with 3 devices and a bitmap file
-# make sure resync does right thing.
-#
-#
-bmf=$targetdir/bitmap
-rm -f $bmf
-mdadm --create -e0.90 --run $md0 --level=1 -n3 --delay=1 --bitmap $bmf $dev1 $dev2 $dev3
-check wait
-testdev $md0 1 $mdsize0 64
-mdadm -S $md0
-
-mdadm --assemble $md0 --bitmap=$bmf $dev1 $dev2 $dev3
-testdev $md0 1 $mdsize0 64
-dirty1=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
-sleep 4
-dirty2=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
-
-if [ $dirty1 -lt 400 -o $dirty2 -ne 0 ]
-then echo >&2 "ERROR bad 'dirty' counts: $dirty1 and $dirty2"
- exit 1
-fi
-mdadm $md0 -f $dev2
-testdev $md0 1 $mdsize0 64
-sleep 4
-dirty3=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
-if [ $dirty3 -lt 400 ]
-then
- echo >&2 "ERROR dirty count $dirty3 is too small"
- exit 2
-fi
-
-mdadm -S $md0
-
-mdadm --assemble -R $md0 --bitmap=$bmf $dev1 $dev3
-check nosync
-mdadm --zero-superblock $dev2
-mdadm $md0 --add $dev2
-check recovery
-
-dirty4=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
-check wait
-sleep 4
-dirty5=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
-
-if [ $dirty4 -lt 400 -o $dirty5 -ne 0 ]
-then echo echo >&2 "ERROR bad 'dirty' counts at end: $dirty4 $dirty5"
- exit 1
-fi
-
-mdadm -S $md0
-exit 0
diff --git a/tests/05r5-bitmapfile b/tests/05r5-bitmapfile
deleted file mode 100644
index 6d173d88..00000000
--- a/tests/05r5-bitmapfile
+++ /dev/null
@@ -1,49 +0,0 @@
-
-#
-# create a raid1 with a bitmap file
-#
-bmf=$targetdir/bitmap
-rm -f $bmf
-mdadm --create --run $md0 --level=5 -n3 --delay=1 --bitmap $bmf $dev1 $dev2 $dev3
-check wait
-testdev $md0 2 $mdsize1 512
-mdadm -S $md0
-
-mdadm --assemble $md0 --bitmap=$bmf $dev1 $dev2 $dev3
-testdev $md0 2 $mdsize1 512
-dirty1=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
-sleep 4
-dirty2=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
-
-if [ $dirty1 -lt 400 -o $dirty2 -ne 0 ]
-then echo >&2 "ERROR bad 'dirty' counts: $dirty1 and $dirty2"
- exit 1
-fi
-mdadm $md0 -f $dev1
-testdev $md0 2 $mdsize1 512
-sleep 4
-dirty3=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
-if [ $dirty3 -lt 400 ]
-then
- echo >&2 "ERROR dirty count $dirty3 is too small"
- exit 2
-fi
-
-mdadm -S $md0
-
-mdadm --assemble -R $md0 --bitmap=$bmf $dev2 $dev3
-mdadm --zero $dev1 # force add, not re-add
-mdadm $md0 --add $dev1
-check recovery
-
-dirty4=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
-check wait
-sleep 4
-dirty5=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
-
-if [ $dirty4 -lt 400 -o $dirty5 -ne 0 ]
-then echo echo >&2 "ERROR bad 'dirty' counts at end: $dirty4 $dirty5"
- exit 1
-fi
-
-mdadm -S $md0
diff --git a/tests/05r6-bitmapfile b/tests/05r6-bitmapfile
deleted file mode 100644
index d11896db..00000000
--- a/tests/05r6-bitmapfile
+++ /dev/null
@@ -1,49 +0,0 @@
-
-#
-# create a raid1 with a bitmap file
-#
-bmf=$targetdir/bitmap
-rm -f $bmf
-mdadm --create --run $md0 --level=6 -n4 --delay=1 --bitmap $bmf $dev1 $dev2 $dev3 $dev4
-check wait
-testdev $md0 2 $mdsize1 512
-mdadm -S $md0
-
-mdadm --assemble $md0 --bitmap=$bmf $dev1 $dev2 $dev3 $dev4
-testdev $md0 2 $mdsize1 512
-dirty1=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
-sleep 4
-dirty2=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
-
-if [ $dirty1 -lt 400 -o $dirty2 -ne 0 ]
-then echo >&2 "ERROR bad 'dirty' counts: $dirty1 and $dirty2"
- exit 1
-fi
-mdadm $md0 -f $dev3
-testdev $md0 2 $mdsize1 512
-sleep 4
-dirty3=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
-if [ $dirty3 -lt 400 ]
-then
- echo >&2 "ERROR dirty count $dirty3 is too small"
- exit 2
-fi
-
-mdadm -S $md0
-
-mdadm --assemble -R $md0 --bitmap=$bmf $dev1 $dev2 $dev4
-mdadm --zero $dev3 # force --add, not --re-add
-mdadm $md0 --add $dev3
-check recovery
-
-dirty4=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
-check wait
-sleep 4
-dirty5=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
-
-if [ $dirty4 -lt 400 -o $dirty5 -ne 0 ]
-then echo echo >&2 "ERROR bad 'dirty' counts at end: $dirty4 $dirty5"
- exit 1
-fi
-
-mdadm -S $md0
--
2.41.0

View File

@ -0,0 +1,31 @@
From 906922ee321d64e2ce8458147e67d4892696fb58 Mon Sep 17 00:00:00 2001
From: Valery Ushakov <valery.ushakov@bell-sw.com>
Date: Wed, 22 May 2024 17:07:38 +0300
Subject: [PATCH 075/201] Makefile: fix make -s detection
Only check the first word of MAKEFLAGS for 's', that's where all the
single letter options are collected.
MAKEFLAGS contains _all_ make flags, so if any command line argument
contains a letter 's', the silent test will be false positive. Think
e.g. make 'DESTDIR=.../aports/main/mdadm/pkg/mdadm' install
---
Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Makefile b/Makefile
index adac7905..446710bd 100644
--- a/Makefile
+++ b/Makefile
@@ -157,7 +157,7 @@ ifndef UDEVDIR
UDEVDIR = /lib/udev
endif
-ifeq (,$(findstring s,$(MAKEFLAGS)))
+ifeq (,$(findstring s,$(firstword -$(MAKEFLAGS))))
ECHO=echo
else
ECHO=:
--
2.41.0

View File

@ -0,0 +1,81 @@
From 13a0e92a3ed70c52246a0f0572dee61203994327 Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Wed, 22 May 2024 16:50:38 +0800
Subject: [PATCH 076/201] Change some error messages to info level
These logs are not error logs. Change them to info level.
Signed-off-by: Xiao Ni <xni@redhat.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
Assemble.c | 16 ++++++----------
Manage.c | 2 +-
util.c | 4 ++--
3 files changed, 9 insertions(+), 13 deletions(-)
diff --git a/Assemble.c b/Assemble.c
index 58dc2c5e..0e6da593 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -1214,23 +1214,19 @@ static int start_array(int mdfd,
if (rv == 0) {
sysfs_rules_apply(mddev, content);
if (c->verbose >= 0) {
- pr_err("%s has been started with %d drive%s",
+ pr_info("%s has been started with %d drive%s",
mddev, okcnt, okcnt==1?"":"s");
if (okcnt < (unsigned)content->array.raid_disks)
- fprintf(stderr, " (out of %d)",
- content->array.raid_disks);
+ printf(" (out of %d)", content->array.raid_disks);
if (rebuilding_cnt)
- fprintf(stderr, "%s %d rebuilding",
- sparecnt?",":" and",
+ printf("%s %d rebuilding", sparecnt?",":" and",
rebuilding_cnt);
if (sparecnt)
- fprintf(stderr, " and %d spare%s",
- sparecnt,
+ printf(" and %d spare%s", sparecnt,
sparecnt == 1 ? "" : "s");
if (content->journal_clean)
- fprintf(stderr, " and %d journal",
- journalcnt);
- fprintf(stderr, ".\n");
+ printf(" and %d journal", journalcnt);
+ printf(".\n");
}
if (content->reshape_active &&
is_level456(content->array.level)) {
diff --git a/Manage.c b/Manage.c
index 96e5ee54..5db72b77 100644
--- a/Manage.c
+++ b/Manage.c
@@ -463,7 +463,7 @@ done:
}
if (verbose >= 0)
- pr_err("stopped %s\n", devname);
+ pr_info("stopped %s\n", devname);
map_lock(&map);
map_remove(&map, devnm);
map_unlock(&map);
diff --git a/util.c b/util.c
index bf79742f..48c97545 100644
--- a/util.c
+++ b/util.c
@@ -633,9 +633,9 @@ int check_ext2(int fd, char *name)
bsize = sb[24]|(sb[25]|(sb[26]|sb[27]<<8)<<8)<<8;
size = sb[4]|(sb[5]|(sb[6]|sb[7]<<8)<<8)<<8;
size <<= bsize;
- pr_err("%s appears to contain an ext2fs file system\n",
+ pr_info("%s appears to contain an ext2fs file system\n",
name);
- cont_err("size=%lluK mtime=%s", size, ctime(&mtime));
+ pr_info("size=%lluK mtime=%s", size, ctime(&mtime));
return 1;
}
--
2.41.0

View File

@ -0,0 +1,40 @@
From 296398299391b10650bdd79d986b115588e60590 Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Wed, 22 May 2024 16:50:39 +0800
Subject: [PATCH 077/201] mdadm: Start update_opt from 0
Before f2e8393bd722 ('Manage&Incremental: code refactor, string to enum'), it uses
NULL to represent it doesn't need to update. So init UOPT_UNDEFINED to 0. This
problem is found by test case 05r6tor0.
Signed-off-by: Xiao Ni <xni@redhat.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
mdadm.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/mdadm.h b/mdadm.h
index b71d7b32..40818941 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -535,7 +535,8 @@ enum special_options {
};
enum update_opt {
- UOPT_NAME = 1,
+ UOPT_UNDEFINED = 0,
+ UOPT_NAME,
UOPT_PPL,
UOPT_NO_PPL,
UOPT_BITMAP,
@@ -575,7 +576,6 @@ enum update_opt {
UOPT_SPEC_FAILFAST,
UOPT_SPEC_NOFAILFAST,
UOPT_SPEC_REVERT_RESHAPE_NOBACKUP,
- UOPT_UNDEFINED
};
extern void fprint_update_options(FILE *outf, enum update_opt update_mode);
--
2.41.0

View File

@ -0,0 +1,49 @@
From f79f7189aa25b9da51736f2c578a51c2c4fe7706 Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Wed, 22 May 2024 16:50:40 +0800
Subject: [PATCH 078/201] Don't control reshape speed in daemon
It tries to set the max sync speed in reshape. This should be done by
administrators by control interfaces /proc/sys/dev/raid/speed_limit_max/min.
Signed-off-by: Xiao Ni <xni@redhat.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
Grow.c | 7 -------
1 file changed, 7 deletions(-)
diff --git a/Grow.c b/Grow.c
index 963792d0..b135930d 100644
--- a/Grow.c
+++ b/Grow.c
@@ -4488,7 +4488,6 @@ int child_monitor(int afd, struct mdinfo *sra, struct reshape *reshape,
*/
char *buf;
int degraded = -1;
- unsigned long long speed;
unsigned long long suspend_point, array_size;
unsigned long long backup_point, wait_point;
unsigned long long reshape_completed;
@@ -4544,10 +4543,6 @@ int child_monitor(int afd, struct mdinfo *sra, struct reshape *reshape,
if (posix_memalign((void**)&buf, 4096, disks * chunk))
/* Don't start the 'reshape' */
return 0;
- if (reshape->before.data_disks == reshape->after.data_disks) {
- sysfs_get_ll(sra, NULL, "sync_speed_min", &speed);
- sysfs_set_num(sra, NULL, "sync_speed_min", 200000);
- }
if (increasing) {
array_size = sra->component_size * reshape->after.data_disks;
@@ -4680,8 +4675,6 @@ int child_monitor(int afd, struct mdinfo *sra, struct reshape *reshape,
sysfs_set_num(sra, NULL, "suspend_lo", 0);
sysfs_set_num(sra, NULL, "sync_min", 0);
- if (reshape->before.data_disks == reshape->after.data_disks)
- sysfs_set_num(sra, NULL, "sync_speed_min", speed);
free(buf);
return done;
}
--
2.41.0

View File

@ -0,0 +1,119 @@
From 6e8af9475cf0ac22f7ac167040dbf92fbfdd97ab Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Wed, 22 May 2024 16:50:41 +0800
Subject: [PATCH 079/201] mdadm/tests: test enhance
There are two changes.
First, if md module is not loaded, it gives error when reading
speed_limit_max. So read the value after loading md module which
is done in do_setup
Second, sometimes the test reports error sync action doesn't
happen. But dmesg shows sync action is done. So limit the sync
speed before test. It doesn't affect the test run time. Because
check wait sets the max speed before waiting sync action. And
recording speed_limit_max/min in do_setup.
Fixes: 4c12714d1ca0 ('test: run tests on system level mdadm')
Signed-off-by: Xiao Ni <xni@redhat.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
test | 10 +++++-----
tests/func.sh | 26 +++++++++++++++++++++++---
2 files changed, 28 insertions(+), 8 deletions(-)
diff --git a/test b/test
index 338c2db4..ff403293 100755
--- a/test
+++ b/test
@@ -6,7 +6,10 @@ targetdir="/var/tmp"
logdir="$targetdir"
config=/tmp/mdadm.conf
testdir=$PWD/tests
-system_speed_limit=`cat /proc/sys/dev/raid/speed_limit_max`
+system_speed_limit_max=0
+system_speed_limit_min=0
+test_speed_limit_min=100
+test_speed_limit_max=500
devlist=
savelogs=0
@@ -39,10 +42,6 @@ ctrl_c() {
ctrl_c_error=1
}
-restore_system_speed_limit() {
- echo $system_speed_limit > /proc/sys/dev/raid/speed_limit_max
-}
-
mdadm() {
rm -f $targetdir/stderr
case $* in
@@ -103,6 +102,7 @@ do_test() {
do_clean
# source script in a subshell, so it has access to our
# namespace, but cannot change it.
+ control_system_speed_limit
echo -ne "$_script... "
if ( set -ex ; . $_script ) &> $targetdir/log
then
diff --git a/tests/func.sh b/tests/func.sh
index b474442b..221cff15 100644
--- a/tests/func.sh
+++ b/tests/func.sh
@@ -136,6 +136,23 @@ check_env() {
fi
}
+record_system_speed_limit() {
+ system_speed_limit_max=`cat /proc/sys/dev/raid/speed_limit_max`
+ system_speed_limit_min=`cat /proc/sys/dev/raid/speed_limit_min`
+}
+
+# To avoid sync action finishes before checking it, it needs to limit
+# the sync speed
+control_system_speed_limit() {
+ echo $test_speed_limit_min > /proc/sys/dev/raid/speed_limit_min
+ echo $test_speed_limit_max > /proc/sys/dev/raid/speed_limit_max
+}
+
+restore_system_speed_limit() {
+ echo $system_speed_limit_min > /proc/sys/dev/raid/speed_limit_max
+ echo $system_speed_limit_max > /proc/sys/dev/raid/speed_limit_max
+}
+
do_setup() {
trap cleanup 0 1 3 15
trap ctrl_c 2
@@ -214,6 +231,7 @@ do_setup() {
ulimit -c unlimited
[ -f /proc/mdstat ] || modprobe md_mod
echo 0 > /sys/module/md_mod/parameters/start_ro
+ record_system_speed_limit
}
# check various things
@@ -265,15 +283,17 @@ check() {
fi
;;
wait )
- p=`cat /proc/sys/dev/raid/speed_limit_max`
- echo 2000000 > /proc/sys/dev/raid/speed_limit_max
+ min=`cat /proc/sys/dev/raid/speed_limit_min`
+ max=`cat /proc/sys/dev/raid/speed_limit_max`
+ echo 200000 > /proc/sys/dev/raid/speed_limit_max
sleep 0.1
while grep -Eq '(resync|recovery|reshape|check|repair) *=' /proc/mdstat ||
grep -v idle > /dev/null /sys/block/md*/md/sync_action
do
sleep 0.5
done
- echo $p > /proc/sys/dev/raid/speed_limit_max
+ echo $min > /proc/sys/dev/raid/speed_limit_min
+ echo $max > /proc/sys/dev/raid/speed_limit_max
;;
state )
grep -sq "blocks.*\[$2\]\$" /proc/mdstat ||
--
2.41.0

View File

@ -0,0 +1,31 @@
From 73ba062ef93d0a57360a2d5200bc7a8f8781e7b6 Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Wed, 22 May 2024 16:50:42 +0800
Subject: [PATCH 080/201] mdadm/tests: test don't fail when systemd reports
error
Sometimes systemd reports error in dmesg and test fails. Add
a condition to avoid this failure.
Signed-off-by: Xiao Ni <xni@redhat.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
test | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test b/test
index ff403293..3da53f87 100755
--- a/test
+++ b/test
@@ -109,7 +109,7 @@ do_test() {
if [ -f "${_script}.inject_error" ]; then
echo "dmesg checking is skipped because test inject error"
else
- dmesg | grep -iq "error\|call trace\|segfault" &&
+ dmesg | grep -iq "error\|call trace\|segfault" | grep -v "systemd" &&
die "dmesg prints errors when testing $_basename!"
fi
echo "succeeded"
--
2.41.0

View File

@ -0,0 +1,109 @@
From 41706a91568472d10153bf4ada3c3f0d93ef327a Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Wed, 22 May 2024 16:50:43 +0800
Subject: [PATCH 081/201] mdadm/tests: names_template enhance
For super1, if the length of hostname is >= 32, it doesn't add hostname
in metadata name. Fix this problem by checking the length of hostname.
Because other cases may use need to check this, so do the check in
do_setup.
And this patch adds a check if link /dev/md/name exists.
Signed-off-by: Xiao Ni <xni@redhat.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
test | 5 +++++
tests/func.sh | 13 +++++++++++++
tests/templates/names_template | 14 ++++++++++++--
3 files changed, 30 insertions(+), 2 deletions(-)
diff --git a/test b/test
index 3da53f87..814ce199 100755
--- a/test
+++ b/test
@@ -11,6 +11,11 @@ system_speed_limit_min=0
test_speed_limit_min=100
test_speed_limit_max=500
devlist=
+# If super1 metadata name doesn't have the same hostname with machine,
+# it's treated as foreign.
+# For example, /dev/md0 is created, stops it, then assemble it, the
+# device node will be /dev/md127 (127 is choosed by mdadm autumatically)
+is_foreign="no"
savelogs=0
exitonerror=1
diff --git a/tests/func.sh b/tests/func.sh
index 221cff15..cfe83e55 100644
--- a/tests/func.sh
+++ b/tests/func.sh
@@ -153,6 +153,18 @@ restore_system_speed_limit() {
echo $system_speed_limit_max > /proc/sys/dev/raid/speed_limit_max
}
+is_raid_foreign() {
+
+ # If the length of hostname is >= 32, super1 doesn't use
+ # hostname in metadata
+ hostname=$(hostname)
+ if [ `expr length $(hostname)` -lt 32 ]; then
+ is_foreign="no"
+ else
+ is_foreign="yes"
+ fi
+}
+
do_setup() {
trap cleanup 0 1 3 15
trap ctrl_c 2
@@ -232,6 +244,7 @@ do_setup() {
[ -f /proc/mdstat ] || modprobe md_mod
echo 0 > /sys/module/md_mod/parameters/start_ro
record_system_speed_limit
+ is_raid_foreign
}
# check various things
diff --git a/tests/templates/names_template b/tests/templates/names_template
index 1b6cd14b..88ad5b8c 100644
--- a/tests/templates/names_template
+++ b/tests/templates/names_template
@@ -30,6 +30,7 @@ function names_verify() {
local DEVNODE_NAME="$1"
local WANTED_LINK="$2"
local WANTED_NAME="$3"
+ local EXPECTED=""
local RES="$(mdadm -D --export $DEVNODE_NAME | grep MD_DEVNAME)"
if [[ "$?" != "0" ]]; then
@@ -38,7 +39,12 @@ function names_verify() {
fi
if [[ "$WANTED_LINK" != "empty" ]]; then
- local EXPECTED="MD_DEVNAME=$WANTED_LINK"
+ EXPECTED="MD_DEVNAME=$WANTED_LINK"
+
+ if [ ! -b /dev/md/$WANTED_LINK ]; then
+ echo "/dev/md/$WANTED_LINK doesn't exit"
+ exit 1
+ fi
fi
if [[ "$RES" != "$EXPECTED" ]]; then
@@ -52,7 +58,11 @@ function names_verify() {
exit 1
fi
- local EXPECTED="MD_NAME=$(hostname):$WANTED_NAME"
+ if [ $is_foreign == "no" ]; then
+ EXPECTED="MD_NAME=$(hostname):$WANTED_NAME"
+ else
+ EXPECTED="MD_NAME=$WANTED_NAME"
+ fi
if [[ "$RES" != "$EXPECTED" ]]; then
echo "$RES doesn't match $EXPECTED."
exit 1
--
2.41.0

View File

@ -0,0 +1,67 @@
From 23f45965a0abe3506885c8e8005ee79473a66422 Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Wed, 22 May 2024 16:50:44 +0800
Subject: [PATCH 082/201] mdadm/tests: 03assem-incr enhance
It fails when hostname lenght > 32. Because the super1 metadata name
doesn't include hostname when hostname length > 32. Then mdadm thinks
the array is a foreign array if no device link is specified when
assembling the array. It chooses a minor number from 127.
Signed-off-by: Xiao Ni <xni@redhat.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
test | 3 +++
tests/03assem-incr | 20 +++++++++++++-------
2 files changed, 16 insertions(+), 7 deletions(-)
diff --git a/test b/test
index 814ce199..1fce6be2 100755
--- a/test
+++ b/test
@@ -33,6 +33,9 @@ LVM_VOLGROUP=mdtest
md0=/dev/md0
md1=/dev/md1
md2=/dev/md2
+# if user doesn't specify minor number, mdadm chooses minor number
+# automatically from 127.
+md127=/dev/md127
mdp0=/dev/md_d0
mdp1=/dev/md_d1
diff --git a/tests/03assem-incr b/tests/03assem-incr
index 38880a7f..21215a34 100644
--- a/tests/03assem-incr
+++ b/tests/03assem-incr
@@ -9,15 +9,21 @@ set -x -e
levels=(raid0 raid1 raid5)
if [ "$LINEAR" == "yes" ]; then
- levels+=( linear )
+ levels+=( linear )
fi
for l in ${levels[@]}
do
- mdadm -CR $md0 -l $l -n5 $dev0 $dev1 $dev2 $dev3 $dev4 --assume-clean
- mdadm -S md0
- mdadm -I $dev1
- mdadm -I $dev3
- mdadm -A /dev/md0 $dev0 $dev1 $dev2 $dev3 $dev4
- mdadm -S /dev/md0
+ mdadm -CR $md0 -l $l -n5 $dev0 $dev1 $dev2 $dev3 $dev4 --assume-clean
+ mdadm -S $md0
+ mdadm -I $dev1
+ mdadm -I $dev3
+ mdadm -A $md0 $dev0 $dev1 $dev2 $dev3 $dev4
+ # If one array is foreign (metadata name doesn't have the machine's
+ # hostname), mdadm chooses a minor number automatically from 127
+ if [ $is_foreign == "no" ]; then
+ mdadm -S $md0
+ else
+ mdadm -S $md127
+ fi
done
--
2.41.0

View File

@ -0,0 +1,38 @@
From f136d9a8b7d8fdfd7539b96707bc9a03528754aa Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Wed, 22 May 2024 16:50:45 +0800
Subject: [PATCH 083/201] mdadm/tests 03r0assem enhance
dcc22ae74a864 ('super1: remove support for name= in config') already
removes name= support. So remove related test codes in 03r0assem.
Signed-off-by: Xiao Ni <xni@redhat.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
tests/03r0assem | 10 ----------
1 file changed, 10 deletions(-)
diff --git a/tests/03r0assem b/tests/03r0assem
index f7c29e8c..4bf8b9e8 100644
--- a/tests/03r0assem
+++ b/tests/03r0assem
@@ -33,16 +33,6 @@ mdadm -As -c $conf $md2
$tst
mdadm -S $md2
-{
- echo DEVICE $devlist
- echo array $md2 name=2
-} > $conf
-
-mdadm -As -c $conf $md2
-$tst
-mdadm -S $md2
-
-
{
echo DEVICE $devlist
echo array $md2 devices=$dev0,$dev1,$dev2
--
2.41.0

View File

@ -0,0 +1,35 @@
From 5c1133ba8d026d65362953f25178fbf974b78ce9 Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Wed, 22 May 2024 16:50:46 +0800
Subject: [PATCH 084/201] mdadm/tests: remove 03r5assem-failed
03r5assem can run successfully with kernel 6.9.0-rc4
Signed-off-by: Xiao Ni <xni@redhat.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
tests/03r5assem-failed | 12 ------------
1 file changed, 12 deletions(-)
delete mode 100644 tests/03r5assem-failed
diff --git a/tests/03r5assem-failed b/tests/03r5assem-failed
deleted file mode 100644
index d38241df..00000000
--- a/tests/03r5assem-failed
+++ /dev/null
@@ -1,12 +0,0 @@
-
-# Create an array, fail one device while array is active, stop array,
-# then re-assemble listing the failed device first.
-
-mdadm -CR $md1 -l5 -n4 $dev0 $dev1 $dev2 $dev3
-check wait
-
-echo 2000 > /sys/block/md1/md/safe_mode_delay
-mkfs $md1
-mdadm $md1 -f $dev0
-mdadm -S $md1
-mdadm -A $md1 $dev0 $dev1 $dev2 $dev3 || exit 1
--
2.41.0

View File

@ -0,0 +1,52 @@
From 6077e9248acda8c70df58fabc8de23195c19a0cf Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Wed, 22 May 2024 16:50:47 +0800
Subject: [PATCH 085/201] mdadm/tests: 03r5assemV1
dcc22ae74a864 ('super1: remove support for name= in config') already
removes name= support. So remove related test codes in 03r5assemV1.
Signed-off-by: Xiao Ni <xni@redhat.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
tests/03r5assemV1 | 17 -----------------
1 file changed, 17 deletions(-)
diff --git a/tests/03r5assemV1 b/tests/03r5assemV1
index bca0c583..6026011e 100644
--- a/tests/03r5assemV1
+++ b/tests/03r5assemV1
@@ -31,14 +31,6 @@ conf=$targetdir/mdadm.conf
mdadm -As -c $conf $md1
eval $tst
-{
- echo DEVICE $devlist
- echo array $md1 name=one
-} > $conf
-
-mdadm -As -c $conf
-eval $tst
-
{
echo DEVICE $devlist
echo array $md1 devices=$dev0,$dev1,$dev2,$dev3,$dev4
@@ -88,15 +80,6 @@ mdadm -As -c $conf $md1
check state U_U
eval $tst
-{
- echo DEVICE $devlist
- echo array $md1 name=one
-} > $conf
-
-mdadm -As -c $conf
-check state U_U
-eval $tst
-
{
echo DEVICE $devlist
echo array $md1 devices=$dev0,$dev1,$dev2
--
2.41.0

View File

@ -0,0 +1,30 @@
From b9b8eaef49e075ce68846abb7cf0ca47c1ba9f2f Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Wed, 22 May 2024 16:50:48 +0800
Subject: [PATCH 086/201] mdadm/tests: remove 04r5swap.broken
04r5swap can run successfully with kernel 6.9.0-rc4
Signed-off-by: Xiao Ni <xni@redhat.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
tests/04r5swap.broken | 7 -------
1 file changed, 7 deletions(-)
delete mode 100644 tests/04r5swap.broken
diff --git a/tests/04r5swap.broken b/tests/04r5swap.broken
deleted file mode 100644
index e38987db..00000000
--- a/tests/04r5swap.broken
+++ /dev/null
@@ -1,7 +0,0 @@
-always fails
-
-Fails with errors:
-
- mdadm: /dev/loop0 has no superblock - assembly aborted
-
- ERROR: no recovery happening
--
2.41.0

View File

@ -0,0 +1,116 @@
From 9808f110c5aea5454e9f56b2b660612a57adb347 Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Wed, 22 May 2024 16:50:49 +0800
Subject: [PATCH 087/201] tests/04update-metadata skip linear
Add one check that if kernel doesn't support linear/multipath, it can
skip linear/multipath testing.
Signed-off-by: Xiao Ni <xni@redhat.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
test | 3 +++
tests/04update-metadata | 35 ++++++++++++++++++++---------------
tests/func.sh | 2 ++
3 files changed, 25 insertions(+), 15 deletions(-)
diff --git a/test b/test
index 1fce6be2..f09994e7 100755
--- a/test
+++ b/test
@@ -17,6 +17,9 @@ devlist=
# device node will be /dev/md127 (127 is choosed by mdadm autumatically)
is_foreign="no"
+skipping_linear="no"
+skipping_multipath="no"
+
savelogs=0
exitonerror=1
ctrl_c_error=0
diff --git a/tests/04update-metadata b/tests/04update-metadata
index 2b72a303..c748770c 100644
--- a/tests/04update-metadata
+++ b/tests/04update-metadata
@@ -8,24 +8,29 @@ set -xe
dlist="$dev0 $dev1 $dev2 $dev3"
-for ls in linear/4 raid1/1 raid5/3 raid6/2
+if [ $skipping_linear == "yes" ]; then
+ level_list="raid1/1 raid5/3 raid6/2"
+else
+ level_list="linear/4 raid1/1 raid5/3 raid6/2"
+fi
+for ls in $level_list
do
- s=${ls#*/} l=${ls%/*}
- if [[ $l == 'raid1' ]]; then
- mdadm -CR --assume-clean -e 0.90 $md0 --level $l -n 4 $dlist
- else
- mdadm -CR --assume-clean -e 0.90 $md0 --level $l -n 4 -c 64 $dlist
- fi
- testdev $md0 $s 19904 64
- mdadm -S $md0
- mdadm -A $md0 --update=metadata $dlist
- testdev $md0 $s 19904 64 check
- mdadm -S $md0
+ s=${ls#*/} l=${ls%/*}
+ if [[ $l == 'raid1' ]]; then
+ mdadm -CR --assume-clean -e 0.90 $md0 --level $l -n 4 $dlist
+ else
+ mdadm -CR --assume-clean -e 0.90 $md0 --level $l -n 4 -c 64 $dlist
+ fi
+ testdev $md0 $s 19904 64
+ mdadm -S $md0
+ mdadm -A $md0 --update=metadata $dlist
+ testdev $md0 $s 19904 64 check
+ mdadm -S $md0
done
if mdadm -A $md0 --update=metadata $dlist
then echo >&2 should fail with v1.0 metadata
- exit 1
+ exit 1
fi
mdadm -CR -e 0.90 $md0 --level=6 -n4 -c32 $dlist
@@ -33,7 +38,7 @@ mdadm -S $md0
if mdadm -A $md0 --update=metadata $dlist
then echo >&2 should fail during resync
- exit 1
+ exit 1
fi
mdadm -A $md0 $dlist
mdadm --wait $md0 || true
@@ -48,5 +53,5 @@ mdadm -S $md0
if mdadm -A $md0 --update=metadata $dlist
then echo >&2 should fail when bitmap present
- exit 1
+ exit 1
fi
diff --git a/tests/func.sh b/tests/func.sh
index cfe83e55..db55542d 100644
--- a/tests/func.sh
+++ b/tests/func.sh
@@ -125,6 +125,7 @@ check_env() {
MULTIPATH="yes"
if [ "$MULTIPATH" != "yes" ]; then
echo "test: skipping tests for multipath, which is removed in upstream 6.8+ kernels"
+ skipping_multipath="yes"
fi
# Check whether to run linear tests
@@ -133,6 +134,7 @@ check_env() {
LINEAR="yes"
if [ "$LINEAR" != "yes" ]; then
echo "test: skipping tests for linear, which is removed in upstream 6.8+ kernels"
+ skipping_linear="yes"
fi
}
--
2.41.0

View File

@ -0,0 +1,68 @@
From 7664a3851476cfcda931d35f495d03f51707bac9 Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Wed, 22 May 2024 16:50:50 +0800
Subject: [PATCH 088/201] mdadm/tests: 05r5-internalbitmap
It's not right to compare bitmap bits with a number after io comes.
Because maybe those bits are already flused. Remove the related
tests.
Signed-off-by: Xiao Ni <xni@redhat.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
tests/05r5-internalbitmap | 21 +++++++++------------
1 file changed, 9 insertions(+), 12 deletions(-)
diff --git a/tests/05r5-internalbitmap b/tests/05r5-internalbitmap
index 13dc5921..1a64482f 100644
--- a/tests/05r5-internalbitmap
+++ b/tests/05r5-internalbitmap
@@ -9,21 +9,20 @@ mdadm -S $md0
mdadm --assemble $md0 $dev1 $dev2 $dev3
testdev $md0 2 $mdsize1 512
-dirty1=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
sleep 4
-dirty2=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
+dirty1=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
-if [ $dirty1 -lt 400 -o $dirty2 -ne 0 ]
-then echo >&2 "ERROR bad 'dirty' counts: $dirty1 and $dirty2"
+if [ $dirty1 -ne 0 ]
+then echo >&2 "ERROR bad 'dirty' counts: $dirty1"
exit 1
fi
mdadm $md0 -f $dev1
testdev $md0 2 $mdsize1 512
sleep 4
-dirty3=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
-if [ $dirty3 -lt 400 ]
+dirty2=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
+if [ $dirty2 -lt 400 ]
then
- echo >&2 "ERROR dirty count $dirty3 is too small"
+ echo >&2 "ERROR dirty count $dirty2 is too small"
exit 2
fi
@@ -33,14 +32,12 @@ mdadm --assemble -R $md0 $dev2 $dev3
mdadm --zero $dev1 # force --add, not --re-add
mdadm $md0 --add $dev1
check recovery
-
-dirty4=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
check wait
sleep 4
-dirty5=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
+dirty3=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
-if [ $dirty4 -lt 400 -o $dirty5 -ne 0 ]
-then echo echo >&2 "ERROR bad 'dirty' counts at end: $dirty4 $dirty5"
+if [ $dirty3 -ne 0 ]
+then echo echo >&2 "ERROR bad 'dirty' counts at end: $dirty3"
exit 1
fi
--
2.41.0

View File

@ -0,0 +1,38 @@
From 6e7d850a57d40e18d525d0739a4f4226f6057d91 Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Wed, 22 May 2024 16:50:52 +0800
Subject: [PATCH 089/201] mdadm/tests: 06name enhance
It needs to check hostname in metadata name if one array is
local. Add the check in this case.
Signed-off-by: Xiao Ni <xni@redhat.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
tests/06name | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/tests/06name b/tests/06name
index 86eaab69..c3213f6c 100644
--- a/tests/06name
+++ b/tests/06name
@@ -3,8 +3,14 @@ set -x
# create an array with a name
mdadm -CR $md0 -l0 -n2 --metadata=1 --name="Fred" $dev0 $dev1
-mdadm -E $dev0 | grep 'Name : Fred' > /dev/null || exit 1
-mdadm -D $md0 | grep 'Name : Fred' > /dev/null || exit 1
+
+if [ $is_foreign == "no" ]; then
+ mdadm -E $dev0 | grep "Name : $(hostname):Fred" > /dev/null || exit 1
+ mdadm -D $md0 | grep "Name : $(hostname):Fred" > /dev/null || exit 1
+else
+ mdadm -E $dev0 | grep "Name : Fred" > /dev/null || exit 1
+ mdadm -D $md0 | grep "Name : Fred" > /dev/null || exit 1
+fi
mdadm -S $md0
mdadm -A $md0 --name="Fred" $devlist
--
2.41.0

View File

@ -0,0 +1,108 @@
From 63e99a49cc02cbe4d1777b477719078897fc8308 Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Wed, 22 May 2024 16:50:53 +0800
Subject: [PATCH 090/201] mdadm/tests: 07autoassemble
This test is used to test stacked array auto assemble.
There are two different cases depends on if array is foreign or not.
If the array is foreign, the stacked array (md0 is on md1 and md2)
can't be assembled with name md0. Because udev rule will run when md1
and md2 are assembled and mdadm -I doesn't specify homehost. So it
will treat stacked array (md0) as foreign array and choose md127 as
the device node name (/dev/md127)
Add the case that stacked array is local.
Signed-off-by: Xiao Ni <xni@redhat.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
test | 2 ++
tests/07autoassemble | 37 +++++++++++++++++++++++++++++++++++--
tests/07autoassemble.broken | 8 --------
3 files changed, 37 insertions(+), 10 deletions(-)
delete mode 100644 tests/07autoassemble.broken
diff --git a/test b/test
index f09994e7..4a88de58 100755
--- a/test
+++ b/test
@@ -39,6 +39,8 @@ md2=/dev/md2
# if user doesn't specify minor number, mdadm chooses minor number
# automatically from 127.
md127=/dev/md127
+md126=/dev/md126
+md125=/dev/md125
mdp0=/dev/md_d0
mdp1=/dev/md_d1
diff --git a/tests/07autoassemble b/tests/07autoassemble
index e689be7c..9dc78149 100644
--- a/tests/07autoassemble
+++ b/tests/07autoassemble
@@ -10,7 +10,14 @@ mdadm -Ss
mdadm -As -c /dev/null --homehost=testing -vvv
testdev $md1 1 $mdsize1a 64
testdev $md2 1 $mdsize1a 64
-testdev $md0 2 $mdsize11a 512
+# md1 and md2 will be incremental assemble by udev rule. And
+# the testing machines' hostname is not testing. The md0 will
+# be considered as a foreign array. It can use 0 as metadata
+# name. md127 will be used
+testdev $md127 2 $mdsize11a 512
+mdadm --stop $md127
+mdadm --zero-superblock $md1
+mdadm --zero-superblock $md2
mdadm -Ss
mdadm --zero-superblock $dev0 $dev1 $dev2 $dev3
@@ -20,5 +27,31 @@ mdadm -CR $md0 -l0 -n2 $md1 $dev2 --homehost=testing
mdadm -Ss
mdadm -As -c /dev/null --homehost=testing -vvv
testdev $md1 1 $mdsize1a 64
-testdev $md0 1 $[mdsize1a+mdsize11a] 512
+testdev $md127 1 $[mdsize1a+mdsize11a] 512
+mdadm --stop $md127
+mdadm --zero-superblock $md1
+mdadm -Ss
+
+# Don't specify homehost when creating raid and use the test
+# machine's homehost. For super1.2, if homehost name's length
+# is > 32, it doesn't use homehost name in metadata name and
+# the array will be treated as foreign array
+mdadm --zero-superblock $dev0 $dev1 $dev2 $dev3
+mdadm -CR $md1 -l1 -n2 $dev0 $dev1
+mdadm -CR $md2 -l1 -n2 $dev2 $dev3
+mdadm -CR $md0 -l0 -n2 $md1 $md2
+mdadm -Ss
+mdadm -As -c /dev/null
+if [ $is_foreign == "yes" ]; then
+ # md127 is md1
+ testdev $md127 1 $mdsize1a 64
+ # md126 is md0, udev rule incremental assemble it
+ testdev $md126 2 $mdsize11a 512
+ # md125 is md2
+ testdev $md125 1 $mdsize1a 64
+else
+ testdev $md1 1 $mdsize1a 64
+ testdev $md2 1 $mdsize1a 64
+ testdev $md0 2 $mdsize11a 512
+fi
mdadm -Ss
diff --git a/tests/07autoassemble.broken b/tests/07autoassemble.broken
deleted file mode 100644
index 8be09407..00000000
--- a/tests/07autoassemble.broken
+++ /dev/null
@@ -1,8 +0,0 @@
-always fails
-
-Prints lots of messages, but the array doesn't assemble. Error
-possibly related to:
-
- mdadm: /dev/md/1 is busy - skipping
- mdadm: no recogniseable superblock on /dev/md/testing:0
- mdadm: /dev/md/2 is busy - skipping
--
2.41.0

View File

@ -0,0 +1,28 @@
From 1d0c61f4baa49bc218687017ccb2e3a664351390 Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Wed, 22 May 2024 16:50:54 +0800
Subject: [PATCH 091/201] mdadm/tests: 07autodetect.broken can be removed
07autodetect can run successfully without error in kernel 6.9.0-rc5.
Signed-off-by: Xiao Ni <xni@redhat.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
tests/07autodetect.broken | 5 -----
1 file changed, 5 deletions(-)
delete mode 100644 tests/07autodetect.broken
diff --git a/tests/07autodetect.broken b/tests/07autodetect.broken
deleted file mode 100644
index 294954a1..00000000
--- a/tests/07autodetect.broken
+++ /dev/null
@@ -1,5 +0,0 @@
-always fails
-
-Fails with error:
-
- ERROR: no resync happening
--
2.41.0

View File

@ -0,0 +1,73 @@
From cd3b2350bef136b20c81190371fb0b60d62a0365 Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Wed, 22 May 2024 16:50:55 +0800
Subject: [PATCH 092/201] mdadm/tests: 07changelevelintr
It needs to specify a 2 powered array size when updating array size.
If not, it can't change chunksize.
And sometimes it reports error reshape doesn't happen. In fact the
reshape has finished. It doesn't need to wait before checking
reshape action. Because check function waits itself.
Signed-off-by: Xiao Ni <xni@redhat.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
tests/07changelevelintr | 9 +++++----
tests/07changelevelintr.broken | 9 ---------
2 files changed, 5 insertions(+), 13 deletions(-)
delete mode 100644 tests/07changelevelintr.broken
diff --git a/tests/07changelevelintr b/tests/07changelevelintr
index 18c63092..d921f2b2 100644
--- a/tests/07changelevelintr
+++ b/tests/07changelevelintr
@@ -27,11 +27,9 @@ checkgeo() {
}
restart() {
- sleep 0.5
check reshape
mdadm -S $md0
mdadm -A $md0 $devs --backup-file=$bu
- sleep 0.5
check reshape
}
@@ -49,13 +47,16 @@ mdadm -G $md0 --layout rs --backup-file=$bu
restart
checkgeo md0 raid5 5 $[128*1024] 3
-mdadm -G $md0 --array-size 58368
+# It needs to shrink array size first. Choose a value that
+# is power of 2 for array size. If not, it can't change
+# chunk size.
+mdadm -G $md0 --array-size 51200
mdadm -G $md0 --raid-disks 4 -c 64 --backup-file=$bu
restart
checkgeo md0 raid5 4 $[64*1024] 3
devs="$dev0 $dev1 $dev2 $dev3"
-mdadm -G $md0 --array-size 19456
+mdadm -G $md0 --array-size 18432
mdadm -G $md0 -n 2 -c 256 --backup-file=$bu
restart
checkgeo md0 raid5 2 $[256*1024] 3
diff --git a/tests/07changelevelintr.broken b/tests/07changelevelintr.broken
deleted file mode 100644
index 284b4906..00000000
--- a/tests/07changelevelintr.broken
+++ /dev/null
@@ -1,9 +0,0 @@
-always fails
-
-Fails with errors:
-
- mdadm: this change will reduce the size of the array.
- use --grow --array-size first to truncate array.
- e.g. mdadm --grow /dev/md0 --array-size 56832
-
- ERROR: no reshape happening
--
2.41.0

View File

@ -0,0 +1,68 @@
From b914aa25ee1fe3e0bd97f58bdf2bfdd185992a79 Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Wed, 22 May 2024 16:50:56 +0800
Subject: [PATCH 093/201] mdadm/tests: disable selinux
Sometimes systemd service fails because selinux. Disable selinux
during testing now. We can enable it in future when having a better
method.
Signed-off-by: Xiao Ni <xni@redhat.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
test | 3 +++
tests/func.sh | 10 ++++++++++
2 files changed, 13 insertions(+)
diff --git a/test b/test
index 4a88de58..47f53ad7 100755
--- a/test
+++ b/test
@@ -16,6 +16,8 @@ devlist=
# For example, /dev/md0 is created, stops it, then assemble it, the
# device node will be /dev/md127 (127 is choosed by mdadm autumatically)
is_foreign="no"
+#disable selinux
+sys_selinux="Permissive"
skipping_linear="no"
skipping_multipath="no"
@@ -351,6 +353,7 @@ main() {
fi
done
+ restore_selinux
exit 0
}
diff --git a/tests/func.sh b/tests/func.sh
index db55542d..b2e4d122 100644
--- a/tests/func.sh
+++ b/tests/func.sh
@@ -167,6 +167,15 @@ is_raid_foreign() {
fi
}
+record_selinux() {
+ sys_selinux=`getenforce`
+ setenforce Permissive
+}
+
+restore_selinux() {
+ setenforce $sys_selinux
+}
+
do_setup() {
trap cleanup 0 1 3 15
trap ctrl_c 2
@@ -247,6 +256,7 @@ do_setup() {
echo 0 > /sys/module/md_mod/parameters/start_ro
record_system_speed_limit
is_raid_foreign
+ record_selinux
}
# check various things
--
2.41.0

View File

@ -0,0 +1,44 @@
From 827e1870f320545796d907f50af594e901399417 Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Tue, 28 May 2024 16:44:39 +0800
Subject: [PATCH 094/201] mdadm/platform-intel: buffer overflow detected
mdadm -CR /dev/md0 -l1 -n2 /dev/nvme0n1 /dev/nvme2n1
*** buffer overflow detected ***: terminated
Aborted (core dumped)
It doesn't happen 100% and it depends on the building environment.
It can be fixed by replacing sprintf with snprintf.
Fixes: d835518b6b53 ('imsm: nvme multipath support')
Reported-by: Guang Wu <guazhang@redhat.com>
Signed-off-by: Xiao Ni <xni@redhat.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
platform-intel.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/platform-intel.c b/platform-intel.c
index 15a9fa5a..d6a53533 100644
--- a/platform-intel.c
+++ b/platform-intel.c
@@ -907,14 +907,14 @@ char *get_nvme_multipath_dev_hw_path(const char *dev_path)
return NULL;
for (ent = readdir(dir); ent; ent = readdir(dir)) {
- char buf[strlen(dev_path) + strlen(ent->d_name) + 1];
+ char buf[PATH_MAX];
/* 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);
+ snprintf(buf, PATH_MAX, "%s/%s", dev_path, ent->d_name);
rp = realpath(buf, NULL);
break;
}
--
2.41.0

View File

@ -0,0 +1,279 @@
From c006602b313e2f6062b51aad37d93dccd29649de Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Tue, 28 May 2024 21:51:47 +0800
Subject: [PATCH 095/201] mdadm/tests: bitmap cases enhance
It fails because bitmap dirty number is smaller than 400 sometimes. It's not
good to compare bitmap dirty bits with a number. It depends on the test
machine, it can flush soon before checking the number. So remove related codes.
Signed-off-by: Xiao Ni <xni@redhat.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
tests/05r1-grow-internal | 11 ++++-------
tests/05r1-grow-internal-1 | 12 ++++--------
tests/05r1-internalbitmap | 22 ++++++++++------------
tests/05r1-internalbitmap-v1a | 22 ++++++++++------------
tests/05r1-internalbitmap-v1b | 23 ++++++++++-------------
tests/05r1-internalbitmap-v1c | 22 ++++++++++------------
6 files changed, 48 insertions(+), 64 deletions(-)
diff --git a/tests/05r1-grow-internal b/tests/05r1-grow-internal
index 24b3aece..f7fff989 100644
--- a/tests/05r1-grow-internal
+++ b/tests/05r1-grow-internal
@@ -8,18 +8,15 @@ testdev $md0 1 $mdsize1a 64
#mdadm -E $dev1
mdadm --grow $md0 --bitmap=internal --bitmap-chunk=4 --delay=1 || { mdadm -X $dev2 ; exit 1; }
-dirty1=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
sleep 4
-dirty2=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
+dirty1=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
testdev $md0 1 $mdsize1a 64
-dirty3=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
sleep 4
-dirty4=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
+dirty2=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
-#echo $dirty1 $dirty2 $dirty3 $dirty4
-if [ $dirty2 -ne 0 -o $dirty4 -ne 0 -o $dirty3 -lt 400 ]
-then
+if [ $dirty1 -ne 0 -o $dirty2 -ne 0 ]
+then echo >&2 "ERROR bad 'dirty' counts: dirty1 $dirty1, dirty2 $dirty2"
echo bad dirty counts
exit 1
fi
diff --git a/tests/05r1-grow-internal-1 b/tests/05r1-grow-internal-1
index 2f0d8237..f0f8349f 100644
--- a/tests/05r1-grow-internal-1
+++ b/tests/05r1-grow-internal-1
@@ -8,19 +8,15 @@ testdev $md0 1 $mdsize1b 64
#mdadm -E $dev1
mdadm --grow $md0 --bitmap=internal --bitmap-chunk=4 --delay=1
-dirty1=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
sleep 4
-dirty2=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
+dirty1=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
testdev $md0 1 $mdsize1b 64
-dirty3=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
sleep 4
-dirty4=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
+dirty2=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
-#echo $dirty1 $dirty2 $dirty3 $dirty4
-if [ $dirty2 -ne 0 -o $dirty4 -ne 0 -o $dirty3 -lt 400 ]
-then
- echo bad dirty counts
+if [ $dirty1 -ne 0 -o $dirty2 -ne 0 ]
+then echo >&2 "ERROR bad 'dirty' counts: dirty1 $dirty1, dirty2 $dirty2"
exit 1
fi
diff --git a/tests/05r1-internalbitmap b/tests/05r1-internalbitmap
index dd7232a7..f1a2843e 100644
--- a/tests/05r1-internalbitmap
+++ b/tests/05r1-internalbitmap
@@ -9,21 +9,20 @@ mdadm -S $md0
mdadm --assemble $md0 $dev1 $dev2
testdev $md0 1 $mdsize0 64
-dirty1=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
sleep 4
-dirty2=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
+dirty1=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
-if [ $dirty1 -lt 400 -o $dirty2 -ne 0 ]
-then echo >&2 "ERROR bad 'dirty' counts: $dirty1 and $dirty2"
+if [ $dirty1 -ne 0 ]
+then echo >&2 "ERROR bad 'dirty' counts: $dirty1"
exit 1
fi
mdadm $md0 -f $dev1
testdev $md0 1 $mdsize0 64
sleep 4
-dirty3=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
-if [ $dirty3 -lt 400 ]
-then
- echo >&2 "ERROR dirty count $dirty3 is too small"
+total=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) bits.*/\1/p'`
+dirty2=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
+if [ $dirty2 -ne $total ]
+then echo >&2 "ERROR bad 'dirty' counts: total $total, dirty2 $dirty2"
exit 2
fi
@@ -34,13 +33,12 @@ mdadm --zero-superblock $dev1
mdadm $md0 --add $dev1
check recovery
-dirty4=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
check wait
sleep 4
-dirty5=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
+dirty3=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
-if [ $dirty4 -lt 400 -o $dirty5 -ne 0 ]
-then echo echo >&2 "ERROR bad 'dirty' counts at end: $dirty4 $dirty5"
+if [ $dirty3 -ne 0 ]
+then echo >&2 "ERROR bad 'dirty' counts: $dirty3"
exit 1
fi
diff --git a/tests/05r1-internalbitmap-v1a b/tests/05r1-internalbitmap-v1a
index 3ddc082f..cf3f3972 100644
--- a/tests/05r1-internalbitmap-v1a
+++ b/tests/05r1-internalbitmap-v1a
@@ -10,21 +10,20 @@ mdadm -S $md0
mdadm --assemble $md0 $dev1 $dev2
testdev $md0 1 $mdsize1b 64
-dirty1=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
sleep 4
-dirty2=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
+dirty1=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
-if [ $dirty1 -lt 400 -o $dirty2 -ne 0 ]
-then echo >&2 "ERROR bad 'dirty' counts: $dirty1 and $dirty2"
+if [ $dirty1 -ne 0 ]
+then echo >&2 "ERROR bad 'dirty' counts: $dirty1"
exit 1
fi
mdadm $md0 -f $dev1
testdev $md0 1 $mdsize1b 64
sleep 4
-dirty3=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
-if [ $dirty3 -lt 400 ]
-then
- echo >&2 "ERROR dirty count $dirty3 is too small"
+total=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) bits.*/\1/p'`
+dirty2=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
+if [ $dirty2 -ne $total ]
+then echo >&2 "ERROR bad 'dirty' counts: total $total, dirty2 $dirty2"
exit 2
fi
@@ -35,13 +34,12 @@ mdadm --assemble -R $md0 $dev2
mdadm $md0 --add $dev1
check recovery
-dirty4=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
check wait
sleep 4
-dirty5=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
+dirty3=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
-if [ $dirty4 -lt 400 -o $dirty5 -ne 0 ]
-then echo echo >&2 "ERROR bad 'dirty' counts at end: $dirty4 $dirty5"
+if [ $dirty3 -ne 0 ]
+then echo >&2 "ERROR bad 'dirty' counts: $dirty3"
exit 1
fi
diff --git a/tests/05r1-internalbitmap-v1b b/tests/05r1-internalbitmap-v1b
index 40f7abea..4952887e 100644
--- a/tests/05r1-internalbitmap-v1b
+++ b/tests/05r1-internalbitmap-v1b
@@ -11,21 +11,20 @@ mdadm -S $md0
mdadm --assemble $md0 $dev1 $dev2
check bitmap
testdev $md0 1 $mdsize11 64
-dirty1=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
sleep 4
-dirty2=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
+dirty1=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
-if [ $dirty1 -lt 400 -o $dirty2 -ne 0 ]
-then echo >&2 "ERROR bad 'dirty' counts: $dirty1 and $dirty2"
+if [ $dirty1 -ne 0 ]
+then echo >&2 "ERROR bad 'dirty' counts: $dirty1"
exit 1
fi
mdadm $md0 -f $dev1
testdev $md0 1 $mdsize11 64
sleep 4
-dirty3=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
-if [ $dirty3 -lt 400 ]
-then
- echo >&2 "ERROR dirty count $dirty3 is too small"
+total=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) bits.*/\1/p'`
+dirty2=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
+if [ $dirty2 -ne $total ]
+then echo >&2 "ERROR bad 'dirty' counts: total $total, dirty2 $dirty2"
exit 2
fi
@@ -35,14 +34,12 @@ mdadm --zero-superblock $dev1
mdadm --assemble -R $md0 $dev2
mdadm $md0 --add $dev1
check recovery
-
-dirty4=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
check wait
sleep 4
-dirty5=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
+dirty3=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
-if [ $dirty4 -lt 400 -o $dirty5 -ne 0 ]
-then echo echo >&2 "ERROR bad 'dirty' counts at end: $dirty4 $dirty5"
+if [ $dirty3 -ne 0 ]
+then echo >&2 "ERROR bad 'dirty' counts: $dirty3"
exit 1
fi
diff --git a/tests/05r1-internalbitmap-v1c b/tests/05r1-internalbitmap-v1c
index 2eaea59b..e1e4472f 100644
--- a/tests/05r1-internalbitmap-v1c
+++ b/tests/05r1-internalbitmap-v1c
@@ -10,21 +10,20 @@ mdadm -S $md0
mdadm --assemble $md0 $dev1 $dev2
testdev $md0 1 $mdsize12 64
-dirty1=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
sleep 4
-dirty2=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
+dirty1=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
-if [ $dirty1 -lt 400 -o $dirty2 -ne 0 ]
-then echo >&2 "ERROR bad 'dirty' counts: $dirty1 and $dirty2"
+if [ $dirty1 -ne 0 ]
+then echo >&2 "ERROR bad 'dirty' counts: $dirty1"
exit 1
fi
mdadm $md0 -f $dev1
testdev $md0 1 $mdsize12 64
sleep 4
-dirty3=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
-if [ $dirty3 -lt 400 ]
-then
- echo >&2 "ERROR dirty count $dirty3 is too small"
+total=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) bits.*/\1/p'`
+dirty2=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
+if [ $dirty2 -ne $total ]
+then echo >&2 "ERROR bad 'dirty' counts: total $total, dirty2 $dirty2"
exit 2
fi
@@ -35,13 +34,12 @@ mdadm --assemble -R $md0 $dev2
mdadm $md0 --add $dev1
check recovery
-dirty4=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
check wait
sleep 4
-dirty5=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
+dirty3=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'`
-if [ $dirty4 -lt 400 -o $dirty5 -ne 0 ]
-then echo echo >&2 "ERROR bad 'dirty' counts at end: $dirty4 $dirty5"
+if [ $dirty3 -ne 0 ]
+then echo >&2 "ERROR bad 'dirty' counts: $dirty3"
exit 1
fi
--
2.41.0

View File

@ -0,0 +1,39 @@
From 19cde79fda386329f69ead15ca6ae26527fab707 Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Tue, 28 May 2024 21:51:48 +0800
Subject: [PATCH 096/201] mdadm/tests: 04update-uuid
Patch 50b100768a11('mdadm: deprecate bitmap custom file') needs to confirm when
creating raid device with bitmap file.
Signed-off-by: Xiao Ni <xni@redhat.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
tests/04update-uuid | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tests/04update-uuid b/tests/04update-uuid
index a4409e78..25314ab5 100644
--- a/tests/04update-uuid
+++ b/tests/04update-uuid
@@ -25,7 +25,7 @@ mdadm -S /dev/md0
# now if we have a bitmap, that needs updating too.
rm -f $targetdir/bitmap
-mdadm -CR --assume-clean -b $targetdir/bitmap $md0 -l5 -n3 $dev0 $dev1 $dev2
+yes | mdadm -CR --assume-clean -b $targetdir/bitmap $md0 -l5 -n3 $dev0 $dev1 $dev2
mdadm -S /dev/md0
mdadm -A /dev/md0 -b $targetdir/bitmap --update=uuid --uuid=0123456789abcdef:fedcba9876543210 $dev0 $dev1 $dev2
no_errors
@@ -41,7 +41,7 @@ mdadm -S /dev/md0
# and bitmap for version1
rm -f $targetdir/bitmap
-mdadm -CR --assume-clean -e1.1 -b $targetdir/bitmap $md0 -l5 -n3 $dev0 $dev1 $dev2
+yes | mdadm -CR --assume-clean -e1.1 -b $targetdir/bitmap $md0 -l5 -n3 $dev0 $dev1 $dev2
mdadm -S /dev/md0
mdadm -A /dev/md0 -b $targetdir/bitmap --update=uuid --uuid=0123456789abcdef:fedcba9876543210 $dev0 $dev1 $dev2
no_errors
--
2.41.0

View File

@ -0,0 +1,30 @@
From c36477fac2e485fd294e5cb48d411b548c654f30 Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Tue, 28 May 2024 21:51:49 +0800
Subject: [PATCH 097/201] mdadm/tests: 05r1-re-add-nosuper
Patch 50b100768a11('mdadm: deprecate bitmap custom file') needs to confirm when
creating raid device with bitmap file.
Signed-off-by: Xiao Ni <xni@redhat.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
tests/05r1-re-add-nosuper | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/05r1-re-add-nosuper b/tests/05r1-re-add-nosuper
index 058d602d..7d41fd7b 100644
--- a/tests/05r1-re-add-nosuper
+++ b/tests/05r1-re-add-nosuper
@@ -6,7 +6,7 @@
#
bmf=$targetdir/bitmap2
rm -f $bmf
-mdadm -B $md0 -l1 -n2 -b$bmf -d1 $dev1 $dev2
+yes | mdadm -B $md0 -l1 -n2 -b$bmf -d1 $dev1 $dev2
check resync
check wait
testdev $md0 1 $size 1
--
2.41.0

View File

@ -0,0 +1,44 @@
From c5a4fe7874f94b3f172027043f9a94b037f4d4dd Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Tue, 28 May 2024 21:51:50 +0800
Subject: [PATCH 098/201] mdadm/tests: remove strace test
Some tests will fail if the test env doesn't have strace
commands. So remove the dependency.
Signed-off-by: Xiao Ni <xni@redhat.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
tests/07revert-grow | 2 +-
tests/07revert-inplace | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/tests/07revert-grow b/tests/07revert-grow
index c8c4e855..333483dc 100644
--- a/tests/07revert-grow
+++ b/tests/07revert-grow
@@ -43,7 +43,7 @@ testdev $md0 2 $mdsize1 512
mdadm -G $md0 -n 5
sleep 3
mdadm -S $md0
-strace -o /tmp/str ./mdadm -A $md0 --update=revert-reshape $devlist4
+mdadm -A $md0 --update=revert-reshape $devlist4
check wait
check raid10
testdev $md0 2 $mdsize1 512
diff --git a/tests/07revert-inplace b/tests/07revert-inplace
index a73eb977..776324ac 100644
--- a/tests/07revert-inplace
+++ b/tests/07revert-inplace
@@ -37,7 +37,7 @@ testdev $md0 3 $mdsize1 64
mdadm -G $md0 -c 32
sleep 2
mdadm -S $md0
-strace -o /tmp/str ./mdadm -A $md0 --update=revert-reshape $devlist5
+mdadm -A $md0 --update=revert-reshape $devlist5
check wait
check raid10
testdev $md0 3 $mdsize1 64
--
2.41.0

View File

@ -0,0 +1,37 @@
From 9dbd11e091f84eb0bf9d717283774816c4c4453d Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Tue, 21 May 2024 16:26:33 +0200
Subject: [PATCH 099/201] mdadm.h: provide basename if GLIBC is not avialable
If GNU basename is not avilable, define it. It is safer to use that
rather than include libgen.h with XPG basename() definition.
Fixes:#12
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
mdadm.h | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/mdadm.h b/mdadm.h
index 40818941..e9f764a2 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -223,6 +223,14 @@ struct dlm_lksb {
struct __una_u16 { __u16 x; } __attribute__ ((packed));
struct __una_u32 { __u32 x; } __attribute__ ((packed));
+/*
+ * Ensure GNU basename behavior on GLIBC less systems.
+ */
+#ifndef __GLIBC__
+#define basename(path) \
+ (strrchr((path), '/') ? strrchr((path),'/') + 1 : (path))
+#endif
+
static inline __u16 __get_unaligned16(const void *p)
{
const struct __una_u16 *ptr = (const struct __una_u16 *)p;
--
2.41.0

View File

@ -0,0 +1,79 @@
From 46f19270265fe54cda1c728cb156b755273b4ab6 Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Thu, 23 May 2024 12:06:36 +0200
Subject: [PATCH 100/201] imsm: fix first volume autolayout with
IMSM_NO_PLATFORM
Autolayout_imsm() is not executed if IMSM_NO_PLATFORM=1 is set.
This causes that first volume cannot be created. Disk for new volume are
never configured.
Fix it by making autolayout_imsm() independent from super->orom because
NULL there means that IMSM_NO_PLATFORM=1 is set. There are not platform
restrictions to create volume, we just analyze drives. It is safe.
Fixes: 6d4d9ab295de ("imsm: use same slot across container")
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
super-intel.c | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/super-intel.c b/super-intel.c
index 0287a618..29652196 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -7706,9 +7706,11 @@ static int validate_geometry_imsm(struct supertype *st, int level, int layout,
char *dev, unsigned long long *freesize,
int consistency_policy, int verbose)
{
- int fd, cfd;
+ struct intel_super *super = st->sb;
struct mdinfo *sra;
int is_member = 0;
+ imsm_status_t rv;
+ int fd, cfd;
/* load capability
* if given unused devices create a container
@@ -7733,11 +7735,10 @@ static int validate_geometry_imsm(struct supertype *st, int level, int layout,
}
if (!dev) {
- struct intel_super *super = st->sb;
-
/*
* Autolayout mode, st->sb must be set.
*/
+
if (!super) {
pr_vrb("superblock must be set for autolayout, aborting\n");
return 0;
@@ -7749,20 +7750,19 @@ static int validate_geometry_imsm(struct supertype *st, int level, int layout,
return 0;
if (super->orom && freesize) {
- imsm_status_t rv;
- int count = count_volumes(super->hba, super->orom->dpa,
- verbose);
+ int count = count_volumes(super->hba, super->orom->dpa, verbose);
+
if (super->orom->vphba <= count) {
pr_vrb("platform does not support more than %d raid volumes.\n",
super->orom->vphba);
return 0;
}
+ }
- rv = autolayout_imsm(super, raiddisks, size, *chunk,
- freesize);
+ rv = autolayout_imsm(super, raiddisks, size, *chunk, freesize);
if (rv != IMSM_STATUS_OK)
return 0;
- }
+
return 1;
}
if (st->sb) {
--
2.41.0

View File

@ -0,0 +1,50 @@
From 4f3efc34644d06f55fc650e4aa6b5a6ec22cea5f Mon Sep 17 00:00:00 2001
From: Kinga Stefaniuk <kinga.stefaniuk@intel.com>
Date: Tue, 11 Jun 2024 07:58:49 +0200
Subject: [PATCH 101/201] imsm: make freesize required to volume autolayout
Autolayout_imsm() shall be executed when IMSM_NO_PLATFORM=1 is set.
It was fixed by listed commit, checking super->orom was removed, but
also checking freesize. Freesize is not set for operations on RAID
volume with no size update, that's why it is not required to have
this value and always run autolayout_imsm().
Fix it by making autolayout_imsm() dependent on freesize.
Fixes: 46f192 ("imsm: fix first volume autolayout with IMSM_NO_PLATFORM")
Signed-off-by: Kinga Stefaniuk <kinga.stefaniuk@intel.com>
---
super-intel.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/super-intel.c b/super-intel.c
index 29652196..ef3f5da1 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -7749,7 +7749,7 @@ static int validate_geometry_imsm(struct supertype *st, int level, int layout,
verbose))
return 0;
- if (super->orom && freesize) {
+ if (super->orom) {
int count = count_volumes(super->hba, super->orom->dpa, verbose);
if (super->orom->vphba <= count) {
@@ -7759,9 +7759,11 @@ static int validate_geometry_imsm(struct supertype *st, int level, int layout,
}
}
- rv = autolayout_imsm(super, raiddisks, size, *chunk, freesize);
- if (rv != IMSM_STATUS_OK)
- return 0;
+ if (freesize) {
+ rv = autolayout_imsm(super, raiddisks, size, *chunk, freesize);
+ if (rv != IMSM_STATUS_OK)
+ return 0;
+ }
return 1;
}
--
2.41.0

View File

@ -0,0 +1,86 @@
From 1a5c0e60308651a20d25ff52511230a20d830330 Mon Sep 17 00:00:00 2001
From: Logan Gunthorpe <logang@deltatee.com>
Date: Tue, 4 Jun 2024 10:38:36 -0600
Subject: [PATCH 102/201] mdadm: Fix hang race condition in
wait_for_zero_forks()
Running a create operation with --write-zeros can randomly hang
forever waiting for child processes. This happens roughly on in
ten runs with when running with small (20MB) loop devices.
The bug is caused by the fact that signals can be coallesced into
one if they are not read by signalfd quick enough. So if two children
finish at exactly the same time, only one SIGCHLD will be received
by the parent.
To fix this, wait on all processes with WNOHANG every time a SIGCHLD
is received and exit when all processes have been waited on.
Reported-by: Xiao Ni <xni@redhat.com>
Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
Create.c | 28 +++++++++++++++-------------
1 file changed, 15 insertions(+), 13 deletions(-)
diff --git a/Create.c b/Create.c
index d033eb68..4f992a22 100644
--- a/Create.c
+++ b/Create.c
@@ -178,6 +178,7 @@ static int wait_for_zero_forks(int *zero_pids, int count)
bool interrupted = false;
sigset_t sigset;
ssize_t s;
+ pid_t pid;
for (i = 0; i < count; i++)
if (zero_pids[i])
@@ -196,7 +197,7 @@ static int wait_for_zero_forks(int *zero_pids, int count)
return 1;
}
- while (1) {
+ while (wait_count) {
s = read(sfd, &fdsi, sizeof(fdsi));
if (s != sizeof(fdsi)) {
pr_err("Invalid signalfd read: %s\n", strerror(errno));
@@ -209,23 +210,24 @@ static int wait_for_zero_forks(int *zero_pids, int count)
pr_info("Interrupting zeroing processes, please wait...\n");
interrupted = true;
} else if (fdsi.ssi_signo == SIGCHLD) {
- if (!--wait_count)
- break;
+ for (i = 0; i < count; i++) {
+ if (!zero_pids[i])
+ continue;
+
+ pid = waitpid(zero_pids[i], &wstatus, WNOHANG);
+ if (pid <= 0)
+ continue;
+
+ zero_pids[i] = 0;
+ if (!WIFEXITED(wstatus) || WEXITSTATUS(wstatus))
+ ret = 1;
+ wait_count--;
+ }
}
}
close(sfd);
- for (i = 0; i < count; i++) {
- if (!zero_pids[i])
- continue;
-
- waitpid(zero_pids[i], &wstatus, 0);
- zero_pids[i] = 0;
- if (!WIFEXITED(wstatus) || WEXITSTATUS(wstatus))
- ret = 1;
- }
-
if (interrupted) {
pr_err("zeroing interrupted!\n");
return 1;
--
2.41.0

View File

@ -0,0 +1,37 @@
From 539ad6e6f9a067646a018d77582af0babf8e125e Mon Sep 17 00:00:00 2001
From: Logan Gunthorpe <logang@deltatee.com>
Date: Tue, 4 Jun 2024 10:38:37 -0600
Subject: [PATCH 103/201] mdadm: Block SIGCHLD processes before starting
children
There is a small race condition noticed during code review, but
never actully hit in practice, with the write_zero feature.
If a write zeros fork finishes quickly before wait_for_zero_forks()
gets called, then the SIGCHLD will be delivered before the signalfd
is setup.
While this is only theoretical, fix this by blocking the SIGCHLD
signal before forking any children.
Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
Create.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/Create.c b/Create.c
index 4f992a22..bd4875e4 100644
--- a/Create.c
+++ b/Create.c
@@ -401,6 +401,7 @@ static int add_disks(int mdfd, struct mdinfo *info, struct shape *s,
*/
sigemptyset(&sigset);
sigaddset(&sigset, SIGINT);
+ sigaddset(&sigset, SIGCHLD);
sigprocmask(SIG_BLOCK, &sigset, &orig_sigset);
memset(zero_pids, 0, sizeof(zero_pids));
--
2.41.0

View File

@ -0,0 +1,137 @@
From 29aa21d94bc7ff10f3f7ef0b7f490f3903f5c6fd Mon Sep 17 00:00:00 2001
From: Mateusz Kusiak <mateusz.kusiak@intel.com>
Date: Fri, 15 Mar 2024 16:03:09 -0400
Subject: [PATCH 104/201] test: pass flags to services
Commit 4c12714d1ca0 ("test: run tests on system level mdadm") removed
MDADM_NO_SYSTEMCTL flag from test suite. This causes imsm tests to fail
as mdadm no longer triggers mdmon and flags exists only within session.
Use systemd set/unset-environment to pass necessary flags.
Introduce colors to grab users attention to warnings and key messages.
Make test suite setup systemd environment.
Add setup/clean_systemd_env() functions.
Warn user about altering systemd environment.
Add colors to success/fail messages and warnings.
Signed-off-by: Mateusz Kusiak <mateusz.kusiak@intel.com>
---
test | 8 +++-----
tests/func.sh | 46 +++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 48 insertions(+), 6 deletions(-)
diff --git a/test b/test
index 47f53ad7..3a05bc9b 100755
--- a/test
+++ b/test
@@ -127,7 +127,7 @@ do_test() {
dmesg | grep -iq "error\|call trace\|segfault" | grep -v "systemd" &&
die "dmesg prints errors when testing $_basename!"
fi
- echo "succeeded"
+ succeed "succeeded\n"
_fail=0
else
save_log fail
@@ -315,10 +315,8 @@ parse_args() {
}
print_warning() {
- cat <<-EOF
- Warning! Tests are performed on system level mdadm!
- If you want to test local build, you need to install it first!
- EOF
+ warn "Warning! Tests are performed on system level mdadm!\n"
+ echo "If you want to test local build, you need to install it first!"
}
main() {
diff --git a/tests/func.sh b/tests/func.sh
index b2e4d122..8c142c76 100644
--- a/tests/func.sh
+++ b/tests/func.sh
@@ -23,6 +23,28 @@ mdsize12=19988
# ddf needs bigger devices as 32Meg is reserved!
ddfsize=65536
+# Systemd flags
+devname_as_serial_flag="IMSM_DEVNAME_AS_SERIAL=1"
+no_platform_flag="IMSM_NO_PLATFORM=1"
+
+# Common colors
+COLOR_FAIL='\033[0;31m' #RED
+COLOR_WARN='\033[1;33m' #YELLOW
+COLOR_SUCCESS='\033[0;32m' #GREEN
+COLOR_NONE='\033[0m'
+
+fail() {
+ printf "${COLOR_FAIL}$1${COLOR_NONE}"
+}
+
+warn() {
+ printf "${COLOR_WARN}$1${COLOR_NONE}"
+}
+
+succeed() {
+ printf "${COLOR_SUCCESS}$1${COLOR_NONE}"
+}
+
# $1 is optional parameter, it shows why to save log
save_log() {
status=$1
@@ -36,7 +58,8 @@ save_log() {
cat /proc/mdstat >> $logdir/$logfile
array=($(mdadm -Ds | cut -d' ' -f2))
[ "$1" == "fail" ] &&
- echo "FAILED - see $logdir/$_basename.log and $logdir/$logfile for details"
+ fail "FAILED"
+ echo " - see $logdir/$_basename.log and $logdir/$logfile for details\n"
if [ $DEVTYPE == 'lvm' ]
then
# not supported lvm type yet
@@ -86,6 +109,7 @@ cleanup() {
$mdadm --zero ${disks[@]} &> /dev/null
;;
esac
+ clean_systemd_env
}
do_clean()
@@ -176,11 +200,31 @@ restore_selinux() {
setenforce $sys_selinux
}
+setup_systemd_env() {
+ warn "Warning! Test suite will set up systemd environment!\n"
+ echo "Use \"systemctl show-environment\" to show systemd environment variables"
+ for env_var in $devname_as_serial_flag $no_platform_flag
+ do
+ systemctl set-environment $env_var
+ echo "Added $env_var" to systemd environment, use \
+ \"systemctl unset-environment $env_var\" to remove it.
+ done
+}
+
+clean_systemd_env() {
+ for env_var in $devname_as_serial_flag $no_platform_flag
+ do
+ systemctl unset-environment $env_var
+ echo "Removed $env_var from systemd environment."
+ done
+}
+
do_setup() {
trap cleanup 0 1 3 15
trap ctrl_c 2
check_env
+ setup_systemd_env
[ -d $logdir ] || mkdir -p $logdir
devlist=
--
2.41.0

View File

@ -0,0 +1,68 @@
From 66a54b266f6c579e5f37b6253820903a55c3346c Mon Sep 17 00:00:00 2001
From: Shminderjit Singh <shminderjit.singh@oracle.com>
Date: Tue, 4 Jun 2024 07:46:03 +0000
Subject: [PATCH 105/201] mdadm: Fix socket connection failure when mdmon runs
in foreground mode.
While creating an IMSM RAID, mdadm will wait for the mdmon main process
to finish if mdmon runs in forking mode. This is because with
"Type=forking" in the mdmon service unit file, "systemctl start service"
will block until the main process of mdmon exits. At that moment, mdmon
has already created the socket, so the subsequent socket connect from
mdadm will succeed.
However, when mdmon runs in foreground mode (without "Type=forking" in
the service unit file), "systemctl start service" will return once the
mdmon process starts. This causes mdadm and mdmon to run in parallel,
which may lead to a socket connection failure since mdmon has not yet
initialized the socket when mdadm tries to connect. If the next
instruction/command is to access this device and try to write to it, a
permission error will occur since mdmon has not yet set the array to RW
mode.
Signed-off-by: Shminderjit Singh <shminderjit.singh@oracle.com>
---
msg.c | 20 +++++++++++++++++++-
1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/msg.c b/msg.c
index ba0e25be..d17f679d 100644
--- a/msg.c
+++ b/msg.c
@@ -151,6 +151,7 @@ int connect_monitor(char *devname)
struct sockaddr_un addr;
int pos;
char *c;
+ int rv, retry_count = 0;
pos = sprintf(path, "%s/", MDMON_DIR);
if (is_subarray(devname)) {
@@ -170,7 +171,24 @@ int connect_monitor(char *devname)
addr.sun_family = PF_LOCAL;
strcpy(addr.sun_path, path);
- if (connect(sfd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
+
+ /* In foreground mode, when mdadm is trying to connect to control
+ * socket it is possible that the mdmon has not created it yet.
+ * Give some time to mdmon to create socket.
+ */
+ for (retry_count = 0; retry_count < 10; retry_count++) {
+ rv = connect(sfd, (struct sockaddr*)&addr, sizeof(addr));
+
+ if (rv < 0) {
+ sleep_for(0, MSEC_TO_NSEC(200), true);
+ continue;
+ }
+ break;
+ }
+
+ if (rv < 0) {
+ pr_err("Failed to connect to control socket. (%s!!)\n",
+ strerror(errno));
close(sfd);
return -1;
}
--
2.41.0

View File

@ -0,0 +1,50 @@
From 027b2d37a8cd56973d117107acc25a64cfe0a92f Mon Sep 17 00:00:00 2001
From: Gwendal Grignou <gwendal@chromium.org>
Date: Wed, 15 May 2024 14:30:59 -0700
Subject: [PATCH 106/201] Makefile: Do not call gcc directly
When mdadm is compiled with clang, direct gcc will fail.
Make sure to use $(CC) variable instead.
Note that Clang does not support --help=warnings,
--print-diagnostic-options should be used instead.
So with Clang, the compilation will go through, but the
extra warning flags will never be added.
Signed-off-by: Gwendal Grignou <gwendal@chromium.org>
---
Makefile | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/Makefile b/Makefile
index 446710bd..3fe0a053 100644
--- a/Makefile
+++ b/Makefile
@@ -56,21 +56,21 @@ CWFLAGS += -Wp -O3
endif
ifeq ($(origin FALLTHROUGH), undefined)
- FALLTHROUGH := $(shell gcc -Q --help=warnings 2>&1 | grep "implicit-fallthrough" | wc -l)
+ FALLTHROUGH := $(shell $(CC) -Q --help=warnings 2>&1 | grep "implicit-fallthrough" | wc -l)
ifneq "$(FALLTHROUGH)" "0"
CWFLAGS += -Wimplicit-fallthrough=0
endif
endif
ifeq ($(origin FORMATOVERFLOW), undefined)
- FORMATOVERFLOW := $(shell gcc -Q --help=warnings 2>&1 | grep "format-overflow" | wc -l)
+ FORMATOVERFLOW := $(shell $(CC) -Q --help=warnings 2>&1 | grep "format-overflow" | wc -l)
ifneq "$(FORMATOVERFLOW)" "0"
CWFLAGS += -Wformat-overflow
endif
endif
ifeq ($(origin STRINGOPOVERFLOW), undefined)
- STRINGOPOVERFLOW := $(shell gcc -Q --help=warnings 2>&1 | grep "stringop-overflow" | wc -l)
+ STRINGOPOVERFLOW := $(shell $(CC) -Q --help=warnings 2>&1 | grep "stringop-overflow" | wc -l)
ifneq "$(STRINGOPOVERFLOW)" "0"
CWFLAGS += -Wstringop-overflow
endif
--
2.41.0

View File

@ -0,0 +1,103 @@
From 23aef35113553cb97ef2e7b01c760d5449592e14 Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Fri, 14 Jun 2024 10:45:01 +0800
Subject: [PATCH 107/201] mdadm/tests: judge foreign array in test cases
It needs to use array name when judging if one array is foreign or not.
So calling is_raid_foreign in test cases which need it.
Fixes: 41706a915684 ('mdadm/tests: names_template enhance')
Signed-off-by: Xiao Ni <xni@redhat.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
tests/03assem-incr | 2 ++
tests/06name | 2 ++
tests/07autoassemble | 3 +++
tests/func.sh | 9 +++++----
tests/templates/names_template | 2 ++
5 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/tests/03assem-incr b/tests/03assem-incr
index 21215a34..56afbf2c 100644
--- a/tests/03assem-incr
+++ b/tests/03assem-incr
@@ -12,6 +12,8 @@ if [ "$LINEAR" == "yes" ]; then
levels+=( linear )
fi
+is_raid_foreign $md0
+
for l in ${levels[@]}
do
mdadm -CR $md0 -l $l -n5 $dev0 $dev1 $dev2 $dev3 $dev4 --assume-clean
diff --git a/tests/06name b/tests/06name
index c3213f6c..9ec3437b 100644
--- a/tests/06name
+++ b/tests/06name
@@ -2,6 +2,8 @@ set -x
# create an array with a name
+is_raid_foreign $md0
+
mdadm -CR $md0 -l0 -n2 --metadata=1 --name="Fred" $dev0 $dev1
if [ $is_foreign == "no" ]; then
diff --git a/tests/07autoassemble b/tests/07autoassemble
index 9dc78149..b6630e17 100644
--- a/tests/07autoassemble
+++ b/tests/07autoassemble
@@ -2,6 +2,9 @@
# create two raid1s, build a raid0 on top, then
# tear it down and get auto-assemble to rebuild it.
+#the length of md0/md1/md2 is same. So use md0 here.
+is_raid_foreign $md0
+
mdadm -CR $md1 -l1 -n2 $dev0 $dev1 --homehost=testing
mdadm -CR $md2 -l1 -n2 $dev2 $dev3 --homehost=testing
mdadm -CR $md0 -l0 -n2 $md1 $md2 --homehost=testing
diff --git a/tests/func.sh b/tests/func.sh
index 8c142c76..e7ccc4fc 100644
--- a/tests/func.sh
+++ b/tests/func.sh
@@ -181,10 +181,12 @@ restore_system_speed_limit() {
is_raid_foreign() {
- # If the length of hostname is >= 32, super1 doesn't use
- # hostname in metadata
+ name=$1
+ # super1 uses this formula strlen(homehost)+1+strlen(name) < 32
+ # to decide if an array is foreign or local. It adds homehost if
+ # one array is local
hostname=$(hostname)
- if [ `expr length $(hostname)` -lt 32 ]; then
+ if [ `expr length "$(hostname)$name"` -lt 31 ]; then
is_foreign="no"
else
is_foreign="yes"
@@ -299,7 +301,6 @@ do_setup() {
[ -f /proc/mdstat ] || modprobe md_mod
echo 0 > /sys/module/md_mod/parameters/start_ro
record_system_speed_limit
- is_raid_foreign
record_selinux
}
diff --git a/tests/templates/names_template b/tests/templates/names_template
index 88ad5b8c..c94245ea 100644
--- a/tests/templates/names_template
+++ b/tests/templates/names_template
@@ -4,6 +4,8 @@ function names_create() {
local NAME=$2
local NEG_TEST=$3
+ is_raid_foreign $DEVNAME
+
if [[ -z "$NAME" ]]; then
mdadm -CR "$DEVNAME" -l0 -n 1 $dev0 --force
else
--
2.41.0

View File

@ -0,0 +1,58 @@
From f98340f1b830d950978abba752b2b9b004528faf Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Thu, 20 Jun 2024 15:22:50 +0200
Subject: [PATCH 108/201] Revert "mdadm: Fix socket connection failure when
mdmon runs in foreground mode."
This reverts commit 66a54b266f6c579e5f37b6253820903a55c3346c.
connect_monitor() is called from ping_monitor() but this function is often
used as advice, without verification that mdmon is really working. This
produces hangs in many scenarios.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
msg.c | 20 +-------------------
1 file changed, 1 insertion(+), 19 deletions(-)
diff --git a/msg.c b/msg.c
index d17f679d..f0772b3f 100644
--- a/msg.c
+++ b/msg.c
@@ -151,7 +151,6 @@ int connect_monitor(char *devname)
struct sockaddr_un addr;
int pos;
char *c;
- int rv, retry_count = 0;
pos = sprintf(path, "%s/", MDMON_DIR);
if (is_subarray(devname)) {
@@ -171,24 +170,7 @@ int connect_monitor(char *devname)
addr.sun_family = PF_LOCAL;
strcpy(addr.sun_path, path);
-
- /* In foreground mode, when mdadm is trying to connect to control
- * socket it is possible that the mdmon has not created it yet.
- * Give some time to mdmon to create socket.
- */
- for (retry_count = 0; retry_count < 10; retry_count++) {
- rv = connect(sfd, (struct sockaddr*)&addr, sizeof(addr));
-
- if (rv < 0) {
- sleep_for(0, MSEC_TO_NSEC(200), true);
- continue;
- }
- break;
- }
-
- if (rv < 0) {
- pr_err("Failed to connect to control socket. (%s!!)\n",
- strerror(errno));
+ if (connect(sfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
close(sfd);
return -1;
}
--
2.41.0

View File

@ -0,0 +1,149 @@
From 3e6358e9aa0618f6a7de3a58e545caaada03739f Mon Sep 17 00:00:00 2001
From: Nigel Croxon <ncroxon@redhat.com>
Date: Tue, 25 Jun 2024 07:57:28 -0400
Subject: [PATCH 109/201] mdadm: Assemble.c fix coverity issues
Fixing the following coding errors the coverity tools found:
* Event dereference: Dereferencing "pre_exist", which is known to be "NULL".
* Event parameter_hidden: Declaration hides parameter "c".
* Event leaked_storage: Variable "pre_exist" going out of scope leaks the
storage it points to.
* Event leaked_storage: Variable "avail" going out of scope leaks the
storage it points to.
Signed-off-by: Nigel Croxon <ncroxon@redhat.com>
---
Assemble.c | 30 ++++++++++++++++++++++++------
1 file changed, 24 insertions(+), 6 deletions(-)
diff --git a/Assemble.c b/Assemble.c
index 0e6da593..77f2b50e 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -567,6 +567,9 @@ static int select_devices(struct mddev_dev *devlist,
tmpdev->used = 1;
content = *contentp;
+ if (!st)
+ return -1;
+
if (!st->sb) {
/* we need sb from one of the spares */
int dfd = dev_open(tmpdev->devname, O_RDONLY);
@@ -815,12 +818,12 @@ static int load_devices(struct devs *devices, char *devmap,
if (i >= bestcnt) {
int newbestcnt = i+10;
int *newbest = xmalloc(sizeof(int)*newbestcnt);
- int c;
- for (c=0; c < newbestcnt; c++)
- if (c < bestcnt)
- newbest[c] = best[c];
+ int cc;
+ for (cc = 0; cc < newbestcnt; cc++)
+ if (cc < bestcnt)
+ newbest[cc] = best[cc];
else
- newbest[c] = -1;
+ newbest[cc] = -1;
if (best)free(best);
best = newbest;
bestcnt = newbestcnt;
@@ -1493,8 +1496,11 @@ try_again:
mp = map_by_uuid(&map, content->uuid);
if (mp) {
struct mdinfo *dv;
- /* array already exists. */
pre_exist = sysfs_read(-1, mp->devnm, GET_LEVEL|GET_DEVS);
+ if (!pre_exist)
+ goto out;
+
+ /* array already exists. */
if (pre_exist->array.level != UnSet) {
pr_err("Found some drive for an array that is already active: %s\n",
mp->path);
@@ -1606,6 +1612,7 @@ try_again:
err = assemble_container_content(st, mdfd, content, c,
chosen_name, NULL);
close(mdfd);
+ sysfs_free(pre_exist);
return err;
}
@@ -1745,23 +1752,27 @@ try_again:
: (O_RDONLY|O_EXCL)))< 0) {
pr_err("Cannot open %s: %s\n",
devices[j].devname, strerror(errno));
+ free(avail);
goto out;
}
if (st->ss->load_super(st,fd, NULL)) {
close(fd);
pr_err("RAID superblock has disappeared from %s\n",
devices[j].devname);
+ free(avail);
goto out;
}
close(fd);
}
if (st->sb == NULL) {
pr_err("No suitable drives found for %s\n", mddev);
+ free(avail);
goto out;
}
st->ss->getinfo_super(st, content, NULL);
if (sysfs_init(content, mdfd, NULL)) {
pr_err("Unable to initialize sysfs\n");
+ free(avail);
goto out;
}
@@ -1824,12 +1835,14 @@ try_again:
if (fd < 0) {
pr_err("Could not open %s for write - cannot Assemble array.\n",
devices[chosen_drive].devname);
+ free(avail);
goto out;
}
if (st->ss->store_super(st, fd)) {
close(fd);
pr_err("Could not re-write superblock on %s\n",
devices[chosen_drive].devname);
+ free(avail);
goto out;
}
if (c->verbose >= 0)
@@ -1888,6 +1901,7 @@ try_again:
pr_err("Failed to restore critical section for reshape, sorry.\n");
if (c->backup_file == NULL)
cont_err("Possibly you needed to specify the --backup-file\n");
+ free(avail);
goto out;
}
}
@@ -1916,6 +1930,7 @@ try_again:
if (rv == 1 && !pre_exist)
ioctl(mdfd, STOP_ARRAY, NULL);
free(devices);
+ free(avail);
out:
map_unlock(&map);
if (rv == 0) {
@@ -1951,11 +1966,14 @@ out:
close(mdfd);
free(best);
+ sysfs_free(pre_exist);
+
/* '2' means 'OK, but not started yet' */
if (rv == -1) {
free(devices);
return 1;
}
+ close(mdfd);
return rv == 2 ? 0 : rv;
}
--
2.41.0

View File

@ -0,0 +1,118 @@
From 3cbe13403ec0c78374343dcd889609aefe791f9b Mon Sep 17 00:00:00 2001
From: Shminderjit Singh <shminderjit.singh@oracle.com>
Date: Mon, 24 Jun 2024 08:58:51 +0000
Subject: [PATCH 111/201] mdadm: Fix socket connection failure when mdmon runs
in foreground mode.
While creating an IMSM RAID, mdadm will wait for the mdmon main process
to finish if mdmon runs in forking mode. This is because with
"Type=forking" in the mdmon service unit file, "systemctl start service"
will block until the main process of mdmon exits. At that moment, mdmon
has already created the socket, so the subsequent socket connect from
mdadm will succeed.
However, when mdmon runs in foreground mode (without "Type=forking" in
the service unit file), "systemctl start service" will return once the
mdmon process starts. This causes mdadm and mdmon to run in parallel,
which may lead to a socket connection failure since mdmon has not yet
initialized the socket when mdadm tries to connect. If the next
instruction/command is to access this device and try to write to it, a
permission error will occur since mdmon has not yet set the array to RW
mode.
Signed-off-by: Shminderjit Singh <shminderjit.singh@oracle.com>
---
Create.c | 6 ++++--
mdadm.h | 1 +
util.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 50 insertions(+), 2 deletions(-)
diff --git a/Create.c b/Create.c
index bd4875e4..479c2715 100644
--- a/Create.c
+++ b/Create.c
@@ -1344,9 +1344,11 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs,
if (c->verbose >= 0)
pr_info("array %s started.\n", chosen_name);
if (st->ss->external && st->container_devnm[0]) {
- if (need_mdmon)
+ if (need_mdmon) {
start_mdmon(st->container_devnm);
-
+ if (wait_for_mdmon_control_socket(st->container_devnm) != MDADM_STATUS_SUCCESS)
+ goto abort;
+ }
ping_monitor(st->container_devnm);
close(container_fd);
}
diff --git a/mdadm.h b/mdadm.h
index e9f764a2..27009154 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -1776,6 +1776,7 @@ extern int is_subarray_active(char *subarray, char *devname);
extern int open_subarray(char *dev, char *subarray, struct supertype *st, int quiet);
extern struct superswitch *version_to_superswitch(char *vers);
+extern mdadm_status_t wait_for_mdmon_control_socket(const char *container_devnm);
extern int mdmon_running(const char *devnm);
extern int mdmon_pid(const char *devnm);
extern mdadm_status_t wait_for_mdmon(const char *devnm);
diff --git a/util.c b/util.c
index 48c97545..908f8430 100644
--- a/util.c
+++ b/util.c
@@ -1932,6 +1932,51 @@ int mdmon_running(const char *devnm)
return 0;
}
+/*
+ * wait_for_mdmon_control_socket() - Waits for mdmon control socket
+ * to be created within specified time.
+ * @container_devnm: Device for which mdmon control socket should start.
+ *
+ * In foreground mode, when mdadm is trying to connect to control
+ * socket it is possible that the mdmon has not created it yet.
+ * Give some time to mdmon to create socket. Timeout set to 2 sec.
+ *
+ * Return: MDADM_STATUS_SUCCESS if connect succeed, otherwise return
+ * error code.
+ */
+mdadm_status_t wait_for_mdmon_control_socket(const char *container_devnm)
+{
+ enum mdadm_status status = MDADM_STATUS_SUCCESS;
+ int sfd, rv, retry_count = 0;
+ struct sockaddr_un addr;
+ char path[PATH_MAX];
+
+ snprintf(path, PATH_MAX, "%s/%s.sock", MDMON_DIR, container_devnm);
+ sfd = socket(PF_LOCAL, SOCK_STREAM, 0);
+ if (!is_fd_valid(sfd))
+ return MDADM_STATUS_ERROR;
+
+ addr.sun_family = PF_LOCAL;
+ strncpy(addr.sun_path, path, sizeof(addr.sun_path) - 1);
+ addr.sun_path[sizeof(addr.sun_path) - 1] = '\0';
+
+ for (retry_count = 0; retry_count < 10; retry_count++) {
+ rv = connect(sfd, (struct sockaddr*)&addr, sizeof(addr));
+ if (rv < 0) {
+ sleep_for(0, MSEC_TO_NSEC(200), true);
+ continue;
+ }
+ break;
+ }
+
+ if (rv < 0) {
+ pr_err("Failed to connect to control socket.\n");
+ status = MDADM_STATUS_ERROR;
+ }
+ close(sfd);
+ return status;
+}
+
/*
* wait_for_mdmon() - Waits for mdmon within specified time.
* @devnm: Device for which mdmon should start.
--
2.41.0

View File

@ -0,0 +1,28 @@
From 44457789fd67168c37932060f9a991f0c611e5a2 Mon Sep 17 00:00:00 2001
From: Anna Sztukowska <anna.sztukowska@intel.com>
Date: Fri, 28 Jun 2024 12:32:16 +0200
Subject: [PATCH 113/201] config.c: Fix memory leak in load_containers()
Fix memory leak in load_containers() in config.c reported by SAST
analysis.
Signed-off-by: Anna Sztukowska <anna.sztukowska@intel.com>
---
config.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/config.c b/config.c
index 612e700d..cd2379bd 100644
--- a/config.c
+++ b/config.c
@@ -379,6 +379,7 @@ struct mddev_dev *load_containers(void)
map = NULL;
}
free_mdstat(mdstat);
+ map_free(map);
return rv;
}
--
2.41.0

View File

@ -0,0 +1,40 @@
From 0244bac0a828e69aef36404437cac4ff148eaea0 Mon Sep 17 00:00:00 2001
From: Nigel Croxon <ncroxon@redhat.com>
Date: Tue, 2 Jul 2024 09:49:13 -0400
Subject: [PATCH 114/201] mdadm: Build.c fix coverity issues
Event leaked_handle: Handle variable "bitmap_fd" going out of
scope leaks the handle.
Signed-off-by: Nigel Croxon <ncroxon@redhat.com>
---
Build.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/Build.c b/Build.c
index 1be90e41..052b1bc2 100644
--- a/Build.c
+++ b/Build.c
@@ -168,13 +168,13 @@ int Build(struct mddev_ident *ident, struct mddev_dev *devlist, struct shape *s,
goto abort;
}
}
- if (bitmap_fd >= 0) {
- if (ioctl(mdfd, SET_BITMAP_FILE, bitmap_fd) < 0) {
- pr_err("Cannot set bitmap file for %s: %s\n", chosen_name,
- strerror(errno));
- goto abort;
- }
+ if (ioctl(mdfd, SET_BITMAP_FILE, bitmap_fd) < 0) {
+ pr_err("Cannot set bitmap file for %s: %s\n", chosen_name,
+ strerror(errno));
+ close(bitmap_fd);
+ goto abort;
}
+ close(bitmap_fd);
}
if (ioctl(mdfd, RUN_ARRAY, &param)) {
pr_err("RUN_ARRAY failed: %s\n", strerror(errno));
--
2.41.0

View File

@ -0,0 +1,45 @@
From 7c524aa83c4463c15a13f6f47a27a18ab4de9eef Mon Sep 17 00:00:00 2001
From: Nigel Croxon <ncroxon@redhat.com>
Date: Fri, 5 Jul 2024 08:45:32 -0400
Subject: [PATCH 115/201] mdadm: Create.c fix coverity issues
* Event negative_returns: "fd" is passed to a parameter that cannot be negative. Which
is set to -1 to start.
* Event open_fn: Returning handle opened by "open_dev_excl".
* Event var_assign: Assigning: "container_fd" = handle returned from
"open_dev_excl(st->container_devnm)"
* Event leaked_handle: Handle variable "container_fd" going out of scope leaks the handle
Signed-off-by: Nigel Croxon <ncroxon@redhat.com>
---
Create.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/Create.c b/Create.c
index 479c2715..7fde1c16 100644
--- a/Create.c
+++ b/Create.c
@@ -297,7 +297,7 @@ static int add_disk_to_super(int mdfd, struct shape *s, struct context *c,
if (st->ss->add_to_super(st, &info->disk, fd, dv->devname,
dv->data_offset)) {
ioctl(mdfd, STOP_ARRAY, NULL);
- close(fd);
+ close_fd(&fd);
return 1;
}
st->ss->getinfo_super(st, info, NULL);
@@ -1370,8 +1370,8 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs,
map_remove(&map, fd2devnm(mdfd));
map_unlock(&map);
- if (mdfd >= 0)
- close(mdfd);
+ close_fd(&mdfd);
+ close_fd(&container_fd);
dev_policy_free(custom_pols);
return 1;
--
2.41.0

View File

@ -0,0 +1,473 @@
From 96b8035a09b6449ea99f2eb91f9ba4f6912e5bd6 Mon Sep 17 00:00:00 2001
From: Nigel Croxon <ncroxon@redhat.com>
Date: Tue, 2 Jul 2024 10:11:26 -0400
Subject: [PATCH 116/201] mdadm: super-ddf.c fix coverity issues
Fixing the following coding errors the coverity tools found:
* Calling "lseek64" without checking return value. This library function may
fail and return an error code.
* Overrunning array "anchor->pad2" of 3 bytes by passing it to a function
which accesses it at byte offset 398 using argument "399UL".
* Event leaked_storage: Variable "sra" going out of scope leaks the storage
it points to.
* Event leaked_storage: Variable "super" going out of scope leaks the storage
it points to.
* Event leaked_handle: Handle variable "dfd" going out of scope leaks the
handle.
* Event leaked_storage: Variable "dl1" going out of scope leaks the storage
it points to
* Event leaked_handle: Handle variable "cfd" going out of scope leaks the
handle.
* Variable "avail" going out of scope leaks the storage it points to.
* Passing unterminated string "super->anchor.revision" to "fprintf", which
expects a null-terminated string.
* You might overrun the 32-character fixed-size string "st->container_devnm"
by copying the return value of "fd2devnm" without checking the length.
* Event fixed_size_dest: You might overrun the 33-character fixed-size string
"dev->name" by copying "(*d).devname" without checking the length.
* Event uninit_use_in_call: Using uninitialized value "info.array.raid_disks"
when calling "getinfo_super_ddf"
V2: clean up validate_geometry_ddf() routine with Mariusz Tkaczyk recommendations.
V3: clean up spaces with Blazej Kucman recommendations.
V4: clean up recommended by Mariusz Tkaczyk.
V5: clean up recommended by Mariusz Tkaczyk.
Signed-off-by: Nigel Croxon <ncroxon@redhat.com>
---
super-ddf.c | 172 +++++++++++++++++++++++++++++++++++-----------------
1 file changed, 115 insertions(+), 57 deletions(-)
diff --git a/super-ddf.c b/super-ddf.c
index 311001c1..d870102d 100644
--- a/super-ddf.c
+++ b/super-ddf.c
@@ -809,7 +809,7 @@ static int load_ddf_header(int fd, unsigned long long lba,
if (lba >= size-1)
return 0;
- if (lseek64(fd, lba<<9, 0) < 0)
+ if (lseek64(fd, lba << 9, 0) == -1L)
return 0;
if (read(fd, hdr, 512) != 512)
@@ -828,8 +828,7 @@ static int load_ddf_header(int fd, unsigned long long lba,
!be64_eq(anchor->primary_lba, hdr->primary_lba) ||
!be64_eq(anchor->secondary_lba, hdr->secondary_lba) ||
hdr->type != type ||
- memcmp(anchor->pad2, hdr->pad2, 512 -
- offsetof(struct ddf_header, pad2)) != 0) {
+ memcmp(anchor->pad2, hdr->pad2, sizeof(anchor->pad2)) != 0) {
pr_err("header mismatch\n");
return 0;
}
@@ -863,7 +862,7 @@ static void *load_section(int fd, struct ddf_super *super, void *buf,
else
offset += be64_to_cpu(super->active->secondary_lba);
- if ((unsigned long long)lseek64(fd, offset<<9, 0) != (offset<<9)) {
+ if ((unsigned long long)lseek64(fd, offset << 9, 0) != (offset << 9)) {
if (dofree)
free(buf);
return NULL;
@@ -882,7 +881,7 @@ static int load_ddf_headers(int fd, struct ddf_super *super, char *devname)
get_dev_size(fd, NULL, &dsize);
- if (lseek64(fd, dsize-512, 0) < 0) {
+ if (lseek64(fd, dsize - 512, 0) == -1L) {
if (devname)
pr_err("Cannot seek to anchor block on %s: %s\n",
devname, strerror(errno));
@@ -909,8 +908,7 @@ static int load_ddf_headers(int fd, struct ddf_super *super, char *devname)
if (memcmp(super->anchor.revision, DDF_REVISION_0, 8) != 0 &&
memcmp(super->anchor.revision, DDF_REVISION_2, 8) != 0) {
if (devname)
- pr_err("can only support super revision %.8s and earlier, not %.8s on %s\n",
- DDF_REVISION_2, super->anchor.revision,devname);
+ pr_err("The DDF revision on %s\n is not supported", devname);
return 2;
}
super->active = NULL;
@@ -1610,6 +1608,7 @@ static unsigned int get_vd_num_of_subarray(struct supertype *st)
return DDF_NOTFOUND;
}
+ sysfs_free(sra);
return vcnum;
}
@@ -1617,11 +1616,11 @@ static void brief_examine_super_ddf(struct supertype *st, int verbose)
{
/* We just write a generic DDF ARRAY entry
*/
- struct mdinfo info;
+ struct mdinfo info = {0};
char nbuf[64];
+
getinfo_super_ddf(st, &info, NULL);
fname_from_uuid(&info, nbuf);
-
printf("ARRAY metadata=ddf UUID=%s\n", nbuf + 5);
}
@@ -1631,9 +1630,10 @@ static void brief_examine_subarrays_ddf(struct supertype *st, int verbose)
* by uuid and member by unit number and uuid.
*/
struct ddf_super *ddf = st->sb;
- struct mdinfo info;
+ struct mdinfo info = {0};
unsigned int i;
char nbuf[64];
+
getinfo_super_ddf(st, &info, NULL);
fname_from_uuid(&info, nbuf);
@@ -1658,8 +1658,9 @@ static void brief_examine_subarrays_ddf(struct supertype *st, int verbose)
static void export_examine_super_ddf(struct supertype *st)
{
- struct mdinfo info;
+ struct mdinfo info = {0};
char nbuf[64];
+
getinfo_super_ddf(st, &info, NULL);
fname_from_uuid(&info, nbuf);
printf("MD_METADATA=ddf\n");
@@ -1692,10 +1693,12 @@ static int copy_metadata_ddf(struct supertype *st, int from, int to)
if (!get_dev_size(from, NULL, &dsize))
goto err;
- if (lseek64(from, dsize-512, 0) < 0)
+ if (lseek64(from, dsize - 512, 0) == -1L)
goto err;
+
if (read(from, buf, 512) != 512)
goto err;
+
ddf = buf;
if (!be32_eq(ddf->magic, DDF_HEADER_MAGIC) ||
!be32_eq(calc_crc(ddf, 512), ddf->crc) ||
@@ -1711,9 +1714,9 @@ static int copy_metadata_ddf(struct supertype *st, int from, int to)
bytes = dsize - offset;
- if (lseek64(from, offset, 0) < 0 ||
- lseek64(to, offset, 0) < 0)
+ if (lseek64(from, offset, 0) == -1L || lseek64(to, offset, 0) == -1L)
goto err;
+
while (written < bytes) {
int n = bytes - written;
if (n > 4096)
@@ -1795,6 +1798,7 @@ static void brief_detail_super_ddf(struct supertype *st, char *subarray)
char nbuf[64];
struct ddf_super *ddf = st->sb;
unsigned int vcnum = get_vd_num_of_subarray(st);
+
if (vcnum == DDF_CONTAINER)
uuid_from_super_ddf(st, info.uuid);
else if (vcnum == DDF_NOTFOUND)
@@ -2971,7 +2975,9 @@ static int __write_ddf_structure(struct dl *d, struct ddf_super *ddf, __u8 type)
header->openflag = 1;
header->crc = calc_crc(header, 512);
- lseek64(fd, sector<<9, 0);
+ if (lseek64(fd, sector << 9, 0) == -1L)
+ goto out;
+
if (write(fd, header, 512) < 0)
goto out;
@@ -2982,6 +2988,7 @@ static int __write_ddf_structure(struct dl *d, struct ddf_super *ddf, __u8 type)
ddf->phys->crc = calc_crc(ddf->phys, ddf->pdsize);
if (write(fd, ddf->phys, ddf->pdsize) < 0)
goto out;
+
ddf->virt->crc = calc_crc(ddf->virt, ddf->vdsize);
if (write(fd, ddf->virt, ddf->vdsize) < 0)
goto out;
@@ -3035,7 +3042,9 @@ out:
header->openflag = 0;
header->crc = calc_crc(header, 512);
- lseek64(fd, sector<<9, 0);
+ if (lseek64(fd, sector << 9, 0) == -1L)
+ return 0;
+
if (write(fd, header, 512) < 0)
ret = 0;
@@ -3088,7 +3097,9 @@ static int _write_super_to_disk(struct ddf_super *ddf, struct dl *d)
if (!__write_ddf_structure(d, ddf, DDF_HEADER_SECONDARY))
return 0;
- lseek64(fd, (size-1)*512, SEEK_SET);
+ if (lseek64(fd, (size - 1) * 512, SEEK_SET) == -1L)
+ return 0;
+
if (write(fd, &ddf->anchor, 512) < 0)
return 0;
@@ -3299,9 +3310,10 @@ static int validate_geometry_ddf(struct supertype *st,
char *dev, unsigned long long *freesize,
int consistency_policy, int verbose)
{
- int fd;
- struct mdinfo *sra;
+ struct mdinfo *sra = NULL;
+ int ret = 1;
int cfd;
+ int fd;
/* ddf potentially supports lots of things, but it depends on
* what devices are offered (and maybe kernel version?)
@@ -3369,7 +3381,7 @@ static int validate_geometry_ddf(struct supertype *st,
* Later we should check for a BVD and make an SVD.
*/
fd = open(dev, O_RDONLY|O_EXCL, 0);
- if (fd >= 0) {
+ if (is_fd_valid(fd)) {
close(fd);
/* Just a bare device, no good to us */
if (verbose)
@@ -3377,44 +3389,58 @@ static int validate_geometry_ddf(struct supertype *st,
dev);
return 0;
}
+
if (errno != EBUSY || (fd = open(dev, O_RDONLY, 0)) < 0) {
if (verbose)
pr_err("ddf: Cannot open %s: %s\n",
dev, strerror(errno));
return 0;
}
+
/* Well, it is in use by someone, maybe a 'ddf' container. */
cfd = open_container(fd);
- if (cfd < 0) {
- close(fd);
+ close(fd);
+
+ if (!is_fd_valid(cfd)) {
if (verbose)
- pr_err("ddf: Cannot use %s: %s\n",
- dev, strerror(EBUSY));
+ pr_err("ddf: Cannot use %s\n", dev);
return 0;
}
+
sra = sysfs_read(cfd, NULL, GET_VERSION);
- close(fd);
- if (sra && sra->array.major_version == -1 &&
- strcmp(sra->text_version, "ddf") == 0) {
+ if (!sra) {
+ pr_err("Cannot read sysfs for /dev/%s\n", fd2kname(cfd));
+ goto error;
+ }
+
+ if (sra->array.major_version == -1 && strcmp(sra->text_version, "ddf") == 0) {
/* This is a member of a ddf container. Load the container
* and try to create a bvd
*/
- struct ddf_super *ddf;
+ struct ddf_super *ddf = NULL;
+
if (load_super_ddf_all(st, cfd, (void **)&ddf, NULL) == 0) {
st->sb = ddf;
- strcpy(st->container_devnm, fd2devnm(cfd));
+ snprintf(st->container_devnm, sizeof(st->container_devnm),
+ "%s", fd2kname(cfd));
close(cfd);
- return validate_geometry_ddf_bvd(st, level, layout,
- raiddisks, chunk, size,
- data_offset,
- dev, freesize,
- verbose);
+ free(sra);
+
+ return validate_geometry_ddf_bvd(st, level, layout, raiddisks,
+ chunk, size, data_offset, dev,
+ freesize, verbose);
}
- close(cfd);
- } else /* device may belong to a different container */
- return 0;
+ free(ddf);
+ }
- return 1;
+ /* device may belong to a different container */
+ ret = 0;
+
+error:
+ free(sra);
+ close(cfd);
+
+ return ret;
}
static int validate_geometry_ddf_bvd(struct supertype *st,
@@ -3483,35 +3509,42 @@ static int validate_geometry_ddf_bvd(struct supertype *st,
static int load_super_ddf_all(struct supertype *st, int fd,
void **sbp, char *devname)
{
- struct mdinfo *sra;
- struct ddf_super *super;
struct mdinfo *sd, *best = NULL;
+ struct ddf_super *super = NULL;
+ struct mdinfo *sra;
int bestseq = 0;
- int seq;
+ int ret = 1;
char nm[20];
+ int seq;
int dfd;
sra = sysfs_read(fd, NULL, GET_LEVEL|GET_VERSION|GET_DEVS|GET_STATE);
if (!sra)
return 1;
- if (sra->array.major_version != -1 ||
- sra->array.minor_version != -2 ||
+ if (sra->array.major_version != -1 || sra->array.minor_version != -2 ||
strcmp(sra->text_version, "ddf") != 0)
- return 1;
+ goto out;
if (posix_memalign((void**)&super, 512, sizeof(*super)) != 0)
- return 1;
+ goto out;
+
memset(super, 0, sizeof(*super));
/* first, try each device, and choose the best ddf */
for (sd = sra->devs ; sd ; sd = sd->next) {
int rv;
+
sprintf(nm, "%d:%d", sd->disk.major, sd->disk.minor);
+
dfd = dev_open(nm, O_RDONLY);
- if (dfd < 0)
- return 2;
+ if (!is_fd_valid(dfd)) {
+ ret = 2;
+ goto out;
+ }
+
rv = load_ddf_headers(dfd, super, NULL);
close(dfd);
+
if (rv == 0) {
seq = be32_to_cpu(super->active->seq);
if (super->active->openflag)
@@ -3523,28 +3556,39 @@ static int load_super_ddf_all(struct supertype *st, int fd,
}
}
if (!best)
- return 1;
+ goto out;
+
/* OK, load this ddf */
sprintf(nm, "%d:%d", best->disk.major, best->disk.minor);
+
dfd = dev_open(nm, O_RDONLY);
if (dfd < 0)
- return 1;
+ goto out;
+
load_ddf_headers(dfd, super, NULL);
load_ddf_global(dfd, super, NULL);
close(dfd);
+
/* Now we need the device-local bits */
for (sd = sra->devs ; sd ; sd = sd->next) {
int rv;
sprintf(nm, "%d:%d", sd->disk.major, sd->disk.minor);
+
dfd = dev_open(nm, O_RDWR);
- if (dfd < 0)
- return 2;
+ if (dfd < 0) {
+ ret = 2;
+ goto out;
+ }
+
rv = load_ddf_headers(dfd, super, NULL);
if (rv == 0)
rv = load_ddf_local(dfd, super, NULL, 1);
- if (rv)
- return 1;
+
+ if (rv) {
+ close(dfd);
+ goto out;
+ }
}
*sbp = super;
@@ -3553,8 +3597,16 @@ static int load_super_ddf_all(struct supertype *st, int fd,
st->minor_version = 0;
st->max_devs = 512;
}
- strcpy(st->container_devnm, fd2devnm(fd));
- return 0;
+
+ snprintf(st->container_devnm, sizeof(st->container_devnm), "%s", fd2devnm(fd));
+ ret = 0;
+
+out:
+ if (sra)
+ free(sra);
+ if (super && ret != 0)
+ free(super);
+ return ret;
}
static int load_container_ddf(struct supertype *st, int fd,
@@ -3791,7 +3843,7 @@ static struct mdinfo *container_content_ddf(struct supertype *st, char *subarray
be64_to_cpu(LBA_OFFSET(ddf, bvd)[iphys]);
dev->component_size = be64_to_cpu(bvd->blocks);
if (d->devname)
- strcpy(dev->name, d->devname);
+ snprintf(dev->name, sizeof(dev->name), "%s", d->devname);
}
}
return rest;
@@ -3840,11 +3892,15 @@ static int store_super_ddf(struct supertype *st, int fd)
return 1;
memset(buf, 0, 512);
- lseek64(fd, dsize-512, 0);
+ if (lseek64(fd, dsize - 512, 0) == -1L) {
+ free(buf);
+ return 1;
+ }
rc = write(fd, buf, 512);
free(buf);
if (rc < 0)
return 1;
+
return 0;
}
@@ -3959,6 +4015,7 @@ static int compare_super_ddf(struct supertype *st, struct supertype *tst,
if (posix_memalign((void **)&dl1->spare, 512,
first->conf_rec_len*512) != 0) {
pr_err("could not allocate spare info buf\n");
+ free(dl1);
return 3;
}
memcpy(dl1->spare, dl2->spare, first->conf_rec_len*512);
@@ -4180,6 +4237,7 @@ static int get_bvd_state(const struct ddf_super *ddf,
state = DDF_state_part_optimal;
break;
}
+ free(avail);
return state;
}
--
2.41.0

View File

@ -0,0 +1,102 @@
From cdce3219a52938fc35f93b5f17561f2ca7175e37 Mon Sep 17 00:00:00 2001
From: Heming Zhao <heming.zhao@suse.com>
Date: Tue, 9 Jul 2024 20:04:51 +0800
Subject: [PATCH 117/201] mdadm/clustermd_tests: add some APIs in func.sh to
support running the tests without errors
clustermd_tests/func.sh lacks some APIs to run, this patch makes
clustermd_tests runnable from the test suite.
Signed-off-by: Heming Zhao <heming.zhao@suse.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
clustermd_tests/func.sh | 60 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 60 insertions(+)
diff --git a/clustermd_tests/func.sh b/clustermd_tests/func.sh
index 801d6043..e659c0ba 100644
--- a/clustermd_tests/func.sh
+++ b/clustermd_tests/func.sh
@@ -1,5 +1,22 @@
#!/bin/bash
+COLOR_FAIL='\033[0;31m' #RED
+COLOR_WARN='\033[1;33m' #YELLOW
+COLOR_SUCCESS='\033[0;32m' #GREEN
+COLOR_NONE='\033[0m'
+
+fail() {
+ printf "${COLOR_FAIL}$1${COLOR_NONE}"
+}
+
+warn() {
+ printf "${COLOR_WARN}$1${COLOR_NONE}"
+}
+
+succeed() {
+ printf "${COLOR_SUCCESS}$1${COLOR_NONE}"
+}
+
check_ssh()
{
NODE1="$(grep '^NODE1' $CLUSTER_CONF | cut -d'=' -f2)"
@@ -151,6 +168,33 @@ stop_md()
fi
}
+record_system_speed_limit() {
+ system_speed_limit_max=`cat /proc/sys/dev/raid/speed_limit_max`
+ system_speed_limit_min=`cat /proc/sys/dev/raid/speed_limit_min`
+}
+
+# To avoid sync action finishes before checking it, it needs to limit
+# the sync speed
+control_system_speed_limit() {
+ echo $test_speed_limit_min > /proc/sys/dev/raid/speed_limit_min
+ echo $test_speed_limit_max > /proc/sys/dev/raid/speed_limit_max
+}
+
+restore_system_speed_limit() {
+ echo $system_speed_limit_min > /proc/sys/dev/raid/speed_limit_max
+ echo $system_speed_limit_max > /proc/sys/dev/raid/speed_limit_max
+}
+
+record_selinux() {
+ # empty
+ return 0
+}
+
+restore_selinux() {
+ # empty
+ return 0
+}
+
# $1/optional, it shows why to save log
save_log()
{
@@ -240,6 +284,22 @@ check()
die "$ip: check '$2' failed."
done
;;
+ recovery-remote )
+ cnt=5
+ for ip in ${NODES[@]}
+ do
+ while ! ssh $ip "grep -sqE 'recovery|REMOTE' /proc/mdstat"
+ do
+ if [ "$cnt" -gt '0' ]
+ then
+ sleep 0.2
+ cnt=$[cnt-1]
+ else
+ die "$ip: no '$2' happening!"
+ fi
+ done
+ done
+ ;;
PENDING | recovery | resync | reshape )
cnt=5
for ip in ${NODES[@]}
--
2.41.0

View File

@ -0,0 +1,81 @@
From bde21cc929d4864bd4b9f459f46ce63dd8c793ca Mon Sep 17 00:00:00 2001
From: Heming Zhao <heming.zhao@suse.com>
Date: Tue, 9 Jul 2024 20:04:52 +0800
Subject: [PATCH 118/201] mdadm/clustermd_tests: adjust test cases to support
md module changes
Since kernel commit db5e653d7c9f ("md: delay choosing sync action to
md_start_sync()") delays the start of the sync action, clustermd
array sync/resync jobs can happen on any leg of the array. This
commit adjusts the test cases to follow the new kernel layer behavior.
Signed-off-by: Heming Zhao <heming.zhao@suse.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
clustermd_tests/02r10_Manage_re-add | 3 ++-
clustermd_tests/02r1_Manage_re-add | 1 +
clustermd_tests/03r10_switch-recovery | 4 ++--
clustermd_tests/03r1_switch-recovery | 4 ++--
4 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/clustermd_tests/02r10_Manage_re-add b/clustermd_tests/02r10_Manage_re-add
index 2288a008..d8764667 100644
--- a/clustermd_tests/02r10_Manage_re-add
+++ b/clustermd_tests/02r10_Manage_re-add
@@ -9,7 +9,8 @@ check all state UU
check all dmesg
mdadm --manage $md0 --fail $dev0 --remove $dev0
mdadm --manage $md0 --re-add $dev0
-check $NODE1 recovery
+#non-clustered array also doesn't do sync job
+#check $NODE1 recovery
check all wait
check all state UU
check all dmesg
diff --git a/clustermd_tests/02r1_Manage_re-add b/clustermd_tests/02r1_Manage_re-add
index d0d13e53..811df87b 100644
--- a/clustermd_tests/02r1_Manage_re-add
+++ b/clustermd_tests/02r1_Manage_re-add
@@ -9,6 +9,7 @@ check all state UU
check all dmesg
mdadm --manage $md0 --fail $dev0 --remove $dev0
mdadm --manage $md0 --re-add $dev0
+check all wait
check all state UU
check all dmesg
stop_md all $md0
diff --git a/clustermd_tests/03r10_switch-recovery b/clustermd_tests/03r10_switch-recovery
index 867388d0..7d0b8812 100644
--- a/clustermd_tests/03r10_switch-recovery
+++ b/clustermd_tests/03r10_switch-recovery
@@ -10,9 +10,9 @@ check all state UU
check all dmesg
mdadm --manage $md0 --fail $dev0
sleep 0.2
-check $NODE1 recovery
+check $NODE1 recovery-remote
stop_md $NODE1 $md0
-check $NODE2 recovery
+check $NODE2 recovery-remote
check $NODE2 wait
check $NODE2 state UU
check all dmesg
diff --git a/clustermd_tests/03r1_switch-recovery b/clustermd_tests/03r1_switch-recovery
index a1a7cbe7..d8483c45 100644
--- a/clustermd_tests/03r1_switch-recovery
+++ b/clustermd_tests/03r1_switch-recovery
@@ -10,9 +10,9 @@ check all state UU
check all dmesg
mdadm --manage $md0 --fail $dev0
sleep 0.3
-check $NODE1 recovery
+check $NODE1 recovery-remote
stop_md $NODE1 $md0
-check $NODE2 recovery
+check $NODE2 recovery-remote
check $NODE2 wait
check $NODE2 state UU
check all dmesg
--
2.41.0

View File

@ -0,0 +1,40 @@
From 48c365376ce7763fd9a9e7735b1e9ec5d0ff1631 Mon Sep 17 00:00:00 2001
From: Anna Sztukowska <anna.sztukowska@intel.com>
Date: Wed, 3 Jul 2024 14:11:58 +0200
Subject: [PATCH 119/201] mapfile.c: Fix STRING_OVERFLOW issue
Fix STRING_OVERFLOW issue found by SAST analysis in map_add() and
map_update() in mapfile.c.
Signed-off-by: Anna Sztukowska <anna.sztukowska@intel.com>
---
mapfile.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/mapfile.c b/mapfile.c
index f1f3ee2c..ea9837ac 100644
--- a/mapfile.c
+++ b/mapfile.c
@@ -165,8 +165,8 @@ void map_add(struct map_ent **melp,
{
struct map_ent *me = xmalloc(sizeof(*me));
- strcpy(me->devnm, devnm);
- strcpy(me->metadata, metadata);
+ snprintf(me->devnm, sizeof(me->devnm), "%s", devnm);
+ snprintf(me->metadata, sizeof(me->metadata), "%s", metadata);
memcpy(me->uuid, uuid, 16);
me->path = path ? xstrdup(path) : NULL;
me->next = *melp;
@@ -227,7 +227,7 @@ int map_update(struct map_ent **mpp, char *devnm, char *metadata,
for (mp = map ; mp ; mp=mp->next)
if (strcmp(mp->devnm, devnm) == 0) {
- strcpy(mp->metadata, metadata);
+ snprintf(mp->metadata, sizeof(mp->metadata), "%s", metadata);
memcpy(mp->uuid, uuid, 16);
free(mp->path);
mp->path = path ? xstrdup(path) : NULL;
--
2.41.0

View File

@ -0,0 +1,484 @@
From 1b4b73fd535a6487075e98f620454ff2e13b5240 Mon Sep 17 00:00:00 2001
From: Nigel Croxon <ncroxon@redhat.com>
Date: Wed, 10 Jul 2024 08:55:08 -0400
Subject: [PATCH 120/201] mdadm: Manage.c fix coverity issues
Fixing the following coding errors the coverity tools found:
* Event parameter_hidden: declaration hides parameter "dv".
* Event leaked_storage: Variable "mdi" going out of scope leaks the storage
it points to.
* Event overwrite_var: Overwriting "mdi" in "mdi = mdi->devs" leaks the
storage that "mdi" points to.
* Event leaked_handle: Handle variable "lfd" going out of scope leaks
the handle.
* Event leaked_handle: Returning without closing handle "fd" leaks it.
* Event fixed_size_dest: You might overrun the 32-character fixed-sizei
string "devnm" by copying the return value of "fd2devnm" without
checking the length.
* Event fixed_size_dest: You might overrun the 32-character fixed-size
string "nm" by copying "nmp" without checking the length.
* Event fixed_size_dest: You might overrun the 32-character fixed-size
string "devnm" by copying the return value of "fd2devnm" without
checking the length.
* Event assigned_value: Assigning value "-1" to "tfd" here, but that
stored value is overwritten before it can be used.
Signed-off-by: Nigel Croxon <ncroxon@redhat.com>
---
Manage.c | 149 ++++++++++++++++++++++++++-----------------------------
1 file changed, 71 insertions(+), 78 deletions(-)
diff --git a/Manage.c b/Manage.c
index 5db72b77..aa5e80b2 100644
--- a/Manage.c
+++ b/Manage.c
@@ -56,7 +56,7 @@ int Manage_ro(char *devname, int fd, int readonly)
vers[9] = '-';
sysfs_set_str(mdi, NULL, "metadata_version", vers);
- close(fd);
+ close_fd(&fd);
rv = sysfs_set_str(mdi, NULL, "array_state", "readonly");
if (rv < 0) {
@@ -165,7 +165,7 @@ int Manage_run(char *devname, int fd, struct context *c)
pr_err("Cannot find %s in sysfs!!\n", devname);
return 1;
}
- strcpy(nm, nmp);
+ snprintf(nm, sizeof(nm), "%s", nmp);
return IncrementalScan(c, nm);
}
@@ -187,7 +187,7 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry)
if (will_retry && verbose == 0)
verbose = -1;
- strcpy(devnm, fd2devnm(fd));
+ snprintf(devnm, sizeof(devnm), "%s", fd2devnm(fd));
/* Get EXCL access first. If this fails, then attempting
* to stop is probably a bad idea.
*/
@@ -195,7 +195,7 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry)
if (mdi && is_subarray(mdi->text_version))
sysfs_get_container_devnm(mdi, container);
- close(fd);
+ close_fd(&fd);
count = 5;
while (((fd = ((devname[0] == '/')
?open(devname, O_RDONLY|O_EXCL)
@@ -206,14 +206,12 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry)
* is a container, so we might be racing with mdmon, so
* retry for a bit.
*/
- if (fd >= 0)
- close(fd);
+ close_fd(&fd);
flush_mdmon(container);
count--;
}
if (fd < 0 || strcmp(fd2devnm(fd), devnm) != 0) {
- if (fd >= 0)
- close(fd);
+ close_fd(&fd);
if (verbose >= 0)
pr_err("Cannot get exclusive access to %s:Perhaps a running process, mounted filesystem or active volume group?\n",
devname);
@@ -228,7 +226,7 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry)
is_subarray(mdi->text_version)) {
int err;
/* This is mdmon managed. */
- close(fd);
+ close_fd(&fd);
/* As we had an O_EXCL open, any use of the device
* which blocks STOP_ARRAY is probably a transient use,
@@ -430,8 +428,7 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry)
break;
sysfs_wait(scfd, &delay);
}
- if (scfd >= 0)
- close(scfd);
+ close_fd(&scfd);
}
done:
@@ -469,6 +466,7 @@ done:
map_unlock(&map);
out:
sysfs_free(mdi);
+ close_fd(&fd);
return rv;
}
@@ -664,7 +662,7 @@ int attempt_re_add(int fd, int tfd, struct mddev_dev *dv,
devname, verbose, 0, NULL);
if (rv == 0)
rv = dev_st->ss->store_super(dev_st, tfd);
- close(tfd);
+ close_fd(&tfd);
if (rv != 0) {
pr_err("failed to update superblock during re-add\n");
return -1;
@@ -766,15 +764,15 @@ mdadm_status_t manage_add_external(struct supertype *st, int fd, char *disk_name
rv = MDADM_STATUS_SUCCESS;
out:
- close(container_fd);
+ close_fd(&container_fd);
dev_policy_free(pols);
if (sra)
sysfs_free(sra);
- if (rv != MDADM_STATUS_SUCCESS && is_fd_valid(disk_fd))
+ if (rv != MDADM_STATUS_SUCCESS)
/* Metadata handler records this descriptor, so release it only on failure. */
- close(disk_fd);
+ close_fd(&disk_fd);
if (st->sb)
st->ss->free_super(st);
@@ -845,10 +843,10 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv,
continue;
if (tst->ss->load_super(tst, dfd,
NULL)) {
- close(dfd);
+ close_fd(&dfd);
continue;
}
- close(dfd);
+ close_fd(&dfd);
break;
}
/* FIXME this is a bad test to be using */
@@ -1100,7 +1098,8 @@ int Manage_remove(struct supertype *tst, int fd, struct mddev_dev *dv,
*/
int ret;
char devnm[32];
- strcpy(devnm, fd2devnm(fd));
+
+ snprintf(devnm, sizeof(devnm), "%s", fd2devnm(fd));
lfd = open_dev_excl(devnm);
if (lfd < 0) {
pr_err("Cannot get exclusive access to container - odd\n");
@@ -1134,13 +1133,13 @@ int Manage_remove(struct supertype *tst, int fd, struct mddev_dev *dv,
if (ret == 0) {
pr_err("%s is not a member, cannot remove.\n",
dv->devname);
- close(lfd);
+ close_fd(&lfd);
return -1;
}
if (ret >= 2) {
pr_err("%s is still in use, cannot remove.\n",
dv->devname);
- close(lfd);
+ close_fd(&lfd);
return -1;
}
}
@@ -1157,26 +1156,27 @@ int Manage_remove(struct supertype *tst, int fd, struct mddev_dev *dv,
/* Old kernels rejected this if no personality
* is registered */
struct mdinfo *sra = sysfs_read(fd, NULL, GET_DEVS);
- struct mdinfo *dv = NULL;
- if (sra)
- dv = sra->devs;
- for ( ; dv ; dv=dv->next)
- if (dv->disk.major == (int)major(rdev) &&
- dv->disk.minor == (int)minor(rdev))
- break;
- if (dv)
- err = sysfs_set_str(sra, dv,
- "state", "remove");
- else
+ struct mdinfo *dev = NULL;
+
+ if (!sra) {
err = -1;
- sysfs_free(sra);
+ } else {
+ for (dev = sra->devs; dev ; dev = dev->next)
+ if (dev->disk.major == (int)major(rdev) &&
+ dev->disk.minor == (int)minor(rdev))
+ break;
+
+ if (dev)
+ err = sysfs_set_str(sra, dev,
+ "state", "remove");
+ sysfs_free(sra);
+ }
}
}
if (err) {
pr_err("hot remove failed for %s: %s\n", dv->devname,
strerror(errno));
- if (lfd >= 0)
- close(lfd);
+ close_fd(&lfd);
return -1;
}
if (tst->ss->external) {
@@ -1190,13 +1190,13 @@ int Manage_remove(struct supertype *tst, int fd, struct mddev_dev *dv,
if (!devnm) {
pr_err("unable to get container name\n");
+ close_fd(&lfd);
return -1;
}
ping_manager(devnm);
}
- if (lfd >= 0)
- close(lfd);
+ close_fd(&lfd);
if (verbose >= 0)
pr_err("hot removed %s from %s\n",
dv->devname, devname);
@@ -1218,7 +1218,7 @@ int Manage_replace(struct supertype *tst, int fd, struct mddev_dev *dv,
if (!mdi || !mdi->devs) {
pr_err("Cannot find status of %s to enable replacement - strange\n",
devname);
- return -1;
+ goto abort;
}
for (di = mdi->devs; di; di = di->next)
if (di->disk.major == (int)major(rdev) &&
@@ -1229,16 +1229,14 @@ int Manage_replace(struct supertype *tst, int fd, struct mddev_dev *dv,
if (di->disk.raid_disk < 0) {
pr_err("%s is not active and so cannot be replaced.\n",
dv->devname);
- sysfs_free(mdi);
- return -1;
+ goto abort;
}
rv = sysfs_set_str(mdi, di,
"state", "want_replacement");
if (rv) {
- sysfs_free(mdi);
pr_err("Failed to request replacement for %s\n",
dv->devname);
- return -1;
+ goto abort;
}
if (verbose >= 0)
pr_err("Marked %s (device %d in %s) for replacement\n",
@@ -1252,11 +1250,13 @@ int Manage_replace(struct supertype *tst, int fd, struct mddev_dev *dv,
dv->disposition = 'w';
dv->used = di->disk.raid_disk;
}
+ sysfs_free(mdi);
return 1;
}
- sysfs_free(mdi);
pr_err("%s not found in %s so cannot --replace it\n",
dv->devname, devname);
+abort:
+ sysfs_free(mdi);
return -1;
}
@@ -1269,7 +1269,7 @@ int Manage_with(struct supertype *tst, int fd, struct mddev_dev *dv,
if (!mdi || !mdi->devs) {
pr_err("Cannot find status of %s to enable replacement - strange\n",
devname);
- return -1;
+ goto abort;
}
for (di = mdi->devs; di; di = di->next)
if (di->disk.major == (int)major(rdev) &&
@@ -1280,31 +1280,30 @@ int Manage_with(struct supertype *tst, int fd, struct mddev_dev *dv,
if (di->disk.state & (1<<MD_DISK_FAULTY)) {
pr_err("%s is faulty and cannot be a replacement\n",
dv->devname);
- sysfs_free(mdi);
- return -1;
+ goto abort;
}
if (di->disk.raid_disk >= 0) {
pr_err("%s is active and cannot be a replacement\n",
dv->devname);
- sysfs_free(mdi);
- return -1;
+ goto abort;
}
rv = sysfs_set_num(mdi, di,
"slot", dv->used);
if (rv) {
- sysfs_free(mdi);
pr_err("Failed to set %s as preferred replacement.\n",
dv->devname);
- return -1;
+ goto abort;
}
if (verbose >= 0)
pr_err("Marked %s in %s as replacement for device %d\n",
dv->devname, devname, dv->used);
+ sysfs_free(mdi);
return 1;
}
- sysfs_free(mdi);
pr_err("%s not found in %s so cannot make it preferred replacement\n",
dv->devname, devname);
+abort:
+ sysfs_free(mdi);
return -1;
}
@@ -1324,6 +1323,7 @@ bool is_remove_safe(mdu_array_info_t *array, const int fd, char *devname, const
{
dev_t devid = devnm2devid(devname + 5);
struct mdinfo *mdi = sysfs_read(fd, NULL, GET_DEVS | GET_DISKS | GET_STATE);
+ struct mdinfo *disk;
if (!mdi) {
if (verbose)
@@ -1333,14 +1333,14 @@ bool is_remove_safe(mdu_array_info_t *array, const int fd, char *devname, const
char *avail = xcalloc(array->raid_disks, sizeof(char));
- for (mdi = mdi->devs; mdi; mdi = mdi->next) {
- if (mdi->disk.raid_disk < 0)
+ for (disk = mdi->devs; disk; disk = mdi->next) {
+ if (disk->disk.raid_disk < 0)
continue;
- if (!(mdi->disk.state & (1 << MD_DISK_SYNC)))
+ if (!(disk->disk.state & (1 << MD_DISK_SYNC)))
continue;
- if (makedev(mdi->disk.major, mdi->disk.minor) == devid)
+ if (makedev(disk->disk.major, disk->disk.minor) == devid)
continue;
- avail[mdi->disk.raid_disk] = 1;
+ avail[disk->disk.raid_disk] = 1;
}
sysfs_free(mdi);
@@ -1550,7 +1550,7 @@ int Manage_subdevs(char *devname, int fd,
rdev = makedev(mj,mn);
found = 1;
}
- close(sysfd);
+ close_fd(&sysfd);
sysfd = -1;
}
if (!found) {
@@ -1572,7 +1572,7 @@ int Manage_subdevs(char *devname, int fd,
tfd = dev_open(dv->devname, O_RDONLY);
if (tfd >= 0) {
fstat_is_blkdev(tfd, dv->devname, &rdev);
- close(tfd);
+ close_fd(&tfd);
} else {
int open_err = errno;
if (!stat_is_blkdev(dv->devname, &rdev)) {
@@ -1635,7 +1635,7 @@ int Manage_subdevs(char *devname, int fd,
* need non-exclusive access to add it, so
* do that now.
*/
- close(tfd);
+ close_fd(&tfd);
tfd = dev_open(dv->devname, O_RDONLY);
}
if (tfd < 0) {
@@ -1654,8 +1654,7 @@ int Manage_subdevs(char *devname, int fd,
rv = Manage_add(fd, tfd, dv, tst, &array,
force, verbose, devname, update,
rdev, array_size, raid_slot);
- close(tfd);
- tfd = -1;
+ close_fd(&tfd);
if (rv < 0)
goto abort;
if (rv > 0)
@@ -1672,7 +1671,7 @@ int Manage_subdevs(char *devname, int fd,
rdev, verbose, force,
devname);
if (sysfd >= 0)
- close(sysfd);
+ close_fd(&sysfd);
sysfd = -1;
if (rv < 0)
goto abort;
@@ -1684,8 +1683,7 @@ int Manage_subdevs(char *devname, int fd,
if (!is_remove_safe(&array, fd, dv->devname, verbose)) {
pr_err("Cannot remove %s from %s, array will be failed.\n",
dv->devname, devname);
- if (sysfd >= 0)
- close(sysfd);
+ close_fd(&sysfd);
goto abort;
}
case 'I': /* incremental fail */
@@ -1696,13 +1694,10 @@ int Manage_subdevs(char *devname, int fd,
busy = 1;
pr_err("set device faulty failed for %s: %s\n",
dv->devname, strerror(errno));
- if (sysfd >= 0)
- close(sysfd);
+ close_fd(&sysfd);
goto abort;
}
- if (sysfd >= 0)
- close(sysfd);
- sysfd = -1;
+ close_fd(&sysfd);
count++;
if (verbose >= 0)
pr_err("set %s faulty in %s\n",
@@ -1762,7 +1757,7 @@ int autodetect(void)
if (fd >= 0) {
if (ioctl(fd, RAID_AUTORUN, 0) == 0)
rv = 0;
- close(fd);
+ close_fd(&fd);
}
return rv;
}
@@ -1825,7 +1820,7 @@ free_super:
if (info)
free(info);
st->ss->free_super(st);
- close(fd);
+ close_fd(&fd);
return rv;
}
@@ -1843,10 +1838,8 @@ int move_spare(char *from_devname, char *to_devname, dev_t devid)
int fd2 = open(from_devname, O_RDONLY);
if (fd1 < 0 || fd2 < 0) {
- if (fd1 >= 0)
- close(fd1);
- if (fd2 >= 0)
- close(fd2);
+ close_fd(&fd1);
+ close_fd(&fd2);
return 0;
}
@@ -1865,15 +1858,15 @@ int move_spare(char *from_devname, char *to_devname, dev_t devid)
/* make sure manager is aware of changes */
ping_manager(to_devname);
ping_manager(from_devname);
- close(fd1);
- close(fd2);
+ close_fd(&fd1);
+ close_fd(&fd2);
return 1;
}
else
Manage_subdevs(from_devname, fd2, &devlist,
-1, 0, UOPT_UNDEFINED, 0);
}
- close(fd1);
- close(fd2);
+ close_fd(&fd1);
+ close_fd(&fd2);
return 0;
}
--
2.41.0

View File

@ -0,0 +1,29 @@
From ec72668a9768ad01b409b68f31f3ca7ffeeaab4e Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Tue, 16 Jul 2024 15:37:34 +0200
Subject: [PATCH 121/201] Manage: fix is_remove_safe()
Fix for to make --set-faulty working.
Fixes: 1b4b73fd535a ("mdadm: Manage.c fix coverity issues")
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
Manage.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Manage.c b/Manage.c
index aa5e80b2..f0304e1e 100644
--- a/Manage.c
+++ b/Manage.c
@@ -1333,7 +1333,7 @@ bool is_remove_safe(mdu_array_info_t *array, const int fd, char *devname, const
char *avail = xcalloc(array->raid_disks, sizeof(char));
- for (disk = mdi->devs; disk; disk = mdi->next) {
+ for (disk = mdi->devs; disk; disk = disk->next) {
if (disk->disk.raid_disk < 0)
continue;
if (!(disk->disk.state & (1 << MD_DISK_SYNC)))
--
2.41.0

View File

@ -0,0 +1,28 @@
From f8274feea5c63300e893109840943513df924da2 Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Mon, 15 Jul 2024 12:21:19 +0200
Subject: [PATCH 122/201] imsm: add indent for encryption details
Improve readability of the output.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
super-intel.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/super-intel.c b/super-intel.c
index ef3f5da1..713bfccf 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -2318,7 +2318,7 @@ void print_encryption_information(int disk_fd, enum sys_dev_type hba_type)
{
struct encryption_information information = {0};
mdadm_status_t status = MDADM_STATUS_SUCCESS;
- const char *indent = " ";
+ const char *indent = " ";
switch (hba_type) {
case SYS_DEV_VMD:
--
2.41.0

View File

@ -0,0 +1,67 @@
From 5cb6df3f190feccc8b3e82da2b01a0e01e612a25 Mon Sep 17 00:00:00 2001
From: Nigel Croxon <ncroxon@redhat.com>
Date: Mon, 15 Jul 2024 10:13:46 -0400
Subject: [PATCH 123/201] mdadm: Monitor.c fix coverity issues
Fixing the following coding errors the coverity tools found:
* Event check_return: Calling "fcntl(fd, 2, 1)" without checking
return value. This library function may fail and return an error code.
* Dereferencing "sl", which is known to be "NULL".
* Event fixed_size_dest: You might overrun the 32-character fixed-size
string "devnm" by copying "tmp" without checking the length.
Signed-off-by: Nigel Croxon <ncroxon@redhat.com>
---
Monitor.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/Monitor.c b/Monitor.c
index 9b016bc3..26c53e13 100644
--- a/Monitor.c
+++ b/Monitor.c
@@ -782,7 +782,9 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
if (!is_container && !md_array_active(fd))
goto disappeared;
- fcntl(fd, F_SETFD, FD_CLOEXEC);
+ if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0)
+ goto out;
+
if (md_get_array_info(fd, &array) < 0)
goto disappeared;
@@ -997,7 +999,8 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist)
snprintf(st->parent_devnm, MD_NAME_MAX,
"%s", mse->metadata_version + 10);
sl = strchr(st->parent_devnm, '/');
- *sl = 0;
+ if (sl)
+ *sl = 0;
} else
st->parent_devnm[0] = 0;
*statelist = st;
@@ -1261,7 +1264,7 @@ int Wait(char *dev)
return 2;
}
- strcpy(devnm, tmp);
+ snprintf(devnm, sizeof(devnm), "%s", tmp);
while(1) {
struct mdstat_ent *ms = mdstat_read(1, 0);
@@ -1332,7 +1335,8 @@ int WaitClean(char *dev, int verbose)
return 1;
}
- strcpy(devnm, fd2devnm(fd));
+ snprintf(devnm, sizeof(devnm), "%s", fd2devnm(fd));
+
mdi = sysfs_read(fd, devnm, GET_VERSION|GET_LEVEL|GET_SAFEMODE);
if (!mdi) {
if (verbose)
--
2.41.0

View File

@ -0,0 +1,42 @@
From bcc3ab1728da61e5519e1f01597c8da0c5bc769b Mon Sep 17 00:00:00 2001
From: Nigel Croxon <ncroxon@redhat.com>
Date: Tue, 16 Jul 2024 07:19:34 -0400
Subject: [PATCH 124/201] mdadm: Query.c fix coverity issues
Fixing the following coding errors the coverity tools found:
* Event leaked_storage: Variable "sra" going out of scope leaks the
storage it points to.
* Event uninit_use_in_call: Using uninitialized value "larray_size" when
calling "human_size_brief".
Signed-off-by: Nigel Croxon <ncroxon@redhat.com>
---
Query.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/Query.c b/Query.c
index adcd231e..aedb4ce7 100644
--- a/Query.c
+++ b/Query.c
@@ -39,7 +39,7 @@ int Query(char *dev)
struct mdinfo info;
struct mdinfo *sra;
struct supertype *st = NULL;
- unsigned long long larray_size;
+ unsigned long long larray_size = 0;
struct stat stb;
char *mddev;
mdu_disk_info_t disc;
@@ -136,5 +136,7 @@ int Query(char *dev)
if (st->ss == &super0)
put_md_name(mddev);
}
+ free(sra);
+
return 0;
}
--
2.41.0

View File

@ -0,0 +1,43 @@
From da7aecdf25371e1476da4ec56e9ec5ddf13af5da Mon Sep 17 00:00:00 2001
From: Nigel Croxon <ncroxon@redhat.com>
Date: Tue, 16 Jul 2024 07:20:10 -0400
Subject: [PATCH 125/201] mdadm: lib.c fix coverity issues
Fixing the following coding errors the coverity tools found:
* Event fixed_size_dest: You might overrun the 32-character fixed-size
string "devnm" by copying "cp + 1" without checking the length.
* Event fixed_size_dest: You might overrun the 32-character fixed-size
string "devnm" by copying "cp" without checking the length.
Signed-off-by: Nigel Croxon <ncroxon@redhat.com>
---
lib.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib.c b/lib.c
index 2b09293c..13d4e4f1 100644
--- a/lib.c
+++ b/lib.c
@@ -109,7 +109,7 @@ char *devid2kname(dev_t devid)
link[n] = 0;
cp = strrchr(link, '/');
if (cp) {
- strcpy(devnm, cp + 1);
+ snprintf(devnm, sizeof(devnm), "%s", cp + 1);
return devnm;
}
}
@@ -159,7 +159,7 @@ char *devid2devnm(dev_t devid)
ep = strchr(cp, '/');
if (ep)
*ep = 0;
- strcpy(devnm, cp);
+ snprintf(devnm, sizeof(devnm), "%s", cp);
return devnm;
}
}
--
2.41.0

View File

@ -0,0 +1,158 @@
From 998544c198c156db027a6e4f1b201910b138041e Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Mon, 15 Jul 2024 12:29:24 +0200
Subject: [PATCH 126/201] mdadm: do not allow leading dot in MD device name
Do not allow to use '.' on first place for named MD device.
Having leading dot might be confusing, MD device cannot be hidden.
It also removes possibility to create md device with name '.'.
Additionally, code optimalizations are done.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
config.c | 75 +++++++++++++++++++++++++++++++-------------------------
1 file changed, 41 insertions(+), 34 deletions(-)
diff --git a/config.c b/config.c
index cd2379bd..6ea905f3 100644
--- a/config.c
+++ b/config.c
@@ -188,8 +188,36 @@ inline void ident_init(struct mddev_ident *ident)
ident->uuid_set = 0;
}
+/** ident_check_name() - helper function to verify name.
+ * @name: name to check.
+ * @prop_name: the name of the property it is validated against, used for logging.
+ * @cmdline: context dependent actions.
+ *
+ * @name must follow name's criteria, be POSIX compatible and does not have leading dot.
+ */
+static mdadm_status_t ident_check_name(const char *name, const char *prop_name, const bool cmdline)
+{
+ if (!is_string_lq(name, MD_NAME_MAX + 1)) {
+ ident_log(prop_name, name, "Too long or empty", cmdline);
+ return MDADM_STATUS_ERROR;
+ }
+
+ if (*name == '.') {
+ /* MD device should not be considered as hidden. */
+ ident_log(prop_name, name, "Leading dot forbidden", cmdline);
+ return MDADM_STATUS_ERROR;
+ }
+
+ if (!is_name_posix_compatible(name)) {
+ ident_log(prop_name, name, "Not POSIX compatible", cmdline);
+ return MDADM_STATUS_ERROR;
+ }
+
+ return MDADM_STATUS_SUCCESS;
+}
+
/**
- * _ident_set_devname()- verify devname and set it in &mddev_ident.
+ * _ident_set_devname() - verify devname and set it in &mddev_ident.
* @ident: pointer to &mddev_ident.
* @devname: devname to be set.
* @cmdline: context dependent actions. If set, ignore keyword is not allowed.
@@ -202,8 +230,7 @@ inline void ident_init(struct mddev_ident *ident)
* /dev/md/{name}
* {name}
*
- * {name} must follow name's criteria and be POSIX compatible.
- * If criteria passed, duplicate memory and set devname in @ident.
+ * If verification passed, duplicate memory and set devname in @ident.
*
* Return: %MDADM_STATUS_SUCCESS or %MDADM_STATUS_ERROR.
*/
@@ -216,6 +243,7 @@ mdadm_status_t _ident_set_devname(struct mddev_ident *ident, const char *devname
static const char named_dev_pref[] = DEV_NUM_PREF "_";
static const int named_dev_pref_size = sizeof(named_dev_pref) - 1;
const char *prop_name = "devname";
+ mdadm_status_t ret;
const char *name;
if (ident->devname) {
@@ -242,53 +270,40 @@ mdadm_status_t _ident_set_devname(struct mddev_ident *ident, const char *devname
else
name = devname;
- if (is_name_posix_compatible(name) == false) {
- ident_log(prop_name, name, "Not POSIX compatible", cmdline);
- return MDADM_STATUS_ERROR;
- }
-
- if (is_string_lq(name, MD_NAME_MAX + 1) == false) {
- ident_log(prop_name, devname, "Invalid length", cmdline);
- return MDADM_STATUS_ERROR;
- }
+ ret = ident_check_name(name, prop_name, cmdline);
+ if (ret)
+ return ret;
pass:
ident->devname = xstrdup(devname);
return MDADM_STATUS_SUCCESS;
}
/**
- * _ident_set_name()- set name in &mddev_ident.
+ * _ident_set_name() - set name in &mddev_ident.
* @ident: pointer to &mddev_ident.
* @name: name to be set.
- * @cmdline: context dependent actions.
*
* If criteria passed, set name in @ident.
* Note: name is not used by config file, it for cmdline only.
*
* Return: %MDADM_STATUS_SUCCESS or %MDADM_STATUS_ERROR.
*/
-static mdadm_status_t _ident_set_name(struct mddev_ident *ident, const char *name,
- const bool cmdline)
+mdadm_status_t ident_set_name(struct mddev_ident *ident, const char *name)
{
assert(name);
assert(ident);
const char *prop_name = "name";
+ mdadm_status_t ret;
if (ident->name[0]) {
- ident_log(prop_name, name, "Already defined", cmdline);
+ ident_log(prop_name, name, "Already defined", true);
return MDADM_STATUS_ERROR;
}
- if (is_string_lq(name, MD_NAME_MAX + 1) == false) {
- ident_log(prop_name, name, "Too long or empty", cmdline);
- return MDADM_STATUS_ERROR;
- }
-
- if (is_name_posix_compatible(name) == false) {
- ident_log(prop_name, name, "Not POSIX compatible", cmdline);
- return MDADM_STATUS_ERROR;
- }
+ ret = ident_check_name(name, prop_name, true);
+ if (ret)
+ return ret;
snprintf(ident->name, MD_NAME_MAX + 1, "%s", name);
return MDADM_STATUS_SUCCESS;
@@ -302,14 +317,6 @@ mdadm_status_t ident_set_devname(struct mddev_ident *ident, const char *name)
return _ident_set_devname(ident, name, true);
}
-/**
- * ident_set_name()- exported, for cmdline.
- */
-mdadm_status_t ident_set_name(struct mddev_ident *ident, const char *name)
-{
- return _ident_set_name(ident, name, true);
-}
-
struct conf_dev {
struct conf_dev *next;
char *name;
--
2.41.0

View File

@ -1,7 +1,7 @@
From 5be749ce416852e7acbb2415be380be358859612 Mon Sep 17 00:00:00 2001 From 5be749ce416852e7acbb2415be380be358859612 Mon Sep 17 00:00:00 2001
From: Kinga Stefaniuk <kinga.stefaniuk@intel.com> From: Kinga Stefaniuk <kinga.stefaniuk@intel.com>
Date: Tue, 23 Jul 2024 15:38:41 +0200 Date: Tue, 23 Jul 2024 15:38:41 +0200
Subject: [PATCH 1/1] Detail: fix --detail --export for uuid_zero Subject: [PATCH 128/201] Detail: fix --detail --export for uuid_zero
Mentioned commit (see Fixes) causes that devices with UUID Mentioned commit (see Fixes) causes that devices with UUID
equal to uuid_zero was not recognized properly. For few devices equal to uuid_zero was not recognized properly. For few devices

View File

@ -0,0 +1,84 @@
From 2bb4efb504d0991eaba755242d3e70facb5d994b Mon Sep 17 00:00:00 2001
From: Blazej Kucman <blazej.kucman@intel.com>
Date: Tue, 23 Jul 2024 12:45:10 +0200
Subject: [PATCH 129/201] drive_encryption: Fix ata passthrough12 verify
Based on documentation SCSI Primary Commands - 4 (SPC-4) only first 7 bits
of first byte in sense data are used to store response code. The current
verification uses all 8 bits for comparison of response code.
Incorrect verification may make impossible to use SATA disks with IMSM,
because IMSM requires verification of the encryption state before use.
There was issue in kernel libata [1]. This issue hides bug in mdadm because
last bit was not set.
Example output with affected mdadm:
Port3 : /dev/sde (BTPR212503EK120LGN)
mdadm: Failed ata passthrough12 ioctl. Device: /dev/sde.
mdadm: Failed to get drive encryption information
The fix is use the first 7 bits of Byte 0, to compare with the expected
values.
[1] https://git.kernel.org/pub/scm/linux/kernel/git/libata/linux.git/commit/?id=38dab832c3f4
Fixes: df38df3052c3 ("Add reading SATA encryption information")
Signed-off-by: Blazej Kucman <blazej.kucman@intel.com>
---
drive_encryption.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/drive_encryption.c b/drive_encryption.c
index a4ad799f..63bdab1a 100644
--- a/drive_encryption.c
+++ b/drive_encryption.c
@@ -65,6 +65,7 @@
#define SENSE_DATA_CURRENT_FIXED (0x70)
#define SENSE_DATA_CURRENT_DESC (0x72)
#define SENSE_CURRENT_RES_DESC_POS (8)
+#define SENSE_RESPONSE_CODE_MASK (0x7f)
#define SG_DRIVER_SENSE (0x08)
typedef enum drive_feature_support_status {
@@ -473,6 +474,7 @@ ata_pass_through12_ioctl(int disk_fd, __u8 ata_command, __u8 sec_protocol, __u1
{
__u8 cdb[ATA_INQUIRY_LENGTH] = {0};
__u8 sense[SG_SENSE_SIZE] = {0};
+ __u8 sense_response_code;
__u8 *sense_desc = NULL;
sg_io_hdr_t sg = {0};
@@ -517,15 +519,17 @@ ata_pass_through12_ioctl(int disk_fd, __u8 ata_command, __u8 sec_protocol, __u1
return MDADM_STATUS_ERROR;
}
+ sense_response_code = sense[0] & SENSE_RESPONSE_CODE_MASK;
/* verify expected sense response code */
- if (!(sense[0] == SENSE_DATA_CURRENT_DESC || sense[0] == SENSE_DATA_CURRENT_FIXED)) {
+ if (!(sense_response_code == SENSE_DATA_CURRENT_DESC ||
+ sense_response_code == SENSE_DATA_CURRENT_FIXED)) {
pr_vrb("Failed ata passthrough12 ioctl. Device: /dev/%s.\n", fd2kname(disk_fd));
return MDADM_STATUS_ERROR;
}
sense_desc = sense + SENSE_CURRENT_RES_DESC_POS;
/* verify sense data current response with descriptor format */
- if (sense[0] == SENSE_DATA_CURRENT_DESC &&
+ if (sense_response_code == SENSE_DATA_CURRENT_DESC &&
!(sense_desc[0] == ATA_STATUS_RETURN_DESCRIPTOR &&
sense_desc[1] == ATA_INQUIRY_LENGTH)) {
pr_vrb("Failed ata passthrough12 ioctl. Device: /dev/%s. Sense data ASC: %d, ASCQ: %d.\n",
@@ -534,7 +538,7 @@ ata_pass_through12_ioctl(int disk_fd, __u8 ata_command, __u8 sec_protocol, __u1
}
/* verify sense data current response with fixed format */
- if (sense[0] == SENSE_DATA_CURRENT_FIXED &&
+ if (sense_response_code == SENSE_DATA_CURRENT_FIXED &&
!(sense[12] == ATA_PT_INFORMATION_AVAILABLE_ASC &&
sense[13] == ATA_PT_INFORMATION_AVAILABLE_ASCQ)) {
pr_vrb("Failed ata passthrough12 ioctl. Device: /dev/%s. Sense data ASC: %d, ASCQ: %d.\n",
--
2.41.0

View File

@ -0,0 +1,46 @@
From 0af8c9ebf50b68ad5f80efad7e94688235544a3d Mon Sep 17 00:00:00 2001
From: Kinga Stefaniuk <kinga.stefaniuk@intel.com>
Date: Thu, 4 Jul 2024 14:53:35 +0200
Subject: [PATCH 130/201] super0: use define for char array in examine_super0
Using nb with 11 length may cause format-truncation errors,
because it was possible to use snprintf with 12 length input
and write it to 11 length output. Added new define and use it
to avoid this error.
Signed-off-by: Kinga Stefaniuk <kinga.stefaniuk@intel.com>
---
mdadm.h | 3 +++
super0.c | 2 +-
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/mdadm.h b/mdadm.h
index 27009154..22d5e8f4 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -2021,6 +2021,9 @@ enum r0layout {
#define PATH_MAX 4096
#endif
+/* The max string length necessary for decimal conversion, cannot be longer than count of bits */
+#define INT_2_DEC_STR_MAX (sizeof(int) * 8)
+
#define RESYNC_NONE -1
#define RESYNC_DELAYED -2
#define RESYNC_PENDING -3
diff --git a/super0.c b/super0.c
index 9b8a1bd6..9b4e187e 100644
--- a/super0.c
+++ b/super0.c
@@ -229,7 +229,7 @@ static void examine_super0(struct supertype *st, char *homehost)
d++) {
mdp_disk_t *dp;
char *dv;
- char nb[11];
+ char nb[INT_2_DEC_STR_MAX];
int wonly, failfast;
if (d>=0) dp = &sb->disks[d];
else dp = &sb->this_disk;
--
2.41.0

View File

@ -0,0 +1,61 @@
From 93c5215677a71e9772f68a449533cb3c97d2b869 Mon Sep 17 00:00:00 2001
From: Kinga Stefaniuk <kinga.stefaniuk@intel.com>
Date: Thu, 4 Jul 2024 15:01:06 +0200
Subject: [PATCH 131/201] Makefile: add more compiler flags
It is essential to avoid vulnerabilities in code as much
as possible using safe compilation flags. It is easier if
they are added to the Makefile and applied during compilation.
Add new gcc flags and make them configurable, because they
may not be supported for some compilers.
Set FORTIFY_SOURCE with the highest supported value for platform.
Signed-off-by: Kinga Stefaniuk <kinga.stefaniuk@intel.com>
---
Makefile | 23 ++++++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
diff --git a/Makefile b/Makefile
index 3fe0a053..a914b178 100644
--- a/Makefile
+++ b/Makefile
@@ -30,7 +30,7 @@
# define "CXFLAGS" to give extra flags to CC.
# e.g. make CXFLAGS=-O to optimise
-CXFLAGS ?=-O2 -D_FORTIFY_SOURCE=2
+CXFLAGS ?=-O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE
TCC = tcc
UCLIBC_GCC = $(shell for nm in i386-uclibc-linux-gcc i386-uclibc-gcc; do which $$nm > /dev/null && { echo $$nm ; exit; } ; done; echo false No uclibc found )
#DIET_GCC = diet gcc
@@ -76,6 +76,27 @@ ifeq ($(origin STRINGOPOVERFLOW), undefined)
endif
endif
+ifeq ($(origin NOSTRICTOVERFLOW), undefined)
+ NOSTRICTOVERFLOW := $(shell $(CC) -Q --help=warning 2>&1 | grep "strict-overflow" | wc -l)
+ ifneq "$(NOSTRICTOVERFLOW)" "0"
+ CWFLAGS += -fno-strict-overflow
+ endif
+endif
+
+ifeq ($(origin NODELETENULLPOINTER), undefined)
+ NODELETENULLPOINTER := $(shell $(CC) -Q --help=optimizers 2>&1 | grep "delete-null-pointer-checks" | wc -l)
+ ifneq "$(NODELETENULLPOINTER)" "0"
+ CWFLAGS += -fno-delete-null-pointer-checks
+ endif
+endif
+
+ifeq ($(origin WRAPV), undefined)
+ WRAPV := $(shell $(CC) -Q --help=optimizers 2>&1 | grep "wrapv" | wc -l)
+ ifneq "$(WRAPV)" "0"
+ CWFLAGS += -fwrapv
+ endif
+endif
+
ifdef DEBIAN
CPPFLAGS += -DDEBIAN
endif
--
2.41.0

View File

@ -0,0 +1,575 @@
From 4b3644ab4ce6df8c7f64c189c12b66627ff3e027 Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Fri, 5 Jul 2024 10:49:27 +0200
Subject: [PATCH 133/201] mdstat: Rework mdstat external arrays handling
To avoid repeating mdstat_read() in IncrementalRemove(), new function
mdstat_find_by_member_name() has been proposed. With that,
IncrementalRemove() handles own copy of mdstat content and there is no
need to repeat reading for external stop.
Additionally, It proposed few helper to avoid repeating
mdstat_ent->metadata_version checks across code.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
Assemble.c | 9 ++--
Incremental.c | 37 +++++++++------
Manage.c | 6 +--
Monitor.c | 18 +++----
config.c | 49 ++++++++++---------
mapfile.c | 12 ++---
mdadm.h | 6 ++-
mdmon.c | 4 +-
mdmon.h | 2 +-
mdstat.c | 129 ++++++++++++++++++++++++++++++++++++--------------
super-intel.c | 9 ++--
util.c | 10 ----
12 files changed, 167 insertions(+), 124 deletions(-)
diff --git a/Assemble.c b/Assemble.c
index 77f2b50e..a2bb7b64 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -114,14 +114,11 @@ static int is_member_busy(char *metadata_version)
int busy = 0;
for (ent = mdstat; ent; ent = ent->next) {
- if (ent->metadata_version == NULL)
- continue;
- if (strncmp(ent->metadata_version, "external:", 9) != 0)
- continue;
- if (!is_subarray(&ent->metadata_version[9]))
+ if (!is_mdstat_ent_subarray(ent))
continue;
+
/* Skip first char - it can be '/' or '-' */
- if (strcmp(&ent->metadata_version[10], metadata_version+1) == 0) {
+ if (strcmp(&ent->metadata_version[10], metadata_version + 1) == 0) {
busy = 1;
break;
}
diff --git a/Incremental.c b/Incremental.c
index 83db0712..abc7721b 100644
--- a/Incremental.c
+++ b/Incremental.c
@@ -1686,12 +1686,13 @@ static void remove_from_member_array(struct mdstat_ent *memb,
*/
int IncrementalRemove(char *devname, char *id_path, int verbose)
{
- int mdfd;
- int rv = 0;
- struct mdstat_ent *ent;
+ struct mdstat_ent *ent = NULL;
+ char buf[SYSFS_MAX_BUF_SIZE];
+ struct mdstat_ent *mdstat;
struct mddev_dev devlist;
struct mdinfo mdi;
- char buf[SYSFS_MAX_BUF_SIZE];
+ int rv = 1;
+ int mdfd;
if (!id_path)
dprintf("incremental removal without --path <id_path> lacks the possibility to re-add new device in this port\n");
@@ -1700,16 +1701,25 @@ int IncrementalRemove(char *devname, char *id_path, int verbose)
pr_err("incremental removal requires a kernel device name, not a file: %s\n", devname);
return 1;
}
- ent = mdstat_by_component(devname);
+
+ mdstat = mdstat_read(0, 0);
+ if (!mdstat) {
+ pr_err("Cannot read /proc/mdstat file, aborting\n");
+ return 1;
+ }
+
+ ent = mdstat_find_by_member_name(mdstat, devname);
if (!ent) {
if (verbose >= 0)
pr_err("%s does not appear to be a component of any array\n", devname);
- return 1;
+ goto out;
}
+
if (sysfs_init(&mdi, -1, ent->devnm)) {
pr_err("unable to initialize sysfs for: %s\n", devname);
- return 1;
+ goto out;
}
+
mdfd = open_dev_excl(ent->devnm);
if (is_fd_valid(mdfd)) {
close_fd(&mdfd);
@@ -1725,8 +1735,7 @@ int IncrementalRemove(char *devname, char *id_path, int verbose)
if (mdfd < 0) {
if (verbose >= 0)
pr_err("Cannot open array %s!!\n", ent->devnm);
- free_mdstat(ent);
- return 1;
+ goto out;
}
if (id_path) {
@@ -1741,16 +1750,13 @@ int IncrementalRemove(char *devname, char *id_path, int verbose)
devlist.devname = devname;
devlist.disposition = 'I';
/* for a container, we must fail each member array */
- if (ent->metadata_version &&
- strncmp(ent->metadata_version, "external:", 9) == 0) {
- struct mdstat_ent *mdstat = mdstat_read(0, 0);
+ if (is_mdstat_ent_external(ent)) {
struct mdstat_ent *memb;
for (memb = mdstat ; memb ; memb = memb->next) {
if (is_container_member(memb, ent->devnm))
remove_from_member_array(memb,
&devlist, verbose);
}
- free_mdstat(mdstat);
} else {
/*
* This 'I' incremental remove is a try-best effort,
@@ -1765,7 +1771,8 @@ int IncrementalRemove(char *devname, char *id_path, int verbose)
rv = Manage_subdevs(ent->devnm, mdfd, &devlist,
verbose, 0, UOPT_UNDEFINED, 0);
- close(mdfd);
- free_mdstat(ent);
+ close_fd(&mdfd);
+out:
+ free_mdstat(mdstat);
return rv;
}
diff --git a/Manage.c b/Manage.c
index f0304e1e..241de055 100644
--- a/Manage.c
+++ b/Manage.c
@@ -276,10 +276,8 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry)
*/
mds = mdstat_read(0, 0);
for (m = mds; m; m = m->next)
- if (m->metadata_version &&
- strncmp(m->metadata_version, "external:", 9)==0 &&
- metadata_container_matches(m->metadata_version+9,
- devnm)) {
+ if (is_mdstat_ent_external(m) &&
+ metadata_container_matches(m->metadata_version + 9, devnm)) {
if (verbose >= 0)
pr_err("Cannot stop container %s: member %s still active\n",
devname, m->devnm);
diff --git a/Monitor.c b/Monitor.c
index 26c53e13..cf14fbb3 100644
--- a/Monitor.c
+++ b/Monitor.c
@@ -879,9 +879,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
}
last_disk = i;
- if (mse->metadata_version &&
- strncmp(mse->metadata_version, "external:", 9) == 0 &&
- is_subarray(mse->metadata_version+9)) {
+ if (is_mdstat_ent_subarray(mse)) {
char *sl;
snprintf(st->parent_devnm, MD_NAME_MAX, "%s", mse->metadata_version + 10);
sl = strchr(st->parent_devnm, '/');
@@ -991,13 +989,12 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist)
snprintf(st->devnm, MD_NAME_MAX, "%s", mse->devnm);
st->percent = RESYNC_UNKNOWN;
st->expected_spares = -1;
- if (mse->metadata_version &&
- strncmp(mse->metadata_version,
- "external:", 9) == 0 &&
- is_subarray(mse->metadata_version+9)) {
+
+ if (is_mdstat_ent_subarray(mse)) {
char *sl;
- snprintf(st->parent_devnm, MD_NAME_MAX,
- "%s", mse->metadata_version + 10);
+
+ snprintf(st->parent_devnm, MD_NAME_MAX, "%s",
+ mse->metadata_version + 10);
sl = strchr(st->parent_devnm, '/');
if (sl)
*sl = 0;
@@ -1297,8 +1294,7 @@ int Wait(char *dev)
}
}
if (!e || e->percent == RESYNC_NONE) {
- if (e && e->metadata_version &&
- strncmp(e->metadata_version, "external:", 9) == 0) {
+ if (e && is_mdstat_ent_external(e)) {
if (is_subarray(&e->metadata_version[9]))
ping_monitor(&e->metadata_version[9]);
else
diff --git a/config.c b/config.c
index 6ea905f3..5411a480 100644
--- a/config.c
+++ b/config.c
@@ -360,35 +360,38 @@ struct mddev_dev *load_partitions(void)
struct mddev_dev *load_containers(void)
{
struct mdstat_ent *mdstat = mdstat_read(0, 0);
+ struct mddev_dev *dev_list = NULL;
+ struct map_ent *map_list = NULL;
struct mdstat_ent *ent;
- struct mddev_dev *d;
- struct mddev_dev *rv = NULL;
- struct map_ent *map = NULL, *me;
- if (!mdstat)
- return NULL;
+ for (ent = mdstat; ent; ent = ent->next) {
+ struct mddev_dev *d;
+ struct map_ent *map;
- for (ent = mdstat; ent; ent = ent->next)
- if (ent->metadata_version &&
- strncmp(ent->metadata_version, "external:", 9) == 0 &&
- !is_subarray(&ent->metadata_version[9])) {
- d = xcalloc(1, sizeof(*d));
- me = map_by_devnm(&map, ent->devnm);
- if (me)
- d->devname = xstrdup(me->path);
- else if (asprintf(&d->devname, "/dev/%s", ent->devnm) < 0) {
- free(d);
- continue;
- }
- d->next = rv;
- rv = d;
- map_free(map);
- map = NULL;
+ if (!is_mdstat_ent_external(ent))
+ continue;
+
+ if (is_mdstat_ent_subarray(ent))
+ continue;
+
+ d = xcalloc(1, sizeof(*d));
+
+ map = map_by_devnm(&map_list, ent->devnm);
+ if (map) {
+ d->devname = xstrdup(map->path);
+ } else if (asprintf(&d->devname, "/dev/%s", ent->devnm) < 0) {
+ free(d);
+ continue;
}
+
+ d->next = dev_list;
+ dev_list = d;
+ }
+
free_mdstat(mdstat);
- map_free(map);
+ map_free(map_list);
- return rv;
+ return dev_list;
}
struct createinfo createinfo = {
diff --git a/mapfile.c b/mapfile.c
index ea9837ac..632cf5e8 100644
--- a/mapfile.c
+++ b/mapfile.c
@@ -339,18 +339,14 @@ struct map_ent *map_by_name(struct map_ent **map, char *name)
*/
static char *get_member_info(struct mdstat_ent *ent)
{
+ char *subarray;
- if (ent->metadata_version == NULL ||
- strncmp(ent->metadata_version, "external:", 9) != 0)
+ if (!is_mdstat_ent_subarray(ent))
return NULL;
- if (is_subarray(&ent->metadata_version[9])) {
- char *subarray;
+ subarray = strrchr(ent->metadata_version, '/');
- subarray = strrchr(ent->metadata_version, '/');
- return subarray + 1;
- }
- return NULL;
+ return subarray + 1;
}
void RebuildMap(void)
diff --git a/mdadm.h b/mdadm.h
index 22d5e8f4..5c3a9836 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -743,8 +743,12 @@ extern int mdstat_wait(int seconds);
extern void mdstat_wait_fd(int fd, const sigset_t *sigmask);
extern int mddev_busy(char *devnm);
extern struct mdstat_ent *mdstat_by_component(char *name);
+extern struct mdstat_ent *mdstat_find_by_member_name(struct mdstat_ent *mdstat, char *member_devnm);
extern struct mdstat_ent *mdstat_by_subdev(char *subdev, char *container);
+extern bool is_mdstat_ent_external(struct mdstat_ent *ent);
+extern bool is_mdstat_ent_subarray(struct mdstat_ent *ent);
+
struct map_ent {
struct map_ent *next;
char devnm[32];
@@ -1771,7 +1775,7 @@ extern int is_mddev(char *dev);
extern int open_container(int fd);
extern int metadata_container_matches(char *metadata, char *devnm);
extern int metadata_subdev_matches(char *metadata, char *devnm);
-extern int is_container_member(struct mdstat_ent *ent, char *devname);
+extern bool is_container_member(struct mdstat_ent *ent, char *devname);
extern int is_subarray_active(char *subarray, char *devname);
extern int open_subarray(char *dev, char *subarray, struct supertype *st, int quiet);
extern struct superswitch *version_to_superswitch(char *vers);
diff --git a/mdmon.c b/mdmon.c
index 5fdb5cdb..95e350f4 100644
--- a/mdmon.c
+++ b/mdmon.c
@@ -394,9 +394,7 @@ int main(int argc, char *argv[])
/* launch an mdmon instance for each container found */
mdstat = mdstat_read(0, 0);
for (e = mdstat; e; e = e->next) {
- if (e->metadata_version &&
- strncmp(e->metadata_version, "external:", 9) == 0 &&
- !is_subarray(&e->metadata_version[9])) {
+ if (is_mdstat_ent_external(e) && !is_mdstat_ent_subarray(e)) {
/* update cmdline so this mdmon instance can be
* distinguished from others in a call to ps(1)
*/
diff --git a/mdmon.h b/mdmon.h
index b3d72ac3..110cbef2 100644
--- a/mdmon.h
+++ b/mdmon.h
@@ -78,7 +78,7 @@ void do_manager(struct supertype *container);
extern int sigterm;
int read_dev_state(int fd);
-int is_container_member(struct mdstat_ent *mdstat, char *container);
+bool is_container_member(struct mdstat_ent *mdstat, char *container);
struct mdstat_ent *mdstat_read(int hold, int start);
diff --git a/mdstat.c b/mdstat.c
index e233f094..cbbace3d 100644
--- a/mdstat.c
+++ b/mdstat.c
@@ -110,6 +110,28 @@ static int add_member_devname(struct dev_member **m, char *name)
return 1;
}
+/* Detach element from the list, it may modify list_head */
+static void mdstat_ent_list_detach_element(struct mdstat_ent **list_head, struct mdstat_ent *el)
+{
+ struct mdstat_ent *ent = *list_head;
+
+ if (ent == el) {
+ *list_head = ent->next;
+ } else {
+ while (ent) {
+ if (ent->next == el) {
+ ent->next = el->next;
+ break;
+ }
+ }
+
+ ent = ent->next;
+ }
+
+ assert(ent);
+ ent->next = NULL;
+}
+
void free_mdstat(struct mdstat_ent *ms)
{
while (ms) {
@@ -124,6 +146,32 @@ void free_mdstat(struct mdstat_ent *ms)
}
}
+bool is_mdstat_ent_external(struct mdstat_ent *ent)
+{
+ if (!ent->metadata_version)
+ return false;
+
+ if (strncmp(ent->metadata_version, "external:", 9) == 0)
+ return true;
+ return false;
+}
+
+bool is_mdstat_ent_subarray(struct mdstat_ent *ent)
+{
+ if (is_mdstat_ent_external(ent) && is_subarray(ent->metadata_version + 9))
+ return true;
+ return false;
+}
+
+bool is_container_member(struct mdstat_ent *mdstat, char *container)
+{
+ if (is_mdstat_ent_external(mdstat) &&
+ metadata_container_matches(mdstat->metadata_version + 9, container))
+ return true;
+
+ return false;
+}
+
static int mdstat_fd = -1;
struct mdstat_ent *mdstat_read(int hold, int start)
{
@@ -382,61 +430,70 @@ int mddev_busy(char *devnm)
return me != NULL;
}
-struct mdstat_ent *mdstat_by_component(char *name)
+/**
+ * mdstat_find_by_member_devnm()- Return first array or external container with member device.
+ * @mdstat: Preloaded mdstat to iterate over.
+ * @member_devnm: devnm of the device to find.
+ *
+ * External subarrays are skipped.
+ */
+struct mdstat_ent *mdstat_find_by_member_name(struct mdstat_ent *mdstat, char *member_devnm)
{
- struct mdstat_ent *mdstat = mdstat_read(0, 0);
+ struct mdstat_ent *ent;
- while (mdstat) {
- struct dev_member *m;
- struct mdstat_ent *ent;
- if (mdstat->metadata_version &&
- strncmp(mdstat->metadata_version, "external:", 9) == 0 &&
- is_subarray(mdstat->metadata_version+9))
- /* don't return subarrays, only containers */
- ;
- else for (m = mdstat->members; m; m = m->next) {
- if (strcmp(m->name, name) == 0) {
- free_mdstat(mdstat->next);
- mdstat->next = NULL;
- return mdstat;
- }
- }
- ent = mdstat;
- mdstat = mdstat->next;
- ent->next = NULL;
- free_mdstat(ent);
+ for (ent = mdstat; ent; ent = ent->next) {
+ struct dev_member *member;
+
+ if (is_mdstat_ent_subarray(ent))
+ continue;
+
+ for (member = ent->members; member; member = member->next)
+ if (strcmp(member->name, member_devnm) == 0)
+ return ent;
}
+
return NULL;
}
+
+struct mdstat_ent *mdstat_by_component(char *name)
+{
+ struct mdstat_ent *mdstat = mdstat_read(0, 0);
+ struct mdstat_ent *ent = mdstat_find_by_member_name(mdstat, name);
+
+ if (ent)
+ mdstat_ent_list_detach_element(&mdstat, ent);
+
+ free_mdstat(mdstat);
+
+ return ent;
+}
+
struct mdstat_ent *mdstat_by_subdev(char *subdev, char *container)
{
struct mdstat_ent *mdstat = mdstat_read(0, 0);
struct mdstat_ent *ent = NULL;
- while (mdstat) {
+ for (ent = mdstat; ent; ent = ent->next) {
/* metadata version must match:
* external:[/-]%s/%s
* where first %s is 'container' and second %s is 'subdev'
*/
- if (ent)
- free_mdstat(ent);
- ent = mdstat;
- mdstat = mdstat->next;
- ent->next = NULL;
- if (ent->metadata_version == NULL ||
- strncmp(ent->metadata_version, "external:", 9) != 0)
+ if (!is_mdstat_ent_external(ent))
continue;
- if (!metadata_container_matches(ent->metadata_version+9,
- container) ||
- !metadata_subdev_matches(ent->metadata_version+9,
- subdev))
+ if (!metadata_container_matches(ent->metadata_version + 9, container))
+ continue;
+ if (!metadata_subdev_matches(ent->metadata_version + 9, subdev))
continue;
- free_mdstat(mdstat);
- return ent;
+ break;
}
- return NULL;
+
+ if (ent)
+ mdstat_ent_list_detach_element(&mdstat, ent);
+
+ free_mdstat(mdstat);
+ return ent;
}
diff --git a/super-intel.c b/super-intel.c
index 713bfccf..c215b910 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -6974,13 +6974,11 @@ active_arrays_by_format(char *name, char* hba, struct md_list **devlist,
int found;
for (memb = mdstat ; memb ; memb = memb->next) {
- if (memb->metadata_version &&
- (strncmp(memb->metadata_version, "external:", 9) == 0) &&
- (strcmp(&memb->metadata_version[9], name) == 0) &&
- !is_subarray(memb->metadata_version+9) &&
- memb->members) {
+ if (is_mdstat_ent_external(memb) && !is_subarray(memb->metadata_version + 9) &&
+ strcmp(&memb->metadata_version[9], name) == 0 && memb->members) {
struct dev_member *dev = memb->members;
int fd = -1;
+
while (dev && !is_fd_valid(fd)) {
char *path = xmalloc(strlen(dev->name) + strlen("/dev/") + 1);
num = snprintf(path, PATH_MAX, "%s%s", "/dev/", dev->name);
@@ -6998,7 +6996,6 @@ active_arrays_by_format(char *name, char* hba, struct md_list **devlist,
struct mdstat_ent *vol;
for (vol = mdstat ; vol ; vol = vol->next) {
if (vol->active > 0 &&
- vol->metadata_version &&
is_container_member(vol, memb->devnm)) {
found++;
count++;
diff --git a/util.c b/util.c
index 908f8430..83d42833 100644
--- a/util.c
+++ b/util.c
@@ -1671,16 +1671,6 @@ int metadata_subdev_matches(char *metadata, char *devnm)
return 0;
}
-int is_container_member(struct mdstat_ent *mdstat, char *container)
-{
- if (mdstat->metadata_version == NULL ||
- strncmp(mdstat->metadata_version, "external:", 9) != 0 ||
- !metadata_container_matches(mdstat->metadata_version+9, container))
- return 0;
-
- return 1;
-}
-
int is_subarray_active(char *subarray, char *container)
{
struct mdstat_ent *mdstat = mdstat_read(0, 0);
--
2.41.0

View File

@ -0,0 +1,56 @@
From 2a4c40766d654dcbf5911d1b7b63bbbe8b2c0128 Mon Sep 17 00:00:00 2001
From: Nigel Croxon <ncroxon@redhat.com>
Date: Wed, 24 Jul 2024 09:04:08 -0400
Subject: [PATCH 134/201] mdadm: managemon.c fix coverity issues
Fixing the following coding errors the coverity tools found:
* Event check_return: Calling "fcntl(fd, 4, fl)" without checking
return value. This library function may fail and return an error code.
* Event check_after_deref: Null-checking "new" suggests that it may
be null, but it has already been dereferenced on all paths leading
to the check.
Signed-off-by: Nigel Croxon <ncroxon@redhat.com>
---
managemon.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/managemon.c b/managemon.c
index 358459e7..add6a79e 100644
--- a/managemon.c
+++ b/managemon.c
@@ -776,10 +776,8 @@ static void manage_new(struct mdstat_ent *mdstat,
error:
pr_err("failed to monitor %s\n", mdstat->metadata_version);
- if (new) {
- new->container = NULL;
- free_aa(new);
- }
+ new->container = NULL;
+ free_aa(new);
if (mdi)
sysfs_free(mdi);
}
@@ -870,8 +868,15 @@ void read_sock(struct supertype *container)
return;
fl = fcntl(fd, F_GETFL, 0);
+ if (fl < 0) {
+ close_fd(&fd);
+ return;
+ }
fl |= O_NONBLOCK;
- fcntl(fd, F_SETFL, fl);
+ if (fcntl(fd, F_SETFL, fl) < 0) {
+ close_fd(&fd);
+ return;
+ }
do {
msg.buf = NULL;
--
2.41.0

View File

@ -0,0 +1,40 @@
From 87f96c870399cd029933a9742ba72e85e3251c3e Mon Sep 17 00:00:00 2001
From: Nigel Croxon <ncroxon@redhat.com>
Date: Wed, 24 Jul 2024 09:20:28 -0400
Subject: [PATCH 135/201] mdadm: msg.c fix coverity issues
Fixing the following coding errors the coverity tools found:
* Event check_return: Calling "fcntl(sfd, 4, fl)" without
checking return value. This library function may fail and
return an error code.
Signed-off-by: Nigel Croxon <ncroxon@redhat.com>
---
msg.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/msg.c b/msg.c
index f0772b3f..b6da91d3 100644
--- a/msg.c
+++ b/msg.c
@@ -176,8 +176,15 @@ int connect_monitor(char *devname)
}
fl = fcntl(sfd, F_GETFL, 0);
+ if (fl < 0) {
+ close(sfd);
+ return -1;
+ }
fl |= O_NONBLOCK;
- fcntl(sfd, F_SETFL, fl);
+ if (fcntl(sfd, F_SETFL, fl) < 0) {
+ close(sfd);
+ return -1;
+ }
return sfd;
}
--
2.41.0

View File

@ -0,0 +1,150 @@
From a944180a7e6a7d6d4cd08f6afcb83e58986c35f9 Mon Sep 17 00:00:00 2001
From: Blazej Kucman <blazej.kucman@intel.com>
Date: Wed, 24 Jul 2024 22:17:42 +0200
Subject: [PATCH 136/201] imsm: refactor chunk size print
- add imsm_chunk_ops struct for better code readability,
- move chunk size mapping to string into array,
- add function to print supported chunk sizes by IMSM controller.
Signed-off-by: Blazej Kucman <blazej.kucman@intel.com>
---
super-intel.c | 92 +++++++++++++++++++++++++++------------------------
1 file changed, 49 insertions(+), 43 deletions(-)
diff --git a/super-intel.c b/super-intel.c
index c215b910..ab9b5d3f 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -647,6 +647,31 @@ static const char *_sys_dev_type[] = {
[SYS_DEV_SATA_VMD] = "SATA VMD"
};
+struct imsm_chunk_ops {
+ uint chunk;
+ char *chunk_str;
+};
+
+static const struct imsm_chunk_ops imsm_chunk_ops[] = {
+ {IMSM_OROM_SSS_2kB, "2k"},
+ {IMSM_OROM_SSS_4kB, "4k"},
+ {IMSM_OROM_SSS_8kB, "8k"},
+ {IMSM_OROM_SSS_16kB, "16k"},
+ {IMSM_OROM_SSS_32kB, "32k"},
+ {IMSM_OROM_SSS_64kB, "64k"},
+ {IMSM_OROM_SSS_128kB, "128k"},
+ {IMSM_OROM_SSS_256kB, "256k"},
+ {IMSM_OROM_SSS_512kB, "512k"},
+ {IMSM_OROM_SSS_1MB, "1M"},
+ {IMSM_OROM_SSS_2MB, "2M"},
+ {IMSM_OROM_SSS_4MB, "4M"},
+ {IMSM_OROM_SSS_8MB, "8M"},
+ {IMSM_OROM_SSS_16MB, "16M"},
+ {IMSM_OROM_SSS_32MB, "32M"},
+ {IMSM_OROM_SSS_64MB, "64M"},
+ {0, NULL}
+};
+
static int no_platform = -1;
static int check_no_platform(void)
@@ -2626,6 +2651,16 @@ static void print_imsm_level_capability(const struct imsm_orom *orom)
printf("%s ", imsm_level_ops[idx].name);
}
+static void print_imsm_chunk_size_capability(const struct imsm_orom *orom)
+{
+ int idx;
+
+ for (idx = 0; imsm_chunk_ops[idx].chunk_str; idx++)
+ if (imsm_chunk_ops[idx].chunk & orom->sss)
+ printf("%s ", imsm_chunk_ops[idx].chunk_str);
+}
+
+
static void print_imsm_capability(const struct imsm_orom *orom)
{
printf(" Platform : Intel(R) ");
@@ -2638,41 +2673,25 @@ static void print_imsm_capability(const struct imsm_orom *orom)
imsm_orom_is_enterprise(orom) ? " enterprise" : "");
if (orom->major_ver || orom->minor_ver || orom->hotfix_ver || orom->build) {
if (imsm_orom_is_vmd_without_efi(orom))
- printf(" Version : %d.%d\n", orom->major_ver,
- orom->minor_ver);
+ printf(" Version : %d.%d\n", orom->major_ver, orom->minor_ver);
else
- printf(" Version : %d.%d.%d.%d\n", orom->major_ver,
- orom->minor_ver, orom->hotfix_ver, orom->build);
+ printf(" Version : %d.%d.%d.%d\n", orom->major_ver, orom->minor_ver,
+ orom->hotfix_ver, orom->build);
}
printf(" RAID Levels : ");
print_imsm_level_capability(orom);
printf("\n");
- printf(" Chunk Sizes :%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
- imsm_orom_has_chunk(orom, 2) ? " 2k" : "",
- imsm_orom_has_chunk(orom, 4) ? " 4k" : "",
- imsm_orom_has_chunk(orom, 8) ? " 8k" : "",
- imsm_orom_has_chunk(orom, 16) ? " 16k" : "",
- imsm_orom_has_chunk(orom, 32) ? " 32k" : "",
- imsm_orom_has_chunk(orom, 64) ? " 64k" : "",
- imsm_orom_has_chunk(orom, 128) ? " 128k" : "",
- imsm_orom_has_chunk(orom, 256) ? " 256k" : "",
- imsm_orom_has_chunk(orom, 512) ? " 512k" : "",
- imsm_orom_has_chunk(orom, 1024*1) ? " 1M" : "",
- imsm_orom_has_chunk(orom, 1024*2) ? " 2M" : "",
- imsm_orom_has_chunk(orom, 1024*4) ? " 4M" : "",
- imsm_orom_has_chunk(orom, 1024*8) ? " 8M" : "",
- imsm_orom_has_chunk(orom, 1024*16) ? " 16M" : "",
- imsm_orom_has_chunk(orom, 1024*32) ? " 32M" : "",
- imsm_orom_has_chunk(orom, 1024*64) ? " 64M" : "");
- printf(" 2TB volumes :%s supported\n",
- (orom->attr & IMSM_OROM_ATTR_2TB)?"":" not");
+ printf(" Chunk Sizes : ");
+ print_imsm_chunk_size_capability(orom);
+ printf("\n");
+
+ printf(" 2TB volumes :%s supported\n", (orom->attr & IMSM_OROM_ATTR_2TB) ? "" : " not");
printf(" 2TB disks :%s supported\n",
- (orom->attr & IMSM_OROM_ATTR_2TB_DISK)?"":" not");
+ (orom->attr & IMSM_OROM_ATTR_2TB_DISK) ? "" : " not");
printf(" Max Disks : %d\n", orom->tds);
- printf(" Max Volumes : %d per array, %d per %s\n",
- orom->vpa, orom->vphba,
+ printf(" Max Volumes : %d per array, %d per %s\n", orom->vpa, orom->vphba,
imsm_orom_is_nvme(orom) ? "platform" : "controller");
return;
}
@@ -2688,23 +2707,10 @@ static void print_imsm_capability_export(const struct imsm_orom *orom)
print_imsm_level_capability(orom);
printf("\n");
- printf("IMSM_SUPPORTED_CHUNK_SIZES=%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
- imsm_orom_has_chunk(orom, 2) ? "2k " : "",
- imsm_orom_has_chunk(orom, 4) ? "4k " : "",
- imsm_orom_has_chunk(orom, 8) ? "8k " : "",
- imsm_orom_has_chunk(orom, 16) ? "16k " : "",
- imsm_orom_has_chunk(orom, 32) ? "32k " : "",
- imsm_orom_has_chunk(orom, 64) ? "64k " : "",
- imsm_orom_has_chunk(orom, 128) ? "128k " : "",
- imsm_orom_has_chunk(orom, 256) ? "256k " : "",
- imsm_orom_has_chunk(orom, 512) ? "512k " : "",
- imsm_orom_has_chunk(orom, 1024*1) ? "1M " : "",
- imsm_orom_has_chunk(orom, 1024*2) ? "2M " : "",
- imsm_orom_has_chunk(orom, 1024*4) ? "4M " : "",
- imsm_orom_has_chunk(orom, 1024*8) ? "8M " : "",
- imsm_orom_has_chunk(orom, 1024*16) ? "16M " : "",
- imsm_orom_has_chunk(orom, 1024*32) ? "32M " : "",
- imsm_orom_has_chunk(orom, 1024*64) ? "64M " : "");
+ printf("IMSM_SUPPORTED_CHUNK_SIZES=");
+ print_imsm_chunk_size_capability(orom);
+ printf("\n");
+
printf("IMSM_2TB_VOLUMES=%s\n",(orom->attr & IMSM_OROM_ATTR_2TB) ? "yes" : "no");
printf("IMSM_2TB_DISKS=%s\n",(orom->attr & IMSM_OROM_ATTR_2TB_DISK) ? "yes" : "no");
printf("IMSM_MAX_DISKS=%d\n",orom->tds);
--
2.41.0

View File

@ -0,0 +1,109 @@
From e0373b734db511cdfec248ff6d769270ec8fd492 Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Fri, 26 Jul 2024 15:14:03 +0800
Subject: [PATCH 137/201] mdadm/Grow: fix coverity issue CHECKED_RETURN
It needs to check return value when functions have return value.
Signed-off-by: Xiao Ni <xni@redhat.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
Grow.c | 43 ++++++++++++++++++++++++++++++++++++-------
1 file changed, 36 insertions(+), 7 deletions(-)
diff --git a/Grow.c b/Grow.c
index b135930d..7ae967bd 100644
--- a/Grow.c
+++ b/Grow.c
@@ -3261,7 +3261,12 @@ static int reshape_array(char *container, int fd, char *devname,
/* This is a spare that wants to
* be part of the array.
*/
- add_disk(fd, st, info2, d);
+ if (add_disk(fd, st, info2, d) < 0) {
+ pr_err("Can not add disk %s\n",
+ d->sys_name);
+ free(info2);
+ goto release;
+ }
}
}
sysfs_free(info2);
@@ -4413,7 +4418,10 @@ static void validate(int afd, int bfd, unsigned long long offset)
*/
if (afd < 0)
return;
- lseek64(bfd, offset - 4096, 0);
+ if (lseek64(bfd, offset - 4096, 0) < 0) {
+ pr_err("lseek64 fails %d:%s\n", errno, strerror(errno));
+ return;
+ }
if (read(bfd, &bsb2, 512) != 512)
fail("cannot read bsb");
if (bsb2.sb_csum != bsb_csum((char*)&bsb2,
@@ -4444,12 +4452,19 @@ static void validate(int afd, int bfd, unsigned long long offset)
}
}
- lseek64(bfd, offset, 0);
+ if (lseek64(bfd, offset, 0) < 0) {
+ pr_err("lseek64 fails %d:%s\n", errno, strerror(errno));
+ goto out;
+ }
if ((unsigned long long)read(bfd, bbuf, len) != len) {
//printf("len %llu\n", len);
fail("read first backup failed");
}
- lseek64(afd, __le64_to_cpu(bsb2.arraystart)*512, 0);
+
+ if (lseek64(afd, __le64_to_cpu(bsb2.arraystart)*512, 0) < 0) {
+ pr_err("lseek64 fails %d:%s\n", errno, strerror(errno));
+ goto out;
+ }
if ((unsigned long long)read(afd, abuf, len) != len)
fail("read first from array failed");
if (memcmp(bbuf, abuf, len) != 0)
@@ -4466,15 +4481,25 @@ static void validate(int afd, int bfd, unsigned long long offset)
bbuf = xmalloc(abuflen);
}
- lseek64(bfd, offset+__le64_to_cpu(bsb2.devstart2)*512, 0);
+ if (lseek64(bfd, offset+__le64_to_cpu(bsb2.devstart2)*512, 0) < 0) {
+ pr_err("lseek64 fails %d:%s\n", errno, strerror(errno));
+ goto out;
+ }
if ((unsigned long long)read(bfd, bbuf, len) != len)
fail("read second backup failed");
- lseek64(afd, __le64_to_cpu(bsb2.arraystart2)*512, 0);
+ if (lseek64(afd, __le64_to_cpu(bsb2.arraystart2)*512, 0) < 0) {
+ pr_err("lseek64 fails %d:%s\n", errno, strerror(errno));
+ goto out;
+ }
if ((unsigned long long)read(afd, abuf, len) != len)
fail("read second from array failed");
if (memcmp(bbuf, abuf, len) != 0)
fail("data2 compare failed");
}
+out:
+ free(abuf);
+ free(bbuf);
+ return;
}
int child_monitor(int afd, struct mdinfo *sra, struct reshape *reshape,
@@ -5033,7 +5058,11 @@ int Grow_continue_command(char *devname, int fd, struct context *c)
goto Grow_continue_command_exit;
}
content = &array;
- sysfs_init(content, fd, NULL);
+ if (sysfs_init(content, fd, NULL) < 0) {
+ pr_err("sysfs_init fails\n");
+ ret_val = 1;
+ goto Grow_continue_command_exit;
+ }
/* Need to load a superblock.
* FIXME we should really get what we need from
* sysfs
--
2.41.0

View File

@ -0,0 +1,166 @@
From 54c09eaa8bc057dfd88ae20d259f88457f67fd1c Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Fri, 26 Jul 2024 15:14:04 +0800
Subject: [PATCH 138/201] mdadm/Grow: fix coverity issue RESOURCE_LEAK
Fix some resource leak problems.
Signed-off-by: Xiao Ni <xni@redhat.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
Grow.c | 42 +++++++++++++++++++++++++++++++-----------
1 file changed, 31 insertions(+), 11 deletions(-)
diff --git a/Grow.c b/Grow.c
index 7ae967bd..907a6e1b 100644
--- a/Grow.c
+++ b/Grow.c
@@ -530,8 +530,10 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s)
pr_err("Cannot add bitmap while array is resyncing or reshaping etc.\n");
pr_err("Cannot set bitmap file for %s: %s\n",
devname, strerror(err));
+ close_fd(&bitmap_fd);
return 1;
}
+ close_fd(&bitmap_fd);
}
return 0;
@@ -3083,6 +3085,7 @@ static int reshape_array(char *container, int fd, char *devname,
int done;
struct mdinfo *sra = NULL;
char buf[SYSFS_MAX_BUF_SIZE];
+ bool located_backup = false;
/* when reshaping a RAID0, the component_size might be zero.
* So try to fix that up.
@@ -3165,8 +3168,10 @@ static int reshape_array(char *container, int fd, char *devname,
goto release;
}
- if (!backup_file)
+ if (!backup_file) {
backup_file = locate_backup(sra->sys_name);
+ located_backup = true;
+ }
goto started;
}
@@ -3612,15 +3617,13 @@ started:
mdstat_wait(30 - (delayed-1) * 25);
} while (delayed);
mdstat_close();
- if (check_env("MDADM_GROW_VERIFY"))
- fd = open(devname, O_RDONLY | O_DIRECT);
- else
- fd = -1;
mlockall(MCL_FUTURE);
if (signal_s(SIGTERM, catch_term) == SIG_ERR)
goto release;
+ if (check_env("MDADM_GROW_VERIFY"))
+ fd = open(devname, O_RDONLY | O_DIRECT);
if (st->ss->external) {
/* metadata handler takes it from here */
done = st->ss->manage_reshape(
@@ -3632,6 +3635,7 @@ started:
fd, sra, &reshape, st, blocks, fdlist, offsets,
d - odisks, fdlist + odisks, offsets + odisks);
+ close_fd(&fd);
free(fdlist);
free(offsets);
@@ -3701,6 +3705,8 @@ out:
exit(0);
release:
+ if (located_backup)
+ free(backup_file);
free(fdlist);
free(offsets);
if (orig_level != UnSet && sra) {
@@ -3839,6 +3845,7 @@ int reshape_container(char *container, char *devname,
pr_err("Unable to initialize sysfs for %s\n",
mdstat->devnm);
rv = 1;
+ close_fd(&fd);
break;
}
@@ -4717,6 +4724,7 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist,
unsigned long long *offsets;
unsigned long long nstripe, ostripe;
int ndata, odata;
+ int fd, backup_fd = -1;
odata = info->array.raid_disks - info->delta_disks - 1;
if (info->array.level == 6)
@@ -4732,9 +4740,18 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist,
* been used
*/
old_disks = cnt;
+
+ if (backup_file) {
+ backup_fd = open(backup_file, O_RDONLY);
+ if (!is_fd_valid(backup_fd)) {
+ pr_err("Can't open backup file %s : %s\n",
+ backup_file, strerror(errno));
+ return -EINVAL;
+ }
+ }
+
for (i=old_disks-(backup_file?1:0); i<cnt; i++) {
struct mdinfo dinfo;
- int fd;
int bsbsize;
char *devname, namebuf[20];
unsigned long long lo, hi;
@@ -4747,12 +4764,9 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist,
* else restore data and update all superblocks
*/
if (i == old_disks-1) {
- fd = open(backup_file, O_RDONLY);
- if (fd<0) {
- pr_err("backup file %s inaccessible: %s\n",
- backup_file, strerror(errno));
+ if (!is_fd_valid(backup_fd))
continue;
- }
+ fd = backup_fd;
devname = backup_file;
} else {
fd = fdlist[i];
@@ -4907,6 +4921,7 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist,
pr_err("Error restoring backup from %s\n",
devname);
free(offsets);
+ close_fd(&backup_fd);
return 1;
}
@@ -4923,6 +4938,7 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist,
pr_err("Error restoring second backup from %s\n",
devname);
free(offsets);
+ close_fd(&backup_fd);
return 1;
}
@@ -4984,8 +5000,12 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist,
st->ss->store_super(st, fdlist[j]);
st->ss->free_super(st);
}
+ close_fd(&backup_fd);
return 0;
}
+
+ close_fd(&backup_fd);
+
/* Didn't find any backup data, try to see if any
* was needed.
*/
--
2.41.0

View File

@ -0,0 +1,29 @@
From 13c1f4a56b3bedbf802d66e86afd787e318e25fb Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Fri, 26 Jul 2024 15:14:05 +0800
Subject: [PATCH 139/201] mdadm/Grow: fix coverity issue STRING_OVERFLOW
Fix string overflow problems in Grow.c
Signed-off-by: Xiao Ni <xni@redhat.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
Grow.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Grow.c b/Grow.c
index 907a6e1b..a5f9027d 100644
--- a/Grow.c
+++ b/Grow.c
@@ -1694,7 +1694,7 @@ char *analyse_change(char *devname, struct mdinfo *info, struct reshape *re)
/* Current RAID6 layout has a RAID5
* equivalent - good
*/
- strcat(strcpy(layout, ls), "-6");
+ snprintf(layout, 40, "%s-6", ls);
l = map_name(r6layout, layout);
if (l == UnSet)
return "Cannot find RAID6 layout to convert to";
--
2.41.0

View File

@ -0,0 +1,87 @@
From 17c99bab3e2e3606961d7ecec62c29921b5d6660 Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Fri, 26 Jul 2024 15:14:06 +0800
Subject: [PATCH 140/201] mdadm/Incremental: fix coverity issues.
There are two issues PW.PARAMETER_HIDDEN (declaration hides
parameter 'devname') and INTEGER_OVERFLOW.
Signed-off-by: Xiao Ni <xni@redhat.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
Incremental.c | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/Incremental.c b/Incremental.c
index abc7721b..fc4e68ff 100644
--- a/Incremental.c
+++ b/Incremental.c
@@ -770,7 +770,7 @@ static int count_active(struct supertype *st, struct mdinfo *sra,
replcnt++;
st->ss->free_super(st);
}
- if (max_journal_events >= max_events - 1)
+ if (max_events > 0 && max_journal_events >= max_events - 1)
bestinfo->journal_clean = 1;
if (!avail)
@@ -1113,7 +1113,7 @@ static int partition_try_spare(char *devname, int *dfdp, struct dev_policy *pol,
int fd = -1;
struct mdinfo info;
struct supertype *st2 = NULL;
- char *devname = NULL;
+ char *dev_path_name = NULL;
unsigned long long devsectors;
char *pathlist[2];
@@ -1142,14 +1142,14 @@ static int partition_try_spare(char *devname, int *dfdp, struct dev_policy *pol,
domain_free(domlist);
domlist = NULL;
- if (asprintf(&devname, "/dev/disk/by-path/%s", de->d_name) != 1) {
- devname = NULL;
+ if (asprintf(&dev_path_name, "/dev/disk/by-path/%s", de->d_name) != 1) {
+ dev_path_name = NULL;
goto next;
}
- fd = open(devname, O_RDONLY);
+ fd = open(dev_path_name, O_RDONLY);
if (fd < 0)
goto next;
- if (get_dev_size(fd, devname, &devsectors) == 0)
+ if (get_dev_size(fd, dev_path_name, &devsectors) == 0)
goto next;
devsectors >>= 9;
@@ -1188,8 +1188,8 @@ static int partition_try_spare(char *devname, int *dfdp, struct dev_policy *pol,
if (chosen == NULL || chosen_size < info.component_size) {
chosen_size = info.component_size;
free(chosen);
- chosen = devname;
- devname = NULL;
+ chosen = dev_path_name;
+ dev_path_name = NULL;
if (chosen_st) {
chosen_st->ss->free_super(chosen_st);
free(chosen_st);
@@ -1199,7 +1199,7 @@ static int partition_try_spare(char *devname, int *dfdp, struct dev_policy *pol,
}
next:
- free(devname);
+ free(dev_path_name);
domain_free(domlist);
dev_policy_free(pol2);
if (st2)
@@ -1246,7 +1246,7 @@ static int is_bare(int dfd)
/* OK, first 4K appear blank, try the end. */
get_dev_size(dfd, NULL, &size);
- if (lseek(dfd, size-4096, SEEK_SET) < 0 ||
+ if ((size >= 4096 && lseek(dfd, size-4096, SEEK_SET) < 0) ||
read(dfd, buf, 4096) != 4096)
return 0;
--
2.41.0

View File

@ -0,0 +1,46 @@
From f9949a04355f0fca29c6bc02ead8425e76daa573 Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Fri, 26 Jul 2024 15:14:07 +0800
Subject: [PATCH 141/201] mdadm/mdmon: fix coverity issue CHECKED_RETURN
It needs to check return values when functions have return value.
Signed-off-by: Xiao Ni <xni@redhat.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
mdmon.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/mdmon.c b/mdmon.c
index 95e350f4..cae63841 100644
--- a/mdmon.c
+++ b/mdmon.c
@@ -198,8 +198,12 @@ static void try_kill_monitor(pid_t pid, char *devname, int sock)
/* Wait for monitor to exit by reading from the socket, after
* clearing the non-blocking flag */
fl = fcntl(sock, F_GETFL, 0);
+ if (fl < 0)
+ return;
+
fl &= ~O_NONBLOCK;
- fcntl(sock, F_SETFL, fl);
+ if (fcntl(sock, F_SETFL, fl) < 0)
+ return;
n = read(sock, buf, 100);
/* If there is I/O going on it might took some time to get to
@@ -249,7 +253,10 @@ static int make_control_sock(char *devname)
listen(sfd, 10);
fl = fcntl(sfd, F_GETFL, 0);
fl |= O_NONBLOCK;
- fcntl(sfd, F_SETFL, fl);
+ if (fcntl(sfd, F_SETFL, fl) < 0) {
+ close_fd(&sfd);
+ return -1;
+ }
return sfd;
}
--
2.41.0

View File

@ -0,0 +1,49 @@
From e7623d5ae4724c72e873e8af17f2ed6bfdc54427 Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Fri, 26 Jul 2024 15:14:08 +0800
Subject: [PATCH 142/201] mdadm/mdmon: fix coverity issue RESOURCE_LEAK
Fix resource leak problem in mdmon.c
Signed-off-by: Xiao Ni <xni@redhat.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
mdmon.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/mdmon.c b/mdmon.c
index cae63841..6e28b56e 100644
--- a/mdmon.c
+++ b/mdmon.c
@@ -456,22 +456,25 @@ static int mdmon(char *devnm, int must_fork, int takeover)
if (must_fork) {
if (pipe(pfd) != 0) {
pr_err("failed to create pipe\n");
+ close_fd(&mdfd);
return 1;
}
switch(fork()) {
case -1:
pr_err("failed to fork: %s\n", strerror(errno));
+ close_fd(&mdfd);
return 1;
case 0: /* child */
- close(pfd[0]);
+ close_fd(&pfd[0]);
break;
default: /* parent */
- close(pfd[1]);
+ close_fd(&pfd[1]);
if (read(pfd[0], &status, sizeof(status)) != sizeof(status)) {
wait(&status);
status = WEXITSTATUS(status);
}
- close(pfd[0]);
+ close_fd(&pfd[0]);
+ close_fd(&mdfd);
return status;
}
} else
--
2.41.0

View File

@ -0,0 +1,33 @@
From f34040081c36ff92180674b89c39ddc7bdd47288 Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Fri, 26 Jul 2024 15:14:09 +0800
Subject: [PATCH 143/201] mdadm/mdopen: fix coverity issue CHECKED_RETURN
It needs to check return values when functions return value.
Signed-off-by: Xiao Ni <xni@redhat.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
mdopen.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/mdopen.c b/mdopen.c
index eaa59b59..c9fda131 100644
--- a/mdopen.c
+++ b/mdopen.c
@@ -406,7 +406,11 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy,
perror("chown");
if (chmod(devname, ci->mode))
perror("chmod");
- stat(devname, &stb);
+ if (stat(devname, &stb) < 0) {
+ pr_err("failed to stat %s\n",
+ devname);
+ return -1;
+ }
add_dev(devname, &stb, 0, NULL);
}
if (use_mdp == 1)
--
2.41.0

View File

@ -0,0 +1,29 @@
From debf421db02c85f176b5eda2e8dcc9d17d89623c Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Fri, 26 Jul 2024 15:14:10 +0800
Subject: [PATCH 144/201] mdadm/mdopen: fix coverity issue STRING_OVERFLOW
Fix string overflow problems in mdopen.c
Signed-off-by: Xiao Ni <xni@redhat.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
mdopen.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mdopen.c b/mdopen.c
index c9fda131..e49defb6 100644
--- a/mdopen.c
+++ b/mdopen.c
@@ -376,7 +376,7 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy,
sprintf(devname, "/dev/%s", devnm);
- if (dev && dev[0] == '/')
+ if (dev && dev[0] == '/' && strlen(dev) < 400)
strcpy(chosen, dev);
else if (cname[0] == 0)
strcpy(chosen, devname);
--
2.41.0

View File

@ -0,0 +1,46 @@
From 6984814b6fd879efae178acb057c1025aa4c64e8 Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Fri, 26 Jul 2024 15:14:11 +0800
Subject: [PATCH 145/201] mdadm/mdstat: fix coverity issue CHECKED_RETURN
It needs to check return values when functions return value.
Signed-off-by: Xiao Ni <xni@redhat.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
mdstat.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/mdstat.c b/mdstat.c
index cbbace3d..a971a957 100644
--- a/mdstat.c
+++ b/mdstat.c
@@ -194,8 +194,11 @@ struct mdstat_ent *mdstat_read(int hold, int start)
f = fopen("/proc/mdstat", "r");
if (f == NULL)
return NULL;
- else
- fcntl(fileno(f), F_SETFD, FD_CLOEXEC);
+
+ if (fcntl(fileno(f), F_SETFD, FD_CLOEXEC) < 0) {
+ fclose(f);
+ return NULL;
+ }
all = NULL;
end = &all;
@@ -329,7 +332,10 @@ struct mdstat_ent *mdstat_read(int hold, int start)
}
if (hold && mdstat_fd == -1) {
mdstat_fd = dup(fileno(f));
- fcntl(mdstat_fd, F_SETFD, FD_CLOEXEC);
+ if (fcntl(mdstat_fd, F_SETFD, FD_CLOEXEC) < 0) {
+ fclose(f);
+ return NULL;
+ }
}
fclose(f);
--
2.41.0

View File

@ -0,0 +1,56 @@
From e055d9236a7d0dca2a311e8bb8013018dc571d6a Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Fri, 26 Jul 2024 15:14:12 +0800
Subject: [PATCH 146/201] mdadm/super0: fix coverity issue CHECKED_RETURN and
EVALUATION_ORDER
Fix coverity problems in super0. It needs to check return value when
functions return value. And fix EVALUATION_ORDER problems in super0.c
Signed-off-by: Xiao Ni <xni@redhat.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
super0.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/super0.c b/super0.c
index 9b4e187e..c428e2a6 100644
--- a/super0.c
+++ b/super0.c
@@ -83,6 +83,9 @@ static void examine_super0(struct supertype *st, char *homehost)
int d;
int delta_extra = 0;
char *c;
+ unsigned long expected_csum = 0;
+
+ expected_csum = calc_sb0_csum(sb);
printf(" Magic : %08x\n", sb->md_magic);
printf(" Version : %d.%02d.%02d\n",
@@ -187,11 +190,11 @@ static void examine_super0(struct supertype *st, char *homehost)
printf("Working Devices : %d\n", sb->working_disks);
printf(" Failed Devices : %d\n", sb->failed_disks);
printf(" Spare Devices : %d\n", sb->spare_disks);
- if (calc_sb0_csum(sb) == sb->sb_csum)
+ if (expected_csum == sb->sb_csum)
printf(" Checksum : %x - correct\n", sb->sb_csum);
else
printf(" Checksum : %x - expected %lx\n",
- sb->sb_csum, calc_sb0_csum(sb));
+ sb->sb_csum, expected_csum);
printf(" Events : %llu\n",
((unsigned long long)sb->events_hi << 32) + sb->events_lo);
printf("\n");
@@ -1212,7 +1215,8 @@ static int locate_bitmap0(struct supertype *st, int fd, int node_num)
offset += MD_SB_BYTES;
- lseek64(fd, offset, 0);
+ if (lseek64(fd, offset, 0) < 0)
+ return -1;
return 0;
}
--
2.41.0

View File

@ -0,0 +1,67 @@
From eb9834599c8c9764bb3e711b6f291b10797eff27 Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Fri, 26 Jul 2024 15:14:13 +0800
Subject: [PATCH 147/201] mdadm/super1: fix coverity issue CHECKED_RETURN
It needs to check return value when functions return value.
Signed-off-by: Xiao Ni <xni@redhat.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
super1.c | 20 ++++++++++++++++----
1 file changed, 16 insertions(+), 4 deletions(-)
diff --git a/super1.c b/super1.c
index 81d29a65..4e4c7bfd 100644
--- a/super1.c
+++ b/super1.c
@@ -260,7 +260,10 @@ static int aread(struct align_fd *afd, void *buf, int len)
n = read(afd->fd, b, iosize);
if (n <= 0)
return n;
- lseek(afd->fd, len - n, 1);
+ if (lseek(afd->fd, len - n, 1) < 0) {
+ pr_err("lseek fails\n");
+ return -1;
+ }
if (n > len)
n = len;
memcpy(buf, b, n);
@@ -294,14 +297,20 @@ static int awrite(struct align_fd *afd, void *buf, int len)
n = read(afd->fd, b, iosize);
if (n <= 0)
return n;
- lseek(afd->fd, -n, 1);
+ if (lseek(afd->fd, -n, 1) < 0) {
+ pr_err("lseek fails\n");
+ return -1;
+ }
}
memcpy(b, buf, len);
n = write(afd->fd, b, iosize);
if (n <= 0)
return n;
- lseek(afd->fd, len - n, 1);
+ if (lseek(afd->fd, len - n, 1) < 0) {
+ pr_err("lseek fails\n");
+ return -1;
+ }
return len;
}
@@ -2667,7 +2676,10 @@ static int locate_bitmap1(struct supertype *st, int fd, int node_num)
}
if (mustfree)
free(sb);
- lseek64(fd, offset<<9, 0);
+ if (lseek64(fd, offset<<9, 0) < 0) {
+ pr_err("lseek fails\n");
+ ret = -1;
+ }
return ret;
}
--
2.41.0

View File

@ -0,0 +1,29 @@
From 7904dc1c576a742c601c40dab4d0a6e562c4d00c Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Fri, 26 Jul 2024 15:14:14 +0800
Subject: [PATCH 148/201] mdadm/super1: fix coverity issue DEADCODE
optimal_space is at most 2046. So space can't be larger than UINT16_MAX.
Signed-off-by: Xiao Ni <xni@redhat.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
super1.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/super1.c b/super1.c
index 4e4c7bfd..24bc1026 100644
--- a/super1.c
+++ b/super1.c
@@ -1466,8 +1466,6 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
__le32_to_cpu(sb->chunksize));
if (space > optimal_space)
space = optimal_space;
- if (space > UINT16_MAX)
- space = UINT16_MAX;
}
sb->ppl.offset = __cpu_to_le16(offset);
--
2.41.0

View File

@ -0,0 +1,46 @@
From 38f712dba339bb9bd6a73cc7219d217871e7f27a Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Fri, 26 Jul 2024 15:14:15 +0800
Subject: [PATCH 149/201] mdadm/super1: fix coverity issue EVALUATION_ORDER
Fix evaluation order problems in super1.c
Signed-off-by: Xiao Ni <xni@redhat.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
super1.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/super1.c b/super1.c
index 24bc1026..243eeb1a 100644
--- a/super1.c
+++ b/super1.c
@@ -340,6 +340,9 @@ static void examine_super1(struct supertype *st, char *homehost)
unsigned long long sb_offset;
struct mdinfo info;
int inconsistent = 0;
+ unsigned int expected_csum = 0;
+
+ expected_csum = calc_sb_1_csum(sb);
printf(" Magic : %08x\n", __le32_to_cpu(sb->magic));
printf(" Version : 1");
@@ -507,13 +510,13 @@ static void examine_super1(struct supertype *st, char *homehost)
printf("\n");
}
- if (calc_sb_1_csum(sb) == sb->sb_csum)
+ if (expected_csum == sb->sb_csum)
printf(" Checksum : %x - correct\n",
__le32_to_cpu(sb->sb_csum));
else
printf(" Checksum : %x - expected %x\n",
__le32_to_cpu(sb->sb_csum),
- __le32_to_cpu(calc_sb_1_csum(sb)));
+ __le32_to_cpu(expected_csum));
printf(" Events : %llu\n",
(unsigned long long)__le64_to_cpu(sb->events));
printf("\n");
--
2.41.0

View File

@ -0,0 +1,41 @@
From ae2308ddf38b8f24a2b5e8e14e31153dfe608239 Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Fri, 26 Jul 2024 15:14:16 +0800
Subject: [PATCH 150/201] mdadm/super1: fix coverity issue RESOURCE_LEAK
Fix resource leak problems in super1.c
Signed-off-by: Xiao Ni <xni@redhat.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
super1.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/super1.c b/super1.c
index 243eeb1a..9c9c7dd1 100644
--- a/super1.c
+++ b/super1.c
@@ -923,10 +923,12 @@ static int examine_badblocks_super1(struct supertype *st, int fd, char *devname)
offset <<= 9;
if (lseek64(fd, offset, 0) < 0) {
pr_err("Cannot seek to bad-blocks list\n");
+ free(bbl);
return 1;
}
if (read(fd, bbl, size) != size) {
pr_err("Cannot read bad-blocks list\n");
+ free(bbl);
return 1;
}
/* 64bits per entry. 10 bits is block-count, 54 bits is block
@@ -947,6 +949,7 @@ static int examine_badblocks_super1(struct supertype *st, int fd, char *devname)
printf("%20llu for %d sectors\n", sector, count);
}
+ free(bbl);
return 0;
}
--
2.41.0

View File

@ -0,0 +1,66 @@
From 44c2a293260952fbb14db23d1ad07e6066641e0a Mon Sep 17 00:00:00 2001
From: Anna Sztukowska <anna.sztukowska@intel.com>
Date: Thu, 11 Jul 2024 14:31:57 +0200
Subject: [PATCH 151/201] policy.c: Fix check_return issue in Write_rules()
Refactor Write_rules() in policy.c to eliminate check_return issue found
by SAST analysis. Create udev rules file directly using rule_name
instead of creating temporary file and renaming it.
Signed-off-by: Anna Sztukowska <anna.sztukowska@intel.com>
---
policy.c | 25 +++++++++----------------
1 file changed, 9 insertions(+), 16 deletions(-)
diff --git a/policy.c b/policy.c
index dfaafdc0..4d4b248d 100644
--- a/policy.c
+++ b/policy.c
@@ -969,19 +969,13 @@ int generate_entries(int fd)
*/
int Write_rules(char *rule_name)
{
- int fd;
- char udev_rule_file[PATH_MAX];
+ int fd = fileno(stdout);
- if (rule_name) {
- strncpy(udev_rule_file, rule_name, sizeof(udev_rule_file) - 6);
- udev_rule_file[sizeof(udev_rule_file) - 6] = '\0';
- strcat(udev_rule_file, ".temp");
- fd = creat(udev_rule_file,
- S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
- if (fd == -1)
- return 1;
- } else
- fd = 1;
+ if (rule_name)
+ fd = creat(rule_name, 0644);
+
+ if (!is_fd_valid(fd))
+ return 1;
/* write static invocation */
if (write(fd, udev_template_start, sizeof(udev_template_start) - 1) !=
@@ -993,15 +987,14 @@ int Write_rules(char *rule_name)
goto abort;
fsync(fd);
- if (rule_name) {
+ if (rule_name)
close(fd);
- rename(udev_rule_file, rule_name);
- }
+
return 0;
abort:
if (rule_name) {
close(fd);
- unlink(udev_rule_file);
+ unlink(rule_name);
}
return 1;
}
--
2.41.0

View File

@ -0,0 +1,40 @@
From 483ff037f1036f5f604e085cf76097a87e2be348 Mon Sep 17 00:00:00 2001
From: Anna Sztukowska <anna.sztukowska@intel.com>
Date: Wed, 24 Jul 2024 11:46:57 +0200
Subject: [PATCH 152/201] super-gpt.c: Fix check_return issue in load_gpt()
Fix check_return issue in load_gpt() reported by SAST analysis in
super-gpt.c.
Signed-off-by: Anna Sztukowska <anna.sztukowska@intel.com>
---
super-gpt.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/super-gpt.c b/super-gpt.c
index a1e9aa9d..ec3cf53f 100644
--- a/super-gpt.c
+++ b/super-gpt.c
@@ -105,7 +105,8 @@ static int load_gpt(struct supertype *st, int fd, char *devname)
return 1;
}
/* Set offset to second block (GPT header) */
- lseek(fd, sector_size, SEEK_SET);
+ if (lseek(fd, sector_size, SEEK_SET) == -1L)
+ goto no_read;
/* Seem to have GPT, load the header */
gpt_head = (struct GPT*)(super+1);
if (read(fd, gpt_head, sizeof(*gpt_head)) != sizeof(*gpt_head))
@@ -118,7 +119,8 @@ static int load_gpt(struct supertype *st, int fd, char *devname)
to_read = __le32_to_cpu(gpt_head->part_cnt) * sizeof(struct GPT_part_entry);
to_read = ((to_read+511)/512) * 512;
/* Set offset to third block (GPT entries) */
- lseek(fd, sector_size*2, SEEK_SET);
+ if (lseek(fd, sector_size * 2, SEEK_SET) == -1L)
+ goto no_read;
if (read(fd, gpt_head+1, to_read) != to_read)
goto no_read;
--
2.41.0

View File

@ -0,0 +1,46 @@
From 734de8b02022bf3b7a5f2111f5314a87ddebcc83 Mon Sep 17 00:00:00 2001
From: Kinga Stefaniuk <kinga.stefaniuk@intel.com>
Date: Tue, 6 Aug 2024 11:14:02 +0200
Subject: [PATCH 153/201] super-intel: fix compilation error
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Fix compilation error:
super-intel.c: In function end_migration:
super-intel.c:4360:29: error: writing 2 bytes into a region
of size 0 [-Werror=stringop-overflow=]
4360 | dev->vol.migr_state = 0;
| ~~~~~~~~~~~~~~~~~~~~^~~
cc1: note: destination object is likely at address zero
cc1: all warnings being treated as errors
make: *** [Makefile:232: super-intel.o] Error 1
reported, when GCC 14 is used. Return when dev is NULL, to avoid it.
Signed-off-by: Kinga Stefaniuk <kinga.stefaniuk@intel.com>
---
super-intel.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/super-intel.c b/super-intel.c
index ab9b5d3f..f6745e10 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -4330,6 +4330,12 @@ static void migrate(struct imsm_dev *dev, struct intel_super *super,
static void end_migration(struct imsm_dev *dev, struct intel_super *super,
__u8 map_state)
{
+ /* To avoid compilation error, saying dev can't be NULL when
+ * migr_state is assigned.
+ */
+ if (dev == NULL)
+ return;
+
struct imsm_map *map = get_imsm_map(dev, MAP_0);
struct imsm_map *prev = get_imsm_map(dev, dev->vol.migr_state == 0 ?
MAP_0 : MAP_1);
--
2.41.0

View File

@ -0,0 +1,92 @@
From 125217e0903ab0eb574d20c698c49b04e3b1a99c Mon Sep 17 00:00:00 2001
From: Kinga Stefaniuk <kinga.stefaniuk@intel.com>
Date: Wed, 31 Jul 2024 15:06:42 +0200
Subject: [PATCH 154/201] super-intel: add define for migr_state
Represent migr_state with the define, which helps in code readability.
Add new values for Normal and Migration states.
Signed-off-by: Kinga Stefaniuk <kinga.stefaniuk@intel.com>
---
super-intel.c | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/super-intel.c b/super-intel.c
index f6745e10..354c292a 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -194,6 +194,8 @@ ASSERT_SIZE(imsm_map, 52)
struct imsm_vol {
__u32 curr_migr_unit_lo;
__u32 checkpoint_id; /* id to access curr_migr_unit */
+#define MIGR_STATE_NORMAL 0
+#define MIGR_STATE_MIGRATING 1
__u8 migr_state; /* Normal or Migrating */
#define MIGR_INIT 0
#define MIGR_REBUILD 1
@@ -4303,7 +4305,7 @@ static void migrate(struct imsm_dev *dev, struct intel_super *super,
struct imsm_map *dest;
struct imsm_map *src = get_imsm_map(dev, MAP_0);
- dev->vol.migr_state = 1;
+ dev->vol.migr_state = MIGR_STATE_MIGRATING;
set_migr_type(dev, migr_type);
set_vol_curr_migr_unit(dev, 0);
dest = get_imsm_map(dev, MAP_1);
@@ -4337,7 +4339,7 @@ static void end_migration(struct imsm_dev *dev, struct intel_super *super,
return;
struct imsm_map *map = get_imsm_map(dev, MAP_0);
- struct imsm_map *prev = get_imsm_map(dev, dev->vol.migr_state == 0 ?
+ struct imsm_map *prev = get_imsm_map(dev, dev->vol.migr_state == MIGR_STATE_NORMAL ?
MAP_0 : MAP_1);
int i, j;
@@ -4369,7 +4371,7 @@ static void end_migration(struct imsm_dev *dev, struct intel_super *super,
map_state = imsm_check_degraded(super, dev, failed, MAP_0);
}
- dev->vol.migr_state = 0;
+ dev->vol.migr_state = MIGR_STATE_NORMAL;
set_migr_type(dev, 0);
set_vol_curr_migr_unit(dev, 0);
map->map_state = map_state;
@@ -4449,7 +4451,7 @@ int check_mpb_migr_compatibility(struct intel_super *super)
for (i = 0; i < super->anchor->num_raid_devs; i++) {
struct imsm_dev *dev_iter = __get_imsm_dev(super->anchor, i);
- if (dev_iter->vol.migr_state == 1 &&
+ if (dev_iter->vol.migr_state == MIGR_STATE_MIGRATING &&
dev_iter->vol.migr_type == MIGR_GEN_MIGR) {
/* This device is migrating */
map0 = get_imsm_map(dev_iter, MAP_0);
@@ -5654,7 +5656,7 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info,
set_imsm_dev_size(dev, array_blocks);
dev->status = (DEV_READ_COALESCING | DEV_WRITE_COALESCING);
vol = &dev->vol;
- vol->migr_state = 0;
+ vol->migr_state = MIGR_STATE_NORMAL;
set_migr_type(dev, MIGR_INIT);
vol->dirty = !info->state;
set_vol_curr_migr_unit(dev, 0);
@@ -8631,7 +8633,7 @@ static void imsm_progress_container_reshape(struct intel_super *super)
copy_map_size = sizeof_imsm_map(map);
prev_num_members = map->num_members;
map->num_members = prev_disks;
- dev->vol.migr_state = 1;
+ dev->vol.migr_state = MIGR_STATE_MIGRATING;
set_vol_curr_migr_unit(dev, 0);
set_migr_type(dev, MIGR_GEN_MIGR);
for (i = prev_num_members;
@@ -9863,7 +9865,7 @@ static int apply_reshape_container_disks_update(struct imsm_update_reshape *u,
dprintf("imsm: modifying subdev: %i\n",
id->index);
devices_to_reshape--;
- newdev->vol.migr_state = 1;
+ newdev->vol.migr_state = MIGR_STATE_MIGRATING;
set_vol_curr_migr_unit(newdev, 0);
set_migr_type(newdev, MIGR_GEN_MIGR);
newmap->num_members = u->new_raid_disks;
--
2.41.0

View File

@ -0,0 +1,52 @@
From c653054b322a03e8912ac05accc87b6a1ba8daab Mon Sep 17 00:00:00 2001
From: Kinga Stefaniuk <kinga.stefaniuk@intel.com>
Date: Fri, 26 Apr 2024 08:33:00 +0200
Subject: [PATCH 156/201] Grow_reshape: set only component_size for size grow
Component_size couldn't be set using ioctl when new drive size is big
(e.g. 5TB). Command value is bigger than 32 bits and error is reported
- it is known ioctl limitation. Remove updating array properties using
ioctl, use sysfs instead. Sysfs was introduced in 3.10, so now it is old
enough to be safely used. Array_size in sysfs should be set for every
size change for external metadata, when grow is performed without
errors.
Signed-off-by: Kinga Stefaniuk <kinga.stefaniuk@intel.com>
---
Grow.c | 19 +++++++------------
1 file changed, 7 insertions(+), 12 deletions(-)
diff --git a/Grow.c b/Grow.c
index a5f9027d..5810b128 100644
--- a/Grow.c
+++ b/Grow.c
@@ -2149,19 +2149,14 @@ int Grow_reshape(char *devname, int fd,
if (s->size == MAX_SIZE)
s->size = 0;
array.size = s->size;
- if (s->size & ~INT32_MAX) {
- /* got truncated to 32bit, write to
- * component_size instead
- */
- rv = sysfs_set_num(sra, NULL, "component_size", s->size);
- } else {
- rv = md_set_array_info(fd, &array);
+ rv = sysfs_set_num(sra, NULL, "component_size", s->size);
- /* manage array size when it is managed externally
- */
- if ((rv == 0) && st->ss->external)
- rv = set_array_size(st, sra, sra->text_version);
- }
+ /*
+ * For native metadata, md/array_size is updated by kernel,
+ * for external management update it here.
+ */
+ if (st->ss->external && rv == MDADM_STATUS_SUCCESS)
+ rv = set_array_size(st, sra, sra->text_version);
if (raid0_takeover) {
/* do not recync non-existing parity,
--
2.41.0

View File

@ -0,0 +1,43 @@
From 4b041873ff5556882bc6f17ac3de00c72eebcc4f Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Tue, 6 Aug 2024 16:11:18 +0200
Subject: [PATCH 157/201] mdstat: fix list detach issues
Move ent = ent->next; to while. It was outside the loop so if there
are more than 2 elements and we are looking for 3rd element it causes
infinite loop..
Fix el->next zeroing. It causes segfault in mdstat_free(). Theses
issues were not visible in my testing because I had only 2 MD devices.
Fixes: 4b3644ab4ce6 ("mdstat: Rework mdstat external arrays handling")
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
mdstat.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/mdstat.c b/mdstat.c
index a971a957..29e78362 100644
--- a/mdstat.c
+++ b/mdstat.c
@@ -123,13 +123,15 @@ static void mdstat_ent_list_detach_element(struct mdstat_ent **list_head, struct
ent->next = el->next;
break;
}
+
+ ent = ent->next;
}
- ent = ent->next;
}
+ /* Guard if not found or list is empty - not allowed */
assert(ent);
- ent->next = NULL;
+ el->next = NULL;
}
void free_mdstat(struct mdstat_ent *ms)
--
2.41.0

View File

@ -0,0 +1,28 @@
From 1f49ecbf3d2ab8003d37eb1c0454c5cfbe335ee5 Mon Sep 17 00:00:00 2001
From: Nicolas Roeser <nicolas.roeser@alumni.uni-ulm.de>
Date: Sun, 4 Aug 2024 14:34:44 +0200
Subject: [PATCH 158/201] md.4: replace wrong word
There is a wrong word in the md(4) man page, this commit corrects it.
Signed-off-by: Nicolas Roeser <nicolas.roeser@alumni.uni-ulm.de>
---
md.4 | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/md.4 b/md.4
index 7a0bc7e6..7aef1577 100644
--- a/md.4
+++ b/md.4
@@ -224,7 +224,7 @@ option. If you use this option to
while running a newer kernel, the array will NOT assemble, but the
metadata will be update so that it can be assembled on an older kernel.
-No that setting the layout to "unspecified" removes protections against
+Note that setting the layout to "unspecified" removes protections against
this bug, and you must be sure that the kernel you use matches the
layout of the array.
--
2.41.0

View File

@ -0,0 +1,134 @@
From ea076e7c4bc8b3122ad9d7131098c4b85902a299 Mon Sep 17 00:00:00 2001
From: Nigel Croxon <ncroxon@redhat.com>
Date: Wed, 7 Aug 2024 11:33:23 -0400
Subject: [PATCH 159/201] mdadm: util.c fix coverity issues
Fixing the following coding errors the coverity tools found:
* Event check_return: Calling "open" without checking return value
* Event check_return: Calling "lseek(fd, sector_size, 0)" without
checking return value.
* Event leaked_handle: Handle variable "fd" going out of scope leaks
the handle.
* Event leaked_storage: Variable "dir" going out of scope leaks the
storage it points to.
* Event fixed_size_dest: You might overrun the 32-character fixed-size
string "st->devnm" by copying "_devnm" without checking the length.
* Event fixed_size_dest: You might overrun the 32-character fixed-size
string "container" by copying "dev" without checking the length.
Signed-off-by: Nigel Croxon <ncroxon@redhat.com>
---
util.c | 41 +++++++++++++++++++++++++----------------
1 file changed, 25 insertions(+), 16 deletions(-)
diff --git a/util.c b/util.c
index 83d42833..1cee0feb 100644
--- a/util.c
+++ b/util.c
@@ -1253,7 +1253,7 @@ struct supertype *super_by_fd(int fd, char **subarrayp)
*subarray++ = '\0';
subarray = xstrdup(subarray);
}
- strcpy(container, dev);
+ snprintf(container, sizeof(container), "%s", dev);
sysfs_free(sra);
sra = sysfs_read(-1, container, GET_VERSION);
if (sra && sra->text_version[0])
@@ -1430,7 +1430,8 @@ static int get_gpt_last_partition_end(int fd, unsigned long long *endofpart)
/* skip protective MBR */
if (!get_dev_sector_size(fd, NULL, &sector_size))
return 0;
- lseek(fd, sector_size, SEEK_SET);
+ if (lseek(fd, sector_size, SEEK_SET) == -1L)
+ return 0;
/* read GPT header */
if (read(fd, &gpt, 512) != 512)
return 0;
@@ -1451,7 +1452,8 @@ static int get_gpt_last_partition_end(int fd, unsigned long long *endofpart)
part = (struct GPT_part_entry *)buf;
/* set offset to third block (GPT entries) */
- lseek(fd, sector_size*2, SEEK_SET);
+ if (lseek(fd, sector_size*2, SEEK_SET) == -1L)
+ return 0;
for (part_nr = 0; part_nr < all_partitions; part_nr++) {
/* read partition entry */
if (read(fd, buf, entry_size) != (ssize_t)entry_size)
@@ -1486,7 +1488,8 @@ static int get_last_partition_end(int fd, unsigned long long *endofpart)
BUILD_BUG_ON(sizeof(boot_sect) != 512);
/* read MBR */
- lseek(fd, 0, 0);
+ if (lseek(fd, 0, 0) == -1L)
+ goto abort;
if (read(fd, &boot_sect, 512) != 512)
goto abort;
@@ -1715,7 +1718,7 @@ int open_subarray(char *dev, char *subarray, struct supertype *st, int quiet)
dev);
goto close_fd;
}
- strcpy(st->devnm, _devnm);
+ snprintf(st->devnm, sizeof(st->devnm), "%s", _devnm);
mdi = sysfs_read(fd, st->devnm, GET_VERSION|GET_LEVEL);
if (!mdi) {
@@ -2293,14 +2296,16 @@ void manage_fork_fds(int close_all)
{
DIR *dir;
struct dirent *dirent;
+ int fd = open("/dev/null", O_RDWR);
- close(0);
- open("/dev/null", O_RDWR);
-
+ if (is_fd_valid(fd)) {
+ dup2(fd, 0);
#ifndef DEBUG
dup2(0, 1);
dup2(0, 2);
+ close_fd(&fd);
#endif
+ }
if (close_all == 0)
return;
@@ -2319,8 +2324,10 @@ void manage_fork_fds(int close_all)
fd = strtol(dirent->d_name, NULL, 10);
if (fd > 2)
- close(fd);
+ close_fd(&fd);
}
+ closedir(dir);
+ return;
}
/* In a systemd/udev world, it is best to get systemd to
@@ -2367,13 +2374,15 @@ void reopen_mddev(int mdfd)
/* Re-open without any O_EXCL, but keep
* the same fd
*/
- char *devnm;
- int fd;
- devnm = fd2devnm(mdfd);
- close(mdfd);
- fd = open_dev(devnm);
- if (fd >= 0 && fd != mdfd)
- dup2(fd, mdfd);
+ char *devnm = fd2devnm(mdfd);
+ int fd = open_dev(devnm);
+
+ if (!is_fd_valid(fd))
+ return;
+
+ dup2(fd, mdfd);
+
+ close_fd(&fd);
}
static struct cmap_hooks *cmap_hooks = NULL;
--
2.41.0

View File

@ -0,0 +1,56 @@
From 18eaf6c5206a37ad059c930d1ee2dbc9b7297513 Mon Sep 17 00:00:00 2001
From: Nigel Croxon <ncroxon@redhat.com>
Date: Thu, 18 Jul 2024 13:05:57 -0400
Subject: [PATCH 160/201] mdadm: sysfs.c fix coverity issues
Fixing the following coding errors the coverity tools found:
* Event fixed_size_dest: You might overrun the 32-character
fixed-size string "mdi->sys_name" by copying "devnm" without
checking the length
* Event fixed_size_dest: You might overrun the 50-character
fixed-size string "sra->text_version" by copying "buf + 9"
without checking the length.
* Event string_overflow: You might overrun the 32-character
destination string "dev->sys_name" by writing 256 characters
from "de->d_name".
Signed-off-by: Nigel Croxon <ncroxon@redhat.com>
---
sysfs.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/sysfs.c b/sysfs.c
index 20fe1e9e..b3c8b10d 100644
--- a/sysfs.c
+++ b/sysfs.c
@@ -139,7 +139,7 @@ int sysfs_init(struct mdinfo *mdi, int fd, char *devnm)
goto out;
if (!S_ISDIR(stb.st_mode))
goto out;
- strcpy(mdi->sys_name, devnm);
+ strncpy(mdi->sys_name, devnm, sizeof(mdi->sys_name) - 1);
retval = 0;
out:
@@ -179,6 +179,7 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options)
sra->array.major_version = -1;
sra->array.minor_version = -2;
strcpy(sra->text_version, buf+9);
+ sra->text_version[sizeof(sra->text_version) - 1] = '\0';
} else {
sscanf(buf, "%d.%d",
&sra->array.major_version,
@@ -340,6 +341,7 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options)
}
strcpy(dev->sys_name, de->d_name);
+ dev->sys_name[sizeof(dev->sys_name) - 1] = '\0';
dev->disk.raid_disk = strtoul(buf, &ep, 10);
if (*ep) dev->disk.raid_disk = -1;
--
2.41.0

View File

@ -0,0 +1,405 @@
From 91845dab52c3f9ab56710338c0c38e9c1473df1d Mon Sep 17 00:00:00 2001
From: Blazej Kucman <blazej.kucman@intel.com>
Date: Thu, 11 Jul 2024 18:45:41 +0200
Subject: [PATCH 161/201] imsm: add read OROM form ACPI UEFI tables
OROM - IMSM hardware capabilities
EFI vars depends on userspace, they need to be mounted to be accessible.
Sporadic problems have been observed with availability at an early
assemble stage. It is not possible to fully synchronize EFI vars mounts
with udev rules processing.
For the reason above, read of IMSM OROM from ACPI tables as secondary
option is added. This method will be used for SATA and VMD family
controllers.
ACPI tables are generated by sysfs, earlier in the boot process, before
the stage of RAID assembly. The way of loading OROM via EFI vars is
retained, ACPI tables will be a backup way.
Two paths will be maintained, because IMSM hardware capabilities are
necessary for RAID assembly during booting, so access to them must be
provided.
Signed-off-by: Blazej Kucman <blazej.kucman@intel.com>
---
platform-intel.c | 324 +++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 299 insertions(+), 25 deletions(-)
diff --git a/platform-intel.c b/platform-intel.c
index d6a53533..9705c925 100644
--- a/platform-intel.c
+++ b/platform-intel.c
@@ -577,6 +577,9 @@ static const struct imsm_orom *find_imsm_hba_orom(struct sys_dev *hba)
#define SYS_EFI_VAR_PATH "/sys/firmware/efi/vars"
#define SYS_EFIVARS_PATH "/sys/firmware/efi/efivars"
+#define ACPI_TABLES_PATH "/sys/firmware/acpi/tables/"
+#define ACPI_UEFI_TABLE_BASE_NAME "UEFI"
+#define ACPI_UEFI_DATA_OFFSET 52
#define SCU_PROP "RstScuV"
#define AHCI_PROP "RstSataV"
#define AHCI_SSATA_PROP "RstsSatV"
@@ -584,10 +587,73 @@ static const struct imsm_orom *find_imsm_hba_orom(struct sys_dev *hba)
#define VROC_VMD_PROP "RstUefiV"
#define RST_VMD_PROP "RstVmdV"
-#define VENDOR_GUID \
+#define PCI_CLASS_RAID_CNTRL 0x010400
+
+/* GUID length in Bytes */
+#define GUID_LENGTH 16
+
+/* GUID entry in 'UEFI' for Sata controller. */
+#define RST_SATA_V_GUID \
+ EFI_GUID(0xe4dd92e0, 0xac7d, 0x11df, 0x94, 0xe2, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66)
+
+/* GUID entry in 'UEFI' for sSata controller. */
+#define RST_SSATA_V_GUID \
+ EFI_GUID(0xb002be42, 0x901d, 0x4018, 0xb4, 0x1e, 0xd7, 0x04, 0xab, 0x3a, 0x0f, 0x15)
+
+/* GUID entry in 'UEFI' for tSata controller. */
+#define RST_TSATA_V_GUID \
+ EFI_GUID(0x101ce8f1, 0xb873, 0x4362, 0xa9, 0x76, 0xb5, 0x54, 0x31, 0x74, 0x52, 0x7e)
+
+/* GUID entry in 'UEFI' for Intel(R) VROC VMD. */
+#define RST_UEFI_V_GUID \
+ EFI_GUID(0x4bf2da96, 0xde6e, 0x4d8a, 0xa8, 0x8b, 0xb3, 0xd, 0x33, 0xf6, 0xf, 0x3e)
+
+/**
+ * GUID entry in 'UEFI' for Intel(R) RST VMD.
+ * Currently is the same like in 'UEFI' for Sata controller.
+ */
+#define RST_VMD_V_GUID RST_SATA_V_GUID
+
+/* GUID of intel RST vendor EFI var. */
+#define INTEL_RST_VENDOR_GUID \
EFI_GUID(0x193dfefa, 0xa445, 0x4302, 0x99, 0xd8, 0xef, 0x3a, 0xad, 0x1a, 0x04, 0xc6)
-#define PCI_CLASS_RAID_CNTRL 0x010400
+/*
+ * Unified Extensible Firmware Interface (UEFI) Specification Release 2.10
+ * UEFI ACPI DATA TABLE, Table O.1
+ */
+typedef struct uefi_acpi_table {
+ char signature[4];
+ __u32 length;
+ __u8 revision;
+ __u8 checksum;
+ char oemid[6];
+ /* controller name */
+ char oem_table_id[8];
+ __u32 oem_revision;
+ __u32 creator_id;
+ __u32 creator_revision;
+ /* controller GUID */
+ struct efi_guid identifier;
+ /* OROM data offeset */
+ __u16 dataOffset;
+} uefi_acpi_table_t;
+
+typedef struct uefi_acpi_table_with_orom {
+ struct uefi_acpi_table table;
+ struct imsm_orom orom;
+} uefi_acpi_table_with_orom_t;
+
+/* imsm_orom_id - Identifier used to match imsm efi var or acpi table
+ * @name: name of the UEFI property, it is part of efivar name or ACPI table oem_table_id
+ * @guid: acpi table guid identifier
+ *
+ * vendor guid (second part of evifar name) is not added here because it is cost.
+ */
+typedef struct imsm_orom_id {
+ char *name;
+ struct efi_guid guid;
+} imsm_orom_id_t;
static int read_efi_var(void *buffer, ssize_t buf_size,
const char *variable_name, struct efi_guid guid)
@@ -669,14 +735,238 @@ static int read_efi_variable(void *buffer, ssize_t buf_size,
return 0;
}
+/**
+ * is_efi_guid_equal() - check if EFI guids are equal.
+ * @guid: EFI guid.
+ * @guid1: EFI guid to compare.
+ *
+ * Return: %true if guid are equal, %false otherwise.
+ */
+static inline bool is_efi_guid_equal(struct efi_guid guid, struct efi_guid guid1)
+{
+ if (memcmp(guid.b, guid1.b, GUID_LENGTH) == 0)
+ return true;
+ return false;
+}
+
+/**
+ * acpi_any_imsm_orom_id_matching() - match ACPI table with any of given imsm_orom_id.
+ * @imsm_orom_ids: array of IMSM OROM Identifiers.
+ * @imsm_orom_ids_number: number of IMSM OROM Identifiers.
+ * @table: struct with read ACPI UEFI table.
+ *
+ * Check if read UEFI table contains requested OROM id.
+ * EFI GUID and controller name are compared with expected.
+ *
+ * Return: %true if length is proper table, %false otherwise.
+ */
+bool acpi_any_imsm_orom_id_matching(imsm_orom_id_t *imsm_orom_ids, int imsm_orom_ids_number,
+ struct uefi_acpi_table table)
+{
+ int index;
+
+ for (index = 0; index < imsm_orom_ids_number; index++)
+ if (strncmp(table.oem_table_id, imsm_orom_ids[index].name,
+ strlen(imsm_orom_ids[index].name)) == 0 &&
+ is_efi_guid_equal(table.identifier,
+ imsm_orom_ids[index].guid) == true)
+ return true;
+ return false;
+}
+
+/**
+ * read_uefi_acpi_orom_data() - read OROM data from UEFI ACPI table.
+ * @fd: file descriptor.
+ * @uefi_table: struct to fill out.
+ *
+ * Read OROM from ACPI UEFI table under given file descriptor.
+ * Table must have the appropriate OROM data, which should be confirmed before call this function.
+ * In case of success, &orom in structure in &uefi_table will be filled..
+ *
+ * Return: %MDADM_STATUS_SUCCESS on success, %MDADM_STATUS_ERROR otherwise.
+ */
+mdadm_status_t
+read_uefi_acpi_orom_data(int fd, uefi_acpi_table_with_orom_t *uefi_table)
+{
+ assert(is_fd_valid(fd));
+
+ if (lseek(fd, uefi_table->table.dataOffset, 0) == -1L)
+ return MDADM_STATUS_ERROR;
+
+ if (read(fd, &uefi_table->orom, sizeof(uefi_table->orom)) == -1)
+ return MDADM_STATUS_ERROR;
+
+ return MDADM_STATUS_SUCCESS;
+}
+
+/**
+ * verify_uefi_acpi_table_length() - verify if ACPI UEFI table have correct length with focus at
+ * OROM.
+ * @table: struct with UEFI table.
+ *
+ * Verify if ACPI UEFI table have correct length with focus at OROM. Make sure that the file is
+ * correct and contains the appropriate length data based on the length of the OROM.
+ *
+ * Return: %true if length is correct, %false otherwise.
+ */
+bool verify_uefi_acpi_table_length(struct uefi_acpi_table table)
+{
+ if (table.length < ACPI_UEFI_DATA_OFFSET)
+ return false;
+
+ if (table.length - table.dataOffset != sizeof(struct imsm_orom))
+ return false;
+ return true;
+}
+
+/**
+ * find_orom_in_acpi_uefi_tables() - find OROM in UEFI ACPI tables based on requested OROM ids.
+ * @imsm_orom_ids: array of IMSM OROM Identifiers.
+ * @imsm_orom_ids_number: number of IMSM OROM Identifiers.
+ * @orom: OROM struct buffer to fill out.
+ *
+ * Find OROM in UEFI ACPI tables provided by Intel, based on requested controllers.
+ * The first one to be matched, will be used.
+ * If found, the buffer with the OROM structure will be filled.
+ *
+ * Return: %MDADM_STATUS_SUCCESS on success, %MDADM_STATUS_ERROR otherwise.
+ */
+mdadm_status_t
+find_orom_in_acpi_uefi_tables(imsm_orom_id_t *imsm_orom_ids, int imsm_orom_ids_number,
+ struct imsm_orom *orom)
+{
+ mdadm_status_t status = MDADM_STATUS_ERROR;
+ uefi_acpi_table_with_orom_t uefi_table;
+ char path[PATH_MAX];
+ struct dirent *ent;
+ int fd = -1;
+ DIR *dir;
+
+ dir = opendir(ACPI_TABLES_PATH);
+ if (!dir)
+ return MDADM_STATUS_ERROR;
+
+ for (ent = readdir(dir); ent; ent = readdir(dir)) {
+ close_fd(&fd);
+
+ /* Check if file is a UEFI table */
+ if (strncmp(ent->d_name, ACPI_UEFI_TABLE_BASE_NAME,
+ strlen(ACPI_UEFI_TABLE_BASE_NAME)) != 0)
+ continue;
+
+ snprintf(path, PATH_MAX, "%s/%s", ACPI_TABLES_PATH, ent->d_name);
+
+ fd = open(path, O_RDONLY);
+ if (!is_fd_valid(fd)) {
+ pr_err("Fail to open ACPI UEFI table file. File: %s, Error: %s\n",
+ ent->d_name, strerror(errno));
+ continue;
+ }
+
+ if (read(fd, &uefi_table.table, sizeof(struct uefi_acpi_table)) == -1) {
+ pr_err("Fail to read IMSM OROM from ACPI UEFI table file. File: %s\n",
+ ent->d_name);
+ continue;
+ }
+
+ if (!acpi_any_imsm_orom_id_matching(imsm_orom_ids, imsm_orom_ids_number,
+ uefi_table.table))
+ continue;
+
+ if (!verify_uefi_acpi_table_length(uefi_table.table))
+ continue;
+
+ if (read_uefi_acpi_orom_data(fd, &uefi_table)) {
+ pr_err("Fail to read IMSM OROM from ACPI UEFI table file. File: %s\n",
+ ent->d_name);
+ continue;
+ }
+
+ memcpy(orom, &uefi_table.orom, sizeof(uefi_table.orom));
+ status = MDADM_STATUS_SUCCESS;
+ break;
+ }
+
+ close_fd(&fd);
+ closedir(dir);
+ return status;
+}
+
+/**
+ * find_orom_in_efi_variables() - find first IMSM OROM in EFI vars that matches any imsm_orom_id.
+ * @imsm_orom_ids: array of IMSM OROM Identifiers.
+ * @imsm_orom_ids_number: number of IMSM OROM Identifiers.
+ * @orom: OROM struct buffer to fill out.
+ *
+ * Find IMSM OROM that matches on of imsm_orom_id in EFI variables. The first match is used.
+ * If found, the buffer with the OROM structure is filled.
+ *
+ * Return: %MDADM_STATUS_SUCCESS on success, %MDADM_STATUS_ERROR otherwise.
+ */
+mdadm_status_t
+find_orom_in_efi_variables(imsm_orom_id_t *imsm_orom_ids, int imsm_orom_ids_number,
+ struct imsm_orom *orom)
+{
+ int index;
+
+ for (index = 0; index < imsm_orom_ids_number; index++)
+ if (!read_efi_variable(orom, sizeof(struct imsm_orom), imsm_orom_ids[index].name,
+ INTEL_RST_VENDOR_GUID))
+ return MDADM_STATUS_SUCCESS;
+ return MDADM_STATUS_ERROR;
+}
+
+/**
+ * find_imsm_efi_orom() - find OROM for requested controller.
+ * @orom: buffer for OROM.
+ * @controller_type: requested controller type.
+ *
+ * Based on controller type, function first search in EFI vars then in ACPI UEFI tables.
+ * For each controller there is defined an array of OROM ids from which we can read OROM,
+ * the first one to be matched, will be used.
+ * In case of success, the structure &orom will be filed out.
+ *
+ * Return: %MDADM_STATUS_SUCCESS on success.
+ */
+static mdadm_status_t
+find_imsm_efi_orom(struct imsm_orom *orom, enum sys_dev_type controller_type)
+{
+ static imsm_orom_id_t sata_imsm_orrom_ids[] = {
+ {AHCI_PROP, RST_SATA_V_GUID},
+ {AHCI_SSATA_PROP, RST_SSATA_V_GUID},
+ {AHCI_TSATA_PROP, RST_TSATA_V_GUID},
+ };
+ static imsm_orom_id_t vmd_imsm_orom_ids[] = {
+ {VROC_VMD_PROP, RST_UEFI_V_GUID},
+ {RST_VMD_PROP, RST_VMD_V_GUID},
+ };
+ static imsm_orom_id_t *imsm_orom_ids;
+ int imsm_orom_ids_number;
+
+ switch (controller_type) {
+ case SYS_DEV_SATA:
+ imsm_orom_ids = sata_imsm_orrom_ids;
+ imsm_orom_ids_number = ARRAY_SIZE(sata_imsm_orrom_ids);
+ break;
+ case SYS_DEV_VMD:
+ case SYS_DEV_SATA_VMD:
+ imsm_orom_ids = vmd_imsm_orom_ids;
+ imsm_orom_ids_number = ARRAY_SIZE(vmd_imsm_orom_ids);
+ break;
+ default:
+ return MDADM_STATUS_UNDEF;
+ }
+
+ if (!find_orom_in_efi_variables(imsm_orom_ids, imsm_orom_ids_number, orom))
+ return MDADM_STATUS_SUCCESS;
+
+ return find_orom_in_acpi_uefi_tables(imsm_orom_ids, imsm_orom_ids_number, orom);
+}
+
const struct imsm_orom *find_imsm_efi(struct sys_dev *hba)
{
struct imsm_orom orom;
struct orom_entry *ret;
- static const char * const sata_efivars[] = {AHCI_PROP, AHCI_SSATA_PROP,
- AHCI_TSATA_PROP};
- static const char * const vmd_efivars[] = {VROC_VMD_PROP, RST_VMD_PROP};
- unsigned long i;
if (check_env("IMSM_TEST_AHCI_EFI") || check_env("IMSM_TEST_SCU_EFI"))
return imsm_platform_test(hba);
@@ -687,36 +977,20 @@ const struct imsm_orom *find_imsm_efi(struct sys_dev *hba)
switch (hba->type) {
case SYS_DEV_SAS:
- if (!read_efi_variable(&orom, sizeof(orom), SCU_PROP,
- VENDOR_GUID))
+ if (!read_efi_variable(&orom, sizeof(orom), SCU_PROP, INTEL_RST_VENDOR_GUID))
break;
-
return NULL;
case SYS_DEV_SATA:
if (hba->class != PCI_CLASS_RAID_CNTRL)
return NULL;
- for (i = 0; i < ARRAY_SIZE(sata_efivars); i++) {
- if (!read_efi_variable(&orom, sizeof(orom),
- sata_efivars[i], VENDOR_GUID))
- break;
-
- }
- if (i == ARRAY_SIZE(sata_efivars))
+ if (find_imsm_efi_orom(&orom, hba->type))
return NULL;
-
break;
case SYS_DEV_VMD:
case SYS_DEV_SATA_VMD:
- for (i = 0; i < ARRAY_SIZE(vmd_efivars); i++) {
- if (!read_efi_variable(&orom, sizeof(orom),
- vmd_efivars[i], VENDOR_GUID))
- break;
- }
-
- if (i == ARRAY_SIZE(vmd_efivars))
+ if (find_imsm_efi_orom(&orom, hba->type))
return NULL;
-
break;
default:
return NULL;
--
2.41.0

View File

@ -0,0 +1,146 @@
From 6e793aeace463d7687656f7ac6968300ba106228 Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Thu, 8 Aug 2024 13:07:50 +0200
Subject: [PATCH 162/201] imsm: get bus from VMD driver directory
Enumeration of VMD child devices is started early, kernel is not waiting
for VMD enumeration to finish. It causes that:
/sys/bus/pci/drivers/vmd/{dev}/domain/device link might be not yet ready.
With PCI gen5 devices we can observe that mdadm is failing to start IMSM
raid arrays because of that. In that case, it needs to find bus path
manually.
Look for bus device in VMD driver directory if realpath() failed with
ENOENT.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
platform-intel.c | 88 ++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 77 insertions(+), 11 deletions(-)
diff --git a/platform-intel.c b/platform-intel.c
index 9705c925..d0ef9111 100644
--- a/platform-intel.c
+++ b/platform-intel.c
@@ -105,12 +105,75 @@ static void free_sys_dev(struct sys_dev **list)
}
}
+/**
+ * vmd_find_pci_bus() - look for PCI bus created by VMD.
+ * @vmd_path: path to vmd driver.
+ * @buf: return buffer, must be PATH_MAX.
+ *
+ * Each VMD device represents one domain and each VMD device adds separate PCI bus.
+ * IMSM must know VMD domains, therefore it needs to determine and follow buses.
+ *
+ */
+mdadm_status_t vmd_find_pci_bus(char *vmd_path, char *buf)
+{
+ char tmp[PATH_MAX];
+ struct dirent *ent;
+ DIR *vmd_dir;
+ char *rp_ret;
+
+ snprintf(tmp, PATH_MAX, "%s/domain/device", vmd_path);
+
+ rp_ret = realpath(tmp, buf);
+
+ if (rp_ret)
+ return MDADM_STATUS_SUCCESS;
+
+ if (errno != ENOENT)
+ return MDADM_STATUS_ERROR;
+
+ /*
+ * If it is done early, there is a chance that kernel is still enumerating VMD device but
+ * kernel did enough to start enumerating child devices, {vmd_path}/domain/device link may
+ * not exist yet. We have to look into @vmd_path directory and find it ourselves.
+ */
+
+ vmd_dir = opendir(vmd_path);
+
+ if (!vmd_dir)
+ return MDADM_STATUS_ERROR;
+
+ for (ent = readdir(vmd_dir); ent; ent = readdir(vmd_dir)) {
+ static const char pci[] = "pci";
+
+ /**
+ * Pci bus must have form pciXXXXX:XX, where X is a digit i.e pci10000:00.
+ * We do not check digits here, it is sysfs so it should be safe to check
+ * length and ':' position only.
+ */
+ if (strncmp(ent->d_name, pci, strlen(pci)) != 0)
+ continue;
+
+ if (ent->d_name[8] != ':' || ent->d_name[11] != 0)
+ continue;
+ break;
+ }
+
+ if (!ent) {
+ closedir(vmd_dir);
+ return MDADM_STATUS_ERROR;
+ }
+
+ snprintf(buf, PATH_MAX, "%s/%s", vmd_path, ent->d_name);
+ closedir(vmd_dir);
+ return MDADM_STATUS_SUCCESS;
+}
+
struct sys_dev *find_driver_devices(const char *bus, const char *driver)
{
/* search sysfs for devices driven by 'driver' */
char path[PATH_MAX];
char link[PATH_MAX];
- char *c, *p;
+ char *c;
DIR *driver_dir;
struct dirent *de;
struct sys_dev *head = NULL;
@@ -142,8 +205,9 @@ struct sys_dev *find_driver_devices(const char *bus, const char *driver)
return NULL;
}
for (de = readdir(driver_dir); de; de = readdir(driver_dir)) {
- int n;
int skip = 0;
+ char *p;
+ int n;
/* is 'de' a device? check that the 'subsystem' link exists and
* that its target matches 'bus'
@@ -195,18 +259,20 @@ struct sys_dev *find_driver_devices(const char *bus, const char *driver)
if (devpath_to_ll(path, "class", &class) != 0)
continue;
- /*
- * Each VMD device (domain) adds separate PCI bus, it is better
- * to store path as a path to that bus (easier further
- * determination which NVMe dev is connected to this particular
- * VMD domain).
- */
if (type == SYS_DEV_VMD) {
- sprintf(path, "/sys/bus/%s/drivers/%s/%s/domain/device",
- bus, driver, de->d_name);
+ char vmd_path[PATH_MAX];
+
+ sprintf(vmd_path, "/sys/bus/%s/drivers/%s/%s", bus, driver, de->d_name);
+
+ if (vmd_find_pci_bus(vmd_path, path)) {
+ pr_err("Cannot determine VMD bus for %s\n", vmd_path);
+ continue;
+ }
}
+
p = realpath(path, NULL);
- if (p == NULL) {
+
+ if (!p) {
pr_err("Unable to get real path for '%s'\n", path);
continue;
}
--
2.41.0

View File

@ -0,0 +1,129 @@
From a6392b419f38a0144a03df90371d6890540a55cf Mon Sep 17 00:00:00 2001
From: Mateusz Kusiak <mateusz.kusiak@intel.com>
Date: Tue, 7 May 2024 12:05:43 -0400
Subject: [PATCH 163/201] platform-intel: refactor path_attached_to_hba()
dprintf() call in path_attached_to_hba() is too noisy. Remove the call
and refactor the function. Remove obsolete env variables check.
Signed-off-by: Mateusz Kusiak <mateusz.kusiak@intel.com>
---
platform-intel.c | 31 ++++++++++++++-----------------
platform-intel.h | 2 +-
super-intel.c | 8 ++++----
3 files changed, 19 insertions(+), 22 deletions(-)
diff --git a/platform-intel.c b/platform-intel.c
index d0ef9111..3a86f785 100644
--- a/platform-intel.c
+++ b/platform-intel.c
@@ -1331,31 +1331,28 @@ char *diskfd_to_devpath(int fd, int dev_level, char *buf)
return devt_to_devpath(st.st_rdev, dev_level, buf);
}
-
-int path_attached_to_hba(const char *disk_path, const char *hba_path)
+/**
+ * is_path_attached_to_hba() - Check if disk is attached to hba
+ *
+ * @disk_path: Path to disk.
+ * @hba_path: Path to hba.
+ *
+ * Returns: true if disk is attached to hba, false otherwise.
+ */
+bool is_path_attached_to_hba(const char *disk_path, const char *hba_path)
{
- int rc;
-
- if (check_env("IMSM_TEST_AHCI_DEV") ||
- check_env("IMSM_TEST_SCU_DEV")) {
- return 1;
- }
-
if (!disk_path || !hba_path)
- return 0;
- dprintf("hba: %s - disk: %s\n", hba_path, disk_path);
+ return false;
if (strncmp(disk_path, hba_path, strlen(hba_path)) == 0)
- rc = 1;
- else
- rc = 0;
+ return true;
- return rc;
+ return false;
}
int devt_attached_to_hba(dev_t dev, const char *hba_path)
{
char *disk_path = devt_to_devpath(dev, 1, NULL);
- int rc = path_attached_to_hba(disk_path, hba_path);
+ int rc = is_path_attached_to_hba(disk_path, hba_path);
if (disk_path)
free(disk_path);
@@ -1366,7 +1363,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, 1, NULL);
- int rc = path_attached_to_hba(disk_path, hba_path);
+ int rc = is_path_attached_to_hba(disk_path, hba_path);
if (disk_path)
free(disk_path);
diff --git a/platform-intel.h b/platform-intel.h
index dcc5aaa7..344624d7 100644
--- a/platform-intel.h
+++ b/platform-intel.h
@@ -257,7 +257,7 @@ 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, int dev_level, char *buf);
-int path_attached_to_hba(const char *disk_path, const char *hba_path);
+bool is_path_attached_to_hba(const char *disk_path, const char *hba_path);
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);
diff --git a/super-intel.c b/super-intel.c
index 354c292a..75d7c060 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -800,7 +800,7 @@ static struct sys_dev* find_disk_attached_hba(int fd, const char *devname)
return 0;
for (elem = list; elem; elem = elem->next)
- if (path_attached_to_hba(disk_path, elem->path))
+ if (is_path_attached_to_hba(disk_path, elem->path))
break;
if (disk_path != devname)
@@ -2412,7 +2412,7 @@ static int ahci_enumerate_ports(struct sys_dev *hba, unsigned long port_count, i
path = devt_to_devpath(makedev(major, minor), 1, NULL);
if (!path)
continue;
- if (!path_attached_to_hba(path, hba->path)) {
+ if (!is_path_attached_to_hba(path, hba->path)) {
free(path);
path = NULL;
continue;
@@ -2563,7 +2563,7 @@ static int print_nvme_info(struct sys_dev *hba)
!diskfd_to_devpath(fd, 1, cntrl_path))
goto skip;
- if (!path_attached_to_hba(cntrl_path, hba->path))
+ if (!is_path_attached_to_hba(cntrl_path, hba->path))
goto skip;
if (!imsm_is_nvme_namespace_supported(fd, 0))
@@ -7077,7 +7077,7 @@ get_devices(const char *hba_path)
path = devt_to_devpath(makedev(major, minor), 1, NULL);
if (!path)
continue;
- if (!path_attached_to_hba(path, hba_path)) {
+ if (!is_path_attached_to_hba(path, hba_path)) {
free(path);
path = NULL;
continue;
--
2.41.0

View File

@ -0,0 +1,44 @@
From bd5511c792ecc73de8897fbd8713e8c6eaf3e835 Mon Sep 17 00:00:00 2001
From: Anna Sztukowska <anna.sztukowska@intel.com>
Date: Wed, 28 Aug 2024 12:04:35 +0200
Subject: [PATCH 164/201] mdadm: Change displaying of devices in --detail
The counts of active, working, failed and spare devices were not
printed when the number was zero.
Refactor the code to always display the counts of all device types,
regardless of their number. This way, it is more reliable for users.
Signed-off-by: Anna Sztukowska <anna.sztukowska@intel.com>
---
Detail.c | 14 ++++----------
1 file changed, 4 insertions(+), 10 deletions(-)
diff --git a/Detail.c b/Detail.c
index f8b9e847..331e1da3 100644
--- a/Detail.c
+++ b/Detail.c
@@ -549,16 +549,10 @@ int Detail(char *dev, struct context *c)
} else if (inactive && !is_container) {
printf(" State : inactive\n");
}
- if (array.raid_disks)
- printf(" Active Devices : %d\n", array.active_disks);
- if (array.working_disks > 0)
- printf(" Working Devices : %d\n",
- array.working_disks);
- if (array.raid_disks) {
- printf(" Failed Devices : %d\n", array.failed_disks);
- if (!external)
- printf(" Spare Devices : %d\n", array.spare_disks);
- }
+ printf(" Active Devices : %d\n", array.active_disks);
+ printf(" Working Devices : %d\n", array.working_disks);
+ printf(" Failed Devices : %d\n", array.failed_disks);
+ printf(" Spare Devices : %d\n", array.spare_disks);
printf("\n");
if (array.level == 5) {
str = map_num(r5layout, array.layout);
--
2.41.0

View File

@ -0,0 +1,196 @@
From 734e7db4dfc502044d2a3dacfab67aeab0081cf9 Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Thu, 22 Aug 2024 11:55:15 +0200
Subject: [PATCH 165/201] imsm: Remove warning and refactor add_to_super_imsm
code
Intel x8 drives are not supported, remove unnecessary warning and
refactor add_to_super_imsm code.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
super-intel.c | 102 +++++++++++++++++++-------------------------------
1 file changed, 39 insertions(+), 63 deletions(-)
diff --git a/super-intel.c b/super-intel.c
index 75d7c060..50fd56d0 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -5976,12 +5976,12 @@ static int add_to_super_imsm(struct supertype *st, mdu_disk_info_t *dk,
unsigned long long data_offset)
{
struct intel_super *super = st->sb;
- struct dl *dd;
- unsigned long long size;
unsigned int member_sector_size;
+ unsigned long long size;
+ struct stat stb;
+ struct dl *dd;
__u32 id;
int rv;
- struct stat stb;
/* If we are on an RAID enabled platform check that the disk is
* attached to the raid controller.
@@ -5991,114 +5991,86 @@ static int add_to_super_imsm(struct supertype *st, mdu_disk_info_t *dk,
rv = find_intel_hba_capability(fd, super, devname);
/* no orom/efi or non-intel hba of the disk */
if (rv != 0) {
- dprintf("capability: %p fd: %d ret: %d\n",
- super->orom, fd, rv);
- return 1;
+ dprintf("capability: %p fd: %d ret: %d\n", super->orom, fd, rv);
+ return MDADM_STATUS_ERROR;
}
if (super->current_vol >= 0)
return add_to_super_imsm_volume(st, dk, fd, devname);
if (fstat(fd, &stb) != 0)
- return 1;
+ return MDADM_STATUS_ERROR;
+
dd = xcalloc(sizeof(*dd), 1);
+
+ if (devname)
+ dd->devname = xstrdup(devname);
+
+ if (sysfs_disk_to_scsi_id(fd, &id) == 0)
+ dd->disk.scsi_id = __cpu_to_le32(id);
+
dd->major = major(stb.st_rdev);
dd->minor = minor(stb.st_rdev);
- dd->devname = devname ? xstrdup(devname) : NULL;
- dd->fd = fd;
- dd->e = NULL;
dd->action = DISK_ADD;
+ dd->fd = fd;
+
rv = imsm_read_serial(fd, devname, dd->serial, MAX_RAID_SERIAL_LEN);
if (rv) {
pr_err("failed to retrieve scsi serial, aborting\n");
- __free_imsm_disk(dd, 0);
- abort();
+ goto error;
}
if (super->hba && ((super->hba->type == SYS_DEV_NVME) ||
(super->hba->type == SYS_DEV_VMD))) {
- int i;
- char cntrl_path[PATH_MAX];
- char *cntrl_name;
char pci_dev_path[PATH_MAX];
+ char cntrl_path[PATH_MAX];
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");
- __free_imsm_disk(dd, 0);
- return 1;
+ goto error;
}
- 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);
+ basename(cntrl_path));
- 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"
- * device (double drive on single PCIe card).
- * User should be warned about potential data loss.
- */
- for (i = MAX_RAID_SERIAL_LEN-1; i > 0; i--) {
- /* Skip empty character at the end */
- if (dd->serial[i] == 0)
- continue;
-
- if (((dd->serial[i] == 'A') ||
- (dd->serial[i] == 'B') ||
- (dd->serial[i] == '1') ||
- (dd->serial[i] == '2')) &&
- (dd->serial[i-1] == '-'))
- pr_err("\tThe action you are about to take may put your data at risk.\n"
- "\tPlease note that x8 devices may consist of two separate x4 devices "
- "located on a single PCIe port.\n"
- "\tRAID 0 is the only supported configuration for this type of x8 device.\n");
- break;
- }
- } else if (super->hba->type == SYS_DEV_VMD && super->orom &&
+ if (super->hba->type == SYS_DEV_VMD && super->orom &&
!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_imsm_disk(dd, 0);
- return 1;
+ goto error;
}
}
- get_dev_size(fd, NULL, &size);
- if (!get_dev_sector_size(fd, NULL, &member_sector_size)) {
- __free_imsm_disk(dd, 0);
- return 1;
- }
+ if (!get_dev_size(fd, NULL, &size) || !get_dev_sector_size(fd, NULL, &member_sector_size))
+ goto error;
- if (super->sector_size == 0) {
+ if (super->sector_size == 0)
/* this a first device, so sector_size is not set yet */
super->sector_size = member_sector_size;
- }
/* clear migr_rec when adding disk to container */
- memset(super->migr_rec_buf, 0, MIGR_REC_BUF_SECTORS*MAX_SECTOR_SIZE);
- if (lseek64(fd, size - MIGR_REC_SECTOR_POSITION*member_sector_size,
- SEEK_SET) >= 0) {
- if ((unsigned int)write(fd, super->migr_rec_buf,
- MIGR_REC_BUF_SECTORS*member_sector_size) !=
- MIGR_REC_BUF_SECTORS*member_sector_size)
+ memset(super->migr_rec_buf, 0, MIGR_REC_BUF_SECTORS * MAX_SECTOR_SIZE);
+
+ if (lseek64(fd, (size - MIGR_REC_SECTOR_POSITION * member_sector_size), SEEK_SET) >= 0) {
+ unsigned int nbytes = MIGR_REC_BUF_SECTORS * member_sector_size;
+
+ if ((unsigned int)write(fd, super->migr_rec_buf, nbytes) != nbytes)
perror("Write migr_rec failed");
}
size /= 512;
serialcpy(dd->disk.serial, dd->serial);
set_total_blocks(&dd->disk, size);
+
if (__le32_to_cpu(dd->disk.total_blocks_hi) > 0) {
struct imsm_super *mpb = super->anchor;
+
mpb->attributes |= MPB_ATTRIB_2TB_DISK;
}
+
mark_spare(dd);
- if (sysfs_disk_to_scsi_id(fd, &id) == 0)
- dd->disk.scsi_id = __cpu_to_le32(id);
- else
- dd->disk.scsi_id = __cpu_to_le32(0);
if (st->update_tail) {
dd->next = super->disk_mgmt_list;
@@ -6113,7 +6085,11 @@ static int add_to_super_imsm(struct supertype *st, mdu_disk_info_t *dk,
write_super_imsm_spare(super, dd);
}
- return 0;
+ return MDADM_STATUS_SUCCESS;
+
+error:
+ __free_imsm_disk(dd, 0);
+ return MDADM_STATUS_ERROR;
}
static int remove_from_super_imsm(struct supertype *st, mdu_disk_info_t *dk)
--
2.41.0

View File

@ -0,0 +1,192 @@
From b1d38b512aa3162b5089fbf6b02357ed5fdf5760 Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Thu, 22 Aug 2024 12:18:06 +0200
Subject: [PATCH 166/201] imsm: add IMSM_OROM_CAPABILITIES_TPV to nvme orom
Add it to avoid excluding. It has some value for users even if it is
always true for nvme virtual orom.
Rework detail-platform printing code, move printing 3rd party nvmes
to print_imsm_capability (as it should be), but keep it meaningful
only for nvme controllers (NVME and VMD hba types). Pass whole
orom_entry instead of orom there.
Squash code responsible for printing NVME and VMD hbas.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
platform-intel.c | 3 +-
super-intel.c | 76 +++++++++++++++++++++++-------------------------
2 files changed, 39 insertions(+), 40 deletions(-)
diff --git a/platform-intel.c b/platform-intel.c
index 3a86f785..21591317 100644
--- a/platform-intel.c
+++ b/platform-intel.c
@@ -1089,7 +1089,8 @@ const struct imsm_orom *find_imsm_nvme(struct sys_dev *hba)
.vpa = IMSM_OROM_VOLUMES_PER_ARRAY,
.vphba = IMSM_OROM_TOTAL_DISKS_NVME / 2 * IMSM_OROM_VOLUMES_PER_ARRAY,
.attr = IMSM_OROM_ATTR_2TB | IMSM_OROM_ATTR_2TB_DISK,
- .driver_features = IMSM_OROM_CAPABILITIES_EnterpriseSystem
+ .driver_features = IMSM_OROM_CAPABILITIES_EnterpriseSystem |
+ IMSM_OROM_CAPABILITIES_TPV
};
nvme_orom = add_orom(&nvme_orom_compat);
}
diff --git a/super-intel.c b/super-intel.c
index 50fd56d0..744715d5 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -2663,9 +2663,12 @@ static void print_imsm_chunk_size_capability(const struct imsm_orom *orom)
}
-static void print_imsm_capability(const struct imsm_orom *orom)
+static void print_imsm_capability(const struct orom_entry *entry)
{
+ const struct imsm_orom *orom = &entry->orom;
+
printf(" Platform : Intel(R) ");
+
if (orom->capabilities == 0 && orom->driver_features == 0)
printf("Matrix Storage Manager\n");
else if (imsm_orom_is_enterprise(orom) && orom->major_ver >= 6)
@@ -2673,6 +2676,7 @@ static void print_imsm_capability(const struct imsm_orom *orom)
else
printf("Rapid Storage Technology%s\n",
imsm_orom_is_enterprise(orom) ? " enterprise" : "");
+
if (orom->major_ver || orom->minor_ver || orom->hotfix_ver || orom->build) {
if (imsm_orom_is_vmd_without_efi(orom))
printf(" Version : %d.%d\n", orom->major_ver, orom->minor_ver);
@@ -2690,11 +2694,19 @@ static void print_imsm_capability(const struct imsm_orom *orom)
printf("\n");
printf(" 2TB volumes :%s supported\n", (orom->attr & IMSM_OROM_ATTR_2TB) ? "" : " not");
+
printf(" 2TB disks :%s supported\n",
(orom->attr & IMSM_OROM_ATTR_2TB_DISK) ? "" : " not");
+
printf(" Max Disks : %d\n", orom->tds);
+
printf(" Max Volumes : %d per array, %d per %s\n", orom->vpa, orom->vphba,
imsm_orom_is_nvme(orom) ? "platform" : "controller");
+
+ if (entry->type == SYS_DEV_VMD || entry->type == SYS_DEV_NVME)
+ /* This is only meaningful for controllers with nvme support */
+ printf(" 3rd party NVMe :%s supported\n",
+ imsm_orom_has_tpv_support(&entry->orom) ? "" : " not");
return;
}
@@ -2733,26 +2745,25 @@ static int detail_platform_imsm(int verbose, int enumerate_only, char *controlle
* platform capabilities. If raid support is disabled in the BIOS the
* option-rom capability structure will not be available.
*/
+ const struct orom_entry *entry;
struct sys_dev *list, *hba;
- int host_base = 0;
+ struct devid_list *devid;
int port_count = 0;
- int result=1;
+ int host_base = 0;
+ int result = 1;
if (enumerate_only) {
if (check_no_platform())
return 0;
+
list = find_intel_devices();
if (!list)
return 2;
- for (hba = list; hba; hba = hba->next) {
- if (find_imsm_capability(hba)) {
- result = 0;
- break;
- }
- else
- result = 2;
- }
- return result;
+
+ for (hba = list; hba; hba = hba->next)
+ if (find_imsm_capability(hba))
+ return 0;
+ return 2;
}
list = find_intel_devices();
@@ -2768,6 +2779,7 @@ static int detail_platform_imsm(int verbose, int enumerate_only, char *controlle
continue;
if (!find_imsm_capability(hba)) {
char buf[PATH_MAX];
+
pr_err("imsm capabilities not found for controller: %s (type %s)\n",
hba->type == SYS_DEV_VMD || hba->type == SYS_DEV_SATA_VMD ?
vmd_domain_to_controller(hba, buf) :
@@ -2783,40 +2795,27 @@ static int detail_platform_imsm(int verbose, int enumerate_only, char *controlle
return result;
}
- const struct orom_entry *entry;
-
for (entry = orom_entries; entry; entry = entry->next) {
- if (entry->type == SYS_DEV_VMD) {
- print_imsm_capability(&entry->orom);
- printf(" 3rd party NVMe :%s supported\n",
- imsm_orom_has_tpv_support(&entry->orom)?"":" not");
+ print_imsm_capability(entry);
+
+ if (entry->type == SYS_DEV_VMD || entry->type == SYS_DEV_NVME) {
for (hba = list; hba; hba = hba->next) {
- if (hba->type == SYS_DEV_VMD) {
- char buf[PATH_MAX];
+ char buf[PATH_MAX];
+
+ if (hba->type != entry->type)
+ continue;
+
+ if (hba->type == SYS_DEV_VMD)
printf(" I/O Controller : %s (%s)\n",
- vmd_domain_to_controller(hba, buf), get_sys_dev_type(hba->type));
- if (print_nvme_info(hba)) {
- if (verbose > 0)
- pr_err("failed to get devices attached to VMD domain.\n");
- result |= 2;
- }
- }
- }
- printf("\n");
- continue;
- }
+ vmd_domain_to_controller(hba, buf),
+ get_sys_dev_type(hba->type));
- print_imsm_capability(&entry->orom);
- if (entry->type == SYS_DEV_NVME) {
- for (hba = list; hba; hba = hba->next) {
- if (hba->type == SYS_DEV_NVME)
- print_nvme_info(hba);
+ print_nvme_info(hba);
}
printf("\n");
continue;
}
- struct devid_list *devid;
for (devid = entry->devid_list; devid; devid = devid->next) {
hba = device_by_id(devid->devid);
if (!hba)
@@ -6035,8 +6034,7 @@ static int add_to_super_imsm(struct supertype *st, mdu_disk_info_t *dk,
pr_err("%s controller supports Multi-Path I/O, Intel (R) VROC does not support multipathing\n",
basename(cntrl_path));
- if (super->hba->type == SYS_DEV_VMD && super->orom &&
- !imsm_orom_has_tpv_support(super->orom)) {
+ if (super->orom && !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");
goto error;
--
2.41.0

View File

@ -0,0 +1,33 @@
From f786072a3e2928766a9b4f1b7d3372a601c259ea Mon Sep 17 00:00:00 2001
From: Shminderjit Singh <shminderjit.singh@oracle.com>
Date: Mon, 26 Aug 2024 10:06:50 +0000
Subject: [PATCH 167/201] mdadm: Increase number limit in md device name to
1024.
Updated the maximum device number in md device names from 127 to 1024.
The previous limit was causing issues in the automation framework.
This change ensures backward compatibility and allows for future
scalability.
Fixes: 25aa7329141c ("mdadm: numbered names verification")
Signed-off-by: Shminderjit Singh <shminderjit.singh@oracle.com>
---
util.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/util.c b/util.c
index 1cee0feb..2fc0e9f8 100644
--- a/util.c
+++ b/util.c
@@ -1003,7 +1003,7 @@ static bool is_devname_numbered(const char *devname, const char *pref, const int
if (parse_num(&val, devname + pref_len) != 0)
return false;
- if (val > 127)
+ if (val > 1024)
return false;
return true;
--
2.41.0

View File

@ -0,0 +1,44 @@
From dd0d193ad8722140e240c95a4fd1e214077dd719 Mon Sep 17 00:00:00 2001
From: Mateusz Kusiak <mateusz.kusiak@intel.com>
Date: Mon, 2 Sep 2024 12:27:56 -0400
Subject: [PATCH 168/201] imsm: save checkpoint prior to exit
If reshape (eg. chunksize migration) is gracefully stopped via SIGTERM
the checkpoint is not saved and reshape cannot be resumed due to "data
being present in copy area". This is because UNIT_SRC_NORMAL isn't set
if SIGTERM occurred.
Move SIGTERM handling at the end of the loop to allow saving checkpoint
(and state) so reshapes can be properly resumed.
Signed-off-by: Mateusz Kusiak <mateusz.kusiak@intel.com>
---
super-intel.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/super-intel.c b/super-intel.c
index 744715d5..30c2939a 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -12631,8 +12631,6 @@ static int imsm_manage_reshape(
dprintf("wait_for_reshape_imsm returned error!\n");
goto abort;
}
- if (sigterm)
- goto abort;
if (save_checkpoint_imsm(st, sra, UNIT_SRC_NORMAL) == 1) {
/* ignore error == 2, this can mean end of reshape here
@@ -12641,6 +12639,9 @@ static int imsm_manage_reshape(
goto abort;
}
+ if (sigterm)
+ goto abort;
+
}
/* clear migr_rec on disks after successful migration */
--
2.41.0

View File

@ -0,0 +1,116 @@
From da26064bfe4457d5037f3a1f1bb83a54225c6375 Mon Sep 17 00:00:00 2001
From: Anna Sztukowska <anna.sztukowska@intel.com>
Date: Thu, 8 Aug 2024 17:02:38 +0200
Subject: [PATCH 169/201] Examine.c: Fix memory leaks in Examine()
Fix memory leaks in Examine() reported by SAST analysis. Implement a
method to traverse and free all the nodes of the doubly linked list.
Replace for loop with while loop in order to improve redability of the
code and free allocated memory correctly.
Signed-off-by: Anna Sztukowska <anna.sztukowska@intel.com>
---
Examine.c | 22 +++++++++++++++++-----
dlink.c | 15 +++++++++++++++
dlink.h | 1 +
3 files changed, 33 insertions(+), 5 deletions(-)
diff --git a/Examine.c b/Examine.c
index c9605a60..fe162167 100644
--- a/Examine.c
+++ b/Examine.c
@@ -111,8 +111,10 @@ int Examine(struct mddev_dev *devlist,
close(fd);
if (err) {
- if (st)
+ if (st) {
st->ss->free_super(st);
+ free(st);
+ }
continue;
}
@@ -152,19 +154,24 @@ int Examine(struct mddev_dev *devlist,
if (st->ss->export_examine_super)
st->ss->export_examine_super(st);
st->ss->free_super(st);
+ free(st);
} else {
printf("%s:\n",devlist->devname);
st->ss->examine_super(st, c->homehost);
st->ss->free_super(st);
+ free(st);
}
}
if (c->brief) {
- struct array *ap;
- for (ap = arrays; ap; ap = ap->next) {
+ struct array *ap = arrays, *next;
+
+ while (ap) {
char sep='=';
char *d;
int newline = 0;
+ next = ap->next;
+
ap->st->ss->brief_examine_super(ap->st, c->verbose > 0);
if (ap->spares && !ap->st->ss->external)
newline += printf(" spares=%d", ap->spares);
@@ -182,10 +189,15 @@ int Examine(struct mddev_dev *devlist,
printf("\n");
ap->st->ss->brief_examine_subarrays(ap->st, c->verbose);
}
- ap->st->ss->free_super(ap->st);
- /* FIXME free ap */
if (ap->spares || c->verbose > 0)
printf("\n");
+
+ ap->st->ss->free_super(ap->st);
+ free(ap->st);
+ dl_free_all(ap->devs);
+ free(ap);
+
+ ap = next;
}
}
return rv;
diff --git a/dlink.c b/dlink.c
index 69aa7aa3..34633672 100644
--- a/dlink.c
+++ b/dlink.c
@@ -26,6 +26,21 @@ void dl_free(void *v)
free(vv-1);
}
+void dl_free_all(void *head)
+{
+ /* The list head is linked with the list tail so in order to free
+ * all the elements properly there is a need to keep starting point.
+ */
+ void *d = dl_next(head), *next;
+
+ while (d != head) {
+ next = dl_next(d);
+ dl_free(d);
+ d = next;
+ }
+ dl_free(head);
+}
+
void dl_init(void *v)
{
dl_next(v) = v;
diff --git a/dlink.h b/dlink.h
index ab2a9459..ce667839 100644
--- a/dlink.h
+++ b/dlink.h
@@ -23,3 +23,4 @@ void dl_add(void*, void*);
void dl_del(void*);
void dl_free(void*);
void dl_init(void*);
+void dl_free_all(void *head);
--
2.41.0

View File

@ -0,0 +1,39 @@
From be1b4ff0957b287b2d8494967a7f0a1e3401dd8a Mon Sep 17 00:00:00 2001
From: Anna Sztukowska <anna.sztukowska@intel.com>
Date: Mon, 9 Sep 2024 09:36:47 +0200
Subject: [PATCH 170/201] dlink.h: Fix checkpatch warnings for function args
Checkpatch issued a warning due to missing function argument names.
Add the names to resolve the warnings.
Signed-off-by: Anna Sztukowska <anna.sztukowska@intel.com>
---
dlink.h | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/dlink.h b/dlink.h
index ce667839..18cc294a 100644
--- a/dlink.h
+++ b/dlink.h
@@ -16,11 +16,11 @@ struct __dl_head
#define dl_prev(p) *(&(((struct __dl_head*)(p))[-1].dh_prev))
void *dl_head(void);
-char *dl_strdup(char *);
-char *dl_strndup(char *, int);
-void dl_insert(void*, void*);
-void dl_add(void*, void*);
-void dl_del(void*);
-void dl_free(void*);
-void dl_init(void*);
+char *dl_strdup(char *s);
+char *dl_strndup(char *s, int l);
+void dl_insert(void *head, void *val);
+void dl_add(void *head, void *val);
+void dl_del(void *val);
+void dl_free(void *v);
+void dl_init(void *v);
void dl_free_all(void *head);
--
2.41.0

View File

@ -0,0 +1,151 @@
From 9b8933bb6dbfcae1bd5a2f933c87684de99412de Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Tue, 25 Jun 2024 12:53:46 +0200
Subject: [PATCH 171/201] Incremental: support devnode in IncrementalRemove.
There are no reasons to keep this interface different than others.
Allow to use devnode but keep old way for backward compatibility.
Method is added to verify that only devnode or kernel name is used.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
Incremental.c | 60 ++++++++++++++++++++++++-------------
mdadm.h | 5 ++++
udev-md-raid-assembly.rules | 4 +--
3 files changed, 46 insertions(+), 23 deletions(-)
diff --git a/Incremental.c b/Incremental.c
index fc4e68ff..c1389a15 100644
--- a/Incremental.c
+++ b/Incremental.c
@@ -1674,33 +1674,52 @@ static void remove_from_member_array(struct mdstat_ent *memb,
}
}
-/*
- * IncrementalRemove - Attempt to see if the passed in device belongs to any
- * raid arrays, and if so first fail (if needed) and then remove the device.
+/**
+ * is_devnode_path() - check if the devname passed might be devnode path.
+ * @devnode: the path to check.
*
- * @devname - The device we want to remove
- * @id_path - name as found in /dev/disk/by-path for this device
+ * Devnode must be located directly in /dev directory. It is not checking existence of the file
+ * because the device might no longer exist during removal from raid array.
+ */
+static bool is_devnode_path(char *devnode)
+{
+ char *devnm = strrchr(devnode, '/');
+
+ if (!devnm || *(devnm + 1) == 0)
+ return false;
+
+ if (strncmp(devnode, DEV_DIR, DEV_DIR_LEN) == 0 && devnode + DEV_DIR_LEN - 1 == devnm)
+ return true;
+
+ return false;
+}
+
+/**
+ * IncrementalRemove() - Remove the device from all raid arrays.
+ * @devname: the device we want to remove, it could be kernel device name or devnode.
+ * @id_path: optional, /dev/disk/by-path path to save for bare scenarios support.
+ * @verbose: verbose flag.
*
- * Note: the device name must be a kernel name like "sda", so
- * that we can find it in /proc/mdstat
+ * First, fail the device (if needed) and then remove the device from native raid array or external
+ * container. If it is external container, the device is removed from each subarray first.
*/
int IncrementalRemove(char *devname, char *id_path, int verbose)
{
- struct mdstat_ent *ent = NULL;
+ char *devnm = basename(devname);
+ struct mddev_dev devlist = {0};
char buf[SYSFS_MAX_BUF_SIZE];
struct mdstat_ent *mdstat;
- struct mddev_dev devlist;
+ struct mdstat_ent *ent;
struct mdinfo mdi;
int rv = 1;
int mdfd;
- if (!id_path)
- dprintf("incremental removal without --path <id_path> lacks the possibility to re-add new device in this port\n");
-
- if (strchr(devname, '/')) {
- pr_err("incremental removal requires a kernel device name, not a file: %s\n", devname);
- return 1;
- }
+ if (strcmp(devnm, devname) != 0)
+ if (!is_devnode_path(devname)) {
+ pr_err("Cannot remove \"%s\", devnode path or kernel device name is allowed.\n",
+ devname);
+ return 1;
+ }
mdstat = mdstat_read(0, 0);
if (!mdstat) {
@@ -1708,15 +1727,15 @@ int IncrementalRemove(char *devname, char *id_path, int verbose)
return 1;
}
- ent = mdstat_find_by_member_name(mdstat, devname);
+ ent = mdstat_find_by_member_name(mdstat, devnm);
if (!ent) {
if (verbose >= 0)
- pr_err("%s does not appear to be a component of any array\n", devname);
+ pr_vrb("%s does not appear to be a component of any array\n", devnm);
goto out;
}
if (sysfs_init(&mdi, -1, ent->devnm)) {
- pr_err("unable to initialize sysfs for: %s\n", devname);
+ pr_err("unable to initialize sysfs for: %s\n", devnm);
goto out;
}
@@ -1746,8 +1765,7 @@ int IncrementalRemove(char *devname, char *id_path, int verbose)
map_free(map);
}
- memset(&devlist, 0, sizeof(devlist));
- devlist.devname = devname;
+ devlist.devname = devnm;
devlist.disposition = 'I';
/* for a container, we must fail each member array */
if (is_mdstat_ent_external(ent)) {
diff --git a/mdadm.h b/mdadm.h
index 5c3a9836..f3b9f54c 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -100,6 +100,11 @@ struct dlm_lksb {
#define DEFAULT_BITMAP_DELAY 5
#define DEFAULT_MAX_WRITE_BEHIND 256
+#ifndef DEV_DIR
+#define DEV_DIR "/dev/"
+#define DEV_DIR_LEN (sizeof(DEV_DIR) - 1)
+#endif /* DEV_DIR */
+
/* DEV_NUM_PREF is a subpath to numbered MD devices, e.g. /dev/md1 or directory name.
* DEV_NUM_PREF_LEN is a length with Null byte excluded.
*/
diff --git a/udev-md-raid-assembly.rules b/udev-md-raid-assembly.rules
index d4a7f0a5..4cd2c6f4 100644
--- a/udev-md-raid-assembly.rules
+++ b/udev-md-raid-assembly.rules
@@ -41,7 +41,7 @@ ACTION=="change", KERNEL!="dm-*|md*", GOTO="md_inc_end"
ACTION!="remove", IMPORT{program}="BINDIR/mdadm --incremental --export $devnode --offroot $env{DEVLINKS}"
ACTION!="remove", ENV{MD_STARTED}=="*unsafe*", ENV{MD_FOREIGN}=="no", ENV{SYSTEMD_WANTS}+="mdadm-last-resort@$env{MD_DEVICE}.timer"
-ACTION=="remove", ENV{ID_PATH}=="?*", RUN+="BINDIR/mdadm -If $name --path $env{ID_PATH}"
-ACTION=="remove", ENV{ID_PATH}!="?*", RUN+="BINDIR/mdadm -If $name"
+ACTION=="remove", ENV{ID_PATH}=="?*", RUN+="BINDIR/mdadm -If $devnode --path $env{ID_PATH}"
+ACTION=="remove", ENV{ID_PATH}!="?*", RUN+="BINDIR/mdadm -If $devnode"
LABEL="md_inc_end"
--
2.41.0

View File

@ -0,0 +1,75 @@
From 7b65dd6d71dfff35847440e19d309990dfcb29d3 Mon Sep 17 00:00:00 2001
From: Anna Sztukowska <anna.sztukowska@intel.com>
Date: Mon, 29 Jul 2024 07:47:39 +0200
Subject: [PATCH 172/201] Detail.c: Fix divide_by_zero issue
Fix divide_by_zero issue reported by SAST analysis in Detail.c when
calling enough() from util.c. Also add missing spaces for better code
readability.
Signed-off-by: Anna Sztukowska <anna.sztukowska@intel.com>
---
util.c | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/util.c b/util.c
index 2fc0e9f8..cc162278 100644
--- a/util.c
+++ b/util.c
@@ -513,6 +513,9 @@ int enough(int level, int raid_disks, int layout, int clean, char *avail)
int i;
int avail_disks = 0;
+ if (raid_disks <= 0)
+ return 0;
+
for (i = 0; i < raid_disks; i++)
avail_disks += !!avail[i];
@@ -521,7 +524,7 @@ int enough(int level, int raid_disks, int layout, int clean, char *avail)
/* This is the tricky one - we need to check
* which actual disks are present.
*/
- copies = (layout&255)* ((layout>>8) & 255);
+ copies = (layout & 255) * ((layout >> 8) & 255);
first = 0;
do {
/* there must be one of the 'copies' form 'first' */
@@ -531,16 +534,16 @@ int enough(int level, int raid_disks, int layout, int clean, char *avail)
while (n--) {
if (avail[this])
cnt++;
- this = (this+1) % raid_disks;
+ this = (this + 1) % raid_disks;
}
if (cnt == 0)
return 0;
- first = (first+(layout&255)) % raid_disks;
+ first = (first + (layout & 255)) % raid_disks;
} while (first != 0);
return 1;
case LEVEL_MULTIPATH:
- return avail_disks>= 1;
+ return avail_disks >= 1;
case LEVEL_LINEAR:
case 0:
return avail_disks == raid_disks;
@@ -556,12 +559,12 @@ int enough(int level, int raid_disks, int layout, int clean, char *avail)
/* FALL THROUGH */
case 5:
if (clean)
- return avail_disks >= raid_disks-1;
+ return avail_disks >= raid_disks - 1;
else
return avail_disks >= raid_disks;
case 6:
if (clean)
- return avail_disks >= raid_disks-2;
+ return avail_disks >= raid_disks - 2;
else
return avail_disks >= raid_disks;
default:
--
2.41.0

View File

@ -0,0 +1,81 @@
From 983e9226fb02a91692c2c55a19b5cd06d8ddd005 Mon Sep 17 00:00:00 2001
From: Anna Sztukowska <anna.sztukowska@intel.com>
Date: Tue, 6 Aug 2024 10:44:01 +0200
Subject: [PATCH 173/201] mdadm: Add compilation process to README.md
Add compilation process and dependencies to README.md.
Signed-off-by: Anna Sztukowska <anna.sztukowska@intel.com>
---
README.md | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 55 insertions(+)
diff --git a/README.md b/README.md
index 486c8929..870ecb7e 100644
--- a/README.md
+++ b/README.md
@@ -87,6 +87,61 @@ If there are differences between github and kernel.org, please contact kernel.or
We do not support kernel versions below **v3.10**. Please be aware that maintainers may remove
workarounds and fixes for legacy issues.
+# Dependencies
+
+The following packages are required for compilation:
+
+| RHEL | SLES | Debian/Ubuntu |
+| :---: | :---: | :---: |
+| `pkgconf` | `pkg-config` | `pkg-config` |
+| `gcc` | `gcc` | `gcc` |
+| `make` | `make` | `make` |
+| `libudev-devel` | `libudev-devel` | `libudev-dev` |
+
+# Compiling mdadm
+
+Run `make` command to compile mdadm.
+
+Specifying more jobs e.g. `make -j4` can decrease compilation time significantly.
+
+Various values can be specified for the `CXFLAGS` variable to customize the build process:
+- Run `make CXFLAGS=-ggdb` to include gdb debugging information.
+- Run `make CXFLAGS=-DDEBUG` to enable additional debug information through dprintf statements
+and call traces.
+- Run `make CXFLAGS=-DNO_LIBUDEV` to compile without `libudev`.
+
+To build with more than one option specified in `CXFLAGS`, separate each option with a space, e.g.
+`make CXFLAGS="-ggdb -DDEBUG"`.
+
+Additionally, the `EXTRAVERSION` variable can be set to build with user-friendly version label,
+useful when customizing mdadm builds or labeling some instance in between major releases,
+e.g. `make EXTRAVERSION="custom-label"`.
+
+# Installing mdadm
+
+Before installing mdadm, it is advised to uninstall vendor-provided packages (mdadm.deb, mdadm.rpm
+etc.) in order to avoid configuration issues.
+
+Run `make install` command to install mdadm. This command invokes the following targets:
+- `install-bin`
+- `install-man`
+- `install-udev`
+
+After installing mdadm, consider rebuilding initramfs to ensure the changes take effect.
+
+List of installation targets:
+- Run `make install-bin` to install the mdadm and mdmon binary files.
+- Run `make install-systemd` to install the systemd services.
+- Run `make install-udev` to install the udev rules.
+- Run `make install-man` to install the manual pages (`mdadm.8`, `md.4`, `mdadm.conf.5`,
+`mdmon.8`).
+
+The following targets are deprecated and should not be used:
+- `install-static`
+- `install-tcc`
+- `install-uclibc`
+- `install-klibc`
+
# License
It is released under the terms of the **GNU General Public License version 2** as published
--
2.41.0

Some files were not shown because too many files have changed in this diff Show More