diff --git a/SOURCES/0078-Makefile-add-EXTRAVERSION-support.patch b/SOURCES/0078-Makefile-add-EXTRAVERSION-support.patch new file mode 100644 index 0000000..c653eaf --- /dev/null +++ b/SOURCES/0078-Makefile-add-EXTRAVERSION-support.patch @@ -0,0 +1,49 @@ +From 03ab9763f51ddf2030f60f83e76cf9c1b50b726c Mon Sep 17 00:00:00 2001 +From: Tkaczyk Mariusz +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 +Signed-off-by: Jes Sorensen +--- + 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 + diff --git a/SOURCES/0079-uuid.c-split-uuid-stuffs-from-util.c.patch b/SOURCES/0079-uuid.c-split-uuid-stuffs-from-util.c.patch new file mode 100644 index 0000000..dfa9e4d --- /dev/null +++ b/SOURCES/0079-uuid.c-split-uuid-stuffs-from-util.c.patch @@ -0,0 +1,284 @@ +From f4c8a605d2467c0ed25fcba5d27dd56540660e55 Mon Sep 17 00:00:00 2001 +From: Guoqing Jiang +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 +Signed-off-by: Jes Sorensen +--- + 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 :. 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 ++ * ++ * ++ * 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: ++ */ ++ ++#include ++ ++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 :. 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 + diff --git a/SOURCES/0080-Include-count-for-0-character-when-using-strncpy-to-.patch b/SOURCES/0080-Include-count-for-0-character-when-using-strncpy-to-.patch new file mode 100644 index 0000000..f53c559 --- /dev/null +++ b/SOURCES/0080-Include-count-for-0-character-when-using-strncpy-to-.patch @@ -0,0 +1,34 @@ +From 7d90f7603af6b59e7144cef6617a1e9dd42161bd Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +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 +--- + 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 + diff --git a/SOURCES/0081-restripe-fix-ignoring-return-value-of-read-and-lseek.patch b/SOURCES/0081-restripe-fix-ignoring-return-value-of-read-and-lseek.patch new file mode 100644 index 0000000..318239d --- /dev/null +++ b/SOURCES/0081-restripe-fix-ignoring-return-value-of-read-and-lseek.patch @@ -0,0 +1,53 @@ +From d92cee7b374db9944b63bdd6c1784a2dd90ee9ca Mon Sep 17 00:00:00 2001 +From: Guoqing Jiang +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 +Signed-off-by: Jes Sorensen +--- + 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 + diff --git a/SOURCES/0082-Block-overwriting-existing-links-while-manual-assemb.patch b/SOURCES/0082-Block-overwriting-existing-links-while-manual-assemb.patch new file mode 100644 index 0000000..ea7fc5e --- /dev/null +++ b/SOURCES/0082-Block-overwriting-existing-links-while-manual-assemb.patch @@ -0,0 +1,33 @@ +From 7758ada9f3872cc9cb4c76c733dbc553562b3d7d Mon Sep 17 00:00:00 2001 +From: Kinga Tanska +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 +Signed-off-by: Jes Sorensen +--- + 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 + diff --git a/SOURCES/0083-Detect-too-small-device-error-rather-than-underflow-.patch b/SOURCES/0083-Detect-too-small-device-error-rather-than-underflow-.patch new file mode 100644 index 0000000..d3d7bd8 --- /dev/null +++ b/SOURCES/0083-Detect-too-small-device-error-rather-than-underflow-.patch @@ -0,0 +1,76 @@ +From 2cf0433063203fca10d26629c9e090b51fb1d806 Mon Sep 17 00:00:00 2001 +From: David Favro +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 +Signed-off-by: Jes Sorensen +--- + 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 + diff --git a/SOURCES/0084-Use-more-secure-HTTPS-URLs.patch b/SOURCES/0084-Use-more-secure-HTTPS-URLs.patch new file mode 100644 index 0000000..6acb14c --- /dev/null +++ b/SOURCES/0084-Use-more-secure-HTTPS-URLs.patch @@ -0,0 +1,123 @@ +From 8e41153c91cdce696618c527906648625217470c Mon Sep 17 00:00:00 2001 +From: Paul Menzel +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 +Signed-off-by: Jes Sorensen +--- + 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 +-# . ++# . + + # This file causes block devices with Linux RAID (mdadm) signatures to + # attempt to set safe timeouts for the drives involved +-- +2.7.5 + diff --git a/SOURCES/0085-Update-link-to-Intel-page-for-IMSM.patch b/SOURCES/0085-Update-link-to-Intel-page-for-IMSM.patch new file mode 100644 index 0000000..9e9443f --- /dev/null +++ b/SOURCES/0085-Update-link-to-Intel-page-for-IMSM.patch @@ -0,0 +1,28 @@ +From bcf40dbb5bf7db9d55a877b805ebb95c2008a132 Mon Sep 17 00:00:00 2001 +From: Jes Sorensen +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 +--- + 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 + diff --git a/SOURCES/0086-mdadm-Grow-prevent-md-s-fd-from-being-occupied-durin.patch b/SOURCES/0086-mdadm-Grow-prevent-md-s-fd-from-being-occupied-durin.patch new file mode 100644 index 0000000..348682d --- /dev/null +++ b/SOURCES/0086-mdadm-Grow-prevent-md-s-fd-from-being-occupied-durin.patch @@ -0,0 +1,64 @@ +From 77b72fa828132a35c8b2e08d3fb07eea80b11895 Mon Sep 17 00:00:00 2001 +From: allenpeng +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 +Reviewed-by: BingJing Chang +Reviewed-by: Danny Shih +Signed-off-by: ChangSyun Peng +Signed-off-by: Jes Sorensen +--- + 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 + diff --git a/SOURCES/0087-Specify-nodes-number-when-updating-cluster-nodes.patch b/SOURCES/0087-Specify-nodes-number-when-updating-cluster-nodes.patch new file mode 100644 index 0000000..a0e5a37 --- /dev/null +++ b/SOURCES/0087-Specify-nodes-number-when-updating-cluster-nodes.patch @@ -0,0 +1,36 @@ +From 138a9e9bbe2622eafc90c976b82f3d84895dbebd Mon Sep 17 00:00:00 2001 +From: Xiao Ni +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 +Signed-off-by: Jes Sorensen +--- + 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 + diff --git a/SOURCES/0088-mdadm-md.4-update-path-to-in-kernel-tree-documentati.patch b/SOURCES/0088-mdadm-md.4-update-path-to-in-kernel-tree-documentati.patch new file mode 100644 index 0000000..f037b90 --- /dev/null +++ b/SOURCES/0088-mdadm-md.4-update-path-to-in-kernel-tree-documentati.patch @@ -0,0 +1,32 @@ +From 5e592e1ed809b94670872b7a4629317fc1c8a5c1 Mon Sep 17 00:00:00 2001 +From: Winston Weinert +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 +Signed-off-by: Jes Sorensen +--- + 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 + diff --git a/SOURCES/0089-manual-update-examine-badblocks.patch b/SOURCES/0089-manual-update-examine-badblocks.patch new file mode 100644 index 0000000..2150671 --- /dev/null +++ b/SOURCES/0089-manual-update-examine-badblocks.patch @@ -0,0 +1,34 @@ +From 5f4184557a98bb641a7889e280265109c73e2f43 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +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 +Signed-off-by: Jes Sorensen +--- + 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 + diff --git a/SOURCES/0090-Detail-show-correct-raid-level-when-the-array-is-ina.patch b/SOURCES/0090-Detail-show-correct-raid-level-when-the-array-is-ina.patch new file mode 100644 index 0000000..2f771a3 --- /dev/null +++ b/SOURCES/0090-Detail-show-correct-raid-level-when-the-array-is-ina.patch @@ -0,0 +1,68 @@ +From 64bf4dff34301a4b44883a8bc03f7835faef121e Mon Sep 17 00:00:00 2001 +From: Lidong Zhong +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 +Signed-off-by: Jes Sorensen +--- + 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 + diff --git a/SOURCES/0091-Don-t-create-bitmap-for-raid5-with-journal-disk.patch b/SOURCES/0091-Don-t-create-bitmap-for-raid5-with-journal-disk.patch new file mode 100644 index 0000000..a1d7450 --- /dev/null +++ b/SOURCES/0091-Don-t-create-bitmap-for-raid5-with-journal-disk.patch @@ -0,0 +1,29 @@ +From 2ce091724031e18f522994ffd1e5eb0dc404bcba Mon Sep 17 00:00:00 2001 +From: Xiao Ni +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 +Signed-off-by: Jes Sorensen +--- + 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 + diff --git a/SOURCES/0092-Monitor-refresh-mdstat-fd-after-select.patch b/SOURCES/0092-Monitor-refresh-mdstat-fd-after-select.patch new file mode 100644 index 0000000..da94683 --- /dev/null +++ b/SOURCES/0092-Monitor-refresh-mdstat-fd-after-select.patch @@ -0,0 +1,70 @@ +From e2308733910a157b0a4d4e78721f239d44b91a24 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +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 +Signed-off-by: Jes Sorensen +--- + 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 + diff --git a/SOURCES/0093-Monitor-stop-notifing-about-containers.patch b/SOURCES/0093-Monitor-stop-notifing-about-containers.patch new file mode 100644 index 0000000..7c968ce --- /dev/null +++ b/SOURCES/0093-Monitor-stop-notifing-about-containers.patch @@ -0,0 +1,78 @@ +From 007087d0898a045901e4e120296e6d9b845b20a6 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +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 +Signed-off-by: Jes Sorensen +--- + 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 + diff --git a/SOURCES/0094-mdmonitor-set-small-delay-once.patch b/SOURCES/0094-mdmonitor-set-small-delay-once.patch new file mode 100644 index 0000000..2645654 --- /dev/null +++ b/SOURCES/0094-mdmonitor-set-small-delay-once.patch @@ -0,0 +1,103 @@ +From cab9c67d461c65a1138359f9f6d39636466b90e4 Mon Sep 17 00:00:00 2001 +From: Blazej Kucman +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 +Signed-off-by: Mariusz Tkaczyk +Signed-off-by: Jes Sorensen +--- + 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 + diff --git a/SOURCES/0095-Check-if-other-Monitor-instance-running-before-fork.patch b/SOURCES/0095-Check-if-other-Monitor-instance-running-before-fork.patch new file mode 100644 index 0000000..28b0637 --- /dev/null +++ b/SOURCES/0095-Check-if-other-Monitor-instance-running-before-fork.patch @@ -0,0 +1,103 @@ +From 7f3b2d1d1621cbdc60b5af4a41445391010fe9e1 Mon Sep 17 00:00:00 2001 +From: Blazej Kucman +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 +Signed-off-by: Mariusz Tkaczyk +Signed-off-by: Jes Sorensen +--- + 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 + diff --git a/SOURCES/0096-Super1-allow-RAID0-layout-setting-to-be-removed.patch b/SOURCES/0096-Super1-allow-RAID0-layout-setting-to-be-removed.patch new file mode 100644 index 0000000..5512709 --- /dev/null +++ b/SOURCES/0096-Super1-allow-RAID0-layout-setting-to-be-removed.patch @@ -0,0 +1,136 @@ +From 97b51a2c2d00b79a59f2a8e37134031b0c9e0223 Mon Sep 17 00:00:00 2001 +From: NeilBrown +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 +Signed-off-by: Jes Sorensen +--- + 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 + diff --git a/SOURCES/0097-Detail-fix-segfault-during-IMSM-raid-creation.patch b/SOURCES/0097-Detail-fix-segfault-during-IMSM-raid-creation.patch new file mode 100644 index 0000000..f2c2e2b --- /dev/null +++ b/SOURCES/0097-Detail-fix-segfault-during-IMSM-raid-creation.patch @@ -0,0 +1,33 @@ +From c3129b39a7d467eec063681529f46f84a2a85308 Mon Sep 17 00:00:00 2001 +From: Lidong Zhong +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 +Reported-by: Tkaczyk Mariusz +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 + diff --git a/SOURCES/0098-Create.c-close-mdfd-and-generate-uevent.patch b/SOURCES/0098-Create.c-close-mdfd-and-generate-uevent.patch new file mode 100644 index 0000000..7edc593 --- /dev/null +++ b/SOURCES/0098-Create.c-close-mdfd-and-generate-uevent.patch @@ -0,0 +1,37 @@ +From ce559078a5650afb9f635204b31a89a1fa0061e3 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +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 +--- + 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 + diff --git a/SOURCES/0099-imsm-update-num_data_stripes-according-to-dev_size.patch b/SOURCES/0099-imsm-update-num_data_stripes-according-to-dev_size.patch new file mode 100644 index 0000000..484208a --- /dev/null +++ b/SOURCES/0099-imsm-update-num_data_stripes-according-to-dev_size.patch @@ -0,0 +1,166 @@ +From 895ffd992954069e4ea67efb8a85bb0fd72c3707 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +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 +--- + 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 + diff --git a/SOURCES/0100-imsm-remove-redundant-calls-to-imsm_get_map.patch b/SOURCES/0100-imsm-remove-redundant-calls-to-imsm_get_map.patch new file mode 100644 index 0000000..49f718d --- /dev/null +++ b/SOURCES/0100-imsm-remove-redundant-calls-to-imsm_get_map.patch @@ -0,0 +1,35 @@ +From b65c1f4a2340e24ae00babc4399fb4030ff99517 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +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 +--- + 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 + diff --git a/SOURCES/0101-Monitor-don-t-use-default-modes-when-creating-a-file.patch b/SOURCES/0101-Monitor-don-t-use-default-modes-when-creating-a-file.patch new file mode 100644 index 0000000..fac4298 --- /dev/null +++ b/SOURCES/0101-Monitor-don-t-use-default-modes-when-creating-a-file.patch @@ -0,0 +1,55 @@ +From ca4b156b2059ee00a9143313267ee4a098967d76 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +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 +--- + 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) + perror("cannot create pid file"); + else { +@@ -368,13 +371,17 @@ static void write_autorebuild_pid() + { + char path[PATH_MAX]; + int pid; +- FILE *fp; ++ FILE *fp = NULL; + sprintf(path, "%s/autorebuild.pid", MDMON_DIR); + +- if (mkdir(MDMON_DIR, S_IRWXU) < 0 && errno != EEXIST) { ++ if (mkdir(MDMON_DIR, 0700) < 0 && errno != EEXIST) { + pr_err("Can't create autorebuild.pid file\n"); + } else { +- fp = fopen(path, "w"); ++ int fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0700); ++ ++ if (fd >= 0) ++ fp = fdopen(fd, "w"); ++ + if (!fp) + pr_err("Can't create autorebuild.pid file\n"); + else { +-- +2.7.5 + diff --git a/SOURCES/0102-imsm-limit-support-to-first-NVMe-namespace.patch b/SOURCES/0102-imsm-limit-support-to-first-NVMe-namespace.patch new file mode 100644 index 0000000..849612b --- /dev/null +++ b/SOURCES/0102-imsm-limit-support-to-first-NVMe-namespace.patch @@ -0,0 +1,95 @@ +From a8f3cfd54e45c8aabc4a99cdc92b6b9080b26607 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Wed, 4 Nov 2020 10:01:28 +0100 +Subject: [PATCH 102/108] imsm: limit support to first NVMe namespace + +Due to metadata limitations NVMe multinamespace support has to be removed. + +Signed-off-by: Mariusz Tkaczyk +--- + platform-intel.c | 31 +++++++++++++++++++++++++++++++ + platform-intel.h | 1 + + super-intel.c | 11 ++++++++++- + 3 files changed, 42 insertions(+), 1 deletion(-) + +diff --git a/platform-intel.c b/platform-intel.c +index 04bffc5..f1f6d4c 100644 +--- a/platform-intel.c ++++ b/platform-intel.c +@@ -766,3 +766,34 @@ char *vmd_domain_to_controller(struct sys_dev *hba, char *buf) + closedir(dir); + return NULL; + } ++/* Verify that NVMe drive is supported by IMSM ++ * Returns: ++ * 0 - not supported ++ * 1 - supported ++ */ ++int imsm_is_nvme_supported(int disk_fd, int verbose) ++{ ++ char nsid_path[PATH_MAX]; ++ char buf[PATH_MAX]; ++ struct stat stb; ++ ++ if (disk_fd < 0) ++ return 0; ++ ++ if (fstat(disk_fd, &stb)) ++ return 0; ++ ++ snprintf(nsid_path, PATH_MAX-1, "/sys/dev/block/%d:%d/nsid", ++ major(stb.st_rdev), minor(stb.st_rdev)); ++ ++ if (load_sys(nsid_path, buf, sizeof(buf))) { ++ pr_err("Cannot read %s, rejecting drive\n", nsid_path); ++ return 0; ++ } ++ if (strtoll(buf, NULL, 10) != 1) { ++ if (verbose) ++ pr_err("Only first namespace is supported by IMSM, aborting\n"); ++ return 0; ++ } ++ return 1; ++} +diff --git a/platform-intel.h b/platform-intel.h +index 7cb370e..7371478 100644 +--- a/platform-intel.h ++++ b/platform-intel.h +@@ -251,4 +251,5 @@ const struct orom_entry *get_orom_entry_by_device_id(__u16 dev_id); + const struct imsm_orom *get_orom_by_device_id(__u16 device_id); + struct sys_dev *device_by_id(__u16 device_id); + struct sys_dev *device_by_id_and_path(__u16 device_id, const char *path); ++int imsm_is_nvme_supported(int disk_fd, int verbose); + char *vmd_domain_to_controller(struct sys_dev *hba, char *buf); +diff --git a/super-intel.c b/super-intel.c +index 95f4eaf..715febf 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -2364,7 +2364,9 @@ static int print_nvme_info(struct sys_dev *hba) + continue; + if (path_attached_to_hba(rp, hba->path)) { + fd = open_dev(ent->d_name); +- if (fd < 0) { ++ if (!imsm_is_nvme_supported(fd, 0)) { ++ if (fd >= 0) ++ close(fd); + free(rp); + continue; + } +@@ -5868,6 +5870,13 @@ static int add_to_super_imsm(struct supertype *st, mdu_disk_info_t *dk, + snprintf(controller_path, PATH_MAX-1, "%s/device", devpath); + free(devpath); + ++ if (!imsm_is_nvme_supported(dd->fd, 1)) { ++ if (dd->devname) ++ free(dd->devname); ++ free(dd); ++ return 1; ++ } ++ + if (devpath_to_vendor(controller_path) == 0x8086) { + /* + * If Intel's NVMe drive has serial ended with +-- +2.7.5 + diff --git a/SOURCES/0103-mdadm-Unify-forks-behaviour.patch b/SOURCES/0103-mdadm-Unify-forks-behaviour.patch new file mode 100644 index 0000000..1ff25e8 --- /dev/null +++ b/SOURCES/0103-mdadm-Unify-forks-behaviour.patch @@ -0,0 +1,354 @@ +From ff6bb131a46e1bac84a26e5b2c4bf408c0e56926 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Wed, 4 Nov 2020 10:02:36 +0100 +Subject: [PATCH 103/108] mdadm: Unify forks behaviour + +If mdadm is run by udev or systemd, it gets a pipe as each stream. +Forks in the background may run after an event or service has been +processed when udev is detached from pipe. As a result process +fails quietly if any message is written. +To prevent from it, each fork has to close all parent streams. Leave +stderr and stdout opened only for debug purposes. +Unify it across all forks. Introduce other descriptors detection by +scanning /proc/self/fd directory. Add generic method for +managing systemd services. + +Signed-off-by: Mariusz Tkaczyk +--- + Grow.c | 52 ++++-------------------- + Incremental.c | 1 + + Monitor.c | 5 +-- + mdadm.h | 10 +++++ + mdmon.c | 9 +---- + util.c | 124 +++++++++++++++++++++++++++++++++++++--------------------- + 6 files changed, 100 insertions(+), 101 deletions(-) + +diff --git a/Grow.c b/Grow.c +index 57db7d4..6b8321c 100644 +--- a/Grow.c ++++ b/Grow.c +@@ -2982,47 +2982,6 @@ static void catch_term(int sig) + sigterm = 1; + } + +-static int continue_via_systemd(char *devnm) +-{ +- int skipped, i, pid, status; +- char pathbuf[1024]; +- /* In a systemd/udev world, it is best to get systemd to +- * run "mdadm --grow --continue" rather than running in the +- * background. +- */ +- switch(fork()) { +- case 0: +- /* FIXME yuk. CLOSE_EXEC?? */ +- skipped = 0; +- for (i = 3; skipped < 20; i++) +- if (close(i) < 0) +- skipped++; +- else +- skipped = 0; +- +- /* Don't want to see error messages from +- * systemctl. If the service doesn't exist, +- * we fork ourselves. +- */ +- close(2); +- open("/dev/null", O_WRONLY); +- snprintf(pathbuf, sizeof(pathbuf), +- "mdadm-grow-continue@%s.service", devnm); +- status = execl("/usr/bin/systemctl", "systemctl", "restart", +- pathbuf, NULL); +- status = execl("/bin/systemctl", "systemctl", "restart", +- pathbuf, NULL); +- exit(1); +- case -1: /* Just do it ourselves. */ +- break; +- default: /* parent - good */ +- pid = wait(&status); +- if (pid >= 0 && status == 0) +- return 1; +- } +- return 0; +-} +- + static int reshape_array(char *container, int fd, char *devname, + struct supertype *st, struct mdinfo *info, + int force, struct mddev_dev *devlist, +@@ -3401,6 +3360,7 @@ static int reshape_array(char *container, int fd, char *devname, + default: /* parent */ + return 0; + case 0: ++ manage_fork_fds(0); + map_fork(); + break; + } +@@ -3509,8 +3469,9 @@ started: + return 1; + } + +- if (!forked && !check_env("MDADM_NO_SYSTEMCTL")) +- if (continue_via_systemd(container ?: sra->sys_name)) { ++ if (!forked) ++ if (continue_via_systemd(container ?: sra->sys_name, ++ GROW_SERVICE)) { + free(fdlist); + free(offsets); + sysfs_free(sra); +@@ -3704,8 +3665,8 @@ int reshape_container(char *container, char *devname, + */ + ping_monitor(container); + +- if (!forked && !freeze_reshape && !check_env("MDADM_NO_SYSTEMCTL")) +- if (continue_via_systemd(container)) ++ if (!forked && !freeze_reshape) ++ if (continue_via_systemd(container, GROW_SERVICE)) + return 0; + + switch (forked ? 0 : fork()) { +@@ -3718,6 +3679,7 @@ int reshape_container(char *container, char *devname, + printf("%s: multi-array reshape continues in background\n", Name); + return 0; + case 0: /* child */ ++ manage_fork_fds(0); + map_fork(); + break; + } +diff --git a/Incremental.c b/Incremental.c +index 98dbcd9..ad9ec1c 100644 +--- a/Incremental.c ++++ b/Incremental.c +@@ -1679,6 +1679,7 @@ static void run_udisks(char *arg1, char *arg2) + int pid = fork(); + int status; + if (pid == 0) { ++ manage_fork_fds(1); + execl("/usr/bin/udisks", "udisks", arg1, arg2, NULL); + execl("/bin/udisks", "udisks", arg1, arg2, NULL); + exit(1); +diff --git a/Monitor.c b/Monitor.c +index a82e99d..3f3005b 100644 +--- a/Monitor.c ++++ b/Monitor.c +@@ -323,10 +323,7 @@ static int make_daemon(char *pidfile) + perror("daemonise"); + return 1; + } +- close(0); +- open("/dev/null", O_RDWR); +- dup2(0, 1); +- dup2(0, 2); ++ manage_fork_fds(0); + setsid(); + return -1; + } +diff --git a/mdadm.h b/mdadm.h +index 4961c0f..56b1b19 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -129,6 +129,14 @@ struct dlm_lksb { + #define FAILED_SLOTS_DIR "/run/mdadm/failed-slots" + #endif /* FAILED_SLOTS */ + ++#ifndef MDMON_SERVICE ++#define MDMON_SERVICE "mdmon" ++#endif /* MDMON_SERVICE */ ++ ++#ifndef GROW_SERVICE ++#define GROW_SERVICE "mdadm-grow-continue" ++#endif /* GROW_SERVICE */ ++ + #include "md_u.h" + #include "md_p.h" + #include "bitmap.h" +@@ -1497,6 +1505,8 @@ extern int is_standard(char *dev, int *nump); + extern int same_dev(char *one, char *two); + extern int compare_paths (char* path1,char* path2); + extern void enable_fds(int devices); ++extern void manage_fork_fds(int close_all); ++extern int continue_via_systemd(char *devnm, char *service_name); + + extern int parse_auto(char *str, char *msg, int config); + extern struct mddev_ident *conf_get_ident(char *dev); +diff --git a/mdmon.c b/mdmon.c +index ff985d2..c71e62c 100644 +--- a/mdmon.c ++++ b/mdmon.c +@@ -546,14 +546,7 @@ static int mdmon(char *devnm, int must_fork, int takeover) + } + + setsid(); +- close(0); +- open("/dev/null", O_RDWR); +- close(1); +- ignore = dup(0); +-#ifndef DEBUG +- close(2); +- ignore = dup(0); +-#endif ++ manage_fork_fds(0); + + /* This silliness is to stop the compiler complaining + * that we ignore 'ignore' +diff --git a/util.c b/util.c +index 579dd42..5879694 100644 +--- a/util.c ++++ b/util.c +@@ -1915,7 +1915,7 @@ int mdmon_running(char *devnm) + + int start_mdmon(char *devnm) + { +- int i, skipped; ++ int i; + int len; + pid_t pid; + int status; +@@ -1929,7 +1929,10 @@ int start_mdmon(char *devnm) + + if (check_env("MDADM_NO_MDMON")) + return 0; ++ if (continue_via_systemd(devnm, MDMON_SERVICE)) ++ return 0; + ++ /* That failed, try running mdmon directly */ + len = readlink("/proc/self/exe", pathbuf, sizeof(pathbuf)-1); + if (len > 0) { + char *sl; +@@ -1943,51 +1946,9 @@ int start_mdmon(char *devnm) + } else + pathbuf[0] = '\0'; + +- /* First try to run systemctl */ +- if (!check_env("MDADM_NO_SYSTEMCTL")) +- switch(fork()) { +- case 0: +- /* FIXME yuk. CLOSE_EXEC?? */ +- skipped = 0; +- for (i = 3; skipped < 20; i++) +- if (close(i) < 0) +- skipped++; +- else +- skipped = 0; +- +- /* Don't want to see error messages from +- * systemctl. If the service doesn't exist, +- * we start mdmon ourselves. +- */ +- close(2); +- open("/dev/null", O_WRONLY); +- snprintf(pathbuf, sizeof(pathbuf), "mdmon@%s.service", +- devnm); +- status = execl("/usr/bin/systemctl", "systemctl", +- "start", +- pathbuf, NULL); +- status = execl("/bin/systemctl", "systemctl", "start", +- pathbuf, NULL); +- exit(1); +- case -1: pr_err("cannot run mdmon. Array remains readonly\n"); +- return -1; +- default: /* parent - good */ +- pid = wait(&status); +- if (pid >= 0 && status == 0) +- return 0; +- } +- +- /* That failed, try running mdmon directly */ + switch(fork()) { + case 0: +- /* FIXME yuk. CLOSE_EXEC?? */ +- skipped = 0; +- for (i = 3; skipped < 20; i++) +- if (close(i) < 0) +- skipped++; +- else +- skipped = 0; +- ++ manage_fork_fds(1); + for (i = 0; paths[i]; i++) + if (paths[i][0]) { + execl(paths[i], paths[i], +@@ -2192,6 +2153,81 @@ void enable_fds(int devices) + setrlimit(RLIMIT_NOFILE, &lim); + } + ++/* Close all opened descriptors if needed and redirect ++ * streams to /dev/null. ++ * For debug purposed, leave STDOUT and STDERR untouched ++ * Returns: ++ * 1- if any error occurred ++ * 0- otherwise ++ */ ++void manage_fork_fds(int close_all) ++{ ++ DIR *dir; ++ struct dirent *dirent; ++ ++ close(0); ++ open("/dev/null", O_RDWR); ++ ++#ifndef DEBUG ++ dup2(0, 1); ++ dup2(0, 2); ++#endif ++ ++ if (close_all == 0) ++ return; ++ ++ dir = opendir("/proc/self/fd"); ++ if (!dir) { ++ pr_err("Cannot open /proc/self/fd directory.\n"); ++ return; ++ } ++ for (dirent = readdir(dir); dirent; dirent = readdir(dir)) { ++ int fd = -1; ++ ++ if ((strcmp(dirent->d_name, ".") == 0) || ++ (strcmp(dirent->d_name, "..")) == 0) ++ continue; ++ ++ fd = strtol(dirent->d_name, NULL, 10); ++ if (fd > 2) ++ close(fd); ++ } ++} ++ ++/* In a systemd/udev world, it is best to get systemd to ++ * run daemon rather than running in the background. ++ * Returns: ++ * 1- if systemd service has been started ++ * 0- otherwise ++ */ ++int continue_via_systemd(char *devnm, char *service_name) ++{ ++ int pid, status; ++ char pathbuf[1024]; ++ ++ /* Simply return that service cannot be started */ ++ if (check_env("MDADM_NO_SYSTEMCTL")) ++ return 0; ++ switch (fork()) { ++ case 0: ++ manage_fork_fds(1); ++ snprintf(pathbuf, sizeof(pathbuf), ++ "%s@%s.service", service_name, devnm); ++ status = execl("/usr/bin/systemctl", "systemctl", "restart", ++ pathbuf, NULL); ++ status = execl("/bin/systemctl", "systemctl", "restart", ++ pathbuf, NULL); ++ exit(1); ++ case -1: /* Just do it ourselves. */ ++ break; ++ default: /* parent - good */ ++ pid = wait(&status); ++ if (pid >= 0 && status == 0) ++ return 1; ++ } ++ return 0; ++} ++ + int in_initrd(void) + { + /* This is based on similar function in systemd. */ +-- +2.7.5 + diff --git a/SOURCES/0104-mdadm-Detail-show-correct-state-for-clustered-array.patch b/SOURCES/0104-mdadm-Detail-show-correct-state-for-clustered-array.patch new file mode 100644 index 0000000..0c30bd9 --- /dev/null +++ b/SOURCES/0104-mdadm-Detail-show-correct-state-for-clustered-array.patch @@ -0,0 +1,197 @@ +From 9c030dadba89b90a4e52b6afe0290076c809684c Mon Sep 17 00:00:00 2001 +From: Zhao Heming +Date: Sat, 24 Oct 2020 17:43:12 +0800 +Subject: [PATCH 104/108] mdadm/Detail: show correct state for clustered array + +After kernel md module commit 480523feae581, in clustered env, +mddev->in_sync always zero, it will make array.state never set +up MD_SB_CLEAN. it causes "mdadm -D /dev/mdX" show state 'active' +all the time. + +bitmap.c: add a new API IsBitmapDirty() to support inquiry bitmap +dirty or clean. + +Signed-off-by: Zhao Heming +--- + Detail.c | 20 ++++++++++++++++- + bitmap.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- + mdadm.h | 1 + + 3 files changed, 86 insertions(+), 10 deletions(-) + +diff --git a/Detail.c b/Detail.c +index ea86884..f8dea6f 100644 +--- a/Detail.c ++++ b/Detail.c +@@ -498,8 +498,26 @@ int Detail(char *dev, struct context *c) + sra->array_state); + else + arrayst = "clean"; +- } else ++ } else { + arrayst = "active"; ++ if (array.state & (1<prefer); ++ if (!dv) ++ continue; ++ arrayst = IsBitmapDirty(dv) ? "active" : "clean"; ++ break; ++ } ++ } ++ } ++ } + + printf(" State : %s%s%s%s%s%s%s \n", + arrayst, st, +diff --git a/bitmap.c b/bitmap.c +index e38cb96..9a7ffe3 100644 +--- a/bitmap.c ++++ b/bitmap.c +@@ -180,13 +180,14 @@ out: + } + + static int +-bitmap_file_open(char *filename, struct supertype **stp, int node_num) ++bitmap_file_open(char *filename, struct supertype **stp, int node_num, int fd) + { +- int fd; + struct stat stb; + struct supertype *st = *stp; + +- fd = open(filename, O_RDONLY|O_DIRECT); ++ /* won't re-open filename when (fd >= 0) */ ++ if (fd < 0) ++ fd = open(filename, O_RDONLY|O_DIRECT); + if (fd < 0) { + pr_err("failed to open bitmap file %s: %s\n", + filename, strerror(errno)); +@@ -249,7 +250,7 @@ int ExamineBitmap(char *filename, int brief, struct supertype *st) + int fd, i; + __u32 uuid32[4]; + +- fd = bitmap_file_open(filename, &st, 0); ++ fd = bitmap_file_open(filename, &st, 0, -1); + if (fd < 0) + return rv; + +@@ -263,7 +264,6 @@ int ExamineBitmap(char *filename, int brief, struct supertype *st) + pr_err("Reporting bitmap that would be used if this array were used\n"); + pr_err("as a member of some other array\n"); + } +- close(fd); + printf(" Filename : %s\n", filename); + printf(" Magic : %08x\n", sb->magic); + if (sb->magic != BITMAP_MAGIC) { +@@ -332,15 +332,13 @@ int ExamineBitmap(char *filename, int brief, struct supertype *st) + for (i = 0; i < (int)sb->nodes; i++) { + st = NULL; + free(info); +- fd = bitmap_file_open(filename, &st, i); ++ fd = bitmap_file_open(filename, &st, i, fd); + if (fd < 0) { + printf(" Unable to open bitmap file on node: %i\n", i); +- + continue; + } + info = bitmap_fd_read(fd, brief); + if (!info) { +- close(fd); + printf(" Unable to read bitmap on node: %i\n", i); + continue; + } +@@ -359,13 +357,72 @@ int ExamineBitmap(char *filename, int brief, struct supertype *st) + printf(" Bitmap : %llu bits (chunks), %llu dirty (%2.1f%%)\n", + info->total_bits, info->dirty_bits, + 100.0 * info->dirty_bits / (info->total_bits?:1)); +- close(fd); + } + } + + free_info: ++ close(fd); ++ free(info); ++ return rv; ++} ++ ++int IsBitmapDirty(char *filename) ++{ ++ /* ++ * Read the bitmap file ++ * It will break reading bitmap action immediately when meeting any error. ++ * ++ * Return: 1(dirty), 0 (clean), -1(error) ++ */ ++ ++ int fd = -1, rv = 0, i; ++ struct supertype *st = NULL; ++ bitmap_info_t *info = NULL; ++ bitmap_super_t *sb = NULL; ++ ++ fd = bitmap_file_open(filename, &st, 0, fd); ++ free(st); ++ if (fd < 0) ++ goto out; ++ ++ info = bitmap_fd_read(fd, 0); ++ if (!info) { ++ close(fd); ++ goto out; ++ } ++ ++ sb = &info->sb; ++ for (i = 0; i < (int)sb->nodes; i++) { ++ st = NULL; ++ free(info); ++ info = NULL; ++ ++ fd = bitmap_file_open(filename, &st, i, fd); ++ free(st); ++ if (fd < 0) ++ goto out; ++ ++ info = bitmap_fd_read(fd, 0); ++ if (!info) { ++ close(fd); ++ goto out; ++ } ++ ++ sb = &info->sb; ++ if (sb->magic != BITMAP_MAGIC) { /* invalid bitmap magic */ ++ free(info); ++ close(fd); ++ goto out; ++ } ++ ++ if (info->dirty_bits) ++ rv = 1; ++ } ++ close(fd); + free(info); + return rv; ++out: ++ return -1; + } + + int CreateBitmap(char *filename, int force, char uuid[16], +diff --git a/mdadm.h b/mdadm.h +index 56b1b19..1ee6c92 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -1455,6 +1455,7 @@ extern int CreateBitmap(char *filename, int force, char uuid[16], + unsigned long long array_size, + int major); + extern int ExamineBitmap(char *filename, int brief, struct supertype *st); ++extern int IsBitmapDirty(char *filename); + extern int Write_rules(char *rule_name); + extern int bitmap_update_uuid(int fd, int *uuid, int swap); + +-- +2.7.5 + diff --git a/SOURCES/0105-Make-target-to-install-binaries-only.patch b/SOURCES/0105-Make-target-to-install-binaries-only.patch new file mode 100644 index 0000000..efbafd0 --- /dev/null +++ b/SOURCES/0105-Make-target-to-install-binaries-only.patch @@ -0,0 +1,43 @@ +From b4a5ad4958cb3ad87c3c5fa993e7572c38596d09 Mon Sep 17 00:00:00 2001 +From: Kinga Tanska +Date: Thu, 22 Oct 2020 14:22:29 +0200 +Subject: [PATCH 105/108] Make target to install binaries only + +Make install causes installation of binaries, udev and man. +This commit contains new target make install-bin, which +results in installation of binaries only. + +Signed-off-by: Kinga Tanska +--- + Makefile | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/Makefile b/Makefile +index 15d05d1..4cd4c9d 100644 +--- a/Makefile ++++ b/Makefile +@@ -245,9 +245,7 @@ $(MON_OBJS) : $(INCL) mdmon.h + sha1.o : sha1.c sha1.h md5.h + $(CC) $(CFLAGS) -DHAVE_STDINT_H -o sha1.o -c sha1.c + +-install : mdadm mdmon install-man install-udev +- $(INSTALL) -D $(STRIP) -m 755 mdadm $(DESTDIR)$(BINDIR)/mdadm +- $(INSTALL) -D $(STRIP) -m 755 mdmon $(DESTDIR)$(BINDIR)/mdmon ++install : install-bin install-man install-udev + + install-static : mdadm.static install-man + $(INSTALL) -D $(STRIP) -m 755 mdadm.static $(DESTDIR)$(BINDIR)/mdadm +@@ -297,6 +295,10 @@ install-systemd: systemd/mdmon@.service + done + if [ -f /etc/SuSE-release -o -n "$(SUSE)" ] ;then $(INSTALL) -D -m 755 systemd/SUSE-mdadm_env.sh $(DESTDIR)$(LIB_DIR)/mdadm_env.sh ;fi + ++install-bin: mdadm mdmon ++ $(INSTALL) -D $(STRIP) -m 755 mdadm $(DESTDIR)$(BINDIR)/mdadm ++ $(INSTALL) -D $(STRIP) -m 755 mdmon $(DESTDIR)$(BINDIR)/mdmon ++ + uninstall: + rm -f $(DESTDIR)$(MAN8DIR)/mdadm.8 $(DESTDIR)$(MAN8DIR)/mdmon.8 $(DESTDIR)$(MAN4DIR)/md.4 $(DESTDIR)$(MAN5DIR)/mdadm.conf.5 $(DESTDIR)$(BINDIR)/mdadm + +-- +2.7.5 + diff --git a/SOURCES/0106-udev-start-grow-service-automatically.patch b/SOURCES/0106-udev-start-grow-service-automatically.patch new file mode 100644 index 0000000..a899c39 --- /dev/null +++ b/SOURCES/0106-udev-start-grow-service-automatically.patch @@ -0,0 +1,37 @@ +From a64f1263a56bd8653267c1a9800daa0bc993a743 Mon Sep 17 00:00:00 2001 +From: Tkaczyk Mariusz +Date: Thu, 15 Oct 2020 10:45:29 +0200 +Subject: [PATCH 106/108] udev: start grow service automatically + +Grow continue via service or fork is started during raid assembly. +If raid was assembled in initrd it will be newer restarted after +switch root. +Add udev support for starting mdadm-grow-continue service. + +Signed-off-by: Mariusz Tkaczyk +--- + udev-md-raid-arrays.rules | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/udev-md-raid-arrays.rules b/udev-md-raid-arrays.rules +index c8fa8e8..13c9076 100644 +--- a/udev-md-raid-arrays.rules ++++ b/udev-md-raid-arrays.rules +@@ -15,6 +15,7 @@ ENV{DEVTYPE}=="partition", GOTO="md_ignore_state" + ATTR{md/metadata_version}=="external:[A-Za-z]*", ATTR{md/array_state}=="inactive", GOTO="md_ignore_state" + TEST!="md/array_state", ENV{SYSTEMD_READY}="0", GOTO="md_end" + ATTR{md/array_state}=="clear*|inactive", ENV{SYSTEMD_READY}="0", GOTO="md_end" ++ATTR{md/sync_action}=="reshape", ENV{RESHAPE_ACTIVE}="yes" + LABEL="md_ignore_state" + + IMPORT{program}="BINDIR/mdadm --detail --no-devices --export $devnode" +@@ -38,5 +39,6 @@ ENV{MD_LEVEL}=="raid[1-9]*", ENV{SYSTEMD_WANTS}+="mdmonitor.service" + # Tell systemd to run mdmon for our container, if we need it. + ENV{MD_LEVEL}=="raid[1-9]*", ENV{MD_CONTAINER}=="?*", PROGRAM="/usr/bin/readlink $env{MD_CONTAINER}", ENV{MD_MON_THIS}="%c" + ENV{MD_MON_THIS}=="?*", PROGRAM="/usr/bin/basename $env{MD_MON_THIS}", ENV{SYSTEMD_WANTS}+="mdmon@%c.service" ++ENV{RESHAPE_ACTIVE}=="yes", PROGRAM="/usr/bin/basename $env{MD_MON_THIS}", ENV{SYSTEMD_WANTS}+="mdadm-grow-continue@%c.service" + + LABEL="md_end" +-- +2.7.5 + diff --git a/SOURCES/0107-Incremental-Remove-redundant-spare-movement-logic.patch b/SOURCES/0107-Incremental-Remove-redundant-spare-movement-logic.patch new file mode 100644 index 0000000..2a5092f --- /dev/null +++ b/SOURCES/0107-Incremental-Remove-redundant-spare-movement-logic.patch @@ -0,0 +1,111 @@ +From 69068584f9ed68b8b2736287a1c9863e11b741d5 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Fri, 11 Dec 2020 12:28:38 +0100 +Subject: [PATCH 107/108] Incremental: Remove redundant spare movement logic + +If policy is set then mdmonitor is responsible for moving spares. +This logic is reduntant and potentialy dangerus, spare could be moved at +initrd stage depending on drives appearance order. + +Remove it. + +Signed-off-by: Mariusz Tkaczyk +Signed-off-by: Jes Sorensen +--- + Incremental.c | 62 ----------------------------------------------------------- + 1 file changed, 62 deletions(-) + +diff --git a/Incremental.c b/Incremental.c +index ad9ec1c..e849bdd 100644 +--- a/Incremental.c ++++ b/Incremental.c +@@ -1460,12 +1460,6 @@ static int Incremental_container(struct supertype *st, char *devname, + int trustworthy; + struct mddev_ident *match; + int rv = 0; +- struct domainlist *domains; +- struct map_ent *smp; +- int suuid[4]; +- int sfd; +- int ra_blocked = 0; +- int ra_all = 0; + int result = 0; + + st->ss->getinfo_super(st, &info, NULL); +@@ -1509,12 +1503,10 @@ static int Incremental_container(struct supertype *st, char *devname, + struct map_ent *mp; + struct mddev_ident *match = NULL; + +- ra_all++; + /* do not activate arrays blocked by metadata handler */ + if (ra->array.state & (1 << MD_SB_BLOCK_VOLUME)) { + pr_err("Cannot activate array %s in %s.\n", + ra->text_version, devname); +- ra_blocked++; + continue; + } + mp = map_by_uuid(&map, ra->uuid); +@@ -1617,60 +1609,6 @@ static int Incremental_container(struct supertype *st, char *devname, + } + printf("\n"); + } +- +- /* don't move spares to container with volume being activated +- when all volumes are blocked */ +- if (ra_all == ra_blocked) +- return 0; +- +- /* Now move all suitable spares from spare container */ +- domains = domain_from_array(list, st->ss->name); +- memcpy(suuid, uuid_zero, sizeof(int[4])); +- if (domains && +- (smp = map_by_uuid(&map, suuid)) != NULL && +- (sfd = open(smp->path, O_RDONLY)) >= 0) { +- /* spare container found */ +- struct supertype *sst = +- super_imsm.match_metadata_desc("imsm"); +- struct mdinfo *sinfo; +- +- if (!sst->ss->load_container(sst, sfd, NULL)) { +- struct spare_criteria sc = {0, 0}; +- +- if (st->ss->get_spare_criteria) +- st->ss->get_spare_criteria(st, &sc); +- +- close(sfd); +- sinfo = container_choose_spares(sst, &sc, +- domains, NULL, +- st->ss->name, 0); +- sst->ss->free_super(sst); +- if (sinfo){ +- int count = 0; +- struct mdinfo *disks = sinfo->devs; +- while (disks) { +- /* move spare from spare +- * container to currently +- * assembled one +- */ +- if (move_spare( +- smp->path, +- devname, +- makedev(disks->disk.major, +- disks->disk.minor))) +- count++; +- disks = disks->next; +- } +- if (count) +- pr_err("Added %d spare%s to %s\n", +- count, count>1?"s":"", devname); +- } +- sysfs_free(sinfo); +- } else +- close(sfd); +- } +- domain_free(domains); +- map_free(map); + return 0; + } + +-- +2.7.5 + diff --git a/SOURCES/0108-Dump-get-stat-from-a-wrong-metadata-file-when-restor.patch b/SOURCES/0108-Dump-get-stat-from-a-wrong-metadata-file-when-restor.patch new file mode 100644 index 0000000..d01c4f6 --- /dev/null +++ b/SOURCES/0108-Dump-get-stat-from-a-wrong-metadata-file-when-restor.patch @@ -0,0 +1,48 @@ +From 75562b57d43bd252399b55d0004b8eac4b337a67 Mon Sep 17 00:00:00 2001 +From: Lidong Zhong +Date: Mon, 14 Dec 2020 22:51:33 +0800 +Subject: [PATCH 108/108] Dump: get stat from a wrong metadata file when + restoring metadata + +The dumped metadata files are shown as below +localhost:~ # ll -ih test/ +total 16K +34565564 -rw-r--r-- 2 root root 1.0G Dec 14 21:15 +scsi-0QEMU_QEMU_HARDDISK_drive-scsi0-0-0-3 +34565563 -rw-r--r-- 2 root root 1.0G Dec 14 21:15 +scsi-0QEMU_QEMU_HARDDISK_drive-scsi0-0-0-4 +34565563 -rw-r--r-- 2 root root 1.0G Dec 14 21:15 sda +34565564 -rw-r--r-- 2 root root 1.0G Dec 14 21:15 sdb + +It reports such error when trying to restore metadata for /dev/sda +localhost:~ # mdadm --restore=test /dev/sda +mdadm: test/scsi-0QEMU_QEMU_HARDDISK_drive-scsi0-0-0-4 is not the same +size as /dev/sda - cannot restore. +It's because the stb value has been changed to other metadata file in +the while statement. + +Signed-off-by: Lidong Zhong +Signed-off-by: Jes Sorensen +--- + Dump.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/Dump.c b/Dump.c +index 38e8f23..736bcb6 100644 +--- a/Dump.c ++++ b/Dump.c +@@ -272,6 +272,11 @@ int Restore_metadata(char *dev, char *dir, struct context *c, + fname); + goto err; + } ++ if (stat(fname, &stb) != 0) { ++ pr_err("Could not stat %s for --restore.\n", ++ fname); ++ goto err; ++ } + if (((unsigned long long)stb.st_size) != size) { + pr_err("%s is not the same size as %s - cannot restore.\n", + fname, dev); +-- +2.7.5 + diff --git a/SOURCES/mdadm-2.5.2-static.patch b/SOURCES/mdadm-2.5.2-static.patch index 1eb335a..188b478 100644 --- a/SOURCES/mdadm-2.5.2-static.patch +++ b/SOURCES/mdadm-2.5.2-static.patch @@ -1,7 +1,7 @@ ---- mdadm-3.2.1/Makefile.static 2011-03-27 22:31:20.000000000 -0400 -+++ mdadm-3.2.1/Makefile 2011-03-28 10:16:55.277900184 -0400 -@@ -238,16 +238,16 @@ install : mdadm mdmon install-man instal - $(INSTALL) -D $(STRIP) -m 755 mdmon $(DESTDIR)$(BINDIR)/mdmon +--- mdadm-3.2.1/Makefile.static 2021-01-11 15:46:47.292126848 +0800 ++++ mdadm-3.2.1/Makefile 2021-01-11 15:46:10.720192519 +0800 +@@ -248,16 +248,16 @@ + install : install-bin install-man install-udev install-static : mdadm.static install-man - $(INSTALL) -D $(STRIP) -m 755 mdadm.static $(DESTDIR)$(BINDIR)/mdadm diff --git a/SPECS/mdadm.spec b/SPECS/mdadm.spec index 19e6d8f..4b2bcd5 100644 --- a/SPECS/mdadm.spec +++ b/SPECS/mdadm.spec @@ -1,7 +1,7 @@ Summary: The mdadm program controls Linux md devices (software RAID arrays) Name: mdadm Version: 4.1 -Release: 14%{?dist} +Release: 15%{?dist} Source: http://www.kernel.org/pub/linux/utils/raid/mdadm/mdadm-%{version}.tar.xz Source1: mdmonitor.init Source2: raid-check @@ -91,10 +91,41 @@ Patch74: 0074-Assemble-print-error-message-if-mdadm-fails-assembli.patch Patch75: 0075-clean-up-meaning-of-small-typo.patch Patch76: 0076-Assemble.c-respect-force-flag.patch Patch77: 0077-mdcheck-Log-when-done.patch +Patch78: 0078-Makefile-add-EXTRAVERSION-support.patch +Patch79: 0079-uuid.c-split-uuid-stuffs-from-util.c.patch +Patch80: 0080-Include-count-for-0-character-when-using-strncpy-to-.patch +Patch81: 0081-restripe-fix-ignoring-return-value-of-read-and-lseek.patch +Patch82: 0082-Block-overwriting-existing-links-while-manual-assemb.patch +Patch83: 0083-Detect-too-small-device-error-rather-than-underflow-.patch +Patch84: 0084-Use-more-secure-HTTPS-URLs.patch +Patch85: 0085-Update-link-to-Intel-page-for-IMSM.patch +Patch86: 0086-mdadm-Grow-prevent-md-s-fd-from-being-occupied-durin.patch +Patch87: 0087-Specify-nodes-number-when-updating-cluster-nodes.patch +Patch88: 0088-mdadm-md.4-update-path-to-in-kernel-tree-documentati.patch +Patch89: 0089-manual-update-examine-badblocks.patch +Patch90: 0090-Detail-show-correct-raid-level-when-the-array-is-ina.patch +Patch91: 0091-Don-t-create-bitmap-for-raid5-with-journal-disk.patch +Patch92: 0092-Monitor-refresh-mdstat-fd-after-select.patch +Patch93: 0093-Monitor-stop-notifing-about-containers.patch +Patch94: 0094-mdmonitor-set-small-delay-once.patch +Patch95: 0095-Check-if-other-Monitor-instance-running-before-fork.patch +Patch96: 0096-Super1-allow-RAID0-layout-setting-to-be-removed.patch +Patch97: 0097-Detail-fix-segfault-during-IMSM-raid-creation.patch +Patch98: 0098-Create.c-close-mdfd-and-generate-uevent.patch +Patch99: 0099-imsm-update-num_data_stripes-according-to-dev_size.patch +Patch100: 0100-imsm-remove-redundant-calls-to-imsm_get_map.patch +Patch101: 0101-Monitor-don-t-use-default-modes-when-creating-a-file.patch +Patch102: 0102-imsm-limit-support-to-first-NVMe-namespace.patch +Patch103: 0103-mdadm-Unify-forks-behaviour.patch +Patch104: 0104-mdadm-Detail-show-correct-state-for-clustered-array.patch +Patch105: 0105-Make-target-to-install-binaries-only.patch +Patch106: 0106-udev-start-grow-service-automatically.patch +Patch107: 0107-Incremental-Remove-redundant-spare-movement-logic.patch +Patch108: 0108-Dump-get-stat-from-a-wrong-metadata-file-when-restor.patch # RHEL customization patches -Patch97: mdadm-3.3-udev.patch -Patch98: mdadm-2.5.2-static.patch +Patch200: mdadm-3.3-udev.patch +Patch201: mdadm-2.5.2-static.patch URL: http://www.kernel.org/pub/linux/utils/raid/mdadm/ License: GPLv2+ @@ -198,10 +229,41 @@ file can be used to help with some common tasks. %patch75 -p1 -b .0075 %patch76 -p1 -b .0076 %patch77 -p1 -b .0077 +%patch78 -p1 -b .0078 +%patch79 -p1 -b .0079 +%patch80 -p1 -b .0080 +%patch81 -p1 -b .0081 +%patch82 -p1 -b .0082 +%patch83 -p1 -b .0083 +%patch84 -p1 -b .0084 +%patch85 -p1 -b .0085 +%patch86 -p1 -b .0086 +%patch87 -p1 -b .0087 +%patch88 -p1 -b .0088 +%patch89 -p1 -b .0089 +%patch90 -p1 -b .0090 +%patch91 -p1 -b .0091 +%patch92 -p1 -b .0092 +%patch93 -p1 -b .0093 +%patch94 -p1 -b .0094 +%patch95 -p1 -b .0095 +%patch96 -p1 -b .0096 +%patch97 -p1 -b .0097 +%patch98 -p1 -b .0098 +%patch99 -p1 -b .0099 +%patch100 -p1 -b .0100 +%patch101 -p1 -b .0101 +%patch102 -p1 -b .0102 +%patch103 -p1 -b .0103 +%patch104 -p1 -b .0104 +%patch105 -p1 -b .0105 +%patch106 -p1 -b .0106 +%patch107 -p1 -b .0107 +%patch108 -p1 -b .0108 # RHEL customization patches -%patch97 -p1 -b .udev -%patch98 -p1 -b .static +%patch200 -p1 -b .udev +%patch201 -p1 -b .static %build make %{?_smp_mflags} CXFLAGS="$RPM_OPT_FLAGS" LDFLAGS="$RPM_LD_FLAGS" SYSCONFDIR="%{_sysconfdir}" mdadm mdmon @@ -269,6 +331,10 @@ rm -rf %{buildroot} /usr/lib/mdadm/mdadm_env.sh %changelog +* Mon Jan 11 2021 Xiao Ni - 4.1.15 +- Update to latest upstream +- Resolves rhbz#1838005 + * Fri Jun 05 2020 Xiao Ni - 4.1.14 - Update to latest upstream - Resolves rhbz#1780501