import mdadm-4.1-15.el8

c8 imports/c8/mdadm-4.1-15.el8
CentOS Sources 2 years ago committed by Andrew Lukoshko
parent 5a71a64698
commit 927e9d8a6e

@ -0,0 +1,49 @@
From 03ab9763f51ddf2030f60f83e76cf9c1b50b726c Mon Sep 17 00:00:00 2001
From: Tkaczyk Mariusz <mariusz.tkaczyk@intel.com>
Date: Fri, 15 May 2020 11:23:14 +0200
Subject: [PATCH 078/108] Makefile: add EXTRAVERSION support
Add optional EXTRAVERSION parameter to Makefile and allow to mark version
by user friendly label. It might be useful when creating custom
spins of mdadm, or labeling some instance in between major releases.
Signed-off-by: Tkaczyk Mariusz <mariusz.tkaczyk@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Makefile | 3 ++-
ReadMe.c | 5 ++++-
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/Makefile b/Makefile
index a33319a..0a20b75 100644
--- a/Makefile
+++ b/Makefile
@@ -105,7 +105,8 @@ VERSION = $(shell [ -d .git ] && git describe HEAD | sed 's/mdadm-//')
VERS_DATE = $(shell [ -d .git ] && date --iso-8601 --date="`git log -n1 --format=format:%cd --date=iso --date=short`")
DVERS = $(if $(VERSION),-DVERSION=\"$(VERSION)\",)
DDATE = $(if $(VERS_DATE),-DVERS_DATE="\"$(VERS_DATE)\"",)
-CFLAGS += $(DVERS) $(DDATE)
+DEXTRAVERSION = $(if $(EXTRAVERSION),-DEXTRAVERSION="\" - $(EXTRAVERSION)\"",)
+CFLAGS += $(DVERS) $(DDATE) $(DEXTRAVERSION)
# The glibc TLS ABI requires applications that call clone(2) to set up
# TLS data structures, use pthreads until mdmon implements this support
diff --git a/ReadMe.c b/ReadMe.c
index eaf1042..06b8f7e 100644
--- a/ReadMe.c
+++ b/ReadMe.c
@@ -33,7 +33,10 @@
#ifndef VERS_DATE
#define VERS_DATE "2018-10-01"
#endif
-char Version[] = "mdadm - v" VERSION " - " VERS_DATE "\n";
+#ifndef EXTRAVERSION
+#define EXTRAVERSION ""
+#endif
+char Version[] = "mdadm - v" VERSION " - " VERS_DATE EXTRAVERSION "\n";
/*
* File: ReadMe.c
--
2.7.5

@ -0,0 +1,284 @@
From f4c8a605d2467c0ed25fcba5d27dd56540660e55 Mon Sep 17 00:00:00 2001
From: Guoqing Jiang <guoqing.jiang@cloud.ionos.com>
Date: Mon, 18 May 2020 23:53:35 +0200
Subject: [PATCH 079/108] uuid.c: split uuid stuffs from util.c
Currently, 'make raid6check' is build broken since commit b06815989
("mdadm: load default sysfs attributes after assemblation").
/usr/bin/ld: sysfs.o: in function `sysfsline':
sysfs.c:(.text+0x2707): undefined reference to `parse_uuid'
/usr/bin/ld: sysfs.c:(.text+0x271a): undefined reference to `uuid_zero'
/usr/bin/ld: sysfs.c:(.text+0x2721): undefined reference to `uuid_zero'
Apparently, the compile of mdadm or raid6check are coupled with uuid
functions inside util.c. However, we can't just add util.o to CHECK_OBJS
which raid6check is needed, because it caused other worse problems.
So, let's introduce a uuid.c file which is indenpended file to fix the
problem, all the contents are splitted from util.c.
Signed-off-by: Guoqing Jiang <guoqing.jiang@cloud.ionos.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Makefile | 6 ++--
util.c | 87 -------------------------------------------------
uuid.c | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 115 insertions(+), 90 deletions(-)
create mode 100644 uuid.c
diff --git a/Makefile b/Makefile
index 0a20b75..15d05d1 100644
--- a/Makefile
+++ b/Makefile
@@ -140,7 +140,7 @@ else
ECHO=:
endif
-OBJS = mdadm.o config.o policy.o mdstat.o ReadMe.o util.o maps.o lib.o \
+OBJS = mdadm.o config.o policy.o mdstat.o ReadMe.o uuid.o util.o maps.o lib.o \
Manage.o Assemble.o Build.o \
Create.o Detail.o Examine.o Grow.o Monitor.o dlink.o Kill.o Query.o \
Incremental.o Dump.o \
@@ -149,13 +149,13 @@ OBJS = mdadm.o config.o policy.o mdstat.o ReadMe.o util.o maps.o lib.o \
restripe.o sysfs.o sha1.o mapfile.o crc32.o sg_io.o msg.o xmalloc.o \
platform-intel.o probe_roms.o crc32c.o
-CHECK_OBJS = restripe.o sysfs.o maps.o lib.o xmalloc.o dlink.o
+CHECK_OBJS = restripe.o uuid.o sysfs.o maps.o lib.o xmalloc.o dlink.o
SRCS = $(patsubst %.o,%.c,$(OBJS))
INCL = mdadm.h part.h bitmap.h
-MON_OBJS = mdmon.o monitor.o managemon.o util.o maps.o mdstat.o sysfs.o \
+MON_OBJS = mdmon.o monitor.o managemon.o uuid.o util.o maps.o mdstat.o sysfs.o \
policy.o lib.o \
Kill.o sg_io.o dlink.o ReadMe.o super-intel.o \
super-mbr.o super-gpt.o \
diff --git a/util.c b/util.c
index 07f9dc3..579dd42 100644
--- a/util.c
+++ b/util.c
@@ -306,43 +306,6 @@ int md_get_disk_info(int fd, struct mdu_disk_info_s *disk)
return ioctl(fd, GET_DISK_INFO, disk);
}
-/*
- * Parse a 128 bit uuid in 4 integers
- * format is 32 hexx nibbles with options :.<space> separator
- * If not exactly 32 hex digits are found, return 0
- * else return 1
- */
-int parse_uuid(char *str, int uuid[4])
-{
- int hit = 0; /* number of Hex digIT */
- int i;
- char c;
- for (i = 0; i < 4; i++)
- uuid[i] = 0;
-
- while ((c = *str++) != 0) {
- int n;
- if (c >= '0' && c <= '9')
- n = c-'0';
- else if (c >= 'a' && c <= 'f')
- n = 10 + c - 'a';
- else if (c >= 'A' && c <= 'F')
- n = 10 + c - 'A';
- else if (strchr(":. -", c))
- continue;
- else return 0;
-
- if (hit<32) {
- uuid[hit/8] <<= 4;
- uuid[hit/8] += n;
- }
- hit++;
- }
- if (hit == 32)
- return 1;
- return 0;
-}
-
int get_linux_version()
{
struct utsname name;
@@ -611,56 +574,6 @@ int enough(int level, int raid_disks, int layout, int clean, char *avail)
}
}
-const int uuid_zero[4] = { 0, 0, 0, 0 };
-
-int same_uuid(int a[4], int b[4], int swapuuid)
-{
- if (swapuuid) {
- /* parse uuids are hostendian.
- * uuid's from some superblocks are big-ending
- * if there is a difference, we need to swap..
- */
- unsigned char *ac = (unsigned char *)a;
- unsigned char *bc = (unsigned char *)b;
- int i;
- for (i = 0; i < 16; i += 4) {
- if (ac[i+0] != bc[i+3] ||
- ac[i+1] != bc[i+2] ||
- ac[i+2] != bc[i+1] ||
- ac[i+3] != bc[i+0])
- return 0;
- }
- return 1;
- } else {
- if (a[0]==b[0] &&
- a[1]==b[1] &&
- a[2]==b[2] &&
- a[3]==b[3])
- return 1;
- return 0;
- }
-}
-
-void copy_uuid(void *a, int b[4], int swapuuid)
-{
- if (swapuuid) {
- /* parse uuids are hostendian.
- * uuid's from some superblocks are big-ending
- * if there is a difference, we need to swap..
- */
- unsigned char *ac = (unsigned char *)a;
- unsigned char *bc = (unsigned char *)b;
- int i;
- for (i = 0; i < 16; i += 4) {
- ac[i+0] = bc[i+3];
- ac[i+1] = bc[i+2];
- ac[i+2] = bc[i+1];
- ac[i+3] = bc[i+0];
- }
- } else
- memcpy(a, b, 16);
-}
-
char *__fname_from_uuid(int id[4], int swap, char *buf, char sep)
{
int i, j;
diff --git a/uuid.c b/uuid.c
new file mode 100644
index 0000000..94b5abd
--- /dev/null
+++ b/uuid.c
@@ -0,0 +1,112 @@
+/*
+ * mdadm - manage Linux "md" devices aka RAID arrays.
+ *
+ * Copyright (C) 2001-2013 Neil Brown <neilb@suse.de>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Neil Brown
+ * Email: <neilb@suse.de>
+ */
+
+#include <string.h>
+
+const int uuid_zero[4] = { 0, 0, 0, 0 };
+
+int same_uuid(int a[4], int b[4], int swapuuid)
+{
+ if (swapuuid) {
+ /* parse uuids are hostendian.
+ * uuid's from some superblocks are big-ending
+ * if there is a difference, we need to swap..
+ */
+ unsigned char *ac = (unsigned char *)a;
+ unsigned char *bc = (unsigned char *)b;
+ int i;
+ for (i = 0; i < 16; i += 4) {
+ if (ac[i+0] != bc[i+3] ||
+ ac[i+1] != bc[i+2] ||
+ ac[i+2] != bc[i+1] ||
+ ac[i+3] != bc[i+0])
+ return 0;
+ }
+ return 1;
+ } else {
+ if (a[0]==b[0] &&
+ a[1]==b[1] &&
+ a[2]==b[2] &&
+ a[3]==b[3])
+ return 1;
+ return 0;
+ }
+}
+
+void copy_uuid(void *a, int b[4], int swapuuid)
+{
+ if (swapuuid) {
+ /* parse uuids are hostendian.
+ * uuid's from some superblocks are big-ending
+ * if there is a difference, we need to swap..
+ */
+ unsigned char *ac = (unsigned char *)a;
+ unsigned char *bc = (unsigned char *)b;
+ int i;
+ for (i = 0; i < 16; i += 4) {
+ ac[i+0] = bc[i+3];
+ ac[i+1] = bc[i+2];
+ ac[i+2] = bc[i+1];
+ ac[i+3] = bc[i+0];
+ }
+ } else
+ memcpy(a, b, 16);
+}
+
+/*
+ * Parse a 128 bit uuid in 4 integers
+ * format is 32 hexx nibbles with options :.<space> separator
+ * If not exactly 32 hex digits are found, return 0
+ * else return 1
+ */
+int parse_uuid(char *str, int uuid[4])
+{
+ int hit = 0; /* number of Hex digIT */
+ int i;
+ char c;
+ for (i = 0; i < 4; i++)
+ uuid[i] = 0;
+
+ while ((c = *str++) != 0) {
+ int n;
+ if (c >= '0' && c <= '9')
+ n = c-'0';
+ else if (c >= 'a' && c <= 'f')
+ n = 10 + c - 'a';
+ else if (c >= 'A' && c <= 'F')
+ n = 10 + c - 'A';
+ else if (strchr(":. -", c))
+ continue;
+ else return 0;
+
+ if (hit<32) {
+ uuid[hit/8] <<= 4;
+ uuid[hit/8] += n;
+ }
+ hit++;
+ }
+ if (hit == 32)
+ return 1;
+ return 0;
+}
--
2.7.5

@ -0,0 +1,34 @@
From 7d90f7603af6b59e7144cef6617a1e9dd42161bd Mon Sep 17 00:00:00 2001
From: Jes Sorensen <jsorensen@fb.com>
Date: Mon, 18 May 2020 20:19:53 -0400
Subject: [PATCH 080/108] Include count for \0 character when using strncpy to
implement strdup.
We have to include the \0 character in the length when copying a
string with strncpy() for which length was found with strlen().
Otherwise the destination will not get null terminated - except that
we explicitly zeroed it out earlier.
This quiets down the compiler's warnings.
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
dlink.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlink.c b/dlink.c
index 3efa94b..69aa7aa 100644
--- a/dlink.c
+++ b/dlink.c
@@ -63,7 +63,7 @@ char *dl_strndup(char *s, int l)
if (s == NULL)
return NULL;
n = dl_newv(char, l+1);
- strncpy(n, s, l);
+ strncpy(n, s, l+1);
n[l] = 0;
return n;
}
--
2.7.5

