Package init

This commit is contained in:
eulerstorage 2019-12-31 22:19:03 +08:00
parent e97e536cb9
commit a8ec19ae0b
25 changed files with 1330 additions and 0 deletions

View File

@ -0,0 +1,52 @@
From c36baf7f81651a72be899d9eb62ed77db28cb608 Mon Sep 17 00:00:00 2001
From: openEuler Buildteam <buildteam@openeuler.org>
Date: Tue, 31 Dec 2019 14:00:22 +0000
Subject: [PATCH] use 65-md-incremental.rules to add the block device to
the array pool and do things like anaconda command line options
---
udev-md-raid-assembly.rules | 30 ------------------------------
1 file changed, 30 deletions(-)
diff --git a/udev-md-raid-assembly.rules b/udev-md-raid-assembly.rules
index 9f055ed..aa67af4 100644
--- a/udev-md-raid-assembly.rules
+++ b/udev-md-raid-assembly.rules
@@ -5,34 +5,4 @@
ENV{ANACONDA}=="?*", GOTO="md_inc_end"
# assemble md arrays
-SUBSYSTEM!="block", GOTO="md_inc_end"
-
-# skip non-initialized devices
-ENV{SYSTEMD_READY}=="0", GOTO="md_inc_end"
-
-# handle potential components of arrays (the ones supported by md)
-ENV{ID_FS_TYPE}=="linux_raid_member", GOTO="md_inc"
-
-# "noiswmd" on kernel command line stops mdadm from handling
-# "isw" (aka IMSM - Intel RAID).
-# "nodmraid" on kernel command line stops mdadm from handling
-# "isw" or "ddf".
-IMPORT{cmdline}="noiswmd"
-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"
-GOTO="md_inc_end"
-
-LABEL="md_inc"
-
-# remember you can limit what gets auto/incrementally assembled by
-# mdadm.conf(5)'s 'AUTO' and selectively whitelist using 'ARRAY'
-ACTION=="add|change", IMPORT{program}="BINDIR/mdadm --incremental --export $devnode --offroot $env{DEVLINKS}"
-ACTION=="add|change", ENV{MD_STARTED}=="*unsafe*", ENV{MD_FOREIGN}=="no", ENV{SYSTEMD_WANTS}+="mdadm-last-resort@$env{MD_DEVICE}.timer"
-ACTION=="remove", ENV{ID_PATH}=="?*", RUN+="BINDIR/mdadm -If $name --path $env{ID_PATH}"
-ACTION=="remove", ENV{ID_PATH}!="?*", RUN+="BINDIR/mdadm -If $name"
-
LABEL="md_inc_end"
--
1.7.12.4

View File

@ -0,0 +1,23 @@
--- mdadm-3.2.1/Makefile.static 2011-03-27 22:31:20.000000000 -0400
+++ mdadm-3.2.1/Makefile 2011-03-28 10:16:55.277900184 -0400
@@ -238,16 +238,16 @@ install : mdadm mdmon install-man instal
$(INSTALL) -D $(STRIP) -m 755 mdmon $(DESTDIR)$(BINDIR)/mdmon
install-static : mdadm.static install-man
- $(INSTALL) -D $(STRIP) -m 755 mdadm.static $(DESTDIR)$(BINDIR)/mdadm
+ $(INSTALL) -D $(STRIP) -m 755 mdadm.static $(DESTDIR)$(BINDIR)/mdadm.static
install-tcc : mdadm.tcc install-man
- $(INSTALL) -D $(STRIP) -m 755 mdadm.tcc $(DESTDIR)$(BINDIR)/mdadm
+ $(INSTALL) -D $(STRIP) -m 755 mdadm.tcc $(DESTDIR)$(BINDIR)/mdadm.tcc
install-uclibc : mdadm.uclibc install-man
- $(INSTALL) -D $(STRIP) -m 755 mdadm.uclibc $(DESTDIR)$(BINDIR)/mdadm
+ $(INSTALL) -D $(STRIP) -m 755 mdadm.uclibc $(DESTDIR)$(BINDIR)/mdadm.uclibc
install-klibc : mdadm.klibc install-man
- $(INSTALL) -D $(STRIP) -m 755 mdadm.klibc $(DESTDIR)$(BINDIR)/mdadm
+ $(INSTALL) -D $(STRIP) -m 755 mdadm.klibc $(DESTDIR)$(BINDIR)/mdadm.klibc
install-man: mdadm.8 md.4 mdadm.conf.5 mdmon.8
$(INSTALL) -D -m 644 mdadm.8 $(DESTDIR)$(MAN8DIR)/mdadm.8

View File

@ -0,0 +1,28 @@
From e4317882e4c87a121b721cdb22cf41cc830c379d Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Wed, 10 Apr 2019 21:31:46 +0800
Subject: [PATCH 1/6] Assemble: free resources in load_devices
Like other failure cases in load_devices, we need
to free those resources as well.
---
Assemble.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/Assemble.c b/Assemble.c
index 23892a3..0264190 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -594,6 +594,9 @@ static int load_devices(struct devs *devices, char *devmap,
if (strcmp(c->update, "ppl") == 0 &&
ident->bitmap_fd >= 0) {
pr_err("PPL is not compatible with bitmap\n");
+ close(mdfd);
+ free(devices);
+ free(devmap);
return -1;
}
--
2.19.1

View File

@ -0,0 +1,36 @@
From 13150f803a18df9b2feddd424bf513b8806bc7e8 Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Wed, 10 Apr 2019 21:33:29 +0800
Subject: [PATCH 2/6] Assemble: set devices to NULL when load_devices can't
load device
Since load_devices frees "devices" when it can't find any
device, we should set it to NULL to avoid double free issue
which can be reproduced by below steps:
mdadm -CR /dev/md/vol -l0 -e 1.2 -n2 /dev/sd[b-c] --assume-clean
mdadm -Ss
mdadm -A /dev/md127 /dev/sd[b-c] --update metadata
---
Assemble.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/Assemble.c b/Assemble.c
index 0264190..a79466c 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -1539,6 +1539,11 @@ try_again:
&most_recent, &bestcnt, &best, inargv);
if (devcnt < 0) {
mdfd = -3;
+ /*
+ * devices is already freed in load_devices, so set devices
+ * to NULL to avoid double free devices.
+ */
+ devices = NULL;
goto out;
}
--
2.19.1

