import mdadm-4.1-14.el8

This commit is contained in:
CentOS Sources 2020-07-28 07:05:36 -04:00 committed by Stepan Oksanichenko
parent adda9f6522
commit f1c66fe0d4
34 changed files with 2848 additions and 3 deletions

View File

@ -0,0 +1,45 @@
From e1512e7b7d060f0346738b237ea34eac21b29a26 Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Wed, 18 Dec 2019 14:46:21 +0800
Subject: [RHEL8.2 PATCH 1/1] mdcheck service can't start succesfully because
of syntax error
It reports error when starting mdcheck_start and mdcheck_continue service.
Invalid environment assignment, ignoring: MDADM_CHECK_DURATION="6 hours"
Signed-off-by: Xiao Ni <xni@redhat.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
systemd/mdcheck_continue.service | 2 +-
systemd/mdcheck_start.service | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/systemd/mdcheck_continue.service b/systemd/mdcheck_continue.service
index deac695..aa02dde 100644
--- a/systemd/mdcheck_continue.service
+++ b/systemd/mdcheck_continue.service
@@ -11,7 +11,7 @@ ConditionPathExistsGlob = /var/lib/mdcheck/MD_UUID_*
[Service]
Type=oneshot
-Environment= MDADM_CHECK_DURATION="6 hours"
+Environment= "MDADM_CHECK_DURATION=6 hours"
EnvironmentFile=-/run/sysconfig/mdadm
ExecStartPre=-/usr/lib/mdadm/mdadm_env.sh
ExecStart=/usr/share/mdadm/mdcheck --continue --duration ${MDADM_CHECK_DURATION}
diff --git a/systemd/mdcheck_start.service b/systemd/mdcheck_start.service
index f17f1aa..da62d5f 100644
--- a/systemd/mdcheck_start.service
+++ b/systemd/mdcheck_start.service
@@ -11,7 +11,7 @@ Wants=mdcheck_continue.timer
[Service]
Type=oneshot
-Environment= MDADM_CHECK_DURATION="6 hours"
+Environment= "MDADM_CHECK_DURATION=6 hours"
EnvironmentFile=-/run/sysconfig/mdadm
ExecStartPre=-/usr/lib/mdadm/mdadm_env.sh
ExecStart=/usr/share/mdadm/mdcheck --duration ${MDADM_CHECK_DURATION}
--
2.7.5

View File

@ -0,0 +1,41 @@
From 02af379337c73e751ad97c0fed9123121f8b4289 Mon Sep 17 00:00:00 2001
From: Jes Sorensen <jsorensen@fb.com>
Date: Wed, 27 Nov 2019 10:19:54 -0500
Subject: [RHEL8.2 PATCH 49/61] Remove last traces of HOT_ADD_DISK
This ioctl is no longer used, so remove all references to it.
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Manage.c | 2 --
md_u.h | 1 -
2 files changed, 3 deletions(-)
diff --git a/Manage.c b/Manage.c
index ffe55f8..deeba2b 100644
--- a/Manage.c
+++ b/Manage.c
@@ -1289,8 +1289,6 @@ int Manage_subdevs(char *devname, int fd,
/* Do something to each dev.
* devmode can be
* 'a' - add the device
- * try HOT_ADD_DISK
- * If that fails EINVAL, try ADD_NEW_DISK
* 'S' - add the device as a spare - don't try re-add
* 'j' - add the device as a journal device
* 'A' - re-add the device
diff --git a/md_u.h b/md_u.h
index 2d66d52..b30893c 100644
--- a/md_u.h
+++ b/md_u.h
@@ -28,7 +28,6 @@
#define ADD_NEW_DISK _IOW (MD_MAJOR, 0x21, mdu_disk_info_t)
#define HOT_REMOVE_DISK _IO (MD_MAJOR, 0x22)
#define SET_ARRAY_INFO _IOW (MD_MAJOR, 0x23, mdu_array_info_t)
-#define HOT_ADD_DISK _IO (MD_MAJOR, 0x28)
#define SET_DISK_FAULTY _IO (MD_MAJOR, 0x29)
#define SET_BITMAP_FILE _IOW (MD_MAJOR, 0x2b, int)
--
2.7.5

View File

@ -0,0 +1,51 @@
From 9cf361f8791d86aaced821c19af556819bc03732 Mon Sep 17 00:00:00 2001
From: Jes Sorensen <jsorensen@fb.com>
Date: Wed, 27 Nov 2019 11:33:15 -0500
Subject: [RHEL8.2 PATCH 50/61] Fix up a few formatting issues
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Manage.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/Manage.c b/Manage.c
index deeba2b..b22c396 100644
--- a/Manage.c
+++ b/Manage.c
@@ -1728,8 +1728,10 @@ int move_spare(char *from_devname, char *to_devname, dev_t devid)
int fd2 = open(from_devname, O_RDONLY);
if (fd1 < 0 || fd2 < 0) {
- if (fd1>=0) close(fd1);
- if (fd2>=0) close(fd2);
+ if (fd1 >= 0)
+ close(fd1);
+ if (fd2 >= 0)
+ close(fd2);
return 0;
}
@@ -1743,7 +1745,8 @@ int move_spare(char *from_devname, char *to_devname, dev_t devid)
devlist.disposition = 'r';
if (Manage_subdevs(from_devname, fd2, &devlist, -1, 0, NULL, 0) == 0) {
devlist.disposition = 'a';
- if (Manage_subdevs(to_devname, fd1, &devlist, -1, 0, NULL, 0) == 0) {
+ if (Manage_subdevs(to_devname, fd1, &devlist, -1, 0,
+ NULL, 0) == 0) {
/* make sure manager is aware of changes */
ping_manager(to_devname);
ping_manager(from_devname);
@@ -1751,7 +1754,9 @@ int move_spare(char *from_devname, char *to_devname, dev_t devid)
close(fd2);
return 1;
}
- else Manage_subdevs(from_devname, fd2, &devlist, -1, 0, NULL, 0);
+ else
+ Manage_subdevs(from_devname, fd2, &devlist,
+ -1, 0, NULL, 0);
}
close(fd1);
close(fd2);
--
2.7.5

View File

@ -0,0 +1,26 @@
From 4b31846f3f90aa24f883ceed80e91f204c0a9389 Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Fri, 29 Nov 2019 17:14:47 +0800
Subject: [RHEL8.2 PATCH 51/61] Remove unused code
Signed-off-by: Xiao Ni <xni@redhat.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
platform-intel.h | 1 -
1 file changed, 1 deletion(-)
diff --git a/platform-intel.h b/platform-intel.h
index 29c85f1..7cb370e 100644
--- a/platform-intel.h
+++ b/platform-intel.h
@@ -169,7 +169,6 @@ static inline int fls(int x)
r -= 2;
}
if (!(x & 0x80000000u)) {
- x <<= 1;
r -= 1;
}
return r;
--
2.7.5

View File

