+/*
+ * mdmon - monitor external metadata arrays
+ *
+ * Copyright (C) 2007-2008 Neil Brown <neilb@suse.de>
+ * Copyright (C) 2007-2008 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
#include "mdadm.h"
#include "mdmon.h"
n = read_attr(buf, 30, a->resync_start_fd);
if (n <= 0)
return n;
-
- a->resync_start = strtoull(buf, NULL, 10);
+ if (strncmp(buf, "none", 4) == 0)
+ a->resync_start = ~0ULL;
+ else
+ a->resync_start = strtoull(buf, NULL, 10);
return 1;
}
int check_degraded = 0;
int deactivate = 0;
struct mdinfo *mdi;
+ int dirty = 0;
a->next_state = bad_word;
a->next_action = bad_action;
get_resync_start(a);
a->container->ss->set_array_state(a, 0);
a->next_state = active;
+ dirty = 1;
}
if (a->curr_state == active_idle) {
/* Set array to 'clean' FIRST, then mark clean
* in the metadata
*/
a->next_state = clean;
+ dirty = 1;
}
if (a->curr_state == clean) {
get_resync_start(a);
a->container->ss->set_array_state(a, 1);
}
-
+ if (a->curr_state == active ||
+ a->curr_state == suspended ||
+ a->curr_state == bad_word)
+ dirty = 1;
if (a->curr_state == readonly) {
/* Well, I'm ready to handle things. If readonly
* wasn't requested, transition to read-auto.
get_resync_start(a);
if (a->container->ss->set_array_state(a, 2))
a->next_state = read_auto; /* array is clean */
- else
+ else {
a->next_state = active; /* Now active for recovery etc */
+ dirty = 1;
+ }
}
}
if (deactivate)
a->container = NULL;
- return 1;
+ return dirty;
}
static struct mdinfo *
* problem as there are no active arrays, there is
* nothing that we need to be ready to do.
*/
- int fd = open(container->device_name, O_RDONLY|O_EXCL);
+ int fd = open_dev_excl(container->devnum);
if (fd >= 0 || errno != EBUSY) {
/* OK, we are safe to leave */
if (sigterm && !dirty_arrays)
sigprocmask(SIG_UNBLOCK, NULL, &set);
sigdelset(&set, SIGUSR1);
monitor_loop_cnt |= 1;
- rv = pselect(maxfd+1, &rfds, NULL, NULL, NULL, &set);
+ rv = pselect(maxfd+1, NULL, NULL, &rfds, NULL, &set);
monitor_loop_cnt += 1;
if (rv == -1 && errno == EINTR)
rv = 0;
/* FIXME check if device->state_fd need to be cleared?*/
signal_manager();
}
- if (a->container)
- rv += read_and_act(a);
- else
- continue;
-
- /* when terminating stop manipulating the array after it is
- * clean, but make sure read_and_act() is given a chance to
- * handle 'active_idle'
- */
- switch (read_state(a->info.state_fd)) {
- case active:
- case active_idle:
- case suspended:
- case bad_word:
- is_dirty = 1;
- break;
- default:
- if (a->curr_state == active_idle)
- is_dirty = 1;
- else
- is_dirty = 0;
- break;
+ if (a->container) {
+ is_dirty = read_and_act(a);
+ rv |= 1;
+ dirty_arrays += is_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)
+ a->container = NULL; /* stop touching this array */
}
- dirty_arrays += is_dirty;
- if (sigterm && !is_dirty)
- a->container = NULL; /* stop touching this array */
}
/* propagate failures across container members */