View File

@ -0,0 +1,74 @@
From 5b8c69383de07be82e44dd7b2cbb9488699192c5 Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Wed, 10 Apr 2019 21:37:33 +0800
Subject: [PATCH 3/6] Document PART-POLICY lines
PART-POLICY has been accepted in mdadm.conf since the same
time that POLICY was accepted, but it was never documented.
So add the missing documentation.
Also fix a bug which would have stopped it from working if
anyone had ever tried to use it.
---
mdadm.conf.5 | 24 +++++++++++++++++++++++-
policy.c | 2 +-
2 files changed, 24 insertions(+), 2 deletions(-)
diff --git a/mdadm.conf.5 b/mdadm.conf.5
index 18512cb..47c962a 100644
--- a/mdadm.conf.5
+++ b/mdadm.conf.5
@@ -501,7 +501,7 @@ To update hot plug configuration it is necessary to execute
.B mdadm \-\-udev\-rules
command after changing the config file
-Key words used in the
+Keywords used in the
.I POLICY
line and supported values are:
@@ -565,6 +565,28 @@ be automatically added to that array (or it's container)
as above and the disk will become a spare in remaining cases
.RE
+.TP
+.B PART-POLICY
+This is similar to
+.B POLICY
+and accepts the same keyword assignments. It allows a consistent set
+of policies to applied to each of the partitions of a device.
+
+A
+.B PART-POLICY
+line should set
+.I type=disk
+and identify the path to one or more disk devices. Each partition on
+these disks will be treated according to the
+.I action=
+setting from this line. If a
+.I domain
+is set in the line, then the domain associated with each patition will
+be based on the domain, but with
+.RB \(dq -part N\(dq
+appended, when N is the partition number for the partition that was
+found.
+
.SH EXAMPLE
DEVICE /dev/sd[bcdjkl]1
.br
diff --git a/policy.c b/policy.c
index c0d18a7..258f393 100644
--- a/policy.c
+++ b/policy.c
@@ -300,7 +300,7 @@ static int path_has_part(char *path, char **part)
l--;
if (l < 5 || strncmp(path+l-5, "-part", 5) != 0)
return 0;
- *part = path+l-4;
+ *part = path+l-5;
return 1;
}
--
2.19.1

View File

@ -0,0 +1,30 @@
From b3d9d18abdf2c7963bb8bfcdd402cdb717c6b3a2 Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Wed, 10 Apr 2019 21:40:46 +0800
Subject: [PATCH 4/6] Grow: avoid overflow in compute_backup_blocks()
With a chunk size of 16Meg and data drive count of 8,
this calculate can easily overflow the 'int' type that
is used for the multiplications.
So force it to use "long" instead.
---
Grow.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/Grow.c b/Grow.c
index 4436a4d..76f82c0 100644
--- a/Grow.c
+++ b/Grow.c
@@ -1196,7 +1196,8 @@ unsigned long compute_backup_blocks(int nchunk, int ochunk,
/* Find GCD */
a = GCD(a, b);
/* LCM == product / GCD */
- blocks = (ochunk/512) * (nchunk/512) * odata * ndata / a;
+ blocks = (unsigned long)(ochunk/512) * (unsigned long)(nchunk/512) *
+ odata * ndata / a;
return blocks;
}
--
2.19.1

View File

@ -0,0 +1,27 @@
From 51561342479a4469a9257562de6289cf4bd2cf1a Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Wed, 10 Apr 2019 21:43:29 +0800
Subject: [PATCH 5/6] Grow: report correct new chunk size.
When using "--grow --chunk=" to change chunk
size, the old chunksize is reported instead of the new.
---
Grow.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Grow.c b/Grow.c
index 76f82c0..363b209 100644
--- a/Grow.c
+++ b/Grow.c
@@ -3286,7 +3286,7 @@ static int reshape_array(char *container, int fd, char *devname,
goto release;
} else if (verbose >= 0)
printf("chunk size for %s set to %d\n",
- devname, array.chunk_size);
+ devname, info->new_chunk);
}
unfreeze(st);
return 0;
--
2.19.1

View File

