summaryrefslogtreecommitdiffstats
path: root/managemon.c
diff options
context:
space:
mode:
authorNeil Brown <neilb@suse.de>2008-05-27 09:18:39 +1000
committerNeil Brown <neilb@suse.de>2008-05-27 09:18:39 +1000
commit1ed3f38758ff23dabfa3f67e2a02ff98d9d0fea8 (patch)
tree4adad57c7c06f3ac2ef8508fc911f256fa77df7b /managemon.c
parent7a7cc50430d0d99dfe9b802e9723537360abf9d9 (diff)
downloadmdadm-1ed3f38758ff23dabfa3f67e2a02ff98d9d0fea8.tar.gz
mdadm-1ed3f38758ff23dabfa3f67e2a02ff98d9d0fea8.tar.xz
mdadm-1ed3f38758ff23dabfa3f67e2a02ff98d9d0fea8.zip
Remove stopped arrays.
When an array becomes inactive, clean up and forget it. This involves signalling the manager.
Diffstat (limited to 'managemon.c')
-rw-r--r--managemon.c45
1 files changed, 36 insertions, 9 deletions
diff --git a/managemon.c b/managemon.c
index c771104..aa10a99 100644
--- a/managemon.c
+++ b/managemon.c
@@ -75,6 +75,7 @@
#include "mdadm.h"
#include "mdmon.h"
#include <sys/socket.h>
+#include <signal.h>
static void close_aa(struct active_array *aa)
{
@@ -116,6 +117,17 @@ static void write_wakeup(struct supertype *c)
read(c->mon_pipe[0], &err, 1);
}
+static void remove_old(void)
+{
+ if (discard_this) {
+ discard_this->next = NULL;
+ free_aa(discard_this);
+ if (pending_discard == discard_this)
+ pending_discard = NULL;
+ discard_this = NULL;
+ }
+}
+
static void replace_array(struct supertype *container,
struct active_array *old,
struct active_array *new)
@@ -126,16 +138,12 @@ static void replace_array(struct supertype *container,
* and put it on 'discard_this'. We take it from there
* and discard it.
*/
-
+ remove_old();
while (pending_discard) {
+ write_wakeup(container);
while (discard_this == NULL)
sleep(1);
- if (discard_this != pending_discard)
- abort();
- discard_this->next = NULL;
- free_aa(discard_this);
- discard_this = NULL;
- pending_discard = NULL;
+ remove_old();
}
pending_discard = old;
new->replaces = old;
@@ -144,7 +152,6 @@ static void replace_array(struct supertype *container,
write_wakeup(container);
}
-
static void manage_container(struct mdstat_ent *mdstat,
struct supertype *container)
{
@@ -368,11 +375,26 @@ void read_sock(struct supertype *container)
close(fd);
}
+
+static int woke = 0;
+void wake_me(int sig)
+{
+ woke = 1;
+}
+
void do_manager(struct supertype *container)
{
struct mdstat_ent *mdstat;
+ sigset_t block, orig;
+
+ sigemptyset(&block);
+ sigaddset(&block, SIGUSR1);
+
+ signal(SIGUSR1, wake_me);
do {
+ woke = 0;
+
mdstat = mdstat_read(1, 0);
manage(mdstat, container);
@@ -381,6 +403,11 @@ void do_manager(struct supertype *container)
free_mdstat(mdstat);
- mdstat_wait_fd(container->sock);
+ remove_old();
+
+ sigprocmask(SIG_SETMASK, &block, &orig);
+ if (woke == 0)
+ mdstat_wait_fd(container->sock, &orig);
+ sigprocmask(SIG_SETMASK, &orig, NULL);
} while(1);
}