]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - managemon.c
Move calls to SET_ARRAY_INFO to common helper.
[thirdparty/mdadm.git] / managemon.c
index 15e431f7fb9b03976919e1108b10c0648c1ed65b..dc3ff7f2f0edd9abbc4fedb7fee827b645aad39a 100644 (file)
@@ -265,8 +265,11 @@ static void manage_container(struct mdstat_ent *mdstat,
                 * These need to be remove from, or added to, the array
                 */
                mdi = sysfs_read(-1, mdstat->devnum, GET_DEVS);
-               if (!mdi)
+               if (!mdi) {
+                       /* invalidate the current count so we can try again */
+                       container->devcnt = -1;
                        return;
+               }
 
                /* check for removals */
                for (cdp = &container->devs; *cdp; ) {
@@ -343,7 +346,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");
@@ -475,8 +482,13 @@ static void manage_new(struct mdstat_ent *mdstat,
                        mdstat->metadata_version);
                new->container = NULL;
                free_aa(new);
-       } else
+       } else {
                replace_array(container, victim, new);
+               if (failed) {
+                       new->check_degraded = 1;
+                       manage_member(mdstat, new);
+               }
+       }
 }
 
 void manage(struct mdstat_ent *mdstat, struct supertype *container)
@@ -520,14 +532,15 @@ static void handle_message(struct supertype *container, struct metadata_update *
 
        struct metadata_update *mu;
 
-       if (msg->len == 0) {
-               int cnt;
-               
+       if (msg->len <= 0)
                while (update_queue_pending || update_queue) {
                        check_update_queue(container);
                        usleep(15*1000);
                }
 
+       if (msg->len == 0) { /* ping_monitor */
+               int cnt;
+               
                cnt = monitor_loop_cnt;
                if (cnt & 1)
                        cnt += 2; /* wait until next pselect */
@@ -537,6 +550,11 @@ static void handle_message(struct supertype *container, struct metadata_update *
 
                while (monitor_loop_cnt - cnt < 0)
                        usleep(10 * 1000);
+       } else if (msg->len == -1) { /* ping_manager */
+               struct mdstat_ent *mdstat = mdstat_read(1, 0);
+
+               manage(mdstat, container);
+               free_mdstat(mdstat);
        } else {
                mu = malloc(sizeof(*mu));
                mu->len = msg->len;
@@ -591,6 +609,7 @@ void do_manager(struct supertype *container)
 
        sigprocmask(SIG_UNBLOCK, NULL, &set);
        sigdelset(&set, SIGUSR1);
+       sigdelset(&set, SIGHUP);
 
        do {
 
@@ -608,6 +627,13 @@ void do_manager(struct supertype *container)
 
                        read_sock(container);
 
+                       if (socket_hup_requested) {
+                               close(container->sock);
+                               container->sock = make_control_sock(container->devname);
+                               make_pidfile(container->devname, 0);
+                               socket_hup_requested = 0;
+                       }
+
                        free_mdstat(mdstat);
                }
                remove_old();