@ -0,0 +1,101 @@
From ebf3be9931f31df54df52b1821479e6a80a4d9c6 Mon Sep 17 00:00:00 2001
From: Dimitri John Ledkov <xnox@ubuntu.com>
Date: Tue, 15 Jan 2019 19:08:37 +0000
Subject: Fix spelling typos.
Signed-off-by: Dimitri John Ledkov <xnox@ubuntu.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Assemble.c | 2 +-
Create.c | 2 +-
Grow.c | 6 +++---
super-ddf.c | 2 +-
super-intel.c | 2 +-
5 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/Assemble.c b/Assemble.c
index 23892a3..816056d 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -873,7 +873,7 @@ static int force_array(struct mdinfo *content,
current_events = devices[chosen_drive].i.events;
add_another:
if (c->verbose >= 0)
- pr_err("forcing event count in %s(%d) from %d upto %d\n",
+ pr_err("forcing event count in %s(%d) from %d up to %d\n",
devices[chosen_drive].devname,
devices[chosen_drive].i.disk.raid_disk,
(int)(devices[chosen_drive].i.events),
diff --git a/Create.c b/Create.c
index 04b1dfc..6f1b228 100644
--- a/Create.c
+++ b/Create.c
@@ -823,7 +823,7 @@ int Create(struct supertype *st, char *mddev,
}
bitmap_fd = open(s->bitmap_file, O_RDWR);
if (bitmap_fd < 0) {
- pr_err("weird: %s cannot be openned\n",
+ pr_err("weird: %s cannot be opened\n",
s->bitmap_file);
goto abort_locked;
}
diff --git a/Grow.c b/Grow.c
index 4436a4d..7388123 100644
--- a/Grow.c
+++ b/Grow.c
@@ -446,7 +446,7 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s)
if (offset_setable) {
st->ss->getinfo_super(st, mdi, NULL);
if (sysfs_init(mdi, fd, NULL)) {
- pr_err("failed to intialize sysfs.\n");
+ pr_err("failed to initialize sysfs.\n");
free(mdi);
}
rv = sysfs_set_num_signed(mdi, NULL, "bitmap/location",
@@ -2177,7 +2177,7 @@ size_change_error:
memset(&info, 0, sizeof(info));
info.array = array;
if (sysfs_init(&info, fd, NULL)) {
- pr_err("failed to intialize sysfs.\n");
+ pr_err("failed to initialize sysfs.\n");
rv = 1;
goto release;
}
@@ -2902,7 +2902,7 @@ static int impose_level(int fd, int level, char *devname, int verbose)
struct mdinfo info;
if (sysfs_init(&info, fd, NULL)) {
- pr_err("failed to intialize sysfs.\n");
+ pr_err("failed to initialize sysfs.\n");
return 1;
}
diff --git a/super-ddf.c b/super-ddf.c
index 618542c..c095e8a 100644
--- a/super-ddf.c
+++ b/super-ddf.c
@@ -1900,7 +1900,7 @@ static struct vd_config *find_vdcr(struct ddf_super *ddf, unsigned int inst,
return conf;
}
bad:
- pr_err("Could't find disk %d in array %u\n", n, inst);
+ pr_err("Couldn't find disk %d in array %u\n", n, inst);
return NULL;
}
diff --git a/super-intel.c b/super-intel.c
index f011a31..add6f2b 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -9939,7 +9939,7 @@ static void imsm_process_update(struct supertype *st,
break;
}
default:
- pr_err("error: unsuported process update type:(type: %d)\n", type);
+ pr_err("error: unsupported process update type:(type: %d)\n", type);
}
}
--
1.7.12.4

View File

@ -0,0 +1,46 @@
From e3615ecb5b6ad8eb408296878aad5628e0e27166 Mon Sep 17 00:00:00 2001
From: Coly Li <colyli@suse.de>
Date: Tue, 12 Feb 2019 12:53:18 +0800
Subject: Detail.c: do not skip first character when calling xstrdup in
Detail()
'Commit b9c9bd9bacaa ("Detail: ensure --export names are acceptable as
shell variables")' duplicates mdi->sys_name to sysdev string by,
char *sysdev = xstrdup(mdi->sys_name + 1);
which skips the first character of mdi->sys_name. Then when running
mdadm --detail <md device> --export, the output looks like,
MD_DEVICE_ev_sda2_ROLE=1
MD_DEVICE_ev_sda2_DEV=/dev/sda2
The first character of md device (between MD_DEVICE and _ROLE/_DEV)
is dropped. The expected output should be,
MD_DEVICE_dev_sda2_ROLE=1
MD_DEVICE_dev_sda2_DEV=/dev/sda2
This patch removes the '+ 1' from calling xstrdup() in Detail(), which
gets the dropped first character back.
Reported-by: Arvin Schnell <aschnell@suse.com>
Fixes: b9c9bd9bacaa ("Detail: ensure --export names are acceptable as 4 shell variables")
Signed-off-by: Coly Li <colyli@suse.de>
Cc: NeilBrown <neilb@suse.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Detail.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Detail.c b/Detail.c
index b3e857a..20ea03a 100644
--- a/Detail.c
+++ b/Detail.c
@@ -284,7 +284,7 @@ int Detail(char *dev, struct context *c)
struct mdinfo *mdi;
for (mdi = sra->devs; mdi; mdi = mdi->next) {
char *path;
- char *sysdev = xstrdup(mdi->sys_name + 1);
+ char *sysdev = xstrdup(mdi->sys_name);
char *cp;
path = map_dev(mdi->disk.major,
--
1.7.12.4

View File

@ -0,0 +1,70 @@
From cab114c5ca870e5f1b57fb2602cd9a038271c2e0 Mon Sep 17 00:00:00 2001
From: Corey Hickey <bugfood-c@fatooh.org>
Date: Mon, 11 Feb 2019 17:18:38 -0800
Subject: Fix reshape for decreasing data offset
...when not changing the number of disks.
This patch needs context to explain. These are the relevant parts of
the original code (condensed and annotated):
if (dir > 0) {
/* Increase data offset (reshape backwards) */
if (data_offset < sd->data_offset + min) {
pr_err("--data-offset too small on %s\n",
dn);
goto release;
}
} else {
/* Decrease data offset (reshape forwards) */
if (data_offset < sd->data_offset - min) {
pr_err("--data-offset too small on %s\n",
dn);
goto release;
}
}
When this code is reached, mdadm has already decided on a reshape
direction. When increasing the data offset, the reshape runs backwards
(dir==1); when decreasing the data offset, the reshape runs forwards
(dir==-1).
The conditional within the backwards reshape is correct: the requested
offset must be larger than the old offset plus a minimum delta; thus the
reshape has room to work.
For the forwards reshape, the requested offset needs to be smaller than
the old offset minus a minimum delta; to do this correctly, the
comparison must be reversed.
Also update the error message.
Note: I have tested this change on a RAID 5 on Linux 4.18.0 and verified
that there were no errors from the kernel and that the device data
remained intact. I do not know if there are considerations for different
RAID levels.
Signed-off-by: Corey Hickey <bugfood-c@fatooh.org>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Grow.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Grow.c b/Grow.c
index 7388123..72b731e 100644
--- a/Grow.c
+++ b/Grow.c
@@ -2612,8 +2612,8 @@ static int set_new_data_offset(struct mdinfo *sra, struct supertype *st,
goto release;
}
if (data_offset != INVALID_SECTORS &&
- data_offset < sd->data_offset - min) {
- pr_err("--data-offset too small on %s\n",
+ data_offset > sd->data_offset - min) {
+ pr_err("--data-offset too large on %s\n",
dn);
goto release;
}
--
1.7.12.4

View File

@ -0,0 +1,49 @@
From 69d084784de196acec8ab703cd1b379af211d624 Mon Sep 17 00:00:00 2001
From: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
Date: Fri, 22 Feb 2019 10:15:45 +0100
Subject: mdmon: don't attempt to manage new arrays when terminating
When mdmon gets a SIGTERM, it stops managing arrays that are clean. If
there is more that one array in the container and one of them is dirty
and the clean one is still present in mdstat, mdmon will treat it as a
new array and start managing it again. This leads to a cycle of
remove_old() / manage_new() calls for the clean array, until the other
one also becomes clean.
Prevent this by not calling manage_new() if sigterm is set. Also, remove
a check for sigterm in manage_new() because the condition will never be
true.
Signed-off-by: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
managemon.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/managemon.c b/managemon.c
index 101231c..29b91ba 100644
--- a/managemon.c
+++ b/managemon.c
@@ -727,9 +727,7 @@ static void manage_new(struct mdstat_ent *mdstat,
dprintf("inst: %s action: %d state: %d\n", inst,
new->action_fd, new->info.state_fd);
- if (sigterm)
- new->info.safe_mode_delay = 1;
- else if (mdi->safe_mode_delay >= 50)
+ if (mdi->safe_mode_delay >= 50)
/* Normal start, mdadm set this. */
new->info.safe_mode_delay = mdi->safe_mode_delay;
else
@@ -803,7 +801,7 @@ void manage(struct mdstat_ent *mdstat, struct supertype *container)
break;
}
}
- if (a == NULL || !a->container)
+ if ((a == NULL || !a->container) && !sigterm)
manage_new(mdstat, container, a);
}
}
--
1.7.12.4

View File

@ -0,0 +1,57 @@
From d2e11da4b7fd0453e942f43e4196dc63b3dbd708 Mon Sep 17 00:00:00 2001
From: Pawel Baldysiak <pawel.baldysiak@intel.com>
Date: Fri, 22 Feb 2019 13:30:27 +0100
Subject: mdmon: wait for previous mdmon to exit during takeover
Since the patch c76242c5("mdmon: get safe mode delay file descriptor
early"), safe_mode_dalay is set properly by initrd mdmon. But in some
cases with filesystem traffic since the very start of the system, it
might take a while to transit to clean state. Due to fact that new
mdmon does not wait for the old one to exit - it might happen that the
new one switches safe_mode_delay back to seconds, before old one exits.
As the result two mdmons are running concurrently on same array.
Wait for the old mdmon to exit by pinging it with SIGUSR1 signal, just
in case it is sleeping.
Signed-off-by: Pawel Baldysiak <pawel.baldysiak@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
mdmon.c | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/mdmon.c b/mdmon.c
index 0955fcc..ff985d2 100644
--- a/mdmon.c
+++ b/mdmon.c
@@ -171,6 +171,7 @@ static void try_kill_monitor(pid_t pid, char *devname, int sock)
int fd;
int n;
long fl;
+ int rv;
/* first rule of survival... don't off yourself */
if (pid == getpid())
@@ -201,9 +202,16 @@ static void try_kill_monitor(pid_t pid, char *devname, int sock)
fl &= ~O_NONBLOCK;
fcntl(sock, F_SETFL, fl);
n = read(sock, buf, 100);
- /* Ignore result, it is just the wait that
- * matters
- */
+
+ /* If there is I/O going on it might took some time to get to
+ * clean state. Wait for monitor to exit fully to avoid races.
+ * Ping it with SIGUSR1 in case that it is sleeping */
+ for (n = 0; n < 25; n++) {
+ rv = kill(pid, SIGUSR1);
+ if (rv < 0)
+ break;
+ usleep(200000);
+ }
}
void remove_pidfile(char *devname)
--
1.7.12.4

View File

@ -0,0 +1,51 @@
From 2b57e4fe041d52ae29866c93a878a11c07223cff Mon Sep 17 00:00:00 2001
From: Pawel Baldysiak <pawel.baldysiak@intel.com>
Date: Fri, 22 Feb 2019 12:56:27 +0100
Subject: Assemble: Fix starting array with initial reshape checkpoint
If array was stopped during reshape initialization,
there might be a "0" checkpoint recorded in metadata.
If array with such condition (reshape with position 0)
is passed to kernel - it will refuse to start such array.
Treat such array as normal during assemble, Grow_continue() will
reinitialize and start the reshape.
Signed-off-by: Pawel Baldysiak <pawel.baldysiak@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Assemble.c | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/Assemble.c b/Assemble.c
index 816056d..3ddfa85 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -2047,8 +2047,22 @@ int assemble_container_content(struct supertype *st, int mdfd,
spare, &c->backup_file, c->verbose) == 1)
return 1;
- err = sysfs_set_str(content, NULL,
- "array_state", "readonly");
+ if (content->reshape_progress == 0) {
+ /* If reshape progress is 0 - we are assembling the
+ * array that was stopped, before reshape has started.
+ * Array needs to be started as active, Grow_continue()
+ * will start the reshape.
+ */
+ sysfs_set_num(content, NULL, "reshape_position",
+ MaxSector);
+ err = sysfs_set_str(content, NULL,
+ "array_state", "active");
+ sysfs_set_num(content, NULL, "reshape_position", 0);
+ } else {
+ err = sysfs_set_str(content, NULL,
+ "array_state", "readonly");
+ }
+
if (err)
return 1;
--
1.7.12.4

View File

@ -0,0 +1,59 @@
From 227aeaa872d4898273cf87a4253898823d556c43 Mon Sep 17 00:00:00 2001
From: Corey Hickey <bugfood-c@fatooh.org>
Date: Mon, 11 Feb 2019 17:42:27 -0800
Subject: add missing units to --examine
Within the output of "mdadm --examine", there are three sizes reported
on adjacent lines. For example:
$ sudo mdadm --examine /dev/md3
[...]
Avail Dev Size : 17580545024 (8383.06 GiB 9001.24 GB)
Array Size : 17580417024 (16765.99 GiB 18002.35 GB)
Used Dev Size : 11720278016 (5588.66 GiB 6000.78 GB)
[...]
This can be confusing, since the first and third line are in 512-byte
sectors, and the second is in KiB.
Add units to avoid ambiguity.
(I don't particularly like the "KiB" notation, but it is at least
unambiguous.)
Signed-off-by: Corey Hickey <bugfood-c@fatooh.org>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
super1.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/super1.c b/super1.c
index 636a286..7178e62 100644
--- a/super1.c
+++ b/super1.c
@@ -360,7 +360,7 @@ static void examine_super1(struct supertype *st, char *homehost)
printf(" Raid Level : %s\n", c?c:"-unknown-");
printf(" Raid Devices : %d\n", __le32_to_cpu(sb->raid_disks));
printf("\n");
- printf(" Avail Dev Size : %llu%s\n",
+ printf(" Avail Dev Size : %llu sectors%s\n",
(unsigned long long)__le64_to_cpu(sb->data_size),
human_size(__le64_to_cpu(sb->data_size)<<9));
if (__le32_to_cpu(sb->level) > 0) {
@@ -378,11 +378,11 @@ static void examine_super1(struct supertype *st, char *homehost)
if (ddsks) {
long long asize = __le64_to_cpu(sb->size);
asize = (asize << 9) * ddsks / ddsks_denom;
- printf(" Array Size : %llu%s\n",
+ printf(" Array Size : %llu KiB%s\n",
asize >> 10, human_size(asize));
}
if (sb->size != sb->data_size)
- printf(" Used Dev Size : %llu%s\n",
+ printf(" Used Dev Size : %llu sectors%s\n",
(unsigned long long)__le64_to_cpu(sb->size),
human_size(__le64_to_cpu(sb->size)<<9));
}
--
1.7.12.4

View File

@ -0,0 +1,94 @@
From 22dc741f63e6403d59c2c14f56fd4791265f9bbb Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
Date: Mon, 1 Apr 2019 16:53:41 +0200
Subject: Create: Block rounding size to max
When passed size is smaller than chunk, mdadm rounds it to 0 but 0 there
means max available space.
Block it for every metadata. Remove the same check from imsm routine.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Create.c | 23 ++++++++++++++++++++---
super-intel.c | 5 ++---
2 files changed, 22 insertions(+), 6 deletions(-)
diff --git a/Create.c b/Create.c
index 6f1b228..292f92a 100644
--- a/Create.c
+++ b/Create.c
@@ -27,6 +27,18 @@
#include "md_p.h"
#include <ctype.h>
+static int round_size_and_verify(unsigned long long *size, int chunk)
+{
+ if (*size == 0)
+ return 0;
+ *size &= ~(unsigned long long)(chunk - 1);
+ if (*size == 0) {
+ pr_err("Size cannot be smaller than chunk.\n");
+ return 1;
+ }
+ return 0;
+}
+
static int default_layout(struct supertype *st, int level, int verbose)
{
int layout = UnSet;
@@ -248,11 +260,14 @@ int Create(struct supertype *st, char *mddev,
pr_err("unknown level %d\n", s->level);
return 1;
}
+
if (s->size == MAX_SIZE)
/* use '0' to mean 'max' now... */
s->size = 0;
if (s->size && s->chunk && s->chunk != UnSet)
- s->size &= ~(unsigned long long)(s->chunk - 1);
+ if (round_size_and_verify(&s->size, s->chunk))
+ return 1;
+
newsize = s->size * 2;
if (st && ! st->ss->validate_geometry(st, s->level, s->layout, s->raiddisks,
&s->chunk, s->size*2,
@@ -267,7 +282,8 @@ int Create(struct supertype *st, char *mddev,
/* default chunk was just set */
if (c->verbose > 0)
pr_err("chunk size defaults to %dK\n", s->chunk);
- s->size &= ~(unsigned long long)(s->chunk - 1);
+ if (round_size_and_verify(&s->size, s->chunk))
+ return 1;
do_default_chunk = 0;
}
}
@@ -413,7 +429,8 @@ int Create(struct supertype *st, char *mddev,
/* default chunk was just set */
if (c->verbose > 0)
pr_err("chunk size defaults to %dK\n", s->chunk);
- s->size &= ~(unsigned long long)(s->chunk - 1);
+ if (round_size_and_verify(&s->size, s->chunk))
+ return 1;
do_default_chunk = 0;
}
}
diff --git a/super-intel.c b/super-intel.c
index add6f2b..0c54737 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -7368,9 +7368,8 @@ static int validate_geometry_imsm(struct supertype *st, int level, int layout,
verbose);
}
- if (size && ((size < 1024) || (*chunk != UnSet &&
- size < (unsigned long long) *chunk))) {
- pr_err("Given size must be greater than 1M and chunk size.\n");
+ if (size && (size < 1024)) {
+ pr_err("Given size must be greater than 1M.\n");
/* Depends on algorithm in Create.c :
* if container was given (dev == NULL) return -1,
* if block device was given ( dev != NULL) return 0.
--
1.7.12.4

BIN
mdadm-4.1-rc2.tar.xz Normal file

Binary file not shown.

3
mdadm-cron Normal file
View File

@ -0,0 +1,3 @@
# Run system wide raid-check once a week on Sunday at 1am by default
0 1 * * Sun root /usr/sbin/raid-check

View File

@ -0,0 +1,60 @@
#!/bin/bash
#
# Configuration file for /etc/cron.weekly/raid-check
#
# options:
# ENABLED - must be yes in order for the raid check to proceed
# CHECK - can be either check or repair depending on the type of
# operation the user desires. A check operation will scan
# the drives looking for bad sectors and automatically
# repairing only bad sectors. If it finds good sectors that
# contain bad data (meaning that the data in a sector does
# not agree with what the data from another disk indicates
# the data should be, for example the parity block + the other
# data blocks would cause us to think that this data block
# is incorrect), then it does nothing but increments the
# counter in the file /sys/block/$dev/md/mismatch_count.
# This allows the sysadmin to inspect the data in the sector
# and the data that would be produced by rebuilding the
# sector from redundant information and pick the correct
# data to keep. The repair option does the same thing, but
# when it encounters a mismatch in the data, it automatically
# updates the data to be consistent. However, since we really
# don't know whether it's the parity or the data block that's
# correct (or which data block in the case of raid1), it's
# luck of the draw whether or not the user gets the right
# data instead of the bad data. This option is the default
# option for devices not listed in either CHECK_DEVS or
# REPAIR_DEVS.
# CHECK_DEVS - a space delimited list of devs that the user specifically
# wants to run a check operation on.
# REPAIR_DEVS - a space delimited list of devs that the user
# specifically wants to run a repair on.
# SKIP_DEVS - a space delimited list of devs that should be skipped
# NICE - Change the raid check CPU and IO priority in order to make
# the system more responsive during lengthy checks. Valid
# values are high, normal, low, idle.
# MAXCONCURENT - Limit the number of devices to be checked at a time.
# By default all devices will be checked at the same time.
#
# Note: the raid-check script intentionaly runs last in the cron.weekly
# sequence. This is so we can wait for all the resync operations to complete
# and then check the mismatch_count on each array without unduly delaying
# other weekly cron jobs. If any arrays have a non-0 mismatch_count after
# the check completes, we echo a warning to stdout which will then me emailed
# to the admin as long as mails from cron jobs have not been redirected to
# /dev/null. We do not wait for repair operations to complete as the
# md stack will correct any mismatch_cnts automatically.
#
# Note2: you can not use symbolic names for the raid devices, such as you
# /dev/md/root. The names used in this file must match the names seen in
# /proc/mdstat and in /sys/block.
ENABLED=yes
CHECK=check
NICE=low
# To check devs /dev/md0 and /dev/md3, use "md0 md3"
CHECK_DEVS=""
REPAIR_DEVS=""
SKIP_DEVS=""
MAXCONCURRENT=

1
mdadm.conf Normal file
View File

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

67
mdadm.rules Normal file
View File

@ -0,0 +1,67 @@
# This file causes block devices with Linux RAID (mdadm) signatures to
# automatically cause mdadm to be run.
# See udev(8) for syntax
# Don't process any events if anaconda is running as anaconda brings up
# raid devices manually
ENV{ANACONDA}=="?*", GOTO="md_end"
# Also don't process disks that are slated to be a multipath device
ENV{DM_MULTIPATH_DEVICE_PATH}=="1", GOTO="md_end"
# We process add events on block devices (since they are ready as soon as
# they are added to the system), but we must process change events as well
# on any dm devices (like LUKS partitions or LVM logical volumes) and on
# md devices because both of these first get added, then get brought live
# and trigger a change event. The reason we don't process change events
# on bare hard disks is because if you stop all arrays on a disk, then
# run fdisk on the disk to change the partitions, when fdisk exits it
# triggers a change event, and we want to wait until all the fdisks on
# all member disks are done before we do anything. Unfortunately, we have
# no way of knowing that, so we just have to let those arrays be brought
# up manually after fdisk has been run on all of the disks.
# First, process all add events (md and dm devices will not really do
# anything here, just regular disks, and this also won't get any imsm
# array members either)
SUBSYSTEM=="block", ACTION=="add", ENV{ID_FS_TYPE}=="linux_raid_member", \
IMPORT{program}="/sbin/mdadm -I $env{DEVNAME} --export $devnode --offroot ${DEVLINKS}"
SUBSYSTEM=="block", ACTION=="add", ENV{ID_FS_TYPE}=="linux_raid_member", \
ENV{MD_STARTED}=="*unsafe*", ENV{MD_FOREIGN}=="no", ENV{SYSTEMD_WANTS}+="mdadm-last-resort@$env{MD_DEVICE}.timer"
SUBSYSTEM=="block", ACTION=="remove", ENV{ID_PATH}=="?*", \
ENV{ID_FS_TYPE}=="linux_raid_member", \
RUN+="/sbin/mdadm -If $name --path $env{ID_PATH}"
SUBSYSTEM=="block", ACTION=="remove", ENV{ID_PATH}!="?*", \
ENV{ID_FS_TYPE}=="linux_raid_member", \
RUN+="/sbin/mdadm -If $name"
# Next, check to make sure the BIOS raid stuff wasn't turned off via cmdline
IMPORT{cmdline}="noiswmd"
IMPORT{cmdline}="nodmraid"
ENV{noiswmd}=="?*", GOTO="md_imsm_inc_end"
ENV{nodmraid}=="?*", GOTO="md_imsm_inc_end"
SUBSYSTEM=="block", ACTION=="add", ENV{ID_FS_TYPE}=="isw_raid_member", \
RUN+="/sbin/mdadm -I $env{DEVNAME}"
SUBSYSTEM=="block", ACTION=="remove", ENV{ID_PATH}=="?*", \
ENV{ID_FS_TYPE}=="isw_raid_member", \
RUN+="/sbin/mdadm -If $name --path $env{ID_PATH}"
SUBSYSTEM=="block", ACTION=="remove", ENV{ID_PATH}!="?*", \
ENV{ID_FS_TYPE}=="isw_raid_member", \
RUN+="/sbin/mdadm -If $name"
LABEL="md_imsm_inc_end"
# Next make sure that this isn't a dm device we should skip for some reason
ENV{DM_UDEV_RULES_VSN}!="?*", GOTO="dm_change_end"
ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}=="1", GOTO="dm_change_end"
ENV{DM_SUSPENDED}=="1", GOTO="dm_change_end"
KERNEL=="dm-*", SUBSYSTEM=="block", ENV{ID_FS_TYPE}=="linux_raid_member", \
ACTION=="change", RUN+="/sbin/mdadm -I $env{DEVNAME}"
LABEL="dm_change_end"
# Finally catch any nested md raid arrays. If we brought up an md raid
# array that's part of another md raid array, it won't be ready to be used
# until the change event that occurs when it becomes live
KERNEL=="md*", SUBSYSTEM=="block", ENV{ID_FS_TYPE}=="linux_raid_member", \
ACTION=="change", RUN+="/sbin/mdadm -I $env{DEVNAME}"
LABEL="md_end"

132
mdadm.spec Normal file
View File

@ -0,0 +1,132 @@
Name: mdadm
Version: 4.1
Release: rc2.0.5
Summary: The software RAID arrays user manage tools
License: GPLv2+
URL: http://www.kernel.org/pub/linux/utils/raid/mdadm/
Source0: http://www.kernel.org/pub/linux/utils/raid/mdadm/mdadm-%{version}-rc2.tar.xz
Source1: mdadm.conf
Source2: raid-check
Source3: mdadm.rules
Source4: mdadm-raid-check-sysconfig
Source5: mdadm-cron
Source6: mdmonitor.service
Patch0: 0000-use-incremental-assembly-rules.patch
Patch1: 0001-mdadm-2.5.2-static.patch
Patch6000: 6000-Assemble-free-resources-in-load_devices.patch
Patch6001: 6001-Assemble-set-devices-to-NULL-when-load_devices-can-t.patch
Patch6002: 6002-Document-PART-POLICY-lines.patch
Patch6003: 6003-Grow-avoid-overflow-in-compute_backup_blocks.patch
Patch6004: 6004-Grow-report-correct-new-chunk-size.patch
Patch6005: 6005-Fix-spelling-typos.patch
Patch6006: 6006-Detail.c-do-not-skip-first-character-when-calling-xs.patch
Patch6007: 6007-Fix-reshape-for-decreasing-data-offset.patch
Patch6008: 6008-mdmon-don-t-attempt-to-manage-new-arrays-when-termin.patch
Patch6009: 6009-mdmon-wait-for-previous-mdmon-to-exit-during-takeove.patch
Patch6010: 6010-Assemble-Fix-starting-array-with-initial-reshape-che.patch
Patch6011: 6011-add-missing-units-to-examine.patch
Patch6012: 6012-Create-Block-rounding-size-to-max.patch
BuildRequires: systemd gcc binutils
Requires(post): systemd coreutils
Requires(preun): systemd
Requires(postun): systemd coreutils
%description
mdadm is a tool for managing Linux Software RAID arrays.
It can create, assemble, report on, and monitor arrays.
It can also move spares between raid arrays when needed.
%package help
Summary: Including man files for mdadm
Requires: man
BuildArch: noarch
%description help
This contains man files for the using of mdadm.
%prep
%autosetup -n %{name}-%{version}_rc2 -p1
%build
%make_build CXFLAGS="$RPM_OPT_FLAGS" LDFLAGS="$RPM_LD_FLAGS" SYSCONFDIR="%{_sysconfdir}" mdadm mdmon
%install
make DESTDIR=%{buildroot} MANDIR=%{_mandir} BINDIR=%{_sbindir} SYSTEMD_DIR=%{_unitdir} install install-systemd
install -Dp -m 755 %{SOURCE2} %{buildroot}%{_sbindir}/raid-check
install -Dp -m 644 %{SOURCE3} %{buildroot}%{_udevrulesdir}/65-md-incremental.rules
install -Dp -m 644 %{SOURCE4} %{buildroot}%{_sysconfdir}/sysconfig/raid-check
install -Dp -m 644 %{SOURCE5} %{buildroot}%{_sysconfdir}/cron.d/raid-check
#install mdmonitor.service from local file
install -D -m 644 %{SOURCE6} %{buildroot}%{_unitdir}
install -D -m 644 %{SOURCE1} %{buildroot}%{_tmpfilesdir}/mdadm.conf
install -d -m 710 %{buildroot}/var/run/mdadm/
%post
%systemd_post mdmonitor.service
/usr/bin/systemctl disable mdmonitor-takeover.service >/dev/null 2>&1 || :
%preun
%systemd_preun mdmonitor.service
%postun
%systemd_postun_with_restart mdmonitor.service
%files
%doc ChangeLog mdadm.conf-example
%license COPYING
%{_udevrulesdir}/*
%{_sbindir}/*
%{_unitdir}/*
/usr/lib/systemd/system-shutdown/mdadm.shutdown
%config(noreplace) %{_sysconfdir}/cron.d/raid-check
%config(noreplace) %{_sysconfdir}/sysconfig/raid-check
%dir %{_localstatedir}/run/mdadm/
%config(noreplace) %{_tmpfilesdir}/mdadm.conf
%files help
%{_mandir}/man*/*
%changelog
* Tue Dec 31 2019 openEuler Buildteam <buildteam@openeuler.org> - 4.1-rc2.0.5
- Type:enhancement
- ID:NA
- SUG:NA
- DESC:use incremental assembly rules
* Wed Aug 28 2019 zhanghaibo <ted.zhang@huawei.com> - 4.1-rc2.0.4
- Type:enhancemnet
- ID:NA
- SUG:NA
- DESCi:openEuler Debranding
* Wed Aug 21 2019 zhanghaibo <ted.zhang@huawei.com> - 4.1-rc2.0.3
- Type:enhancemnet
- ID:NA
- SUG:NA
- DESCi:openEuler Debranding
* Thu Aug 8 2019 zhanghaibo <ted.zhang@huawei.com> - 4.1-rc2.0.2.h3
- Type:enhancemnet
- ID:NA
- SUG:NA
- DESCi:openEuler Debranding
* Sat Jun 22 2019 zhangsaisai<zhangsaisai@huawei.com> - 4.1-rc2.0.2.h2
- Type:bugfix
- ID:NA
- SUG:NA
- DESC:backport patch from community
* Wed Apr 10 2019 wangjufeng<wangjufeng@huawei.com> - 4.1-rc2.0.2.h1
- Type:bugfix
- ID:NA
- SUG:NA
- DESC:backport patch from community
- Package Initialization

5
mdadm_event.conf Normal file
View File

@ -0,0 +1,5 @@
# Save /proc/mdstat in case of crash in mdadm/mdmon
EVENT=post-create component=mdadm
cat /proc/mdstat >> mdstat_data
echo "Saved output of /proc/mdstat"

118
mdmonitor.init Normal file
View File

@ -0,0 +1,118 @@
#!/bin/bash
#
# mdmonitor This starts, stops, and reloads the mdadm-based
# software RAID monitoring and management facility
#
# chkconfig: 2345 15 85
# description: software RAID monitoring and management
# config: /etc/mdadm.conf
#
# Copyright 2002 Red Hat, Inc.
#
### BEGIN INIT INFO
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start and stop the MD software RAID monitor
# Description: The mdmonitor service checks the status of all software
# RAID arrays on the system. In the event that any of the arrays
# transition into a degraded state, it notifies the system
# administrator. Other options are available, see the mdadm.conf
# and mdadm man pages for possible ways to configure this service.
### END INIT INFO
PIDPATH=/var/run/mdadm
PIDFILE=/var/run/mdadm/mdadm.pid
PATH=/sbin:/usr/sbin:$PATH
RETVAL=0
OPTIONS="--monitor --scan -f --pid-file=$PIDFILE"
prog=mdmonitor
# Source function library.
. /etc/rc.d/init.d/functions
usage ()
{
echo "Usage: service $prog {start|stop|status|restart|try-restart|force-reload}"
RETVAL=1
}
start ()
{
# (Re)start mdmon to take over monitoring of mdmon started from the initrd
for i in /dev/md/*.pid; do
if [ -r $i ]; then
origprog="$prog"; prog="mdmon"
action $"Starting $prog: " /sbin/mdmon --takeover --all
prog="$origprog"
break
fi
done
# Make sure configuration file exists and has information we can use
# MAILADDR or PROGRAM or both must be set in order to run mdadm --monitor
[ -f /etc/mdadm.conf ] || return 6
grep '^\(MAILADDR\|PROGRAM\) .' /etc/mdadm.conf >/dev/null 2>&1 || return 6
# Create our directory if it isn't there yet
if [ ! -d $PIDPATH ]; then
mkdir -m 0700 $PIDPATH >&/dev/null
RC=$?
[ -x /sbin/restorecon ] && /sbin/restorecon $PIDPATH
if [ $RC -ne 0 ]; then
echo -n "Failed to create /var/run/mdadm"
failure
echo
return 1
fi
fi
if [ -f "$PIDFILE" ]; then
checkpid `cat $PIDFILE` && return 0
fi
echo -n $"Starting $prog: "
cd /
daemon --user=root mdadm ${OPTIONS}
ret=$?
[ $ret -eq "0" ] && touch /var/lock/subsys/$prog
echo
return $ret
}
stop ()
{
[ -f /var/lock/subsys/$prog ] || return 0
echo -n "Killing $prog: "
killproc mdadm
echo
rm -f $PIDFILE
rm -f /var/lock/subsys/$prog
}
restart ()
{
stop
start
}
condrestart ()
{
[ -e /var/lock/subsys/$prog ] && restart || return 0
}
case "$1" in
start|stop|restart|condrestart|try-restart|force-reload)
[ `id -u` != "0" ] && exit 4 ;;
esac
case "$1" in
start) start; RETVAL=$? ;;
stop) stop; RETVAL=$? ;;
status) status -p $PIDFILE $prog ; RETVAL=$? ;;
restart) restart; RETVAL=$? ;;
reload) RETVAL=3 ;;
condrestart|try-restart|force-reload) condrestart; RETVAL=$? ;;
*) usage ; RETVAL=2 ;;
esac
exit $RETVAL

12
mdmonitor.service Normal file
View File

@ -0,0 +1,12 @@
[Unit]
Description=Software RAID monitoring and management
ConditionPathExists=/etc/mdadm.conf
[Service]
Type=forking
PIDFile=/var/run/mdadm/mdadm.pid
EnvironmentFile=-/etc/sysconfig/mdmonitor
ExecStart=/sbin/mdadm --monitor --scan -f --pid-file=/var/run/mdadm/mdadm.pid
[Install]
WantedBy=multi-user.target

135
raid-check Normal file
View File

@ -0,0 +1,135 @@
#!/bin/bash
#
# This script reads it's configuration from /etc/sysconfig/raid-check
# Please use that file to enable/disable this script or to set the
# type of check you wish performed.
# We might be on a kernel with no raid support at all, exit if so
[ -f /proc/mdstat ] || exit 0
# and exit if we haven't been set up properly
[ -f /etc/sysconfig/raid-check ] || exit 0
. /etc/sysconfig/raid-check
# Wait until no more than arg1 arrays in arg2 list are busy
waitbusy() {
local threshold=$(($1 + 1))
local dev_list="$2"
while true
do
local busy=0
local dev=""
for dev in $dev_list; do
local sync_action=`cat /sys/block/$dev/md/sync_action`
if [ "$sync_action" != "idle" ]; then
let busy++
fi
done
[ $busy -lt $threshold ] && break
sleep 60
done
}
[ "$ENABLED" != "yes" ] && exit 0
case "$CHECK" in
check) ;;
repair) ;;
*) exit 0;;
esac
ionice=""
renice=""
case $NICE in
high)
renice="-n -5"
;;
low)
renice="-n 5"
ionice="-c2 -n7"
;;
idle)
renice="-n 15"
ionice="-c3"
;;
*)
;;
esac
active_list=`grep "^md.*: active" /proc/mdstat | cut -f 1 -d ' '`
[ -z "$active_list" ] && exit 0
declare -A check
dev_list=""
check_list=""
for dev in $active_list; do
echo $SKIP_DEVS | grep -w $dev >&/dev/null && continue
if [ -f /sys/block/$dev/md/sync_action ]; then
# Only perform the checks on idle, healthy arrays, but delay
# actually writing the check field until the next loop so we
# don't switch currently idle arrays to active, which happens
# when two or more arrays are on the same physical disk
array_state=`cat /sys/block/$dev/md/array_state`
if [ "$array_state" != "clean" -a "$array_state" != "active" ]; then
continue
fi
sync_action=`cat /sys/block/$dev/md/sync_action`
if [ "$sync_action" != idle ]; then
continue
fi
ck=""
echo $REPAIR_DEVS | grep -w $dev >&/dev/null && ck="repair"
echo $CHECK_DEVS | grep -w $dev >&/dev/null && ck="check"
[ -z "$ck" ] && ck=$CHECK
dev_list="$dev_list $dev"
check[$dev]=$ck
[ "$ck" = "check" ] && check_list="$check_list $dev"
fi
done
[ -z "$dev_list" ] && exit 0
for dev in $dev_list; do
#Only run $MAXCONCURRENT checks at a time
if [ -n "$MAXCONCURRENT" ]; then
waitbusy $((MAXCONCURRENT - 1)) "$dev_list"
fi
echo "${check[$dev]}" > /sys/block/$dev/md/sync_action
resync_pid=""
wait=10
while [ $wait -gt 0 -a -z "$resync_pid" ]; do
sleep 6
let wait--
resync_pid=$(ps -ef | awk -v mddev=$dev 'BEGIN { pattern = "^\\[" mddev "_resync]$" } $8 ~ pattern { print $2 }')
done
[ -n "$resync_pid" -a -n "$renice" ] &&
renice $renice -p $resync_pid >&/dev/null
[ -n "$resync_pid" -a -n "$ionice" ] &&
ionice $ionice -p $resync_pid >&/dev/null
done
[ -z "$check_list" ] && exit 0
waitbusy 0 "$check_list"
for dev in $check_list; do
mismatch_cnt=`cat /sys/block/$dev/md/mismatch_cnt`
# Due to the fact that raid1/10 writes in the kernel are unbuffered,
# a raid1 array can have non-0 mismatch counts even when the
# array is healthy. These non-0 counts will only exist in
# transient data areas where they don't pose a problem. However,
# since we can't tell the difference between a non-0 count that
# is just in transient data or a non-0 count that signifies a
# real problem, simply don't check the mismatch_cnt on raid1
# devices as it's providing far too many false positives. But by
# leaving the raid1 device in the check list and performing the
# check, we still catch and correct any bad sectors there might
# be in the device.
raid_lvl=`cat /sys/block/$dev/md/level`
if [ "$raid_lvl" = "raid1" -o "$raid_lvl" = "raid10" ]; then
continue
fi
if [ "$mismatch_cnt" -ne 0 ]; then
echo "WARNING: mismatch_cnt is not 0 on /dev/$dev"
fi
done