@ -0,0 +1,176 @@
From b771faef931c798a4553db0a8c1366aff90079c6 Mon Sep 17 00:00:00 2001
From: Blazej Kucman <blazej.kucman@intel.com>
Date: Fri, 29 Nov 2019 15:21:08 +0100
Subject: [RHEL8.2 PATCH 52/61] imsm: return correct uuid for volume in detail
Fixes the side effect of the patch b6180160f ("imsm: save current_vol number")
- wrong UUID is printed in detail for each volume.
New parameter "subarray" is added to determine what info should be extracted
from metadata (subarray or container).
The parameter affects only IMSM metadata.
Signed-off-by: Blazej Kucman <blazej.kucman@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Detail.c | 4 ++--
mdadm.h | 5 +++--
super-ddf.c | 5 +++--
super-intel.c | 20 ++++++++++++++++++--
super0.c | 4 ++--
super1.c | 4 ++--
6 files changed, 30 insertions(+), 12 deletions(-)
diff --git a/Detail.c b/Detail.c
index 3e61e37..24fa462 100644
--- a/Detail.c
+++ b/Detail.c
@@ -623,7 +623,7 @@ This is pretty boring
free_mdstat(ms);
if (st && st->sb)
- st->ss->detail_super(st, c->homehost);
+ st->ss->detail_super(st, c->homehost, subarray);
if (array.raid_disks == 0 && sra &&
sra->array.major_version == -1 &&
@@ -767,7 +767,7 @@ skip_devices_state:
if (spares && c->brief && array.raid_disks)
printf(" spares=%d", spares);
if (c->brief && st && st->sb)
- st->ss->brief_detail_super(st);
+ st->ss->brief_detail_super(st, subarray);
if (st)
st->ss->free_super(st);
diff --git a/mdadm.h b/mdadm.h
index c88ceab..91f1338 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -847,8 +847,9 @@ extern struct superswitch {
/* Used to report details of an active array.
* ->load_super was possibly given a 'component' string.
*/
- void (*detail_super)(struct supertype *st, char *homehost);
- void (*brief_detail_super)(struct supertype *st);
+ void (*detail_super)(struct supertype *st, char *homehost,
+ char *subarray);
+ void (*brief_detail_super)(struct supertype *st, char *subarray);
void (*export_detail_super)(struct supertype *st);
/* Optional: platform hardware / firmware details */
diff --git a/super-ddf.c b/super-ddf.c
index c095e8a..7802063 100644
--- a/super-ddf.c
+++ b/super-ddf.c
@@ -1730,7 +1730,8 @@ err:
return 1;
}
-static void detail_super_ddf(struct supertype *st, char *homehost)
+static void detail_super_ddf(struct supertype *st, char *homehost,
+ char *subarray)
{
struct ddf_super *sb = st->sb;
int cnt = be16_to_cpu(sb->virt->populated_vdes);
@@ -1787,7 +1788,7 @@ static void uuid_of_ddf_subarray(const struct ddf_super *ddf,
memcpy(uuid, sha, 4*4);
}
-static void brief_detail_super_ddf(struct supertype *st)
+static void brief_detail_super_ddf(struct supertype *st, char *subarray)
{
struct mdinfo info;
char nbuf[64];
diff --git a/super-intel.c b/super-intel.c
index a7fbed4..86dcb69 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -2183,23 +2183,39 @@ err:
return 1;
}
-static void detail_super_imsm(struct supertype *st, char *homehost)
+static void detail_super_imsm(struct supertype *st, char *homehost,
+ char *subarray)
{
struct mdinfo info;
char nbuf[64];
+ struct intel_super *super = st->sb;
+ int temp_vol = super->current_vol;
+
+ if (subarray)
+ super->current_vol = strtoul(subarray, NULL, 10);
getinfo_super_imsm(st, &info, NULL);
fname_from_uuid(st, &info, nbuf, ':');
printf("\n UUID : %s\n", nbuf + 5);
+
+ super->current_vol = temp_vol;
}
-static void brief_detail_super_imsm(struct supertype *st)
+static void brief_detail_super_imsm(struct supertype *st, char *subarray)
{
struct mdinfo info;
char nbuf[64];
+ struct intel_super *super = st->sb;
+ int temp_vol = super->current_vol;
+
+ if (subarray)
+ super->current_vol = strtoul(subarray, NULL, 10);
+
getinfo_super_imsm(st, &info, NULL);
fname_from_uuid(st, &info, nbuf, ':');
printf(" UUID=%s", nbuf + 5);
+
+ super->current_vol = temp_vol;
}
static int imsm_read_serial(int fd, char *devname, __u8 *serial);
diff --git a/super0.c b/super0.c
index 42989b9..6b7c0e3 100644
--- a/super0.c
+++ b/super0.c
@@ -348,7 +348,7 @@ err:
return 1;
}
-static void detail_super0(struct supertype *st, char *homehost)
+static void detail_super0(struct supertype *st, char *homehost, char *subarray)
{
mdp_super_t *sb = st->sb;
printf(" UUID : ");
@@ -368,7 +368,7 @@ static void detail_super0(struct supertype *st, char *homehost)
printf("\n Events : %d.%d\n\n", sb->events_hi, sb->events_lo);
}
-static void brief_detail_super0(struct supertype *st)
+static void brief_detail_super0(struct supertype *st, char *subarray)
{
mdp_super_t *sb = st->sb;
printf(" UUID=");
diff --git a/super1.c b/super1.c
index b85dc20..929466d 100644
--- a/super1.c
+++ b/super1.c
@@ -833,7 +833,7 @@ err:
return 1;
}
-static void detail_super1(struct supertype *st, char *homehost)
+static void detail_super1(struct supertype *st, char *homehost, char *subarray)
{
struct mdp_superblock_1 *sb = st->sb;
bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb) + MAX_SB_SIZE);
@@ -857,7 +857,7 @@ static void detail_super1(struct supertype *st, char *homehost)
(unsigned long long)__le64_to_cpu(sb->events));
}
-static void brief_detail_super1(struct supertype *st)
+static void brief_detail_super1(struct supertype *st, char *subarray)
{
struct mdp_superblock_1 *sb = st->sb;
int i;
--
2.7.5

View File

@ -0,0 +1,208 @@
From 6da53c0e2aab200605722795798b1e4f2352cd64 Mon Sep 17 00:00:00 2001
From: Blazej Kucman <blazej.kucman@intel.com>
Date: Mon, 2 Dec 2019 10:52:05 +0100
Subject: [RHEL8.2 PATCH 53/61] imsm: Change the way of printing nvme drives in
detail-platform.
Change NVMe controller path to device node path
in mdadm --detail-platform and print serial number.
The method imsm_read_serial always trimes serial to
MAX_RAID_SERIAL_LEN, added parameter 'serial_buf_len'
will be used to check the serial fit
to passed buffor, if not, will be trimed.
Signed-off-by: Blazej Kucman <blazej.kucman@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
super-intel.c | 97 ++++++++++++++++++++++++++++-------------------------------
1 file changed, 46 insertions(+), 51 deletions(-)
diff --git a/super-intel.c b/super-intel.c
index 86dcb69..5c1f759 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -2218,7 +2218,8 @@ static void brief_detail_super_imsm(struct supertype *st, char *subarray)
super->current_vol = temp_vol;
}
-static int imsm_read_serial(int fd, char *devname, __u8 *serial);
+static int imsm_read_serial(int fd, char *devname, __u8 *serial,
+ size_t serial_buf_len);
static void fd2devname(int fd, char *name);
static int ahci_enumerate_ports(const char *hba_path, int port_count, int host_base, int verbose)
@@ -2364,8 +2365,9 @@ static int ahci_enumerate_ports(const char *hba_path, int port_count, int host_b
else {
fd2devname(fd, buf);
printf(" Port%d : %s", port, buf);
- if (imsm_read_serial(fd, NULL, (__u8 *) buf) == 0)
- printf(" (%.*s)\n", MAX_RAID_SERIAL_LEN, buf);
+ if (imsm_read_serial(fd, NULL, (__u8 *)buf,
+ sizeof(buf)) == 0)
+ printf(" (%s)\n", buf);
else
printf(" ()\n");
close(fd);
@@ -2388,52 +2390,45 @@ static int ahci_enumerate_ports(const char *hba_path, int port_count, int host_b
return err;
}
-static int print_vmd_attached_devs(struct sys_dev *hba)
+static int print_nvme_info(struct sys_dev *hba)
{
+ char buf[1024];
struct dirent *ent;
DIR *dir;
- char path[292];
- char link[256];
- char *c, *rp;
-
- if (hba->type != SYS_DEV_VMD)
- return 1;
+ char *rp;
+ int fd;
- /* scroll through /sys/dev/block looking for devices attached to
- * this hba
- */
- dir = opendir("/sys/bus/pci/drivers/nvme");
+ dir = opendir("/sys/block/");
if (!dir)
return 1;
for (ent = readdir(dir); ent; ent = readdir(dir)) {
- int n;
-
- /* is 'ent' a device? check that the 'subsystem' link exists and
- * that its target matches 'bus'
- */
- sprintf(path, "/sys/bus/pci/drivers/nvme/%s/subsystem",
- ent->d_name);
- n = readlink(path, link, sizeof(link));
- if (n < 0 || n >= (int)sizeof(link))
- continue;
- link[n] = '\0';
- c = strrchr(link, '/');
- if (!c)
- continue;
- if (strncmp("pci", c+1, strlen("pci")) != 0)
- continue;
-
- sprintf(path, "/sys/bus/pci/drivers/nvme/%s", ent->d_name);
-
- rp = realpath(path, NULL);
- if (!rp)
- continue;
+ if (strstr(ent->d_name, "nvme")) {
+ sprintf(buf, "/sys/block/%s", ent->d_name);
+ rp = realpath(buf, NULL);
+ if (!rp)
+ continue;
+ if (path_attached_to_hba(rp, hba->path)) {
+ fd = open_dev(ent->d_name);
+ if (fd < 0) {
+ free(rp);
+ continue;
+ }
- if (path_attached_to_hba(rp, hba->path)) {
- printf(" NVMe under VMD : %s\n", rp);
+ fd2devname(fd, buf);
+ if (hba->type == SYS_DEV_VMD)
+ printf(" NVMe under VMD : %s", buf);
+ else if (hba->type == SYS_DEV_NVME)
+ printf(" NVMe Device : %s", buf);
+ if (!imsm_read_serial(fd, NULL, (__u8 *)buf,
+ sizeof(buf)))
+ printf(" (%s)\n", buf);
+ else
+ printf("()\n");
+ close(fd);
+ }
+ free(rp);
}
- free(rp);
}
closedir(dir);
@@ -2648,7 +2643,7 @@ static int detail_platform_imsm(int verbose, int enumerate_only, char *controlle
char buf[PATH_MAX];
printf(" I/O Controller : %s (%s)\n",
vmd_domain_to_controller(hba, buf), get_sys_dev_type(hba->type));
- if (print_vmd_attached_devs(hba)) {
+ if (print_nvme_info(hba)) {
if (verbose > 0)
pr_err("failed to get devices attached to VMD domain.\n");
result |= 2;
@@ -2663,7 +2658,7 @@ static int detail_platform_imsm(int verbose, int enumerate_only, char *controlle
if (entry->type == SYS_DEV_NVME) {
for (hba = list; hba; hba = hba->next) {
if (hba->type == SYS_DEV_NVME)
- printf(" NVMe Device : %s\n", hba->path);
+ print_nvme_info(hba);
}
printf("\n");
continue;
@@ -4028,11 +4023,11 @@ static int nvme_get_serial(int fd, void *buf, size_t buf_len)
extern int scsi_get_serial(int fd, void *buf, size_t buf_len);
static int imsm_read_serial(int fd, char *devname,
- __u8 serial[MAX_RAID_SERIAL_LEN])
+ __u8 *serial, size_t serial_buf_len)
{
char buf[50];
int rv;
- int len;
+ size_t len;
char *dest;
char *src;
unsigned int i;
@@ -4075,13 +4070,13 @@ static int imsm_read_serial(int fd, char *devname,
len = dest - buf;
dest = buf;
- /* truncate leading characters */
- if (len > MAX_RAID_SERIAL_LEN) {
- dest += len - MAX_RAID_SERIAL_LEN;
- len = MAX_RAID_SERIAL_LEN;
+ if (len > serial_buf_len) {
+ /* truncate leading characters */
+ dest += len - serial_buf_len;
+ len = serial_buf_len;
}
- memset(serial, 0, MAX_RAID_SERIAL_LEN);
+ memset(serial, 0, serial_buf_len);
memcpy(serial, dest, len);
return 0;
@@ -4136,7 +4131,7 @@ load_imsm_disk(int fd, struct intel_super *super, char *devname, int keep_fd)
char name[40];
__u8 serial[MAX_RAID_SERIAL_LEN];
- rv = imsm_read_serial(fd, devname, serial);
+ rv = imsm_read_serial(fd, devname, serial, MAX_RAID_SERIAL_LEN);
if (rv != 0)
return 2;
@@ -5844,7 +5839,7 @@ int mark_spare(struct dl *disk)
return ret_val;
ret_val = 0;
- if (!imsm_read_serial(disk->fd, NULL, serial)) {
+ if (!imsm_read_serial(disk->fd, NULL, serial, MAX_RAID_SERIAL_LEN)) {
/* Restore disk serial number, because takeover marks disk
* as failed and adds to serial ':0' before it becomes
* a spare disk.
@@ -5895,7 +5890,7 @@ static int add_to_super_imsm(struct supertype *st, mdu_disk_info_t *dk,
dd->fd = fd;
dd->e = NULL;
dd->action = DISK_ADD;
- rv = imsm_read_serial(fd, devname, dd->serial);
+ rv = imsm_read_serial(fd, devname, dd->serial, MAX_RAID_SERIAL_LEN);
if (rv) {
pr_err("failed to retrieve scsi serial, aborting\n");
if (dd->devname)
--
2.7.5

View File

@ -0,0 +1,342 @@
From 329dfc28debb58ffe7bd1967cea00fc583139aca Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.de>
Date: Mon, 4 Nov 2019 14:27:49 +1100
Subject: [RHEL8.2 PATCH 54/61] Create: add support for RAID0 layouts.
Since Linux 5.4 a layout is needed for RAID0 arrays with
varying device sizes.
This patch makes the layout of an array visible (via --examine)
and sets the layout on newly created arrays.
--layout=dangerous
can be used to avoid setting a layout so that they array
can be used on older kernels.
Tested-by: dann frazier <dann.frazier@canonical.com>
Signed-off-by: NeilBrown <neilb@suse.de>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Create.c | 11 +++++++++++
Detail.c | 5 +++++
maps.c | 12 ++++++++++++
md.4 | 14 ++++++++++++++
mdadm.8.in | 30 +++++++++++++++++++++++++++++-
mdadm.c | 8 ++++++++
mdadm.h | 8 +++++++-
super0.c | 6 ++++++
super1.c | 30 +++++++++++++++++++++++++++++-
9 files changed, 121 insertions(+), 3 deletions(-)
diff --git a/Create.c b/Create.c
index 292f92a..6f84e5b 100644
--- a/Create.c
+++ b/Create.c
@@ -51,6 +51,9 @@ static int default_layout(struct supertype *st, int level, int verbose)
default: /* no layout */
layout = 0;
break;
+ case 0:
+ layout = RAID0_ORIG_LAYOUT;
+ break;
case 10:
layout = 0x102; /* near=2, far=1 */
if (verbose > 0)
@@ -950,6 +953,11 @@ int Create(struct supertype *st, char *mddev,
if (rv) {
pr_err("ADD_NEW_DISK for %s failed: %s\n",
dv->devname, strerror(errno));
+ if (errno == EINVAL &&
+ info.array.level == 0) {
+ pr_err("Possibly your kernel doesn't support RAID0 layouts.\n");
+ pr_err("Either upgrade, or use --layout=dangerous\n");
+ }
goto abort_locked;
}
break;
@@ -1046,6 +1054,9 @@ int Create(struct supertype *st, char *mddev,
if (ioctl(mdfd, RUN_ARRAY, &param)) {
pr_err("RUN_ARRAY failed: %s\n",
strerror(errno));
+ if (errno == 524 /* ENOTSUP */ &&
+ info.array.level == 0)
+ cont_err("Please use --layout=original or --layout=alternate\n");
if (info.array.chunk_size & (info.array.chunk_size-1)) {
cont_err("Problem may be that chunk size is not a power of 2\n");
}
diff --git a/Detail.c b/Detail.c
index 24fa462..832485f 100644
--- a/Detail.c
+++ b/Detail.c
@@ -525,6 +525,11 @@ int Detail(char *dev, struct context *c)
printf(" Layout : %s\n",
str ? str : "-unknown-");
}
+ if (array.level == 0 && array.layout) {
+ str = map_num(r0layout, array.layout);
+ printf(" Layout : %s\n",
+ str ? str : "-unknown-");
+ }
if (array.level == 6) {
str = map_num(r6layout, array.layout);
printf(" Layout : %s\n",
diff --git a/maps.c b/maps.c
index 49b7f2c..a4fd279 100644
--- a/maps.c
+++ b/maps.c
@@ -73,6 +73,18 @@ mapping_t r6layout[] = {
{ NULL, UnSet }
};
+/* raid0 layout is only needed because of a bug in 3.14 which changed
+ * the effective layout of raid0 arrays with varying device sizes.
+ */
+mapping_t r0layout[] = {
+ { "original", RAID0_ORIG_LAYOUT},
+ { "alternate", RAID0_ALT_MULTIZONE_LAYOUT},
+ { "1", 1}, /* aka ORIG */
+ { "2", 2}, /* aka ALT */
+ { "dangerous", 0},
+ { NULL, UnSet},
+};
+
mapping_t pers[] = {
{ "linear", LEVEL_LINEAR},
{ "raid0", 0},
diff --git a/md.4 b/md.4
index e86707a..6fe2755 100644
--- a/md.4
+++ b/md.4
@@ -193,6 +193,20 @@ smallest device has been exhausted, the RAID0 driver starts
collecting chunks into smaller stripes that only span the drives which
still have remaining space.
+A bug was introduced in linux 3.14 which changed the layout of blocks in
+a RAID0 beyond the region that is striped over all devices. This bug
+does not affect an array with all devices the same size, but can affect
+other RAID0 arrays.
+
+Linux 5.4 (and some stable kernels to which the change was backported)
+will not normally assemble such an array as it cannot know which layout
+to use. There is a module parameter "raid0.default_layout" which can be
+set to "1" to force the kernel to use the pre-3.14 layout or to "2" to
+force it to use the 3.14-and-later layout. when creating a new RAID0
+array,
+.I mdadm
+will record the chosen layout in the metadata in a way that allows newer
+kernels to assemble the array without needing a module parameter.
.SS RAID1
diff --git a/mdadm.8.in b/mdadm.8.in
index 9aec9f4..fc9b6a6 100644
--- a/mdadm.8.in
+++ b/mdadm.8.in
@@ -593,6 +593,8 @@ to change the RAID level in some cases. See LEVEL CHANGES below.
This option configures the fine details of data layout for RAID5, RAID6,
and RAID10 arrays, and controls the failure modes for
.IR faulty .
+It can also be used for working around a kernel bug with RAID0, but generally
+doesn't need to be used explicitly.
The layout of the RAID5 parity block can be one of
.BR left\-asymmetric ,
@@ -652,7 +654,7 @@ option to set subsequent failure modes.
"clear" or "none" will remove any pending or periodic failure modes,
and "flush" will clear any persistent faults.
-Finally, the layout options for RAID10 are one of 'n', 'o' or 'f' followed
+The layout options for RAID10 are one of 'n', 'o' or 'f' followed
by a small number. The default is 'n2'. The supported options are:
.I 'n'
@@ -677,6 +679,32 @@ devices in the array. It does not need to divide evenly into that
number (e.g. it is perfectly legal to have an 'n2' layout for an array
with an odd number of devices).
+A bug introduced in Linux 3.14 means that RAID0 arrays
+.B "with devices of differing sizes"
+started using a different layout. This could lead to
+data corruption. Since Linux 5.4 (and various stable releases that received
+backports), the kernel will not accept such an array unless
+a layout is explictly set. It can be set to
+.RB ' original '
+or
+.RB ' alternate '.
+When creating a new array,
+.I mdadm
+will select
+.RB ' original '
+by default, so the layout does not normally need to be set.
+An array created for either
+.RB ' original '
+or
+.RB ' alternate '
+will not be recognized by an (unpatched) kernel prior to 5.4. To create
+a RAID0 array with devices of differing sizes that can be used on an
+older kernel, you can set the layout to
+.RB ' dangerous '.
+This will use whichever layout the running kernel supports, so the data
+on the array may become corrupt when changing kernel from pre-3.14 to a
+later kernel.
+
When an array is converted between RAID5 and RAID6 an intermediate
RAID6 layout is used in which the second parity block (Q) is always on
the last device. To convert a RAID5 to RAID6 and leave it in this new
diff --git a/mdadm.c b/mdadm.c
index 1fb8086..e438f9c 100644
--- a/mdadm.c
+++ b/mdadm.c
@@ -550,6 +550,14 @@ int main(int argc, char *argv[])
pr_err("raid level must be given before layout.\n");
exit(2);
+ case 0:
+ s.layout = map_name(r0layout, optarg);
+ if (s.layout == UnSet) {
+ pr_err("layout %s not understood for raid0.\n",
+ optarg);
+ exit(2);
+ }
+ break;
case 5:
s.layout = map_name(r5layout, optarg);
if (s.layout == UnSet) {
diff --git a/mdadm.h b/mdadm.h
index 91f1338..9e98778 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -763,7 +763,8 @@ extern int restore_stripes(int *dest, unsigned long long *offsets,
extern char *map_num(mapping_t *map, int num);
extern int map_name(mapping_t *map, char *name);
-extern mapping_t r5layout[], r6layout[], pers[], modes[], faultylayout[];
+extern mapping_t r0layout[], r5layout[], r6layout[],
+ pers[], modes[], faultylayout[];
extern mapping_t consistency_policies[], sysfs_array_states[];
extern char *map_dev_preferred(int major, int minor, int create,
@@ -1758,6 +1759,11 @@ char *xstrdup(const char *str);
#define makedev(M,m) (((M)<<8) | (m))
#endif
+enum r0layout {
+ RAID0_ORIG_LAYOUT = 1,
+ RAID0_ALT_MULTIZONE_LAYOUT = 2,
+};
+
/* for raid4/5/6 */
#define ALGORITHM_LEFT_ASYMMETRIC 0
#define ALGORITHM_RIGHT_ASYMMETRIC 1
diff --git a/super0.c b/super0.c
index 6b7c0e3..6af140b 100644
--- a/super0.c
+++ b/super0.c
@@ -1291,6 +1291,12 @@ static int validate_geometry0(struct supertype *st, int level,
if (*chunk == UnSet)
*chunk = DEFAULT_CHUNK;
+ if (level == 0 && layout != UnSet) {
+ if (verbose)
+ pr_err("0.90 metadata does not support layouts for RAID0\n");
+ return 0;
+ }
+
if (!subdev)
return 1;
diff --git a/super1.c b/super1.c
index 929466d..cedbb53 100644
--- a/super1.c
+++ b/super1.c
@@ -43,7 +43,7 @@ struct mdp_superblock_1 {
__u64 ctime; /* lo 40 bits are seconds, top 24 are microseconds or 0*/
__u32 level; /* -4 (multipath), -1 (linear), 0,1,4,5 */
- __u32 layout; /* only for raid5 currently */
+ __u32 layout; /* used for raid5, raid6, raid10, and raid0 */
__u64 size; /* used size of component devices, in 512byte sectors */
__u32 chunksize; /* in 512byte sectors */
@@ -144,6 +144,7 @@ struct misc_dev_info {
#define MD_FEATURE_JOURNAL 512 /* support write journal */
#define MD_FEATURE_PPL 1024 /* support PPL */
#define MD_FEATURE_MUTLIPLE_PPLS 2048 /* support for multiple PPLs */
+#define MD_FEATURE_RAID0_LAYOUT 4096 /* layout is meaningful in RAID0 */
#define MD_FEATURE_ALL (MD_FEATURE_BITMAP_OFFSET \
|MD_FEATURE_RECOVERY_OFFSET \
|MD_FEATURE_RESHAPE_ACTIVE \
@@ -155,6 +156,7 @@ struct misc_dev_info {
|MD_FEATURE_JOURNAL \
|MD_FEATURE_PPL \
|MD_FEATURE_MULTIPLE_PPLS \
+ |MD_FEATURE_RAID0_LAYOUT \
)
static int role_from_sb(struct mdp_superblock_1 *sb)
@@ -498,6 +500,11 @@ static void examine_super1(struct supertype *st, char *homehost)
printf(" Events : %llu\n",
(unsigned long long)__le64_to_cpu(sb->events));
printf("\n");
+ if (__le32_to_cpu(sb->level) == 0 &&
+ (sb->feature_map & __cpu_to_le32(MD_FEATURE_RAID0_LAYOUT))) {
+ c = map_num(r0layout, __le32_to_cpu(sb->layout));
+ printf(" Layout : %s\n", c?c:"-unknown-");
+ }
if (__le32_to_cpu(sb->level) == 5) {
c = map_num(r5layout, __le32_to_cpu(sb->layout));
printf(" Layout : %s\n", c?c:"-unknown-");
@@ -1646,6 +1653,7 @@ struct devinfo {
int fd;
char *devname;
long long data_offset;
+ unsigned long long dev_size;
mdu_disk_info_t disk;
struct devinfo *next;
};
@@ -1687,6 +1695,7 @@ static int add_to_super1(struct supertype *st, mdu_disk_info_t *dk,
di->devname = devname;
di->disk = *dk;
di->data_offset = data_offset;
+ get_dev_size(fd, NULL, &di->dev_size);
di->next = NULL;
*dip = di;
@@ -1888,10 +1897,25 @@ static int write_init_super1(struct supertype *st)
unsigned long long sb_offset;
unsigned long long data_offset;
long bm_offset;
+ int raid0_need_layout = 0;
for (di = st->info; di; di = di->next) {
if (di->disk.state & (1 << MD_DISK_JOURNAL))
sb->feature_map |= __cpu_to_le32(MD_FEATURE_JOURNAL);
+ if (sb->level == 0 && sb->layout != 0) {
+ struct devinfo *di2 = st->info;
+ unsigned long long s1, s2;
+ s1 = di->dev_size;
+ if (di->data_offset != INVALID_SECTORS)
+ s1 -= di->data_offset;
+ s1 /= __le32_to_cpu(sb->chunksize);
+ s2 = di2->dev_size;
+ if (di2->data_offset != INVALID_SECTORS)
+ s2 -= di2->data_offset;
+ s2 /= __le32_to_cpu(sb->chunksize);
+ if (s1 != s2)
+ raid0_need_layout = 1;
+ }
}
for (di = st->info; di; di = di->next) {
@@ -2039,6 +2063,10 @@ static int write_init_super1(struct supertype *st)
sb->bblog_offset = 0;
}
+ /* RAID0 needs a layout if devices aren't all the same size */
+ if (raid0_need_layout)
+ sb->feature_map |= __cpu_to_le32(MD_FEATURE_RAID0_LAYOUT);
+
sb->sb_csum = calc_sb_1_csum(sb);
rv = store_super1(st, di->fd);
--
2.7.5

View File

@ -0,0 +1,150 @@
From 027c099fd1a31fb3815e592de75d0791a22353b4 Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.de>
Date: Mon, 4 Nov 2019 14:27:49 +1100
Subject: [RHEL8.2 PATCH 55/61] Assemble: add support for RAID0 layouts.
If you have a RAID0 array with varying sized devices
on a kernel before 5.4, you cannot assembling it on
5.4 or later without explicitly setting the layout.
This is now possible with
--update=layout-original (For 3.13 and earlier kernels)
or
--update=layout-alternate (for 3.14 and later kernels)
Signed-off-by: NeilBrown <neilb@suse.de>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Assemble.c | 8 ++++++++
md.4 | 7 +++++++
mdadm.8.in | 17 +++++++++++++++++
mdadm.c | 4 ++++
super1.c | 12 +++++++++++-
5 files changed, 47 insertions(+), 1 deletion(-)
diff --git a/Assemble.c b/Assemble.c
index b2e6914..6b5a7c8 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -1031,6 +1031,11 @@ static int start_array(int mdfd,
pr_err("failed to add %s to %s: %s\n",
devices[j].devname, mddev,
strerror(errno));
+ if (errno == EINVAL && content->array.level == 0 &&
+ content->array.layout != 0) {
+ cont_err("Possibly your kernel doesn't support RAID0 layouts.\n");
+ cont_err("Please upgrade.\n");
+ }
if (i < content->array.raid_disks * 2 ||
i == bestcnt)
okcnt--;
@@ -1220,6 +1225,9 @@ static int start_array(int mdfd,
return 0;
}
pr_err("failed to RUN_ARRAY %s: %s\n", mddev, strerror(errno));
+ if (errno == 524 /* ENOTSUP */ &&
+ content->array.level == 0 && content->array.layout == 0)
+ cont_err("Please use --update=layout-original or --update=layout-alternate\n");
if (!enough(content->array.level, content->array.raid_disks,
content->array.layout, 1, avail))
diff --git a/md.4 b/md.4
index 6fe2755..0712af2 100644
--- a/md.4
+++ b/md.4
@@ -208,6 +208,13 @@ array,
will record the chosen layout in the metadata in a way that allows newer
kernels to assemble the array without needing a module parameter.
+To assemble an old array on a new kernel without using the module parameter,
+use either the
+.B "--update=layout-original"
+option or the
+.B "--update=layout-alternate"
+option.
+
.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 fc9b6a6..6b63bb4 100644
--- a/mdadm.8.in
+++ b/mdadm.8.in
@@ -1213,6 +1213,8 @@ argument given to this flag can be one of
.BR no\-bbl ,
.BR ppl ,
.BR no\-ppl ,
+.BR layout\-original ,
+.BR layout\-alternate ,
.BR metadata ,
or
.BR super\-minor .
@@ -1364,6 +1366,21 @@ The
.B no\-ppl
option will disable PPL in the superblock.
+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,
+.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
+.B \-\-update=layout\-alternate
+must be given. This only needs to be given once. Subsequent assembly of the array
+will happen normally.
+For more information, see
+.IR md (4).
+
.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 e438f9c..256a97e 100644
--- a/mdadm.c
+++ b/mdadm.c
@@ -795,6 +795,9 @@ int main(int argc, char *argv[])
continue;
if (strcmp(c.update, "revert-reshape") == 0)
continue;
+ if (strcmp(c.update, "layout-original") == 0 ||
+ strcmp(c.update, "layout-alternate") == 0)
+ continue;
if (strcmp(c.update, "byteorder") == 0) {
if (ss) {
pr_err("must not set metadata type with --update=byteorder.\n");
@@ -825,6 +828,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"
);
exit(outf == stdout ? 0 : 2);
diff --git a/super1.c b/super1.c
index cedbb53..e0d80be 100644
--- a/super1.c
+++ b/super1.c
@@ -1550,7 +1550,17 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
sb->devflags |= FailFast1;
else if (strcmp(update, "nofailfast") == 0)
sb->devflags &= ~FailFast1;
- else
+ else if (strcmp(update, "layout-original") == 0 ||
+ strcmp(update, "layout-alternate") == 0) {
+ if (__le32_to_cpu(sb->level) != 0) {
+ pr_err("%s: %s only supported for RAID0\n",
+ devname?:"", update);
+ rv = -1;
+ } else {
+ sb->feature_map |= __cpu_to_le32(MD_FEATURE_RAID0_LAYOUT);
+ sb->layout = __cpu_to_le32(update[7] == 'o' ? 1 : 2);
+ }
+ } else
rv = -1;
sb->sb_csum = calc_sb_1_csum(sb);
--
2.7.5

View File

@ -0,0 +1,36 @@
From aced6fc9542077a69b00d05bc9cd66c12fc34950 Mon Sep 17 00:00:00 2001
From: dann frazier <dann.frazier@canonical.com>
Date: Mon, 9 Dec 2019 13:54:13 -0700
Subject: [RHEL8.2 PATCH 56/61] Respect $(CROSS_COMPILE) when $(CC) is the
default
Commit 1180ed5 told make to only respect $(CROSS_COMPILE) when $(CC)
was unset. But that will never be the case, as make provides
a default value for $(CC). Change this logic to respect $(CROSS_COMPILE)
when $(CC) is the default. Patch originally by Helmet Grohne.
Fixes: 1180ed5 ("Makefile: make the CC definition conditional")
Signed-off-by: dann frazier <dann.frazier@canonical.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Makefile | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/Makefile b/Makefile
index dfe00b0..a33319a 100644
--- a/Makefile
+++ b/Makefile
@@ -46,7 +46,9 @@ ifdef COVERITY
COVERITY_FLAGS=-include coverity-gcc-hack.h
endif
-CC ?= $(CROSS_COMPILE)gcc
+ifeq ($(origin CC),default)
+CC := $(CROSS_COMPILE)gcc
+endif
CXFLAGS ?= -ggdb
CWFLAGS = -Wall -Werror -Wstrict-prototypes -Wextra -Wno-unused-parameter
ifdef WARN_UNUSED
--
2.7.5

View File

@ -0,0 +1,39 @@
From 1a87493014050e3bd94000cd36122c3cadf21270 Mon Sep 17 00:00:00 2001
From: Kinga Tanska <kinga.tanska@intel.com>
Date: Tue, 10 Dec 2019 12:21:21 +0100
Subject: [RHEL8.2 PATCH 57/61] Change warning message
In commit 039b7225e6 ("md: allow creation of mdNNN arrays via
md_mod/parameters/new_array") support for name like mdNNN
was added. Special warning, when kernel is unable to handle
request, was added in commit 7105228e19
("mdadm/mdopen: create new function create_named_array for
writing to new_array"), but it was not adequate enough,
because in this situation mdadm tries to do it in old way.
This commit changes warning to be more relevant when
creating RAID container with "/dev/mdNNN" name and mdadm
back to old approach.
Signed-off-by: Kinga Tanska <kinga.tanska@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
mdopen.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/mdopen.c b/mdopen.c
index 98c54e4..245be53 100644
--- a/mdopen.c
+++ b/mdopen.c
@@ -120,7 +120,8 @@ int create_named_array(char *devnm)
close(fd);
}
if (fd < 0 || n != (int)strlen(devnm)) {
- pr_err("Fail create %s when using %s\n", devnm, new_array_file);
+ pr_err("Fail to create %s when using %s, fallback to creation via node\n",
+ devnm, new_array_file);
return 0;
}
--
2.7.5

View File

@ -0,0 +1,52 @@
From 1cc3965d48deb0fb3e0657159c608ffb124643c1 Mon Sep 17 00:00:00 2001
From: Xiao Yang <ice_yangxiao@163.com>
Date: Wed, 27 Nov 2019 11:59:24 +0800
Subject: [RHEL8.2 PATCH 48/61] Manage: Remove the legacy code for md driver
prior to 0.90.03
Previous re-add operation only calls ioctl(HOT_ADD_DISK) for array without
metadata(e.g. mdadm -B/--build) when md driver is less than 0.90.02, but
commit 091e8e6 breaks the logic and current re-add operation can call
ioctl(HOT_ADD_DISK) even if md driver is 0.90.03.
This issue is reproduced by 05r1-re-add-nosuper:
------------------------------------------------
++ die 'resync or recovery is happening!'
++ echo -e '\n\tERROR: resync or recovery is happening! \n'
ERROR: resync or recovery is happening!
------------------------------------------------
Fixes: 091e8e6("Manage: Remove all references to md_get_version()")
Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Xiao Yang <ice_yangxiao@163.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Manage.c | 12 ------------
1 file changed, 12 deletions(-)
diff --git a/Manage.c b/Manage.c
index 21536f5..ffe55f8 100644
--- a/Manage.c
+++ b/Manage.c
@@ -741,18 +741,6 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv,
" Adding anyway as --force was given.\n",
dv->devname, devname);
}
- if (!tst->ss->external && array->major_version == 0) {
- if (ioctl(fd, HOT_ADD_DISK, rdev)==0) {
- if (verbose >= 0)
- pr_err("hot added %s\n",
- dv->devname);
- return 1;
- }
-
- pr_err("hot add failed for %s: %s\n",
- dv->devname, strerror(errno));
- return -1;
- }
if (array->not_persistent == 0 || tst->ss->external) {
--
2.7.5

View File

@ -0,0 +1,43 @@
From 4431efebabd0dd39f33dc1dd8ada312b8da1c9d8 Mon Sep 17 00:00:00 2001
From: Blazej Kucman <blazej.kucman@intel.com>
Date: Thu, 16 Jan 2020 09:34:44 +0100
Subject: [RHEL8.2 PATCH 59/61] imsm: Update grow manual.
Update --grow option description in manual, according to
the supported grow operations by IMSM.
Signed-off-by: Blazej Kucman <blazej.kucman@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
mdadm.8.in | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/mdadm.8.in b/mdadm.8.in
index 6b63bb4..ca02a33 100644
--- a/mdadm.8.in
+++ b/mdadm.8.in
@@ -481,9 +481,7 @@ still be larger than any replacement.
This value can be set with
.B \-\-grow
for RAID level 1/4/5/6 though
-.B CONTAINER
-based arrays such as those with IMSM metadata may not be able to
-support this.
+DDF arrays may not be able to support this.
If the array was created with a size smaller than the currently
active drives, the extra space can be accessed using
.BR \-\-grow .
@@ -2759,9 +2757,7 @@ container format. The number of devices in a container can be
increased - which affects all arrays in the container - or an array
in a container can be converted between levels where those levels are
supported by the container, and the conversion is on of those listed
-above. Resizing arrays in an IMSM container with
-.B "--grow --size"
-is not yet supported.
+above.
.PP
Notes:
--
2.7.5

View File

@ -0,0 +1,192 @@
From 42e641abeb312a91b841f1b1ea73661e4bd5a31c Mon Sep 17 00:00:00 2001
From: Kinga Tanska <kinga.tanska@intel.com>
Date: Tue, 21 Jan 2020 10:38:52 +0100
Subject: [RHEL8.2 PATCH 60/61] Add support for Tebibytes
Adding support for Tebibytes enables display size of
volumes in Tebibytes and Terabytes when they are
bigger than 2048 GiB (or GB).
Signed-off-by: Kinga Tanska <kinga.tanska@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
mdadm.8.in | 20 ++++++++++----------
util.c | 47 +++++++++++++++++++++++++++++++++--------------
2 files changed, 43 insertions(+), 24 deletions(-)
diff --git a/mdadm.8.in b/mdadm.8.in
index ca02a33..5d00faf 100644
--- a/mdadm.8.in
+++ b/mdadm.8.in
@@ -467,8 +467,8 @@ If this is not specified
size, though if there is a variance among the drives of greater than 1%, a warning is
issued.
-A suffix of 'K', 'M' or 'G' can be given to indicate Kilobytes, Megabytes or
-Gigabytes respectively.
+A suffix of 'K', 'M', 'G' or 'T' can be given to indicate Kilobytes,
+Megabytes, Gigabytes or Terabytes respectively.
Sometimes a replacement drive can be a little smaller than the
original drives though this should be minimised by IDEMA standards.
@@ -532,8 +532,8 @@ problems the array can be made bigger again with no loss with another
.B "\-\-grow \-\-array\-size="
command.
-A suffix of 'K', 'M' or 'G' can be given to indicate Kilobytes, Megabytes or
-Gigabytes respectively.
+A suffix of 'K', 'M', 'G' or 'T' can be given to indicate Kilobytes,
+Megabytes, Gigabytes or Terabytes respectively.
A value of
.B max
restores the apparent size of the array to be whatever the real
@@ -551,8 +551,8 @@ This is only meaningful for RAID0, RAID4, RAID5, RAID6, and RAID10.
RAID4, RAID5, RAID6, and RAID10 require the chunk size to be a power
of 2. In any case it must be a multiple of 4KB.
-A suffix of 'K', 'M' or 'G' can be given to indicate Kilobytes, Megabytes or
-Gigabytes respectively.
+A suffix of 'K', 'M', 'G' or 'T' can be given to indicate Kilobytes,
+Megabytes, Gigabytes or Terabytes respectively.
.TP
.BR \-\-rounding=
@@ -767,8 +767,8 @@ When using an
bitmap, the chunksize defaults to 64Meg, or larger if necessary to
fit the bitmap into the available space.
-A suffix of 'K', 'M' or 'G' can be given to indicate Kilobytes, Megabytes or
-Gigabytes respectively.
+A suffix of 'K', 'M', 'G' or 'T' can be given to indicate Kilobytes,
+Megabytes, Gigabytes or Terabytes respectively.
.TP
.BR \-W ", " \-\-write\-mostly
@@ -857,8 +857,8 @@ an array which was originally created using a different version of
which computed a different offset.
Setting the offset explicitly over-rides the default. The value given
-is in Kilobytes unless a suffix of 'K', 'M' or 'G' is used to explicitly
-indicate Kilobytes, Megabytes or Gigabytes respectively.
+is in Kilobytes unless a suffix of 'K', 'M', 'G' or 'T' is used to explicitly
+indicate Kilobytes, Megabytes, Gigabytes or Terabytes respectively.
Since Linux 3.4,
.B \-\-data\-offset
diff --git a/util.c b/util.c
index 64dd409..07f9dc3 100644
--- a/util.c
+++ b/util.c
@@ -389,7 +389,7 @@ int mdadm_version(char *version)
unsigned long long parse_size(char *size)
{
/* parse 'size' which should be a number optionally
- * followed by 'K', 'M', or 'G'.
+ * followed by 'K', 'M'. 'G' or 'T'.
* Without a suffix, K is assumed.
* Number returned is in sectors (half-K)
* INVALID_SECTORS returned on error.
@@ -411,6 +411,10 @@ unsigned long long parse_size(char *size)
c++;
s *= 1024 * 1024 * 2;
break;
+ case 'T':
+ c++;
+ s *= 1024 * 1024 * 1024 * 2LL;
+ break;
case 's': /* sectors */
c++;
break;
@@ -893,13 +897,14 @@ char *human_size(long long bytes)
{
static char buf[47];
- /* We convert bytes to either centi-M{ega,ibi}bytes or
- * centi-G{igi,ibi}bytes, with appropriate rounding,
- * and then print 1/100th of those as a decimal.
+ /* We convert bytes to either centi-M{ega,ibi}bytes,
+ * centi-G{igi,ibi}bytes or centi-T{era,ebi}bytes
+ * with appropriate rounding, and then print
+ * 1/100th of those as a decimal.
* We allow upto 2048Megabytes before converting to
- * gigabytes, as that shows more precision and isn't
+ * gigabytes and 2048Gigabytes before converting to
+ * terabytes, as that shows more precision and isn't
* too large a number.
- * Terabytes are not yet handled.
*/
if (bytes < 5000*1024)
@@ -909,11 +914,16 @@ char *human_size(long long bytes)
long cMB = (bytes / ( 1000000LL / 200LL ) +1) /2;
snprintf(buf, sizeof(buf), " (%ld.%02ld MiB %ld.%02ld MB)",
cMiB/100, cMiB % 100, cMB/100, cMB % 100);
- } else {
+ } else if (bytes < 2*1024LL*1024LL*1024LL*1024LL) {
long cGiB = (bytes * 200LL / (1LL<<30) +1) / 2;
long cGB = (bytes / (1000000000LL/200LL ) +1) /2;
snprintf(buf, sizeof(buf), " (%ld.%02ld GiB %ld.%02ld GB)",
cGiB/100, cGiB % 100, cGB/100, cGB % 100);
+ } else {
+ long cTiB = (bytes * 200LL / (1LL<<40) + 1) / 2;
+ long cTB = (bytes / (1000000000000LL / 200LL) + 1) / 2;
+ snprintf(buf, sizeof(buf), " (%ld.%02ld TiB %ld.%02ld TB)",
+ cTiB/100, cTiB % 100, cTB/100, cTB % 100);
}
return buf;
}
@@ -922,13 +932,14 @@ char *human_size_brief(long long bytes, int prefix)
{
static char buf[30];
- /* We convert bytes to either centi-M{ega,ibi}bytes or
- * centi-G{igi,ibi}bytes, with appropriate rounding,
- * and then print 1/100th of those as a decimal.
+ /* We convert bytes to either centi-M{ega,ibi}bytes,
+ * centi-G{igi,ibi}bytes or centi-T{era,ebi}bytes
+ * with appropriate rounding, and then print
+ * 1/100th of those as a decimal.
* We allow upto 2048Megabytes before converting to
- * gigabytes, as that shows more precision and isn't
+ * gigabytes and 2048Gigabytes before converting to
+ * terabytes, as that shows more precision and isn't
* too large a number.
- * Terabytes are not yet handled.
*
* If prefix == IEC, we mean prefixes like kibi,mebi,gibi etc.
* If prefix == JEDEC, we mean prefixes like kilo,mega,giga etc.
@@ -941,10 +952,14 @@ char *human_size_brief(long long bytes, int prefix)
long cMiB = (bytes * 200LL / (1LL<<20) +1) /2;
snprintf(buf, sizeof(buf), "%ld.%02ldMiB",
cMiB/100, cMiB % 100);
- } else {
+ } else if (bytes < 2*1024LL*1024LL*1024LL*1024LL) {
long cGiB = (bytes * 200LL / (1LL<<30) +1) /2;
snprintf(buf, sizeof(buf), "%ld.%02ldGiB",
cGiB/100, cGiB % 100);
+ } else {
+ long cTiB = (bytes * 200LL / (1LL<<40) + 1) / 2;
+ snprintf(buf, sizeof(buf), "%ld.%02ldTiB",
+ cTiB/100, cTiB % 100);
}
}
else if (prefix == JEDEC) {
@@ -952,10 +967,14 @@ char *human_size_brief(long long bytes, int prefix)
long cMB = (bytes / ( 1000000LL / 200LL ) +1) /2;
snprintf(buf, sizeof(buf), "%ld.%02ldMB",
cMB/100, cMB % 100);
- } else {
+ } else if (bytes < 2*1024LL*1024LL*1024LL*1024LL) {
long cGB = (bytes / (1000000000LL/200LL ) +1) /2;
snprintf(buf, sizeof(buf), "%ld.%02ldGB",
cGB/100, cGB % 100);
+ } else {
+ long cTB = (bytes / (1000000000000LL / 200LL) + 1) / 2;
+ snprintf(buf, sizeof(buf), "%ld.%02ldTB",
+ cTB/100, cTB % 100);
}
}
else
--
2.7.5

View File

@ -0,0 +1,65 @@
From 1e93d0d15913c3fa6d0de5af3fb5e4e3b3f068da Mon Sep 17 00:00:00 2001
From: Blazej Kucman <blazej.kucman@intel.com>
Date: Fri, 17 Jan 2020 15:24:04 +0100
Subject: [RHEL8.2 PATCH 61/61] imsm: fill working_disks according to metadata.
Imsm tracks as "working_disk" each visible drive.
Assemble routine expects that the value will return count
of active member drives recorded in metadata.
As a side effect "--no-degraded" doesn't work correctly for imsm.
Align this field to others.
Added check, if the option --no-degraded is called with --scan.
Signed-off-by: Blazej Kucman <blazej.kucman@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
mdadm.c | 9 ++++++---
super-intel.c | 5 ++---
2 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/mdadm.c b/mdadm.c
index 256a97e..13dc24e 100644
--- a/mdadm.c
+++ b/mdadm.c
@@ -1485,9 +1485,12 @@ int main(int argc, char *argv[])
rv = Manage_stop(devlist->devname, mdfd, c.verbose, 0);
break;
case ASSEMBLE:
- if (devs_found == 1 && ident.uuid_set == 0 &&
- ident.super_minor == UnSet && ident.name[0] == 0 &&
- !c.scan ) {
+ if (!c.scan && c.runstop == -1) {
+ pr_err("--no-degraded not meaningful without a --scan assembly.\n");
+ exit(1);
+ } else if (devs_found == 1 && ident.uuid_set == 0 &&
+ ident.super_minor == UnSet && ident.name[0] == 0 &&
+ !c.scan) {
/* Only a device has been given, so get details from config file */
struct mddev_ident *array_ident = conf_get_ident(devlist->devname);
if (array_ident == NULL) {
diff --git a/super-intel.c b/super-intel.c
index 5c1f759..47809bc 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -7946,7 +7946,8 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra
skip = 1;
if (!skip && (ord & IMSM_ORD_REBUILD))
recovery_start = 0;
-
+ if (!(ord & IMSM_ORD_REBUILD))
+ this->array.working_disks++;
/*
* if we skip some disks the array will be assmebled degraded;
* reset resync start to avoid a dirty-degraded
@@ -7988,8 +7989,6 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra
else
this->array.spare_disks++;
}
- if (info_d->recovery_start == MaxSector)
- this->array.working_disks++;
info_d->events = __le32_to_cpu(mpb->generation_num);
info_d->data_offset = pba_of_lba0(map);
--
2.7.5

View File

@ -0,0 +1,55 @@
From 2551061c253b8fd45ee93d1aab3e91d2c7ac9c20 Mon Sep 17 00:00:00 2001
From: Coly Li <colyli@suse.de>
Date: Mon, 24 Feb 2020 12:34:09 +0100
Subject: [RHEL7.9 PATCH 62/77] mdadm.8: add note information for raid0 growing
operation
When growing a raid0 device, if the new component disk size is not
big enough, the grow operation may fail due to lack of backup space.
The minimum backup space should be larger than:
LCM(old, new) * chunk-size * 2
where LCM() is the least common multiple of the old and new count of
component disks, and "* 2" comes from the fact that mdadm refuses to
use more than half of a spare device for backup space.
There are users reporting such failure when they grew a raid0 array
with small component disk. Neil Brown points out this is not a bug
and how the failure comes. This patch adds note information into
mdadm(8) man page in the Notes part of GROW MODE section to explain
the minimum size requirement of new component disk size or external
backup size.
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Cc: NeilBrown <neilb@suse.de>
Cc: Jes Sorensen <jsorensen@fb.com>
Cc: Paul Menzel <pmenzel@molgen.mpg.de>
Cc: Wols Lists <antlists@youngman.org.uk>
Cc: Nix <nix@esperi.org.uk>
Signed-off-by: Coly Li <colyli@suse.de>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
mdadm.8.in | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/mdadm.8.in b/mdadm.8.in
index 5d00faf..a3494a1 100644
--- a/mdadm.8.in
+++ b/mdadm.8.in
@@ -2768,6 +2768,12 @@ option and it is transparent for assembly feature.
.IP \(bu 4
Roaming between Windows(R) and Linux systems for IMSM metadata is not
supported during grow process.
+.IP \(bu 4
+When growing a raid0 device, the new component disk size (or external
+backup size) should be larger than LCM(old, new) * chunk-size * 2,
+where LCM() is the least common multiple of the old and new count of
+component disks, and "* 2" comes from the fact that mdadm refuses to
+use more than half of a spare device for backup space.
.SS SIZE CHANGES
Normally when an array is built the "size" is taken from the smallest
--
2.7.5

View File

@ -0,0 +1,59 @@
From fd38b8ea80ff8e0317e12d1d70431148ceedd5fd Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Tue, 11 Feb 2020 21:44:15 +0800
Subject: [RHEL7.9 PATCH 63/77] Remove the legacy whitespace
The whitespace between Environment= and the true value causes confusion.
To avoid confusing other people in future, remove the whitespace to keep
it a simple, unambiguous syntax
Signed-off-by: Xiao Ni <xni@redhat.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
systemd/mdcheck_continue.service | 2 +-
systemd/mdcheck_start.service | 2 +-
systemd/mdmonitor-oneshot.service | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/systemd/mdcheck_continue.service b/systemd/mdcheck_continue.service
index aa02dde..854317f 100644
--- a/systemd/mdcheck_continue.service
+++ b/systemd/mdcheck_continue.service
@@ -11,7 +11,7 @@ ConditionPathExistsGlob = /var/lib/mdcheck/MD_UUID_*
[Service]
Type=oneshot
-Environment= "MDADM_CHECK_DURATION=6 hours"
+Environment="MDADM_CHECK_DURATION=6 hours"
EnvironmentFile=-/run/sysconfig/mdadm
ExecStartPre=-/usr/lib/mdadm/mdadm_env.sh
ExecStart=/usr/share/mdadm/mdcheck --continue --duration ${MDADM_CHECK_DURATION}
diff --git a/systemd/mdcheck_start.service b/systemd/mdcheck_start.service
index da62d5f..3bb3d13 100644
--- a/systemd/mdcheck_start.service
+++ b/systemd/mdcheck_start.service
@@ -11,7 +11,7 @@ Wants=mdcheck_continue.timer
[Service]
Type=oneshot
-Environment= "MDADM_CHECK_DURATION=6 hours"
+Environment="MDADM_CHECK_DURATION=6 hours"
EnvironmentFile=-/run/sysconfig/mdadm
ExecStartPre=-/usr/lib/mdadm/mdadm_env.sh
ExecStart=/usr/share/mdadm/mdcheck --duration ${MDADM_CHECK_DURATION}
diff --git a/systemd/mdmonitor-oneshot.service b/systemd/mdmonitor-oneshot.service
index fd469b1..373955a 100644
--- a/systemd/mdmonitor-oneshot.service
+++ b/systemd/mdmonitor-oneshot.service
@@ -9,7 +9,7 @@
Description=Reminder for degraded MD arrays
[Service]
-Environment= MDADM_MONITOR_ARGS=--scan
+Environment=MDADM_MONITOR_ARGS=--scan
EnvironmentFile=-/run/sysconfig/mdadm
ExecStartPre=-/usr/lib/mdadm/mdadm_env.sh
ExecStart=BINDIR/mdadm --monitor --oneshot $MDADM_MONITOR_ARGS
--
2.7.5

View File

@ -0,0 +1,91 @@
From 3364781b929f571a3dc3a6afed09eb1b03ce607c Mon Sep 17 00:00:00 2001
From: Blazej Kucman <blazej.kucman@intel.com>
Date: Wed, 19 Feb 2020 10:54:49 +0100
Subject: [RHEL7.9 PATCH 64/77] imsm: pass subarray id to kill_subarray
function
After patch b6180160f ("imsm: save current_vol number")
current_vol for imsm is not set and kill_subarray()
cannot determine which volume has to be deleted.
Volume has to be passed as "subarray_id".
The parameter affects only IMSM metadata.
Signed-off-by: Blazej Kucman <blazej.kucman@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Kill.c | 2 +-
mdadm.h | 3 ++-
super-ddf.c | 2 +-
super-intel.c | 9 ++++-----
4 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/Kill.c b/Kill.c
index d4767e2..bfd0efd 100644
--- a/Kill.c
+++ b/Kill.c
@@ -119,7 +119,7 @@ int Kill_subarray(char *dev, char *subarray, int verbose)
st->update_tail = &st->updates;
/* ok we've found our victim, drop the axe */
- rv = st->ss->kill_subarray(st);
+ rv = st->ss->kill_subarray(st, subarray);
if (rv) {
if (verbose >= 0)
pr_err("Failed to delete subarray-%s from %s\n",
diff --git a/mdadm.h b/mdadm.h
index 9e98778..d94569f 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -1038,7 +1038,8 @@ extern struct superswitch {
/* query the supertype for default geometry */
void (*default_geometry)(struct supertype *st, int *level, int *layout, int *chunk); /* optional */
/* Permit subarray's to be deleted from inactive containers */
- int (*kill_subarray)(struct supertype *st); /* optional */
+ int (*kill_subarray)(struct supertype *st,
+ char *subarray_id); /* optional */
/* Permit subarray's to be modified */
int (*update_subarray)(struct supertype *st, char *subarray,
char *update, struct mddev_ident *ident); /* optional */
diff --git a/super-ddf.c b/super-ddf.c
index 7802063..7cd5702 100644
--- a/super-ddf.c
+++ b/super-ddf.c
@@ -4446,7 +4446,7 @@ static int _kill_subarray_ddf(struct ddf_super *ddf, const char *guid)
return 0;
}
-static int kill_subarray_ddf(struct supertype *st)
+static int kill_subarray_ddf(struct supertype *st, char *subarray_id)
{
struct ddf_super *ddf = st->sb;
/*
diff --git a/super-intel.c b/super-intel.c
index 47809bc..e4d2122 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -7600,18 +7600,17 @@ static void default_geometry_imsm(struct supertype *st, int *level, int *layout,
static void handle_missing(struct intel_super *super, struct imsm_dev *dev);
-static int kill_subarray_imsm(struct supertype *st)
+static int kill_subarray_imsm(struct supertype *st, char *subarray_id)
{
- /* remove the subarray currently referenced by ->current_vol */
+ /* remove the subarray currently referenced by subarray_id */
__u8 i;
struct intel_dev **dp;
struct intel_super *super = st->sb;
- __u8 current_vol = super->current_vol;
+ __u8 current_vol = strtoul(subarray_id, NULL, 10);
struct imsm_super *mpb = super->anchor;
- if (super->current_vol < 0)
+ if (mpb->num_raid_devs == 0)
return 2;
- super->current_vol = -1; /* invalidate subarray cursor */
/* block deletions that would change the uuid of active subarrays
*
--
2.7.5

View File

@ -0,0 +1,91 @@
From 45c43276d02a32876c7e1f9f0d04580595141b3d Mon Sep 17 00:00:00 2001
From: Blazej Kucman <blazej.kucman@intel.com>
Date: Wed, 19 Feb 2020 11:13:17 +0100
Subject: [RHEL7.9 PATCH 65/77] imsm: Remove --dump/--restore implementation
Functionalities --dump and --restore are not supported.
Remove dead code from imsm.
Signed-off-by: Blazej Kucman <blazej.kucman@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
super-intel.c | 56 --------------------------------------------------------
1 file changed, 56 deletions(-)
diff --git a/super-intel.c b/super-intel.c
index e4d2122..c9a1af5 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -2128,61 +2128,6 @@ static void export_examine_super_imsm(struct supertype *st)
printf("MD_DEVICES=%u\n", mpb->num_disks);
}
-static int copy_metadata_imsm(struct supertype *st, int from, int to)
-{
- /* The second last sector of the device contains
- * the "struct imsm_super" metadata.
- * This contains mpb_size which is the size in bytes of the
- * extended metadata. This is located immediately before
- * the imsm_super.
- * We want to read all that, plus the last sector which
- * may contain a migration record, and write it all
- * to the target.
- */
- void *buf;
- unsigned long long dsize, offset;
- int sectors;
- struct imsm_super *sb;
- struct intel_super *super = st->sb;
- unsigned int sector_size = super->sector_size;
- unsigned int written = 0;
-
- if (posix_memalign(&buf, MAX_SECTOR_SIZE, MAX_SECTOR_SIZE) != 0)
- return 1;
-
- if (!get_dev_size(from, NULL, &dsize))
- goto err;
-
- if (lseek64(from, dsize-(2*sector_size), 0) < 0)
- goto err;
- if ((unsigned int)read(from, buf, sector_size) != sector_size)
- goto err;
- sb = buf;
- if (strncmp((char*)sb->sig, MPB_SIGNATURE, MPB_SIG_LEN) != 0)
- goto err;
-
- sectors = mpb_sectors(sb, sector_size) + 2;
- offset = dsize - sectors * sector_size;
- if (lseek64(from, offset, 0) < 0 ||
- lseek64(to, offset, 0) < 0)
- goto err;
- while (written < sectors * sector_size) {
- int n = sectors*sector_size - written;
- if (n > 4096)
- n = 4096;
- if (read(from, buf, n) != n)
- goto err;
- if (write(to, buf, n) != n)
- goto err;
- written += n;
- }
- free(buf);
- return 0;
-err:
- free(buf);
- return 1;
-}
-
static void detail_super_imsm(struct supertype *st, char *homehost,
char *subarray)
{
@@ -12270,7 +12215,6 @@ struct superswitch super_imsm = {
.reshape_super = imsm_reshape_super,
.manage_reshape = imsm_manage_reshape,
.recover_backup = recover_backup_imsm,
- .copy_metadata = copy_metadata_imsm,
.examine_badblocks = examine_badblocks_imsm,
.match_home = match_home_imsm,
.uuid_from_super= uuid_from_super_imsm,
--
2.7.5

View File

@ -0,0 +1,32 @@
From 06a6101c0a4d2658798dc42f461ace8e6900f840 Mon Sep 17 00:00:00 2001
From: Blazej Kucman <blazej.kucman@intel.com>
Date: Wed, 11 Mar 2020 15:40:13 +0100
Subject: [RHEL7.9 PATCH 66/77] imsm: Correct minimal device size.
Check if given size of member drive is not less than 1 MibiByte.
Signed-off-by: Blazej Kucman <blazej.kucman@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
super-intel.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/super-intel.c b/super-intel.c
index c9a1af5..6680df2 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -7425,7 +7425,10 @@ static int validate_geometry_imsm(struct supertype *st, int level, int layout,
verbose);
}
- if (size && (size < 1024)) {
+ /*
+ * Size is given in sectors.
+ */
+ if (size && (size < 2048)) {
pr_err("Given size must be greater than 1M.\n");
/* Depends on algorithm in Create.c :
* if container was given (dev == NULL) return -1,
--
2.7.5

View File

@ -0,0 +1,30 @@
From 9e4494051de3f53228fabae56c116879bff5a0c8 Mon Sep 17 00:00:00 2001
From: Lidong Zhong <lidong.zhong@suse.com>
Date: Mon, 16 Mar 2020 10:16:49 +0800
Subject: [RHEL7.9 PATCH 67/77] Detail: show correct bitmap info for cluster
raid device
Signed-off-by: Lidong Zhong <lidong.zhong@suse.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Detail.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/Detail.c b/Detail.c
index 832485f..daec4f1 100644
--- a/Detail.c
+++ b/Detail.c
@@ -468,7 +468,9 @@ int Detail(char *dev, struct context *c)
if (ioctl(fd, GET_BITMAP_FILE, &bmf) == 0 && bmf.pathname[0]) {
printf(" Intent Bitmap : %s\n", bmf.pathname);
printf("\n");
- } else if (array.state & (1<<MD_SB_BITMAP_PRESENT))
+ } else if (array.state & (1<<MD_SB_CLUSTERED))
+ printf(" Intent Bitmap : Internal(Clustered)\n\n");
+ else if (array.state & (1<<MD_SB_BITMAP_PRESENT))
printf(" Intent Bitmap : Internal\n\n");
atime = array.utime;
if (atime)
--
2.7.5

View File

@ -0,0 +1,67 @@
From e48aed3c81a75fa3f761fb5b84e5d16f2baee709 Mon Sep 17 00:00:00 2001
From: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
Date: Tue, 17 Mar 2020 10:20:12 +0100
Subject: [RHEL7.9 PATCH 68/77] imsm: support the Array Creation Time field in
metadata
Also present its value in --examine and --examine --export.
Signed-off-by: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
super-intel.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/super-intel.c b/super-intel.c
index 6680df2..8840fff 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -260,8 +260,9 @@ struct imsm_super {
* (starts at 1)
*/
__u16 filler1; /* 0x4E - 0x4F */
-#define IMSM_FILLERS 34
- __u32 filler[IMSM_FILLERS]; /* 0x50 - 0xD7 RAID_MPB_FILLERS */
+ __u64 creation_time; /* 0x50 - 0x57 Array creation time */
+#define IMSM_FILLERS 32
+ __u32 filler[IMSM_FILLERS]; /* 0x58 - 0xD7 RAID_MPB_FILLERS */
struct imsm_disk disk[1]; /* 0xD8 diskTbl[numDisks] */
/* here comes imsm_dev[num_raid_devs] */
/* here comes BBM logs */
@@ -2014,6 +2015,7 @@ static void examine_super_imsm(struct supertype *st, char *homehost)
__u32 sum;
__u32 reserved = imsm_reserved_sectors(super, super->disks);
struct dl *dl;
+ time_t creation_time;
strncpy(str, (char *)mpb->sig, MPB_SIG_LEN);
str[MPB_SIG_LEN-1] = '\0';
@@ -2022,6 +2024,9 @@ static void examine_super_imsm(struct supertype *st, char *homehost)
printf(" Orig Family : %08x\n", __le32_to_cpu(mpb->orig_family_num));
printf(" Family : %08x\n", __le32_to_cpu(mpb->family_num));
printf(" Generation : %08x\n", __le32_to_cpu(mpb->generation_num));
+ creation_time = __le64_to_cpu(mpb->creation_time);
+ printf(" Creation Time : %.24s\n",
+ creation_time ? ctime(&creation_time) : "Unknown");
printf(" Attributes : ");
if (imsm_check_attributes(mpb->attributes))
printf("All supported\n");
@@ -2126,6 +2131,7 @@ static void export_examine_super_imsm(struct supertype *st)
printf("MD_LEVEL=container\n");
printf("MD_UUID=%s\n", nbuf+5);
printf("MD_DEVICES=%u\n", mpb->num_disks);
+ printf("MD_CREATION_TIME=%llu\n", __le64_to_cpu(mpb->creation_time));
}
static void detail_super_imsm(struct supertype *st, char *homehost,
@@ -5762,6 +5768,7 @@ static int add_to_super_imsm_volume(struct supertype *st, mdu_disk_info_t *dk,
sum += __gen_imsm_checksum(mpb);
mpb->family_num = __cpu_to_le32(sum);
mpb->orig_family_num = mpb->family_num;
+ mpb->creation_time = __cpu_to_le64((__u64)time(NULL));
}
super->current_disk = dl;
return 0;
--
2.7.5

View File

@ -0,0 +1,39 @@
From ba1b3bc80ea555c288f1119e69d9273249967081 Mon Sep 17 00:00:00 2001
From: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
Date: Tue, 17 Mar 2020 10:21:03 +0100
Subject: [RHEL7.9 PATCH 69/77] imsm: show Subarray and Volume ID in --examine
output
Show the index of the subarray as 'Subarray' and the value of the
my_vol_raid_dev_num field as 'Volume ID'.
Signed-off-by: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
super-intel.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/super-intel.c b/super-intel.c
index 8840fff..562a58c 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -1579,6 +1579,7 @@ static void print_imsm_dev(struct intel_super *super,
printf("\n");
printf("[%.16s]:\n", dev->volume);
+ printf(" Subarray : %d\n", super->current_vol);
printf(" UUID : %s\n", uuid);
printf(" RAID Level : %d", get_imsm_raid_level(map));
if (map2)
@@ -1683,6 +1684,8 @@ static void print_imsm_dev(struct intel_super *super,
printf("Multiple PPLs on journaling drive\n");
else
printf("<unknown:%d>\n", dev->rwh_policy);
+
+ printf(" Volume ID : %u\n", dev->my_vol_raid_dev_num);
}
static void print_imsm_disk(struct imsm_disk *disk,
--
2.7.5

View File

@ -0,0 +1,35 @@
From e1b92ee0de26576a33b20c9dd6ef6bd8cab8e283 Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
Date: Wed, 8 Apr 2020 16:44:52 +0200
Subject: [RHEL7.9 PATCH 70/77] udev: Ignore change event for imsm
When adding a device to a container mdadm has to close its file
descriptor before sysfs_add_disk(). This generates change event.
There is race possibility because metadata is already written and other
-I process can place drive differently. As a result device can be added
to two containers simultaneously.
From IMSM perspective there is no need to react for change event. IMSM
doesn't support stacked devices.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
udev-md-raid-assembly.rules | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/udev-md-raid-assembly.rules b/udev-md-raid-assembly.rules
index 9f055ed..d668cdd 100644
--- a/udev-md-raid-assembly.rules
+++ b/udev-md-raid-assembly.rules
@@ -23,7 +23,7 @@ IMPORT{cmdline}="nodmraid"
ENV{nodmraid}=="?*", GOTO="md_inc_end"
ENV{ID_FS_TYPE}=="ddf_raid_member", GOTO="md_inc"
ENV{noiswmd}=="?*", GOTO="md_inc_end"
-ENV{ID_FS_TYPE}=="isw_raid_member", GOTO="md_inc"
+ENV{ID_FS_TYPE}=="isw_raid_member", ACTION!="change", GOTO="md_inc"
GOTO="md_inc_end"
LABEL="md_inc"
--
2.7.5

View File

@ -0,0 +1,109 @@
From 185ec4397e61ad00dd68c841e15eaa8629eb9514 Mon Sep 17 00:00:00 2001
From: Coly Li <colyli@suse.de>
Date: Sat, 11 Apr 2020 00:24:46 +0800
Subject: [RHEL7.9 PATCH 71/77] Monitor: improve check_one_sharer() for
checking duplicated process
When running mdadm monitor with scan mode, only one autorebuild process
is allowed. check_one_sharer() checks duplicated process by following
steps,
1) Read autorebuild.pid file,
- if file does not exist, no duplicated process, go to 3).
- if file exists, continue to next step.
2) Read pid number from autorebuild.pid file, then check procfs pid
directory /proc/<PID>,
- if the directory does not exist, no duplicated process, go to 3)
- if the directory exists, print error message for duplicated process
and exit this mdadm.
3) Write current pid into autorebuild.pid file, continue to monitor in
scan mode.
The problem for the above step 2) is, if after system reboots and
another different process happens to have exact same pid number which
autorebuild.pid file records, check_one_sharer() will treat it as a
duplicated mdadm process and returns error with message "Only one
autorebuild process allowed in scan mode, aborting".
This patch tries to fix the above same-pid-but-different-process issue
by one more step to check the process command name,
1) Read autorebuild.pid file
- if file does not exist, no duplicated process, go to 4).
- if file exists, continue to next step.
2) Read pid number from autorebuild.pid file, then check procfs file
comm with the specific pid directory /proc/<PID>/comm
- if the file does not exit, it means the directory /proc/<PID> does
not exist, go to 4)
- if the file exits, continue next step
3) Read process command name from /proc/<PIC>/comm, compare the command
name with "mdadm" process name,
- if not equal, no duplicated process, goto 4)
- if strings are equal, print error message for duplicated process
and exit this mdadm.
4) Write current pid into autorebuild.pid file, continue to monitor in
scan mode.
Now check_one_sharer() returns error for duplicated process only when
the recorded pid from autorebuild.pid exists, and the process has exact
same command name as "mdadm".
Reported-by: Shinkichi Yamazaki <shinkichi.yamazaki@suse.com>
Signed-off-by: Coly Li <colyli@suse.de>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Monitor.c | 32 ++++++++++++++++++++------------
1 file changed, 20 insertions(+), 12 deletions(-)
diff --git a/Monitor.c b/Monitor.c
index b527165..2d6b3b9 100644
--- a/Monitor.c
+++ b/Monitor.c
@@ -301,26 +301,34 @@ static int make_daemon(char *pidfile)
static int check_one_sharer(int scan)
{
- int pid, rv;
+ int pid;
+ FILE *comm_fp;
FILE *fp;
- char dir[20];
+ char comm_path[100];
char path[100];
- struct stat buf;
+ char comm[20];
+
sprintf(path, "%s/autorebuild.pid", MDMON_DIR);
fp = fopen(path, "r");
if (fp) {
if (fscanf(fp, "%d", &pid) != 1)
pid = -1;
- sprintf(dir, "/proc/%d", pid);
- rv = stat(dir, &buf);
- if (rv != -1) {
- if (scan) {
- pr_err("Only one autorebuild process allowed in scan mode, aborting\n");
- fclose(fp);
- return 1;
- } else {
- pr_err("Warning: One autorebuild process already running.\n");
+ snprintf(comm_path, sizeof(comm_path),
+ "/proc/%d/comm", pid);
+ comm_fp = fopen(comm_path, "r");
+ if (comm_fp) {
+ if (fscanf(comm_fp, "%s", comm) &&
+ strncmp(basename(comm), Name, strlen(Name)) == 0) {
+ if (scan) {
+ pr_err("Only one autorebuild process allowed in scan mode, aborting\n");
+ fclose(comm_fp);
+ fclose(fp);
+ return 1;
+ } else {
+ pr_err("Warning: One autorebuild process already running.\n");
+ }
}
+ fclose(comm_fp);
}
fclose(fp);
}
--
2.7.5

View File

@ -0,0 +1,85 @@
From 1c294b5d960abeeb9e0f188af294d019bc82b20e Mon Sep 17 00:00:00 2001
From: Lidong Zhong <lidong.zhong@suse.com>
Date: Tue, 14 Apr 2020 16:19:41 +0800
Subject: [RHEL7.9 PATCH 72/77] Detail: adding sync status for cluster device
On the node with /proc/mdstat is
Personalities : [raid1]
md0 : active raid1 sdb[4] sdc[3] sdd[2]
1046528 blocks super 1.2 [3/2] [UU_]
recover=REMOTE
bitmap: 1/1 pages [4KB], 65536KB chunk
Let's change the 'State' of 'mdadm -Q -D' accordingly
State : clean, degraded
With this patch, it will be
State : clean, degraded, recovering (REMOTE)
Signed-off-by: Lidong Zhong <lidong.zhong@suse.com>
Acked-by: Guoqing Jiang <guoqing.jiang@cloud.ionos.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Detail.c | 9 ++++++---
mdadm.h | 3 ++-
mdstat.c | 2 ++
3 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/Detail.c b/Detail.c
index daec4f1..24eeba0 100644
--- a/Detail.c
+++ b/Detail.c
@@ -498,17 +498,20 @@ int Detail(char *dev, struct context *c)
} else
arrayst = "active";
- printf(" State : %s%s%s%s%s%s \n",
+ printf(" State : %s%s%s%s%s%s%s \n",
arrayst, st,
(!e || (e->percent < 0 &&
e->percent != RESYNC_PENDING &&
- e->percent != RESYNC_DELAYED)) ?
+ e->percent != RESYNC_DELAYED &&
+ e->percent != RESYNC_REMOTE)) ?
"" : sync_action[e->resync],
larray_size ? "": ", Not Started",
(e && e->percent == RESYNC_DELAYED) ?
" (DELAYED)": "",
(e && e->percent == RESYNC_PENDING) ?
- " (PENDING)": "");
+ " (PENDING)": "",
+ (e && e->percent == RESYNC_REMOTE) ?
+ " (REMOTE)": "");
} else if (inactive && !is_container) {
printf(" State : inactive\n");
}
diff --git a/mdadm.h b/mdadm.h
index d94569f..399478b 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -1815,7 +1815,8 @@ enum r0layout {
#define RESYNC_NONE -1
#define RESYNC_DELAYED -2
#define RESYNC_PENDING -3
-#define RESYNC_UNKNOWN -4
+#define RESYNC_REMOTE -4
+#define RESYNC_UNKNOWN -5
/* When using "GET_DISK_INFO" it isn't certain how high
* we need to check. So we impose an absolute limit of
diff --git a/mdstat.c b/mdstat.c
index 7e600d0..20577a3 100644
--- a/mdstat.c
+++ b/mdstat.c
@@ -257,6 +257,8 @@ struct mdstat_ent *mdstat_read(int hold, int start)
ent->percent = RESYNC_DELAYED;
if (l > 8 && strcmp(w+l-8, "=PENDING") == 0)
ent->percent = RESYNC_PENDING;
+ if (l > 7 && strcmp(w+l-7, "=REMOTE") == 0)
+ ent->percent = RESYNC_REMOTE;
} else if (ent->percent == RESYNC_NONE &&
w[0] >= '0' &&
w[0] <= '9' &&
--
2.7.5

View File

@ -0,0 +1,164 @@
From 12724c018c964596aa277489fd287d5c3506361a Mon Sep 17 00:00:00 2001
From: Tkaczyk Mariusz <mariusz.tkaczyk@intel.com>
Date: Fri, 17 Apr 2020 13:55:55 +0200
Subject: [RHEL7.9 PATCH 73/77] Manage, imsm: Write metadata before add
New drive in container always appears as spare. Manager is able to
handle that, and queues appropriative update to monitor.
No update from mdadm side has to be processed, just insert the drive and
ping the mdmon. Metadata has to be written if no mdmon is running (case
for Raid0 or container without arrays).
If bare drive is added very early on startup (by custom bare rule),
there is possiblity that mdmon was not restarted after switch root. Old
one is not able to handle new drive. New one fails because there is
drive without metadata in container and metadata cannot be loaded.
To prevent this, write spare metadata before adding device
to container. Mdmon will overwrite it (same case as spare migration,
if drive appears it writes the most recent metadata).
Metadata has to be written only on new drive before sysfs_add_disk(),
don't race with mdmon if running.
Signed-off-by: Tkaczyk Mariusz <mariusz.tkaczyk@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Manage.c | 6 +-----
super-intel.c | 66 ++++++++++++++++++++++++++++++++++++++---------------------
2 files changed, 44 insertions(+), 28 deletions(-)
diff --git a/Manage.c b/Manage.c
index b22c396..0a5f09b 100644
--- a/Manage.c
+++ b/Manage.c
@@ -994,17 +994,13 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv,
Kill(dv->devname, NULL, 0, -1, 0);
dfd = dev_open(dv->devname, O_RDWR | O_EXCL|O_DIRECT);
- if (mdmon_running(tst->container_devnm))
- tst->update_tail = &tst->updates;
if (tst->ss->add_to_super(tst, &disc, dfd,
dv->devname, INVALID_SECTORS)) {
close(dfd);
close(container_fd);
return -1;
}
- if (tst->update_tail)
- flush_metadata_updates(tst);
- else
+ if (!mdmon_running(tst->container_devnm))
tst->ss->sync_metadata(tst);
sra = sysfs_read(container_fd, NULL, 0);
diff --git a/super-intel.c b/super-intel.c
index 562a58c..3a73d2b 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -5809,6 +5809,9 @@ int mark_spare(struct dl *disk)
return ret_val;
}
+
+static int write_super_imsm_spare(struct intel_super *super, struct dl *d);
+
static int add_to_super_imsm(struct supertype *st, mdu_disk_info_t *dk,
int fd, char *devname,
unsigned long long data_offset)
@@ -5938,9 +5941,13 @@ static int add_to_super_imsm(struct supertype *st, mdu_disk_info_t *dk,
dd->next = super->disk_mgmt_list;
super->disk_mgmt_list = dd;
} else {
+ /* this is called outside of mdmon
+ * write initial spare metadata
+ * mdmon will overwrite it.
+ */
dd->next = super->disks;
super->disks = dd;
- super->updates_pending++;
+ write_super_imsm_spare(super, dd);
}
return 0;
@@ -5979,15 +5986,15 @@ static union {
struct imsm_super anchor;
} spare_record __attribute__ ((aligned(MAX_SECTOR_SIZE)));
-/* spare records have their own family number and do not have any defined raid
- * devices
- */
-static int write_super_imsm_spares(struct intel_super *super, int doclose)
+
+static int write_super_imsm_spare(struct intel_super *super, struct dl *d)
{
struct imsm_super *mpb = super->anchor;
struct imsm_super *spare = &spare_record.anchor;
__u32 sum;
- struct dl *d;
+
+ if (d->index != -1)
+ return 1;
spare->mpb_size = __cpu_to_le32(sizeof(struct imsm_super));
spare->generation_num = __cpu_to_le32(1UL);
@@ -6000,28 +6007,41 @@ static int write_super_imsm_spares(struct intel_super *super, int doclose)
snprintf((char *) spare->sig, MAX_SIGNATURE_LENGTH,
MPB_SIGNATURE MPB_VERSION_RAID0);
- for (d = super->disks; d; d = d->next) {
- if (d->index != -1)
- continue;
+ spare->disk[0] = d->disk;
+ if (__le32_to_cpu(d->disk.total_blocks_hi) > 0)
+ spare->attributes |= MPB_ATTRIB_2TB_DISK;
- spare->disk[0] = d->disk;
- if (__le32_to_cpu(d->disk.total_blocks_hi) > 0)
- spare->attributes |= MPB_ATTRIB_2TB_DISK;
+ if (super->sector_size == 4096)
+ convert_to_4k_imsm_disk(&spare->disk[0]);
- if (super->sector_size == 4096)
- convert_to_4k_imsm_disk(&spare->disk[0]);
+ sum = __gen_imsm_checksum(spare);
+ spare->family_num = __cpu_to_le32(sum);
+ spare->orig_family_num = 0;
+ sum = __gen_imsm_checksum(spare);
+ spare->check_sum = __cpu_to_le32(sum);
- sum = __gen_imsm_checksum(spare);
- spare->family_num = __cpu_to_le32(sum);
- spare->orig_family_num = 0;
- sum = __gen_imsm_checksum(spare);
- spare->check_sum = __cpu_to_le32(sum);
+ if (store_imsm_mpb(d->fd, spare)) {
+ pr_err("failed for device %d:%d %s\n",
+ d->major, d->minor, strerror(errno));
+ return 1;
+ }
+
+ return 0;
+}
+/* spare records have their own family number and do not have any defined raid
+ * devices
+ */
+static int write_super_imsm_spares(struct intel_super *super, int doclose)
+{
+ struct dl *d;
+
+ for (d = super->disks; d; d = d->next) {
+ if (d->index != -1)
+ continue;
- if (store_imsm_mpb(d->fd, spare)) {
- pr_err("failed for device %d:%d %s\n",
- d->major, d->minor, strerror(errno));
+ if (write_super_imsm_spare(super, d))
return 1;
- }
+
if (doclose) {
close(d->fd);
d->fd = -1;
--
2.7.5

View File

@ -0,0 +1,57 @@
From 5cfb79dea26d9d7266f79c7c196a1a9f70c16a28 Mon Sep 17 00:00:00 2001
From: Gioh Kim <gi-oh.kim@cloud.ionos.com>
Date: Tue, 16 Apr 2019 18:08:17 +0200
Subject: [RHEL7.9 PATCH 74/77] Assemble: print error message if mdadm fails
assembling with --uuid option
When mdadm tries to assemble one working device and one zeroed-out device,
it failed but print successful message because there is --uuid option.
Following script always reproduce it.
dd if=/dev/zero of=/dev/ram0 oflag=direct
dd if=/dev/zero of=/dev/ram1 oflag=direct
./mdadm -C /dev/md111 -e 1.2 --uuid="12345678:12345678:12345678:12345678" \
-l1 -n2 /dev/ram0 /dev/ram1
./mdadm -S /dev/md111
dd if=/dev/zero of=/dev/ram1 oflag=direct
./mdadm -A /dev/md111 --uuid="12345678:12345678:12345678:12345678" \
/dev/ram0 /dev/ram1
Following is message from mdadm.
mdadm: No super block found on /dev/ram1 (Expected magic a92b4efc, got 00000000)
mdadm: no RAID superblock on /dev/ram1
mdadm: /dev/md111 assembled from 1 drive - need all 2 to start it (use --run to insist).
The mdadm say that it assembled but mdadm does not create /dev/md111.
The message is wrong.
After applying this patch, mdadm reports error correctly as following.
mdadm: No super block found on /dev/ram1 (Expected magic a92b4efc, got 00000000)
mdadm: no RAID superblock on /dev/ram1
mdadm: /dev/ram1 has no superblock - assembly aborted
Signed-off-by: Gioh Kim <gi-oh.kim@cloud.ionos.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Assemble.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Assemble.c b/Assemble.c
index 6b5a7c8..2ed5884 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -269,7 +269,7 @@ static int select_devices(struct mddev_dev *devlist,
if (auto_assem || !inargv)
/* Ignore unrecognised devices during auto-assembly */
goto loop;
- if (ident->uuid_set || ident->name[0] ||
+ if (ident->name[0] ||
ident->super_minor != UnSet)
/* Ignore unrecognised device if looking for
* specific array */
--
2.7.5

View File

@ -0,0 +1,29 @@
From ec7d7ceefc1c2b9ba82cac1ba0f6a34d41a4a913 Mon Sep 17 00:00:00 2001
From: Nigel Croxon <ncroxon@redhat.com>
Date: Mon, 4 May 2020 12:27:45 -0400
Subject: [RHEL7.9 PATCH 75/77] clean up meaning of small typo
Clean up the typo which leads to wrong understanding.
Signed-off-by: Nigel Croxon <ncroxon@redhat.com>
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 a3494a1..9e7cb96 100644
--- a/mdadm.8.in
+++ b/mdadm.8.in
@@ -2878,7 +2878,7 @@ operation, as described below under LAYOUT CHANGES.
.SS CHUNK-SIZE AND LAYOUT CHANGES
-Changing the chunk-size of layout without also changing the number of
+Changing the chunk-size or layout without also changing the number of
devices as the same time will involve re-writing all blocks in-place.
To ensure against data loss in the case of a crash, a
.B --backup-file
--
2.7.5

View File

@ -0,0 +1,95 @@
From 7b99edab2834d5d08ef774b4cff784caaa1a186f Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
Date: Tue, 5 May 2020 12:17:17 +0200
Subject: [RHEL7.9 PATCH 76/77] Assemble.c: respect force flag.
If the array is dirty handler will set resync_start to 0 to inform kernel
that resync is needed. RWH affects only raid456 module, for other
levels array will be started even array is degraded and resync cannot be
performed.
Force is really meaningful for raid456. If array is degraded and resync
is requested, kernel will reject an attempt to start the array. To
respect force, it has to be marked as clean (this will be done for each
array without PPL) and remove the resync request (only for raid 456).
Data corruption may occur so proper warning is added.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Assemble.c | 51 ++++++++++++++++++++++++++++++++++++++-------------
1 file changed, 38 insertions(+), 13 deletions(-)
diff --git a/Assemble.c b/Assemble.c
index 2ed5884..3e5d4e6 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -2030,6 +2030,15 @@ int assemble_container_content(struct supertype *st, int mdfd,
free(avail);
return err;
}
+ } else if (c->force) {
+ /* Set the array as 'clean' so that we can proceed with starting
+ * it even if we don't have all devices. Mdmon doesn't care
+ * if the dirty flag is set in metadata, it will start managing
+ * it anyway.
+ * This is really important for raid456 (RWH case), other levels
+ * are started anyway.
+ */
+ content->array.state |= 1;
}
if (enough(content->array.level, content->array.raid_disks,
@@ -2049,20 +2058,36 @@ int assemble_container_content(struct supertype *st, int mdfd,
}
free(avail);
- if (c->runstop <= 0 &&
- (working + preexist + expansion) <
- content->array.working_disks) {
- if (c->export && result)
- *result |= INCR_UNSAFE;
- else if (c->verbose >= 0) {
- pr_err("%s assembled with %d device%s",
- chosen_name, preexist + working,
- preexist + working == 1 ? "":"s");
- if (preexist)
- fprintf(stderr, " (%d new)", working);
- fprintf(stderr, " but not safe to start\n");
+ if ((working + preexist + expansion) < content->array.working_disks) {
+ if (c->runstop <= 0) {
+ if (c->export && result)
+ *result |= INCR_UNSAFE;
+ else if (c->verbose >= 0) {
+ pr_err("%s assembled with %d device%s",
+ chosen_name, preexist + working,
+ preexist + working == 1 ? "":"s");
+ if (preexist)
+ fprintf(stderr, " (%d new)", working);
+ fprintf(stderr, " but not safe to start\n");
+ if (c->force)
+ pr_err("Consider --run to start array as degraded.\n");
+ }
+ return 1;
+ } else if (content->array.level >= 4 &&
+ content->array.level <= 6 &&
+ content->resync_start != MaxSector &&
+ c->force) {
+ /* Don't inform the kernel that the array is not
+ * clean and requires resync.
+ */
+ content->resync_start = MaxSector;
+ err = sysfs_set_num(content, NULL, "resync_start",
+ MaxSector);
+ if (err)
+ return 1;
+ pr_err("%s array state forced to clean. It may cause data corruption.\n",
+ chosen_name);
}
- return 1;
}
--
2.7.5

View File

@ -0,0 +1,45 @@
From 3b7aae927bdb6e150d1aaf3aaf0d183a06abda0b Mon Sep 17 00:00:00 2001
From: Donald Buczek <buczek@molgen.mpg.de>
Date: Wed, 13 May 2020 15:16:46 +0200
Subject: [RHEL7.9 PATCH 77/77] mdcheck: Log when done
Currently mdcheck (when called with `--duration`) logs only the
beginning of the check, the pausing and the continuation but not the
completion.
So, log the completion, too, so that it can be determined how long the
raid check took.
2020-05-08T18:00:02+02:00 deadpool root: mdcheck start checking /dev/md0
2020-05-08T18:00:02+02:00 deadpool root: mdcheck start checking /dev/md1
2020-05-09T15:32:04+02:00 deadpool root: mdcheck finished checking /dev/md1
2020-05-09T17:38:04+02:00 deadpool root: mdcheck finished checking /dev/md0
Cc: linux-raid@vger.kernel.org
Signed-off-by: Paul Menzel <pmenzel@molgen.mpg.de>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
misc/mdcheck | 2 ++
1 file changed, 2 insertions(+)
diff --git a/misc/mdcheck b/misc/mdcheck
index 42d4094..700c3e2 100644
--- a/misc/mdcheck
+++ b/misc/mdcheck
@@ -125,11 +125,13 @@ do
do
eval fl=\$MD_${i}_fl
eval sys=\$MD_${i}_sys
+ eval dev=\$MD_${i}_dev
if [ -z "$fl" ]; then continue; fi
if [ "`cat $sys/md/sync_action`" != 'check' ]
then
+ logger -p daemon.info mdcheck finished checking $dev
eval MD_${i}_fl=
rm -f $fl
continue;
--
2.7.5

View File

@ -1 +1 @@
d /var/run/mdadm 0710 root root -
d /run/mdadm 0710 root root -

48
SOURCES/mdadm_env.sh Normal file
View File

@ -0,0 +1,48 @@
#!/bin/sh
# extract configuration from /etc/sysconfig/mdadm and write
# environment to /run/sysconfig/mdadm to be used by
# systemd unit files.
MDADM_SCAN="yes"
# Following adapted from /etc/init.d/mdadmd on openSUSE
mdadmd_CONFIG=/etc/sysconfig/mdadm
if test -r $mdadmd_CONFIG; then
. $mdadmd_CONFIG
fi
if [ x$MDADM_DELAY != x"" ]; then
MDADM_DELAY="-d "$MDADM_DELAY;
fi
if [ x$MDADM_MAIL != x"" ]; then
MDADM_MAIL="-m \"$MDADM_MAIL\""
fi
if [ x$MDADM_PROGRAM != x"" ]; then
MDADM_PROGRAM="-p \"$MDADM_PROGRAM\""
fi
if [ x$MDADM_SCAN = x"yes" ]; then
MDADM_SCAN="--scan"
else
MDADM_SCAN=""
fi
if [ x$MDADM_SEND_MAIL_ON_START = x"yes" ]; then
MDADM_SEND_MAIL="-t"
else
MDADM_SEND_MAIL=""
fi
if [ x$MDADM_CONFIG != x"" ]; then
MDADM_CONFIG="-c \"$MDADM_CONFIG\""
fi
mkdir -p /run/sysconfig
echo "MDADM_MONITOR_ARGS=$MDADM_RAIDDEVICES $MDADM_DELAY $MDADM_MAIL $MDADM_PROGRAM $MDADM_SCAN $MDADM_SEND_MAIL $MDADM_CONFIG" > /run/sysconfig/mdadm
if [ -n "$MDADM_CHECK_DURATION" ]; then
echo "MDADM_CHECK_DURATION=$MDADM_CHECK_DURATION" >> /run/sysconfig/mdadm
fi

164
SOURCES/mdcheck Normal file
View File

@ -0,0 +1,164 @@
#!/bin/bash
# Copyright (C) 2014-2017 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.
#
# Author: Neil Brown
# Email: <neilb@suse.com>
# This script should be run periodically to automatically
# perform a 'check' on any md arrays.
#
# It supports a 'time budget' such that any incomplete 'check'
# will be checkpointed when that time has expired.
# A subsequent invocation can allow the 'check' to continue.
#
# Options are:
# --continue Don't start new checks, only continue old ones.
# --duration This is passed to "date --date=$duration" to find out
# when to finish
#
# To support '--continue', arrays are identified by UUID and the 'sync_completed'
# value is stored in /var/lib/mdcheck/$UUID
# convert a /dev/md name into /sys/.../md equivalent
sysname() {
set `ls -lLd $1`
maj=${5%,}
min=$6
readlink -f /sys/dev/block/$maj:$min
}
args=$(getopt -o hcd: -l help,continue,duration: -n mdcheck -- "$@")
rv=$?
if [ $rv -ne 0 ]; then exit $rv; fi
eval set -- $args
cont=
endtime=
while [ " $1" != " --" ]
do
case $1 in
--help )
echo >&2 'Usage: mdcheck [--continue] [--duration time-offset]'
echo >&2 ' time-offset must be understood by "date --date"'
exit 0
;;
--continue ) cont=yes ;;
--duration ) shift; dur=$1
endtime=$(date --date "$dur" "+%s")
;;
esac
shift
done
shift
# We need a temp file occasionally...
tmp=/var/lib/mdcheck/.md-check-$$
trap 'rm -f "$tmp"' 0 2 3 15
# firstly, clean out really old state files
mkdir -p /var/lib/mdcheck
find /var/lib/mdcheck -name "MD_UUID*" -type f -mtime +180 -exec rm {} \;
# Now look at each md device.
cnt=0
for dev in /dev/md?*
do
[ -e "$dev" ] || continue
sys=`sysname $dev`
if [ ! -f "$sys/md/sync_action" ]
then # cannot check this array
continue
fi
if [ "`cat $sys/md/sync_action`" != 'idle' ]
then # This array is busy
continue
fi
mdadm --detail --export "$dev" | grep '^MD_UUID=' > $tmp || continue
source $tmp
fl="/var/lib/mdcheck/MD_UUID_$MD_UUID"
if [ -z "$cont" ]
then
start=0
logger -p daemon.info mdcheck start checking $dev
elif [ -z "$MD_UUID" -o ! -f "$fl" ]
then
# Nothing to continue here
continue
else
start=`cat "$fl"`
logger -p daemon.info mdcheck continue checking $dev from $start
fi
cnt=$[cnt+1]
eval MD_${cnt}_fl=\$fl
eval MD_${cnt}_sys=\$sys
eval MD_${cnt}_dev=\$dev
echo $start > $fl
echo $start > $sys/md/sync_min
echo check > $sys/md/sync_action
done
if [ -z "$endtime" ]
then
exit 0
fi
while [ `date +%s` -lt $endtime ]
do
any=
for i in `eval echo {1..$cnt}`
do
eval fl=\$MD_${i}_fl
eval sys=\$MD_${i}_sys
if [ -z "$fl" ]; then continue; fi
if [ "`cat $sys/md/sync_action`" != 'check' ]
then
eval MD_${i}_fl=
rm -f $fl
continue;
fi
read a rest < $sys/md/sync_completed
echo $a > $fl
any=yes
done
if [ -z "$any" ]; then exit 0; fi
sleep 120
done
# We've waited, and there are still checks running.
# Time to stop them.
for i in `eval echo {1..$cnt}`
do
eval fl=\$MD_${i}_fl
eval sys=\$MD_${i}_sys
eval dev=\$MD_${i}_dev
if [ -z "$fl" ]; then continue; fi
if [ "`cat $sys/md/sync_action`" != 'check' ]
then
eval MD_${i}_fl=
rm -f $fl
continue;
fi
echo idle > $sys/md/sync_action
cat $sys/md/sync_min > $fl
logger -p daemon.info pause checking $dev at `cat $fl`
done

View File

@ -1,7 +1,7 @@
Summary: The mdadm program controls Linux md devices (software RAID arrays)
Name: mdadm
Version: 4.1
Release: 10%{?dist}
Release: 14%{?dist}
Source: http://www.kernel.org/pub/linux/utils/raid/mdadm/mdadm-%{version}.tar.xz
Source1: mdmonitor.init
Source2: raid-check
@ -11,6 +11,8 @@ Source5: mdadm-cron
Source6: mdmonitor.service
Source7: mdadm.conf
Source8: mdadm_event.conf
Source9: mdcheck
Source10: mdadm_env.sh
Patch1: 0001-Assemble-keep-MD_DISK_FAILFAST-and-MD_DISK_WRITEMOST.patch
Patch2: 0002-Document-PART-POLICY-lines.patch
@ -59,6 +61,36 @@ Patch44: 0044-mdcheck-when-mdcheck_start-is-enabled-enable-mdcheck.patch
Patch45: 0045-mdcheck-use-to-pass-variable-to-mdcheck.patch
Patch46: 0046-SUSE-mdadm_env.sh-handle-MDADM_CHECK_DURATION.patch
Patch47: 0047-super-intel-don-t-mark-structs-packed-unnecessarily.patch
Patch48: 0048-mdcheck-service-can-t-start-succesfully-because-of-s.patch
Patch49: 0049-Remove-last-traces-of-HOT_ADD_DISK.patch
Patch50: 0050-Fix-up-a-few-formatting-issues.patch
Patch51: 0051-Remove-unused-code.patch
Patch52: 0052-imsm-return-correct-uuid-for-volume-in-detail.patch
Patch53: 0053-imsm-Change-the-way-of-printing-nvme-drives-in-detai.patch
Patch54: 0054-Create-add-support-for-RAID0-layouts.patch
Patch55: 0055-Assemble-add-support-for-RAID0-layouts.patch
Patch56: 0056-Respect-CROSS_COMPILE-when-CC-is-the-default.patch
Patch57: 0057-Change-warning-message.patch
Patch58: 0058-Manage-Remove-the-legacy-code-for-md-driver-prior-to.patch
Patch59: 0059-imsm-Update-grow-manual.patch
Patch60: 0060-Add-support-for-Tebibytes.patch
Patch61: 0061-imsm-fill-working_disks-according-to-metadata.patch
Patch62: 0062-mdadm.8-add-note-information-for-raid0-growing-opera.patch
Patch63: 0063-Remove-the-legacy-whitespace.patch
Patch64: 0064-imsm-pass-subarray-id-to-kill_subarray-function.patch
Patch65: 0065-imsm-Remove-dump-restore-implementation.patch
Patch66: 0066-imsm-Correct-minimal-device-size.patch
Patch67: 0067-Detail-show-correct-bitmap-info-for-cluster-raid-dev.patch
Patch68: 0068-imsm-support-the-Array-Creation-Time-field-in-metada.patch
Patch69: 0069-imsm-show-Subarray-and-Volume-ID-in-examine-output.patch
Patch70: 0070-udev-Ignore-change-event-for-imsm.patch
Patch71: 0071-Monitor-improve-check_one_sharer-for-checking-duplic.patch
Patch72: 0072-Detail-adding-sync-status-for-cluster-device.patch
Patch73: 0073-Manage-imsm-Write-metadata-before-add.patch
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
# RHEL customization patches
Patch97: mdadm-3.3-udev.patch
@ -136,6 +168,36 @@ file can be used to help with some common tasks.
%patch45 -p1 -b .0045
%patch46 -p1 -b .0046
%patch47 -p1 -b .0047
%patch48 -p1 -b .0048
%patch49 -p1 -b .0049
%patch50 -p1 -b .0050
%patch51 -p1 -b .0051
%patch52 -p1 -b .0052
%patch53 -p1 -b .0053
%patch54 -p1 -b .0054
%patch55 -p1 -b .0055
%patch56 -p1 -b .0056
%patch57 -p1 -b .0057
%patch58 -p1 -b .0058
%patch59 -p1 -b .0059
%patch60 -p1 -b .0060
%patch61 -p1 -b .0061
%patch62 -p1 -b .0062
%patch63 -p1 -b .0063
%patch64 -p1 -b .0064
%patch65 -p1 -b .0065
%patch66 -p1 -b .0066
%patch67 -p1 -b .0067
%patch68 -p1 -b .0068
%patch69 -p1 -b .0069
%patch70 -p1 -b .0070
%patch71 -p1 -b .0071
%patch72 -p1 -b .0072
%patch73 -p1 -b .0073
%patch74 -p1 -b .0074
%patch75 -p1 -b .0075
%patch76 -p1 -b .0076
%patch77 -p1 -b .0077
# RHEL customization patches
%patch97 -p1 -b .udev
@ -152,6 +214,10 @@ install -Dp -m 644 %{SOURCE3} %{buildroot}%{_udevrulesdir}/65-md-incremental.rul
install -Dp -m 644 %{SOURCE4} %{buildroot}%{_sysconfdir}/sysconfig/raid-check
install -Dp -m 644 %{SOURCE5} %{buildroot}%{_sysconfdir}/cron.d/raid-check
mkdir -p -m 710 %{buildroot}/var/run/mdadm
mkdir -p -m 700 %{buildroot}/usr/share/mdadm
mkdir -p -m 700 %{buildroot}/usr/lib/mdadm
install -Dp -m 755 %{SOURCE9} %{buildroot}/usr/share/mdadm/mdcheck
install -Dp -m 755 %{SOURCE10} %{buildroot}/usr/lib/mdadm/mdadm_env.sh
# systemd
mkdir -p %{buildroot}%{_unitdir}
@ -199,13 +265,31 @@ rm -rf %{buildroot}
%dir %{_localstatedir}/run/%{name}/
%config(noreplace) %{_tmpfilesdir}/%{name}.conf
/etc/libreport/events.d/*
/usr/share/mdadm/mdcheck
/usr/lib/mdadm/mdadm_env.sh
%changelog
* Fri Jun 05 2020 Xiao Ni <xni@redhat.com> - 4.1.14
- Update to latest upstream
- Resolves rhbz#1780501
* Fri Feb 28 2020 Xiao Ni <xni@redhat.com> - 4.1.13
- Remove the unnecessary whitespace in .service file
- Resolves rhbz#1803470
* Tue Feb 11 2020 Xiao Ni <xni@redhat.com> - 4.1.12
- Update mdadm to latest upstream && change tmpfiles directory && correct changelog date
- Resolves rhbz#1800521 and rhbz#1657265
* Sun Feb 09 2020 Xiao Ni <xni@redhat.com> - 4.1.11
- mdcheck start service can't start
- Resolves rhbz#1769823
* Fri Nov 15 2019 Xiao Ni <xni@redhat.com> - 4.1.10
- Update mdadm to latest upstream
- Resolves rhbz#1721937
* Thu Jul 10 2019 Xiao Ni <xni@redhat.com> - 4.1.9
* Wed Jul 10 2019 Xiao Ni <xni@redhat.com> - 4.1.9
- Add --incremental for ddf member disk in udev rule
- Resolves rhbz#1693583