+/*
+ * 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.
+ */
/*
* The management thread for monitoring active md arrays.
struct mdinfo *newd;
if (sysfs_add_disk(&newa->info, d) < 0)
continue;
- newd = newa->info.devs;
+ newd = malloc(sizeof(*newd));
+ *newd = *d;
+ newd->next = newa->info.devs;
+ newa->info.devs = newd;
+
newd->state_fd = sysfs_open(a->devnum,
newd->sys_name,
"state");
manage_container(mdstat, container);
continue;
}
- if (mdstat->metadata_version == NULL ||
- strncmp(mdstat->metadata_version, "external:", 9) != 0 ||
- !is_subarray(mdstat->metadata_version+9) ||
- strncmp(mdstat->metadata_version+10, container->devname,
- strlen(container->devname)) != 0 ||
- mdstat->metadata_version[10+strlen(container->devname)]
- != '/')
+ if (!is_container_member(mdstat, container->devname))
/* Not for this array */
continue;
/* Looks like a member of this container */
manage(mdstat, container);
free_mdstat(mdstat);
- } else {
+ } else if (!sigterm) {
mu = malloc(sizeof(*mu));
mu->len = msg->len;
mu->buf = msg->buf;
{
struct mdstat_ent *mdstat;
sigset_t set;
+ int proc_fd;
sigprocmask(SIG_UNBLOCK, NULL, &set);
sigdelset(&set, SIGUSR1);
sigdelset(&set, SIGHUP);
+ sigdelset(&set, SIGALRM);
+ sigdelset(&set, SIGTERM);
+ proc_fd = open("/proc/mounts", O_RDONLY);
do {
read_sock(container);
- if (socket_hup_requested) {
+ if (container->sock < 0 || socket_hup_requested) {
close(container->sock);
container->sock = make_control_sock(container->devname);
make_pidfile(container->devname, 0);
socket_hup_requested = 0;
}
+ if (container->sock < 0)
+ alarm(30);
free_mdstat(mdstat);
}
manager_ready = 1;
- if (update_queue == NULL)
- mdstat_wait_fd(container->sock, &set);
- else
+ if (sigterm)
+ wakeup_monitor();
+
+ if (update_queue == NULL) {
+ if (container->sock < 0)
+ mdstat_wait_fd(proc_fd, &set);
+ else
+ mdstat_wait_fd(container->sock, &set);
+ } else
/* If an update is happening, just wait for signal */
pselect(0, NULL, NULL, NULL, NULL, &set);
} while(1);