Make sure to retry in case a remove fails due to an array being busy

Signed-off-by: Jes Sorensen <Jes.Sorensen@redhat.com>
This commit is contained in:
Jes Sorensen 2012-01-12 13:39:08 +01:00
parent 67924ca9b5
commit 9d26a69f72
3 changed files with 209 additions and 1 deletions

View File

@ -0,0 +1,92 @@
From 68226a80812cd9fce63dbd14d2225ffdf16a781b Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.de>
Date: Tue, 3 Jan 2012 00:36:23 +1100
Subject: [PATCH 2/2] monitor: ensure we retry soon when 'remove' fails.
If a 'remove' fails there is no certainty that another event will
happen soon, so make sure we retry soon anyway.
Reported-by: Adam Kwolek <adam.kwolek@intel.com>
Signed-off-by: NeilBrown <neilb@suse.de>
---
mdadm.h | 1 +
monitor.c | 16 ++++++++++------
2 files changed, 11 insertions(+), 6 deletions(-)
diff --git a/mdadm.h b/mdadm.h
index 3bcd052..381ef86 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -867,6 +867,7 @@ struct supertype {
* external:/md0/12
*/
int devcnt;
+ int retry_soon;
struct mdinfo *devs;
diff --git a/monitor.c b/monitor.c
index cfe4178..c987d10 100644
--- a/monitor.c
+++ b/monitor.c
@@ -212,6 +212,7 @@ static void signal_manager(void)
*/
#define ARRAY_DIRTY 1
+#define ARRAY_BUSY 2
static int read_and_act(struct active_array *a)
{
unsigned long long sync_completed;
@@ -419,9 +420,9 @@ static int read_and_act(struct active_array *a)
if ((mdi->next_state & DS_REMOVE) && mdi->state_fd >= 0) {
int remove_result;
- /* the kernel may not be able to immediately remove the
- * disk, we can simply wait until the next event to try
- * again.
+ /* The kernel may not be able to immediately remove the
+ * disk. In that case we wait a little while and
+ * try again.
*/
remove_result = write_attr("remove", mdi->state_fd);
if (remove_result > 0) {
@@ -429,7 +430,8 @@ static int read_and_act(struct active_array *a)
close(mdi->state_fd);
close(mdi->recovery_fd);
mdi->state_fd = -1;
- }
+ } else
+ ret |= ARRAY_BUSY;
}
if (mdi->next_state & DS_INSYNC) {
write_attr("+in_sync", mdi->state_fd);
@@ -597,7 +599,7 @@ static int wait_and_act(struct supertype *container, int nowait)
struct timespec ts;
ts.tv_sec = 24*3600;
ts.tv_nsec = 0;
- if (*aap == NULL) {
+ if (*aap == NULL || container->retry_soon) {
/* just waiting to get O_EXCL access */
ts.tv_sec = 0;
ts.tv_nsec = 20000000ULL;
@@ -612,7 +614,7 @@ static int wait_and_act(struct supertype *container, int nowait)
#ifdef DEBUG
dprint_wake_reasons(&rfds);
#endif
-
+ container->retry_soon = 0;
}
if (update_queue) {
@@ -653,6 +655,8 @@ static int wait_and_act(struct supertype *container, int nowait)
*/
if (sigterm && !(ret & ARRAY_DIRTY))
a->container = NULL; /* stop touching this array */
+ if (ret & ARRAY_BUSY)
+ container->retry_soon = 1;
}
}
--
1.7.8.2

View File

@ -0,0 +1,109 @@
From 77b3ac8c6521d836dd3c6ef247c252293920fd52 Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.de>
Date: Tue, 3 Jan 2012 11:18:59 +1100
Subject: [PATCH 1/2] monitor: make return from read_and_act more symbolic.
Rather than just a number, use a named flag.
This makes the code easier to understand and allows room for returning
more flags later.
Signed-off-by: NeilBrown <neilb@suse.de>
---
monitor.c | 20 ++++++++++----------
1 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/monitor.c b/monitor.c
index 29bde18..cfe4178 100644
--- a/monitor.c
+++ b/monitor.c
@@ -211,6 +211,7 @@ static void signal_manager(void)
*
*/
+#define ARRAY_DIRTY 1
static int read_and_act(struct active_array *a)
{
unsigned long long sync_completed;
@@ -218,7 +219,7 @@ static int read_and_act(struct active_array *a)
int check_reshape = 0;
int deactivate = 0;
struct mdinfo *mdi;
- int dirty = 0;
+ int ret = 0;
int count = 0;
a->next_state = bad_word;
@@ -254,14 +255,14 @@ static int read_and_act(struct active_array *a)
if (a->curr_state == write_pending) {
a->container->ss->set_array_state(a, 0);
a->next_state = active;
- dirty = 1;
+ ret |= ARRAY_DIRTY;
}
if (a->curr_state == active_idle) {
/* Set array to 'clean' FIRST, then mark clean
* in the metadata
*/
a->next_state = clean;
- dirty = 1;
+ ret |= ARRAY_DIRTY;
}
if (a->curr_state == clean) {
a->container->ss->set_array_state(a, 1);
@@ -269,7 +270,7 @@ static int read_and_act(struct active_array *a)
if (a->curr_state == active ||
a->curr_state == suspended ||
a->curr_state == bad_word)
- dirty = 1;
+ ret |= ARRAY_DIRTY;
if (a->curr_state == readonly) {
/* Well, I'm ready to handle things. If readonly
* wasn't requested, transition to read-auto.
@@ -284,7 +285,7 @@ static int read_and_act(struct active_array *a)
a->next_state = read_auto; /* array is clean */
else {
a->next_state = active; /* Now active for recovery etc */
- dirty = 1;
+ ret |= ARRAY_DIRTY;
}
}
}
@@ -459,7 +460,7 @@ static int read_and_act(struct active_array *a)
if (deactivate)
a->container = NULL;
- return dirty;
+ return ret;
}
static struct mdinfo *
@@ -629,7 +630,6 @@ static int wait_and_act(struct supertype *container, int nowait)
rv = 0;
dirty_arrays = 0;
for (a = *aap; a ; a = a->next) {
- int is_dirty;
if (a->replaces && !discard_this) {
struct active_array **ap;
@@ -644,14 +644,14 @@ static int wait_and_act(struct supertype *container, int nowait)
signal_manager();
}
if (a->container && !a->to_remove) {
- is_dirty = read_and_act(a);
+ int ret = read_and_act(a);
rv |= 1;
- dirty_arrays += is_dirty;
+ dirty_arrays += !!(ret & ARRAY_DIRTY);
/* when terminating stop manipulating the array after it
* is clean, but make sure read_and_act() is given a
* chance to handle 'active_idle'
*/
- if (sigterm && !is_dirty)
+ if (sigterm && !(ret & ARRAY_DIRTY))
a->container = NULL; /* stop touching this array */
}
}
--
1.7.8.2

View File

@ -1,7 +1,7 @@
Summary: The mdadm program controls Linux md devices (software RAID arrays) Summary: The mdadm program controls Linux md devices (software RAID arrays)
Name: mdadm Name: mdadm
Version: 3.2.3 Version: 3.2.3
Release: 2%{?dist} Release: 3%{?dist}
Source: http://www.kernel.org/pub/linux/utils/raid/mdadm/mdadm-%{version}.tar.bz2 Source: http://www.kernel.org/pub/linux/utils/raid/mdadm/mdadm-%{version}.tar.bz2
Source1: mdmonitor.init Source1: mdmonitor.init
Source2: raid-check Source2: raid-check
@ -12,6 +12,8 @@ Source6: mdmonitor.service
Source7: mdmonitor-takeover.service Source7: mdmonitor-takeover.service
Source8: mdadm.conf Source8: mdadm.conf
Patch1: mdadm-3.2.3-Work-around-gcc-4.7-s-strict-aliasing-checks.patch Patch1: mdadm-3.2.3-Work-around-gcc-4.7-s-strict-aliasing-checks.patch
Patch2: mdadm-3.2.3-monitor-make-return-from-read_and_act-more-symbolic.patch
Patch3: mdadm-3.2.3-monitor-ensure-we-retry-soon-when-remove-fails.patch
Patch19: mdadm-3.2.3-udev.patch Patch19: mdadm-3.2.3-udev.patch
Patch20: mdadm-2.5.2-static.patch Patch20: mdadm-2.5.2-static.patch
URL: http://www.kernel.org/pub/linux/utils/raid/mdadm/ URL: http://www.kernel.org/pub/linux/utils/raid/mdadm/
@ -121,6 +123,11 @@ fi
%{_initrddir}/* %{_initrddir}/*
%changelog %changelog
* Thu Jan 12 2012 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.2.3-3
- Fix case where we have to retry in case a remove fails due to an array
being busy
- Resolves: bz773337 (rawhide) bz773340 (f16) bz773341 (f15)
* Thu Jan 5 2012 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.2.3-2 * Thu Jan 5 2012 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.2.3-2
- Workaround for gcc-4.7 strict aliasing breaking the build - Workaround for gcc-4.7 strict aliasing breaking the build