@ -0,0 +1,53 @@
From d92cee7b374db9944b63bdd6c1784a2dd90ee9ca Mon Sep 17 00:00:00 2001
From: Guoqing Jiang <guoqing.jiang@cloud.ionos.com>
Date: Mon, 18 May 2020 23:53:36 +0200
Subject: [PATCH 081/108] =?UTF-8?q?restripe:=20fix=20ignoring=20return=20v?=
=?UTF-8?q?alue=20of=20=E2=80=98read=E2=80=99=20and=20lseek?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Got below error when run "make everything".
restripe.c: In function test_stripes:
restripe.c:870:4: error: ignoring return value of read, declared with attribute warn_unused_result [-Werror=unused-result]
read(source[i], stripes[i], chunk_size);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Fix it by check the return value of read, and free memory
in the failure case.
And check the return value of lseek as well per Jes's comment.
Signed-off-by: Guoqing Jiang <guoqing.jiang@cloud.ionos.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
restripe.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/restripe.c b/restripe.c
index 31b07e8..86e1d00 100644
--- a/restripe.c
+++ b/restripe.c
@@ -866,8 +866,16 @@ int test_stripes(int *source, unsigned long long *offsets,
int disk;
for (i = 0 ; i < raid_disks ; i++) {
- lseek64(source[i], offsets[i]+start, 0);
- read(source[i], stripes[i], chunk_size);
+ if ((lseek64(source[i], offsets[i]+start, 0) < 0) ||
+ (read(source[i], stripes[i], chunk_size) !=
+ chunk_size)) {
+ free(q);
+ free(p);
+ free(blocks);
+ free(stripes);
+ free(stripe_buf);
+ return -1;
+ }
}
for (i = 0 ; i < data_disks ; i++) {
int disk = geo_map(i, start/chunk_size, raid_disks,
--
2.7.5

@ -0,0 +1,33 @@
From 7758ada9f3872cc9cb4c76c733dbc553562b3d7d Mon Sep 17 00:00:00 2001
From: Kinga Tanska <kinga.tanska@intel.com>
Date: Fri, 29 May 2020 08:31:36 +0200
Subject: [PATCH 082/108] Block overwriting existing links while manual
assembly
Manual assembly with existing link caused overwriting
this link. Add checking link and block this situation.
Signed-off-by: Kinga Tanska <kinga.tanska@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Assemble.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/Assemble.c b/Assemble.c
index 3e5d4e6..ed0ddfb 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -1482,6 +1482,10 @@ try_again:
name = content->name;
break;
}
+ if (mddev && map_by_name(&map, mddev) != NULL) {
+ pr_err("Cannot create device with %s because is in use\n", mddev);
+ goto out;
+ }
if (!auto_assem)
/* If the array is listed in mdadm.conf or on
* command line, then we trust the name
--
2.7.5

@ -0,0 +1,76 @@
From 2cf0433063203fca10d26629c9e090b51fb1d806 Mon Sep 17 00:00:00 2001
From: David Favro <dfavro@meta-dynamic.com>
Date: Sat, 23 May 2020 08:24:59 -0400
Subject: [PATCH 083/108] Detect too-small device: error rather than
underflow/crash
For 1.x metadata, when the user requested creation of an array on
component devices that were too small even to hold the superblock,
an undetected integer wraparound (underflow) resulted in an enormous
computed size which resulted in various follow-on errors such as
floating-point exception.
This patch detects this condition, prints a reasonable diagnostic
message, and refuses to continue.
Signed-off-by: David Favro <dfavro@meta-dynamic.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
super1.c | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/super1.c b/super1.c
index e0d80be..7664883 100644
--- a/super1.c
+++ b/super1.c
@@ -2753,6 +2753,7 @@ static int validate_geometry1(struct supertype *st, int level,
unsigned long long ldsize, devsize;
int bmspace;
unsigned long long headroom;
+ unsigned long long overhead;
int fd;
if (level == LEVEL_CONTAINER) {
@@ -2785,10 +2786,6 @@ static int validate_geometry1(struct supertype *st, int level,
close(fd);
devsize = ldsize >> 9;
- if (devsize < 24) {
- *freesize = 0;
- return 0;
- }
/* creating: allow suitable space for bitmap or PPL */
if (consistency_policy == CONSISTENCY_POLICY_PPL)
@@ -2829,15 +2826,27 @@ static int validate_geometry1(struct supertype *st, int level,
case 0: /* metadata at end. Round down and subtract space to reserve */
devsize = (devsize & ~(4ULL*2-1));
/* space for metadata, bblog, bitmap/ppl */
- devsize -= 8*2 + 8 + bmspace;
+ overhead = 8*2 + 8 + bmspace;
+ if (devsize < overhead) /* detect underflow */
+ goto dev_too_small_err;
+ devsize -= overhead;
break;
case 1:
case 2:
+ if (devsize < data_offset) /* detect underflow */
+ goto dev_too_small_err;
devsize -= data_offset;
break;
}
*freesize = devsize;
return 1;
+
+/* Error condition, device cannot even hold the overhead. */
+dev_too_small_err:
+ fprintf(stderr, "device %s is too small (%lluK) for "
+ "required metadata!\n", subdev, devsize>>1);
+ *freesize = 0;
+ return 0;
}
void *super1_make_v0(struct supertype *st, struct mdinfo *info, mdp_super_t *sb0)
--
2.7.5

@ -0,0 +1,123 @@
From 8e41153c91cdce696618c527906648625217470c Mon Sep 17 00:00:00 2001
From: Paul Menzel <pmenzel@molgen.mpg.de>
Date: Thu, 28 May 2020 16:52:24 +0200
Subject: [PATCH 084/108] Use more secure HTTPS URLs
All URLs in the source are available over HTTPS, so convert all URLs to
HTTPS with the command below.
git grep -l 'http://' | xargs sed -i 's,http://,https://,g'
Revert the changes to announcement files `ANNOUNCE-*` as requested by
the maintainer.
Cc: linux-raid@vger.kernel.org
Signed-off-by: Paul Menzel <pmenzel@molgen.mpg.de>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
external-reshape-design.txt | 2 +-
mdadm.8.in | 6 +++---
mdadm.spec | 4 ++--
raid6check.8 | 2 +-
restripe.c | 2 +-
udev-md-raid-safe-timeouts.rules | 2 +-
6 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/external-reshape-design.txt b/external-reshape-design.txt
index 10c57cc..e4cf4e1 100644
--- a/external-reshape-design.txt
+++ b/external-reshape-design.txt
@@ -277,4 +277,4 @@ sync_action
...
-[1]: Linux kernel design patterns - part 3, Neil Brown http://lwn.net/Articles/336262/
+[1]: Linux kernel design patterns - part 3, Neil Brown https://lwn.net/Articles/336262/
diff --git a/mdadm.8.in b/mdadm.8.in
index 9e7cb96..7f32762 100644
--- a/mdadm.8.in
+++ b/mdadm.8.in
@@ -367,7 +367,7 @@ Use the Intel(R) Matrix Storage Manager metadata format. This creates a
which is managed in a similar manner to DDF, and is supported by an
option-rom on some platforms:
.IP
-.B http://www.intel.com/design/chipsets/matrixstorage_sb.htm
+.B https://www.intel.com/design/chipsets/matrixstorage_sb.htm
.PP
.RE
@@ -3407,7 +3407,7 @@ was previously known as
For further information on mdadm usage, MD and the various levels of
RAID, see:
.IP
-.B http://raid.wiki.kernel.org/
+.B https://raid.wiki.kernel.org/
.PP
(based upon Jakob \(/Ostergaard's Software\-RAID.HOWTO)
.PP
@@ -3415,7 +3415,7 @@ The latest version of
.I mdadm
should always be available from
.IP
-.B http://www.kernel.org/pub/linux/utils/raid/mdadm/
+.B https://www.kernel.org/pub/linux/utils/raid/mdadm/
.PP
Related man pages:
.PP
diff --git a/mdadm.spec b/mdadm.spec
index 1c66894..506ea33 100644
--- a/mdadm.spec
+++ b/mdadm.spec
@@ -2,8 +2,8 @@ Summary: mdadm is used for controlling Linux md devices (aka RAID arrays)
Name: mdadm
Version: 4.1
Release: 1
-Source: http://www.kernel.org/pub/linux/utils/raid/mdadm/mdadm-%{version}.tar.gz
-URL: http://neil.brown.name/blog/mdadm
+Source: https://www.kernel.org/pub/linux/utils/raid/mdadm/mdadm-%{version}.tar.gz
+URL: https://neil.brown.name/blog/mdadm
License: GPL
Group: Utilities/System
BuildRoot: %{_tmppath}/%{name}-root
diff --git a/raid6check.8 b/raid6check.8
index 5003343..8999ca8 100644
--- a/raid6check.8
+++ b/raid6check.8
@@ -86,7 +86,7 @@ The latest version of
.I raid6check
should always be available from
.IP
-.B http://www.kernel.org/pub/linux/utils/raid/mdadm/
+.B https://www.kernel.org/pub/linux/utils/raid/mdadm/
.PP
Related man pages:
.PP
diff --git a/restripe.c b/restripe.c
index 86e1d00..a7a7229 100644
--- a/restripe.c
+++ b/restripe.c
@@ -333,7 +333,7 @@ void make_tables(void)
/* Compute log and inverse log */
/* Modified code from:
- * http://web.eecs.utk.edu/~plank/plank/papers/CS-96-332.html
+ * https://web.eecs.utk.edu/~plank/plank/papers/CS-96-332.html
*/
b = 1;
raid6_gflog[0] = 0;
diff --git a/udev-md-raid-safe-timeouts.rules b/udev-md-raid-safe-timeouts.rules
index 13c23d8..12bdcaa 100644
--- a/udev-md-raid-safe-timeouts.rules
+++ b/udev-md-raid-safe-timeouts.rules
@@ -13,7 +13,7 @@
#
# You should have received a copy of the GNU General Public License
# along with mdraid-safe-timeouts. If not, see
-# <http://www.gnu.org/licenses/>.
+# <https://www.gnu.org/licenses/>.
# This file causes block devices with Linux RAID (mdadm) signatures to
# attempt to set safe timeouts for the drives involved
--
2.7.5

@ -0,0 +1,28 @@
From bcf40dbb5bf7db9d55a877b805ebb95c2008a132 Mon Sep 17 00:00:00 2001
From: Jes Sorensen <jsorensen@fb.com>
Date: Fri, 12 Jun 2020 10:49:11 -0400
Subject: [PATCH 085/108] Update link to Intel page for IMSM
The old design page is gone, so update to the current overview page.
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
mdadm.8.in | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mdadm.8.in b/mdadm.8.in
index 7f32762..1474602 100644
--- a/mdadm.8.in
+++ b/mdadm.8.in
@@ -367,7 +367,7 @@ Use the Intel(R) Matrix Storage Manager metadata format. This creates a
which is managed in a similar manner to DDF, and is supported by an
option-rom on some platforms:
.IP
-.B https://www.intel.com/design/chipsets/matrixstorage_sb.htm
+.B https://www.intel.com/content/www/us/en/support/products/122484/memory-and-storage/ssd-software/intel-virtual-raid-on-cpu-intel-vroc.html
.PP
.RE
--
2.7.5

@ -0,0 +1,64 @@
From 77b72fa828132a35c8b2e08d3fb07eea80b11895 Mon Sep 17 00:00:00 2001
From: allenpeng <allenpeng@synology.com>
Date: Fri, 12 Jun 2020 17:00:39 +0800
Subject: [PATCH 086/108] mdadm/Grow: prevent md's fd from being occupied
during delayed time
If we start reshaping on md which shares sub-devices with another
resyncing md, it may be forced to wait for others to complete. mdadm
occupies the md's fd during this time, which causes the md can not be
stopped and the filesystem can not be mounted on the md. We can close
md's fd earlier to solve this problem.
Reproducible Steps:
1. create two partitions on sda, sdb, sdc, sdd
2. create raid1 with sda1, sdb1
mdadm -C /dev/md1 --assume-clean -l1 -n2 /dev/sda1 /dev/sdb1
3. create raid5 with sda2, sdb2, sdc2
mdadm -C /dev/md2 --assume-clean -l5 -n3 /dev/sda2 /dev/sdb2 /dev/sdc2
4. start resync at md1
echo repair > /sys/block/md1/md/sync_action
5. reshape raid5 to raid6
mdadm -a /dev/md2 /dev/sdd2
mdadm --grow /dev/md2 -n4 -l6 --backup-file=/root/md2-backup
Now mdadm is occupying the fd of md2, causing md2 unable to be stopped
6.Try to stop md2, an error message shows
mdadm -S /dev/md2
mdadm: Cannot get exclusive access to /dev/md3:Perhaps a running process,
mounted filesystem or active volume group?
Reviewed-by: Alex Wu <alexwu@synology.com>
Reviewed-by: BingJing Chang <bingjingc@synology.com>
Reviewed-by: Danny Shih <dannyshih@synology.com>
Signed-off-by: ChangSyun Peng <allenpeng@synology.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Grow.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Grow.c b/Grow.c
index 764374f..57db7d4 100644
--- a/Grow.c
+++ b/Grow.c
@@ -3517,6 +3517,7 @@ started:
return 0;
}
+ close(fd);
/* Now we just need to kick off the reshape and watch, while
* handling backups of the data...
* This is all done by a forked background process.
@@ -3569,7 +3570,6 @@ started:
mdstat_wait(30 - (delayed-1) * 25);
} while (delayed);
mdstat_close();
- close(fd);
if (check_env("MDADM_GROW_VERIFY"))
fd = open(devname, O_RDONLY | O_DIRECT);
else
--
2.7.5

@ -0,0 +1,36 @@
From 138a9e9bbe2622eafc90c976b82f3d84895dbebd Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Mon, 27 Jul 2020 09:14:20 +0800
Subject: [PATCH 087/108] Specify nodes number when updating cluster nodes
Now it allows updating cluster nodes without specify --nodes. It can write superblock
with zero nodes. It can break the current cluster. Add this check to avoid this problem.
v2: It needs check c.update first to avoid NULL pointer reference
v3: Wol points the typo error
Signed-off-by: Xiao Ni <xni@redhat.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
mdadm.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/mdadm.c b/mdadm.c
index 13dc24e..1b3467f 100644
--- a/mdadm.c
+++ b/mdadm.c
@@ -1433,6 +1433,11 @@ int main(int argc, char *argv[])
}
}
+ if (c.update && strcmp(c.update, "nodes") == 0 && c.nodes == 0) {
+ pr_err("Please specify nodes number with --nodes\n");
+ exit(1);
+ }
+
if (c.backup_file && data_offset != INVALID_SECTORS) {
pr_err("--backup-file and --data-offset are incompatible\n");
exit(2);
--
2.7.5

@ -0,0 +1,32 @@
From 5e592e1ed809b94670872b7a4629317fc1c8a5c1 Mon Sep 17 00:00:00 2001
From: Winston Weinert <winston@ml1.net>
Date: Wed, 22 Jul 2020 08:33:22 -0500
Subject: [PATCH 088/108] mdadm/md.4: update path to in-kernel-tree
documentation
Documentation/md.txt was renamed to Documentation/admin-guide/md.rst
in linux commit 9d85025b0418163fae079c9ba8f8445212de8568 (Oct 26,
2016).
Signed-off-by: Winston Weinert <winston@ml1.net>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
md.4 | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/md.4 b/md.4
index 0712af2..aecff38 100644
--- a/md.4
+++ b/md.4
@@ -1061,7 +1061,7 @@ which contains various files for providing access to information about
the array.
This interface is documented more fully in the file
-.B Documentation/md.txt
+.B Documentation/admin-guide/md.rst
which is distributed with the kernel sources. That file should be
consulted for full documentation. The following are just a selection
of attribute files that are available.
--
2.7.5

@ -0,0 +1,34 @@
From 5f4184557a98bb641a7889e280265109c73e2f43 Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
Date: Thu, 6 Aug 2020 13:57:50 +0200
Subject: [PATCH 089/108] manual: update --examine-badblocks
IMSM also supports it.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
mdadm.8.in | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/mdadm.8.in b/mdadm.8.in
index 1474602..ab832e8 100644
--- a/mdadm.8.in
+++ b/mdadm.8.in
@@ -1695,9 +1695,11 @@ does not report the bitmap for that array.
.TP
.B \-\-examine\-badblocks
List the bad-blocks recorded for the device, if a bad-blocks list has
-been configured. Currently only
+been configured. Currently only
.B 1.x
-metadata supports bad-blocks lists.
+and
+.B IMSM
+metadata support bad-blocks lists.
.TP
.BI \-\-dump= directory
--
2.7.5

@ -0,0 +1,68 @@
From 64bf4dff34301a4b44883a8bc03f7835faef121e Mon Sep 17 00:00:00 2001
From: Lidong Zhong <lidong.zhong@suse.com>
Date: Mon, 14 Sep 2020 10:52:18 +0800
Subject: [PATCH 090/108] Detail: show correct raid level when the array is
inactive
Sometimes the raid level in the output of `mdadm -D /dev/mdX` is
misleading when the array is in inactive state. Here is a testcase for
introduction.
1\ creating a raid1 device with two disks. Specify a different hostname
rather than the real one for later verfication.
node1:~ # mdadm --create /dev/md0 --homehost TESTARRAY -o -l 1 -n 2 /dev/sdb
/dev/sdc
2\ remove one of the devices and reboot
3\ show the detail of raid1 device
node1:~ # mdadm -D /dev/md127
/dev/md127:
Version : 1.2
Raid Level : raid0
Total Devices : 1
Persistence : Superblock is persistent
State : inactive
Working Devices : 1
You can see that the "Raid Level" in /dev/md127 is raid0 now.
After step 2\ is done, the degraded raid1 device is recognized
as a "foreign" array in 64-md-raid-assembly.rules. And thus the
timer to activate the raid1 device is not triggered. The array
level returned from GET_ARRAY_INFO ioctl is 0. And the string
shown for "Raid Level" is
str = map_num(pers, array.level);
And the definition of pers is
mapping_t pers[] = {
{ "linear", LEVEL_LINEAR},
{ "raid0", 0},
{ "0", 0}
...
So the misleading "raid0" is shown in this testcase.
Changelog:
v1: don't show "Raid Level" when array is inactive
Signed-off-by: Lidong Zhong <lidong.zhong@suse.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Detail.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/Detail.c b/Detail.c
index 24eeba0..b6587c8 100644
--- a/Detail.c
+++ b/Detail.c
@@ -224,7 +224,10 @@ int Detail(char *dev, struct context *c)
}
/* Ok, we have some info to print... */
- str = map_num(pers, array.level);
+ if (inactive)
+ str = map_num(pers, info->array.level);
+ else
+ str = map_num(pers, array.level);
if (c->export) {
if (array.raid_disks) {
--
2.7.5

@ -0,0 +1,29 @@
From 2ce091724031e18f522994ffd1e5eb0dc404bcba Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Tue, 15 Sep 2020 15:44:42 +0800
Subject: [PATCH 091/108] Don't create bitmap for raid5 with journal disk
Journal disk and bitmap can't exist at the same time. It needs to check if the raid
has a journal disk when creating bitmap.
Signed-off-by: Xiao Ni <xni@redhat.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Create.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/Create.c b/Create.c
index 6f84e5b..0efa19c 100644
--- a/Create.c
+++ b/Create.c
@@ -542,6 +542,7 @@ int Create(struct supertype *st, char *mddev,
if (!s->bitmap_file &&
s->level >= 1 &&
st->ss->add_internal_bitmap &&
+ s->journaldisks == 0 &&
(s->consistency_policy != CONSISTENCY_POLICY_RESYNC &&
s->consistency_policy != CONSISTENCY_POLICY_PPL) &&
(s->write_behind || s->size > 100*1024*1024ULL)) {
--
2.7.5

@ -0,0 +1,70 @@
From e2308733910a157b0a4d4e78721f239d44b91a24 Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
Date: Wed, 9 Sep 2020 10:31:17 +0200
Subject: [PATCH 092/108] Monitor: refresh mdstat fd after select
After 52209d6ee118 ("Monitor: release /proc/mdstat fd when no arrays
present") mdstat fd is closed if mdstat is empty or cannot be opened.
It causes that monitor is not able to select on mdstat. Select
doesn't fail because it gets valid descriptor to a different resource.
As a result any new event will be unnoticed until timeout (delay).
Refresh mdstat after wake up, don't poll on wrong resource.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Monitor.c | 6 +++---
mdstat.c | 4 ++--
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/Monitor.c b/Monitor.c
index 2d6b3b9..80a3200 100644
--- a/Monitor.c
+++ b/Monitor.c
@@ -216,8 +216,6 @@ int Monitor(struct mddev_dev *devlist,
if (mdstat)
free_mdstat(mdstat);
mdstat = mdstat_read(oneshot ? 0 : 1, 0);
- if (!mdstat)
- mdstat_close();
for (st = statelist; st; st = st->next)
if (check_array(st, mdstat, c->test, &info,
@@ -238,8 +236,10 @@ int Monitor(struct mddev_dev *devlist,
if (!new_found) {
if (oneshot)
break;
- else
+ else {
mdstat_wait(c->delay);
+ mdstat_close();
+ }
}
c->test = 0;
diff --git a/mdstat.c b/mdstat.c
index 20577a3..48559e6 100644
--- a/mdstat.c
+++ b/mdstat.c
@@ -135,7 +135,6 @@ struct mdstat_ent *mdstat_read(int hold, int start)
if (hold && mdstat_fd != -1) {
off_t offset = lseek(mdstat_fd, 0L, 0);
if (offset == (off_t)-1) {
- mdstat_close();
return NULL;
}
fd = dup(mdstat_fd);
@@ -312,7 +311,8 @@ void mdstat_wait(int seconds)
if (mdstat_fd >= 0) {
FD_SET(mdstat_fd, &fds);
maxfd = mdstat_fd;
- }
+ } else
+ return;
tm.tv_sec = seconds;
tm.tv_usec = 0;
select(maxfd + 1, NULL, NULL, &fds, &tm);
--
2.7.5

@ -0,0 +1,78 @@
From 007087d0898a045901e4e120296e6d9b845b20a6 Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
Date: Wed, 9 Sep 2020 10:31:18 +0200
Subject: [PATCH 093/108] Monitor: stop notifing about containers.
Stop reporting any events from container but still track them,
it is important for spare migration.
Stop mdmonitor if no redundant array is presented in mdstat.
There is nothing to follow.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Monitor.c | 19 ++++++++++++++++---
1 file changed, 16 insertions(+), 3 deletions(-)
diff --git a/Monitor.c b/Monitor.c
index 80a3200..aed7a69 100644
--- a/Monitor.c
+++ b/Monitor.c
@@ -212,15 +212,24 @@ int Monitor(struct mddev_dev *devlist,
int new_found = 0;
struct state *st, **stp;
int anydegraded = 0;
+ int anyredundant = 0;
if (mdstat)
free_mdstat(mdstat);
mdstat = mdstat_read(oneshot ? 0 : 1, 0);
- for (st = statelist; st; st = st->next)
+ for (st = statelist; st; st = st->next) {
if (check_array(st, mdstat, c->test, &info,
increments, c->prefer))
anydegraded = 1;
+ /* for external arrays, metadata is filled for
+ * containers only
+ */
+ if (st->metadata && st->metadata->ss->external)
+ continue;
+ if (st->err == 0 && !anyredundant)
+ anyredundant = 1;
+ }
/* now check if there are any new devices found in mdstat */
if (c->scan)
@@ -236,6 +245,9 @@ int Monitor(struct mddev_dev *devlist,
if (!new_found) {
if (oneshot)
break;
+ else if (!anyredundant) {
+ break;
+ }
else {
mdstat_wait(c->delay);
mdstat_close();
@@ -542,7 +554,8 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
st->err = 0;
st->percent = RESYNC_NONE;
new_array = 1;
- alert("NewArray", st->devname, NULL, ainfo);
+ if (!is_container)
+ alert("NewArray", st->devname, NULL, ainfo);
}
if (st->utime == array.utime && st->failed == sra->array.failed_disks &&
@@ -676,7 +689,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
return retval;
disappeared:
- if (!st->err)
+ if (!st->err && !is_container)
alert("DeviceDisappeared", dev, NULL, ainfo);
st->err++;
goto out;
--
2.7.5

@ -0,0 +1,103 @@
From cab9c67d461c65a1138359f9f6d39636466b90e4 Mon Sep 17 00:00:00 2001
From: Blazej Kucman <blazej.kucman@intel.com>
Date: Wed, 9 Sep 2020 10:31:19 +0200
Subject: [PATCH 094/108] mdmonitor: set small delay once
If mdmonitor is awakened by event, set small delay once
to deal with udev and mdadm.
Signed-off-by: Blazej Kucman <blazej.kucman@intel.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Monitor.c | 14 +++++++++++++-
mdadm.h | 2 +-
mdstat.c | 18 +++++++++++++++---
3 files changed, 29 insertions(+), 5 deletions(-)
diff --git a/Monitor.c b/Monitor.c
index aed7a69..0fb4f77 100644
--- a/Monitor.c
+++ b/Monitor.c
@@ -128,6 +128,7 @@ int Monitor(struct mddev_dev *devlist,
char *mailfrom;
struct alert_info info;
struct mddev_ident *mdlist;
+ int delay_for_event = c->delay;
if (!mailaddr) {
mailaddr = conf_get_mailaddr();
@@ -249,7 +250,18 @@ int Monitor(struct mddev_dev *devlist,
break;
}
else {
- mdstat_wait(c->delay);
+ int wait_result = mdstat_wait(delay_for_event);
+
+ /*
+ * If mdmonitor is awaken by event, set small delay once
+ * to deal with udev and mdadm.
+ */
+ if (wait_result != 0) {
+ if (c->delay > 5)
+ delay_for_event = 5;
+ } else
+ delay_for_event = c->delay;
+
mdstat_close();
}
}
diff --git a/mdadm.h b/mdadm.h
index 399478b..4961c0f 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -628,7 +628,7 @@ struct mdstat_ent {
extern struct mdstat_ent *mdstat_read(int hold, int start);
extern void mdstat_close(void);
extern void free_mdstat(struct mdstat_ent *ms);
-extern void mdstat_wait(int seconds);
+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);
diff --git a/mdstat.c b/mdstat.c
index 48559e6..dd96cca 100644
--- a/mdstat.c
+++ b/mdstat.c
@@ -302,7 +302,17 @@ void mdstat_close(void)
mdstat_fd = -1;
}
-void mdstat_wait(int seconds)
+/*
+ * function: mdstat_wait
+ * Description: Function waits for event on mdstat.
+ * Parameters:
+ * seconds - timeout for waiting
+ * Returns:
+ * > 0 - detected event
+ * 0 - timeout
+ * < 0 - detected error
+ */
+int mdstat_wait(int seconds)
{
fd_set fds;
struct timeval tm;
@@ -312,10 +322,12 @@ void mdstat_wait(int seconds)
FD_SET(mdstat_fd, &fds);
maxfd = mdstat_fd;
} else
- return;
+ return -1;
+
tm.tv_sec = seconds;
tm.tv_usec = 0;
- select(maxfd + 1, NULL, NULL, &fds, &tm);
+
+ return select(maxfd + 1, NULL, NULL, &fds, &tm);
}
void mdstat_wait_fd(int fd, const sigset_t *sigmask)
--
2.7.5

@ -0,0 +1,103 @@
From 7f3b2d1d1621cbdc60b5af4a41445391010fe9e1 Mon Sep 17 00:00:00 2001
From: Blazej Kucman <blazej.kucman@intel.com>
Date: Wed, 9 Sep 2020 10:31:20 +0200
Subject: [PATCH 095/108] Check if other Monitor instance running before fork.
Make error message visible to the user.
Signed-off-by: Blazej Kucman <blazej.kucman@intel.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Monitor.c | 44 ++++++++++++++++++++++++++++----------------
1 file changed, 28 insertions(+), 16 deletions(-)
diff --git a/Monitor.c b/Monitor.c
index 0fb4f77..7fd4808 100644
--- a/Monitor.c
+++ b/Monitor.c
@@ -63,6 +63,7 @@ struct alert_info {
};
static int make_daemon(char *pidfile);
static int check_one_sharer(int scan);
+static void write_autorebuild_pid(void);
static void alert(char *event, char *dev, char *disc, struct alert_info *info);
static int check_array(struct state *st, struct mdstat_ent *mdstat,
int test, struct alert_info *info,
@@ -153,6 +154,11 @@ int Monitor(struct mddev_dev *devlist,
info.mailfrom = mailfrom;
info.dosyslog = dosyslog;
+ if (share){
+ if (check_one_sharer(c->scan))
+ return 1;
+ }
+
if (daemonise) {
int rv = make_daemon(pidfile);
if (rv >= 0)
@@ -160,8 +166,7 @@ int Monitor(struct mddev_dev *devlist,
}
if (share)
- if (check_one_sharer(c->scan))
- return 1;
+ write_autorebuild_pid();
if (devlist == NULL) {
mdlist = conf_get_ident(NULL);
@@ -328,8 +333,8 @@ static int check_one_sharer(int scan)
int pid;
FILE *comm_fp;
FILE *fp;
- char comm_path[100];
- char path[100];
+ char comm_path[PATH_MAX];
+ char path[PATH_MAX];
char comm[20];
sprintf(path, "%s/autorebuild.pid", MDMON_DIR);
@@ -356,21 +361,28 @@ static int check_one_sharer(int scan)
}
fclose(fp);
}
- if (scan) {
- if (mkdir(MDMON_DIR, S_IRWXU) < 0 && errno != EEXIST) {
+ return 0;
+}
+
+static void write_autorebuild_pid()
+{
+ char path[PATH_MAX];
+ int pid;
+ FILE *fp;
+ sprintf(path, "%s/autorebuild.pid", MDMON_DIR);
+
+ if (mkdir(MDMON_DIR, S_IRWXU) < 0 && errno != EEXIST) {
+ pr_err("Can't create autorebuild.pid file\n");
+ } else {
+ fp = fopen(path, "w");
+ if (!fp)
pr_err("Can't create autorebuild.pid file\n");
- } else {
- fp = fopen(path, "w");
- if (!fp)
- pr_err("Cannot create autorebuild.pidfile\n");
- else {
- pid = getpid();
- fprintf(fp, "%d\n", pid);
- fclose(fp);
- }
+ else {
+ pid = getpid();
+ fprintf(fp, "%d\n", pid);
+ fclose(fp);
}
}
- return 0;
}
static void alert(char *event, char *dev, char *disc, struct alert_info *info)
--
2.7.5

@ -0,0 +1,136 @@
From 97b51a2c2d00b79a59f2a8e37134031b0c9e0223 Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.de>
Date: Wed, 14 Oct 2020 13:12:48 +1100
Subject: [PATCH 096/108] Super1: allow RAID0 layout setting to be removed.
Once the RAID0 layout has been set, the RAID0 array cannot be assembled
on an older kernel which doesn't understand layouts.
This is an intentional safety feature, but sometimes people need the
ability to roll-back to a previously working configuration.
So add "--update=layout-unspecified" to remove RAID0 layout information
from the superblock.
Running "--assemble --update=layout-unspecified" will cause the assembly
the fail when run on a newer kernel, but will allow it to work on
an older kernel.
Signed-off-by: NeilBrown <neilb@suse.de>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
md.4 | 13 +++++++++++++
mdadm.8.in | 15 +++++++++++++--
mdadm.c | 5 +++--
super1.c | 6 +++++-
4 files changed, 34 insertions(+), 5 deletions(-)
diff --git a/md.4 b/md.4
index aecff38..60fdd27 100644
--- a/md.4
+++ b/md.4
@@ -215,6 +215,19 @@ option or the
.B "--update=layout-alternate"
option.
+Once you have updated the layout you will not be able to mount the array
+on an older kernel. If you need to revert to an older kernel, the
+layout information can be erased with the
+.B "--update=layout-unspecificed"
+option. If you use this option to
+.B --assemble
+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
+this bug, and you must be sure that the kernel you use matches the
+layout of the array.
+
.SS RAID1
A RAID1 array is also known as a mirrored set (though mirrors tend to
diff --git a/mdadm.8.in b/mdadm.8.in
index ab832e8..34a93a8 100644
--- a/mdadm.8.in
+++ b/mdadm.8.in
@@ -1213,6 +1213,7 @@ argument given to this flag can be one of
.BR no\-ppl ,
.BR layout\-original ,
.BR layout\-alternate ,
+.BR layout\-unspecified ,
.BR metadata ,
or
.BR super\-minor .
@@ -1368,8 +1369,9 @@ The
.B layout\-original
and
.B layout\-alternate
-options are for RAID0 arrays in use before Linux 5.4. If the array was being
-used with Linux 3.13 or earlier, then to assemble the array on a new kernel,
+options are for RAID0 arrays with non-uniform devices size that were in
+use before Linux 5.4. If the array was being used with Linux 3.13 or
+earlier, then to assemble the array on a new kernel,
.B \-\-update=layout\-original
must be given. If the array was created and used with a kernel from Linux 3.14 to
Linux 5.3, then
@@ -1379,6 +1381,15 @@ will happen normally.
For more information, see
.IR md (4).
+The
+.B layout\-unspecified
+option reverts the effect of
+.B layout\-orignal
+or
+.B layout\-alternate
+and allows the array to be again used on a kernel prior to Linux 5.3.
+This option should be used with great caution.
+
.TP
.BR \-\-freeze\-reshape
Option is intended to be used in start-up scripts during initrd boot phase.
diff --git a/mdadm.c b/mdadm.c
index 1b3467f..493d70e 100644
--- a/mdadm.c
+++ b/mdadm.c
@@ -796,7 +796,8 @@ int main(int argc, char *argv[])
if (strcmp(c.update, "revert-reshape") == 0)
continue;
if (strcmp(c.update, "layout-original") == 0 ||
- strcmp(c.update, "layout-alternate") == 0)
+ strcmp(c.update, "layout-alternate") == 0 ||
+ strcmp(c.update, "layout-unspecified") == 0)
continue;
if (strcmp(c.update, "byteorder") == 0) {
if (ss) {
@@ -828,7 +829,7 @@ int main(int argc, char *argv[])
" 'summaries', 'homehost', 'home-cluster', 'byteorder', 'devicesize',\n"
" 'no-bitmap', 'metadata', 'revert-reshape'\n"
" 'bbl', 'no-bbl', 'force-no-bbl', 'ppl', 'no-ppl'\n"
- " 'layout-original', 'layout-alternate'\n"
+ " 'layout-original', 'layout-alternate', 'layout-unspecified'\n"
);
exit(outf == stdout ? 0 : 2);
diff --git a/super1.c b/super1.c
index 7664883..8b0d6ff 100644
--- a/super1.c
+++ b/super1.c
@@ -1551,11 +1551,15 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
else if (strcmp(update, "nofailfast") == 0)
sb->devflags &= ~FailFast1;
else if (strcmp(update, "layout-original") == 0 ||
- strcmp(update, "layout-alternate") == 0) {
+ strcmp(update, "layout-alternate") == 0 ||
+ strcmp(update, "layout-unspecified") == 0) {
if (__le32_to_cpu(sb->level) != 0) {
pr_err("%s: %s only supported for RAID0\n",
devname?:"", update);
rv = -1;
+ } else if (strcmp(update, "layout-unspecified") == 0) {
+ sb->feature_map &= ~__cpu_to_le32(MD_FEATURE_RAID0_LAYOUT);
+ sb->layout = 0;
} else {
sb->feature_map |= __cpu_to_le32(MD_FEATURE_RAID0_LAYOUT);
sb->layout = __cpu_to_le32(update[7] == 'o' ? 1 : 2);
--
2.7.5

@ -0,0 +1,33 @@
From c3129b39a7d467eec063681529f46f84a2a85308 Mon Sep 17 00:00:00 2001
From: Lidong Zhong <lidong.zhong@suse.com>
Date: Sun, 22 Nov 2020 23:12:29 +0800
Subject: [PATCH 097/108] Detail: fix segfault during IMSM raid creation
It can be reproduced with non IMSM hardware and IMSM_NO_PLATFORM
environmental variable set. The array state is inactive when creating
an IMSM container. And the structure info is NULL because load_super()
always fails since no intel HBA information could be obtained.
Signed-off-by: Lidong Zhong <lidong.zhong@suse.com>
Reported-by: Tkaczyk Mariusz <mariusz.tkaczyk@intel.com>
Fixes: 64bf4dff3430 (Detail: show correct raid level when the array is inactive)
---
Detail.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Detail.c b/Detail.c
index b6587c8..ea86884 100644
--- a/Detail.c
+++ b/Detail.c
@@ -224,7 +224,7 @@ int Detail(char *dev, struct context *c)
}
/* Ok, we have some info to print... */
- if (inactive)
+ if (inactive && info)
str = map_num(pers, info->array.level);
else
str = map_num(pers, array.level);
--
2.7.5

@ -0,0 +1,37 @@
From ce559078a5650afb9f635204b31a89a1fa0061e3 Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Tue, 24 Nov 2020 13:39:49 +0100
Subject: [PATCH 098/108] Create.c: close mdfd and generate uevent
During mdfd closing change event is not generated because open() is
called before start watching mddevice by udev.
Device is ready at this stage. Unblock device, close fd and
generate event to give a chance next layers to work.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
Create.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/Create.c b/Create.c
index 0efa19c..51f8826 100644
--- a/Create.c
+++ b/Create.c
@@ -1083,12 +1083,9 @@ int Create(struct supertype *st, char *mddev,
} else {
pr_err("not starting array - not enough devices.\n");
}
- close(mdfd);
- /* Give udev a moment to process the Change event caused
- * by the close.
- */
- usleep(100*1000);
udev_unblock();
+ close(mdfd);
+ sysfs_uevent(&info, "change");
return 0;
abort:
--
2.7.5

@ -0,0 +1,166 @@
From 895ffd992954069e4ea67efb8a85bb0fd72c3707 Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Tue, 24 Nov 2020 14:15:15 +0100
Subject: [PATCH 099/108] imsm: update num_data_stripes according to dev_size
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
If array was created in UEFI there is possibility that
member size is not rounded to 1MB. After any size reconfiguration
it will be rounded down to 1MB per each member but the old
component size will remain in metadata.
During reshape old array size is calculated from component size because
dev_size is not a part of map and is bumped to new value quickly.
It may result in size mismatch if array is assembled during reshape.
If difference in calculated size and dev_size is observed try to fix it.
num_data_stripes value can be safety updated to smaller value if array
doesn't occuppy whole reserved component space.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
super-intel.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 78 insertions(+), 6 deletions(-)
diff --git a/super-intel.c b/super-intel.c
index 3a73d2b..9562064 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -3453,7 +3453,6 @@ static void getinfo_super_imsm_volume(struct supertype *st, struct mdinfo *info,
__u64 blocks_per_unit = blocks_per_migr_unit(super,
dev);
__u64 units = current_migr_unit(migr_rec);
- unsigned long long array_blocks;
int used_disks;
if (__le32_to_cpu(migr_rec->ascending_migr) &&
@@ -3472,12 +3471,8 @@ static void getinfo_super_imsm_volume(struct supertype *st, struct mdinfo *info,
used_disks = imsm_num_data_members(prev_map);
if (used_disks > 0) {
- array_blocks = per_dev_array_size(map) *
+ info->custom_array_size = per_dev_array_size(map) *
used_disks;
- info->custom_array_size =
- round_size_to_mb(array_blocks,
- used_disks);
-
}
}
case MIGR_VERIFY:
@@ -11682,6 +11677,68 @@ int imsm_takeover(struct supertype *st, struct geo_params *geo)
return 0;
}
+/* Flush size update if size calculated by num_data_stripes is higher than
+ * imsm_dev_size to eliminate differences during reshape.
+ * Mdmon will recalculate them correctly.
+ * If subarray index is not set then check whole container.
+ * Returns:
+ * 0 - no error occurred
+ * 1 - error detected
+ */
+static int imsm_fix_size_mismatch(struct supertype *st, int subarray_index)
+{
+ struct intel_super *super = st->sb;
+ int tmp = super->current_vol;
+ int ret_val = 1;
+ int i;
+
+ for (i = 0; i < super->anchor->num_raid_devs; i++) {
+ if (subarray_index >= 0 && i != subarray_index)
+ continue;
+ super->current_vol = i;
+ struct imsm_dev *dev = get_imsm_dev(super, super->current_vol);
+ struct imsm_map *map = get_imsm_map(dev, MAP_0);
+ unsigned int disc_count = imsm_num_data_members(map);
+ struct geo_params geo;
+ struct imsm_update_size_change *update;
+ unsigned long long calc_size = per_dev_array_size(map) * disc_count;
+ unsigned long long d_size = imsm_dev_size(dev);
+ int u_size;
+
+ if (calc_size == d_size || dev->vol.migr_type == MIGR_GEN_MIGR)
+ continue;
+
+ /* There is a difference, verify that imsm_dev_size is
+ * rounded correctly and push update.
+ */
+ if (d_size != round_size_to_mb(d_size, disc_count)) {
+ dprintf("imsm: Size of volume %d is not rounded correctly\n",
+ i);
+ goto exit;
+ }
+ memset(&geo, 0, sizeof(struct geo_params));
+ geo.size = d_size;
+ u_size = imsm_create_metadata_update_for_size_change(st, &geo,
+ &update);
+ if (u_size < 1) {
+ dprintf("imsm: Cannot prepare size change update\n");
+ goto exit;
+ }
+ imsm_update_metadata_locally(st, update, u_size);
+ if (st->update_tail) {
+ append_metadata_update(st, update, u_size);
+ flush_metadata_updates(st);
+ st->update_tail = &st->updates;
+ } else {
+ imsm_sync_metadata(st);
+ }
+ }
+ ret_val = 0;
+exit:
+ super->current_vol = tmp;
+ return ret_val;
+}
+
static int imsm_reshape_super(struct supertype *st, unsigned long long size,
int level,
int layout, int chunksize, int raid_disks,
@@ -11718,6 +11775,11 @@ static int imsm_reshape_super(struct supertype *st, unsigned long long size,
struct imsm_update_reshape *u = NULL;
int len;
+ if (imsm_fix_size_mismatch(st, -1)) {
+ dprintf("imsm: Cannot fix size mismatch\n");
+ goto exit_imsm_reshape_super;
+ }
+
len = imsm_create_metadata_update_for_reshape(
st, &geo, old_raid_disks, &u);
@@ -12020,6 +12082,7 @@ static int imsm_manage_reshape(
unsigned long long start_buf_shift; /* [bytes] */
int degraded = 0;
int source_layout = 0;
+ int subarray_index = -1;
if (!sra)
return ret_val;
@@ -12033,6 +12096,7 @@ static int imsm_manage_reshape(
dv->dev->vol.migr_state == 1) {
dev = dv->dev;
migr_vol_qan++;
+ subarray_index = dv->index;
}
}
/* Only one volume can migrate at the same time */
@@ -12217,6 +12281,14 @@ static int imsm_manage_reshape(
/* return '1' if done */
ret_val = 1;
+
+ /* After the reshape eliminate size mismatch in metadata.
+ * Don't update md/component_size here, volume hasn't
+ * to take whole space. It is allowed by kernel.
+ * md/component_size will be set propoperly after next assembly.
+ */
+ imsm_fix_size_mismatch(st, subarray_index);
+
abort:
free(buf);
/* See Grow.c: abort_reshape() for further explanation */
--
2.7.5

@ -0,0 +1,35 @@
From b65c1f4a2340e24ae00babc4399fb4030ff99517 Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Tue, 24 Nov 2020 15:58:53 +0100
Subject: [PATCH 100/108] imsm: remove redundant calls to imsm_get_map
MAP_0 is gotten and the beginning, there is no need to get it again.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
super-intel.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/super-intel.c b/super-intel.c
index 9562064..95f4eaf 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -8598,7 +8598,6 @@ static void imsm_set_disk(struct active_array *a, int n, int state)
break;
}
end_migration(dev, super, map_state);
- map = get_imsm_map(dev, MAP_0);
map->failed_disk_num = ~0;
super->updates_pending++;
a->last_checkpoint = 0;
@@ -8610,7 +8609,6 @@ static void imsm_set_disk(struct active_array *a, int n, int state)
end_migration(dev, super, map_state);
else
map->map_state = map_state;
- map = get_imsm_map(dev, MAP_0);
map->failed_disk_num = ~0;
super->updates_pending++;
break;
--
2.7.5

@ -0,0 +1,55 @@
From ca4b156b2059ee00a9143313267ee4a098967d76 Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Tue, 24 Nov 2020 16:41:01 +0100
Subject: [PATCH 101/108] Monitor: don't use default modes when creating a file
Replace fopen() calls by open() with creation mode directly specified.
This fixes the potential security issue. Use octal values instead masks.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
Monitor.c | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/Monitor.c b/Monitor.c
index 7fd4808..a82e99d 100644
--- a/Monitor.c
+++ b/Monitor.c
@@ -305,8 +305,11 @@ static int make_daemon(char *pidfile)
if (!pidfile)
printf("%d\n", pid);
else {
- FILE *pid_file;
- pid_file=fopen(pidfile, "w");
+ FILE *pid_file = NULL;
+ int fd = open(pidfile, O_WRONLY | O_CREAT | O_TRUNC,
+ 0644);
+ if (fd >= 0)
+ pid_file = fdopen(fd, "w");
if (!pid_file)