#include "mdadm.h"
#include "mdmon.h"
#include <sys/socket.h>
+#include <signal.h>
static void close_aa(struct active_array *aa)
{
close(aa->action_fd);
close(aa->info.state_fd);
close(aa->resync_start_fd);
- close(aa->sync_pos_fd);
}
static void free_aa(struct active_array *aa)
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)
* 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;
write_wakeup(container);
}
-
static void manage_container(struct mdstat_ent *mdstat,
struct supertype *container)
{
new = malloc(sizeof(*new));
+ memset(new, 0, sizeof(*new));
+
new->devnum = mdstat->devnum;
new->prev_state = new->curr_state = new->next_state = inactive;
new->action_fd = sysfs_open(new->devnum, NULL, "sync_action");
new->info.state_fd = sysfs_open(new->devnum, NULL, "array_state");
new->resync_start_fd = sysfs_open(new->devnum, NULL, "resync_start");
- new->sync_pos_fd = sysfs_open(new->devnum, NULL, "sync_completed");
- new->sync_pos = 0;
+ new->resync_start = 0;
sysfs_free(mdi);
// finds and compares.
return;
}
-void manage(struct mdstat_ent *mdstat, struct active_array *aa,
- struct supertype *container)
+void manage(struct mdstat_ent *mdstat, struct supertype *container)
{
/* We have just read mdstat and need to compare it with
* the known active arrays.
/* Not for this array */
continue;
/* Looks like a member of this container */
- for (a = aa; a; a = a->next) {
+ for (a = container->arrays; a; a = a->next) {
if (mdstat->devnum == a->devnum) {
if (a->container)
manage_member(mdstat, a);
close(fd);
}
+
+static int woke = 0;
+void wake_me(int sig)
+{
+ woke = 1;
+}
+
+int exit_now = 0;
+int manager_ready = 0;
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;
+
+ if (exit_now)
+ exit(0);
+
mdstat = mdstat_read(1, 0);
- manage(mdstat, array_list, container);
+ manage(mdstat, container);
read_sock(container);
free_mdstat(mdstat);
- mdstat_wait_fd(container->sock);
+ remove_old();
+
+ manager_ready = 1;
+ sigprocmask(SIG_SETMASK, &block, &orig);
+ if (woke == 0)
+ mdstat_wait_fd(container->sock, &orig);
+ sigprocmask(SIG_SETMASK, &orig, NULL);
} while(1);
}