summaryrefslogtreecommitdiffstats
path: root/monitor.c
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2008-10-02 06:32:08 -0700
committerDan Williams <dan.j.williams@intel.com>2008-10-15 14:43:57 -0700
commit6144ed441445ee4d567614aaed78dd24148881ce (patch)
tree7c98537390691aca6739ea2ed9f4d151a9a9f027 /monitor.c
parent57ed8c9155d31ca78c48979f4f98d40e4c0deac3 (diff)
downloadmdadm-6144ed441445ee4d567614aaed78dd24148881ce.tar.gz
mdadm-6144ed441445ee4d567614aaed78dd24148881ce.tar.xz
mdadm-6144ed441445ee4d567614aaed78dd24148881ce.zip
mdmon: terminate clean
We generally don't want mdmon to be terminated, but if a SIGTERM gets through try to leave the monitored arrays in a clean state, block attempts to mark the array dirty, and stop servicing the socket. When we are killed by sigterm don't remove the pidfile let that be cleaned up by the next monitor. Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'monitor.c')
-rw-r--r--monitor.c44
1 files changed, 38 insertions, 6 deletions
diff --git a/monitor.c b/monitor.c
index 1bf69a7..d8ac45e 100644
--- a/monitor.c
+++ b/monitor.c
@@ -414,6 +414,7 @@ static int wait_and_act(struct supertype *container, int nowait)
struct active_array *a, **ap;
int rv;
struct mdinfo *mdi;
+ static unsigned int dirty_arrays = ~0; /* start at some non-zero value */
FD_ZERO(&rfds);
@@ -442,16 +443,20 @@ static int wait_and_act(struct supertype *container, int nowait)
ap = &(*ap)->next;
}
- if (manager_ready && *aap == NULL) {
- /* No interesting arrays. Lets see about exiting.
- * Note that blocking at this point is not a problem
- * as there are no active arrays, there is nothing that
- * we need to be ready to do.
+ if (manager_ready && (*aap == NULL || (sigterm && !dirty_arrays))) {
+ /* No interesting arrays, or we have been told to
+ * terminate and everything is clean. Lets see about
+ * exiting. Note that blocking at this point is not a
+ * 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);
if (fd >= 0 || errno != EBUSY) {
/* OK, we are safe to leave */
- dprintf("no arrays to monitor... exiting\n");
+ if (sigterm && !dirty_arrays)
+ dprintf("caught sigterm, all clean... exiting\n");
+ else
+ dprintf("no arrays to monitor... exiting\n");
remove_pidfile(container->devname);
exit_now = 1;
signal_manager();
@@ -487,7 +492,10 @@ 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;
for (ap = &a->next; *ap && *ap != a->replaces;
@@ -502,6 +510,30 @@ static int wait_and_act(struct supertype *container, int nowait)
}
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;
+ }
+ dirty_arrays += is_dirty;
+ if (sigterm && !is_dirty)
+ a->container = NULL; /* stop touching this array */
}
/* propagate failures across container members */