]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - managemon.c
Assemble: return correct status from assemble_container_content.
[thirdparty/mdadm.git] / managemon.c
index 779cb237e77308a91c58f33e7ec635d05216d309..c9b054ff4a0605953a28792a463e959a067c24f1 100644 (file)
@@ -1,3 +1,22 @@
+/*
+ * 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.
@@ -346,7 +365,11 @@ static void manage_member(struct mdstat_ent *mdstat,
                                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");
@@ -500,13 +523,7 @@ void manage(struct mdstat_ent *mdstat, struct supertype *container)
                        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 */
@@ -551,7 +568,7 @@ static void handle_message(struct supertype *container, struct metadata_update *
 
                manage(mdstat, container);
                free_mdstat(mdstat);
-       } else {
+       } else if (!sigterm) {
                mu = malloc(sizeof(*mu));
                mu->len = msg->len;
                mu->buf = msg->buf;
@@ -602,10 +619,14 @@ void do_manager(struct supertype *container)
 {
        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 {
 
@@ -623,12 +644,14 @@ void do_manager(struct supertype *container)
 
                        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);
                }
@@ -638,9 +661,15 @@ void do_manager(struct supertype *container)
 
                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);