]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - managemon.c
Detail: clean up handing of the 'info' we load from superblock.
[thirdparty/mdadm.git] / managemon.c
index f9d545d46fbac9142c06f1ea540896a78980e01d..bab0397921a7d30dc24e012cfa9decc8d5e877f5 100644 (file)
@@ -112,8 +112,10 @@ static void close_aa(struct active_array *aa)
 {
        struct mdinfo *d;
 
-       for (d = aa->info.devs; d; d = d->next)
+       for (d = aa->info.devs; d; d = d->next) {
+               close(d->recovery_fd);
                close(d->state_fd);
+       }
 
        close(aa->action_fd);
        close(aa->info.state_fd);
@@ -209,16 +211,22 @@ struct metadata_update *update_queue = NULL;
 struct metadata_update *update_queue_handled = NULL;
 struct metadata_update *update_queue_pending = NULL;
 
-void check_update_queue(struct supertype *container)
+static void free_updates(struct metadata_update **update)
 {
-       while (update_queue_handled) {
-               struct metadata_update *this = update_queue_handled;
-               update_queue_handled = this->next;
+       while (*update) {
+               struct metadata_update *this = *update;
+
+               *update = this->next;
                free(this->buf);
-               if (this->space)
-                       free(this->space);
+               free(this->space);
                free(this);
        }
+}
+
+void check_update_queue(struct supertype *container)
+{
+       free_updates(&update_queue_handled);
+
        if (update_queue == NULL &&
            update_queue_pending) {
                update_queue = update_queue_pending;
@@ -307,7 +315,7 @@ static void manage_container(struct mdstat_ent *mdstat,
                 * To see what is removed and what is added.
                 * These need to be remove from, or added to, the array
                 */
-               mdi = sysfs_read(-1, mdstat->devnum, GET_DEVS|SKIP_GONE_DEVS);
+               mdi = sysfs_read(-1, mdstat->devnum, GET_DEVS);
                if (!mdi) {
                        /* invalidate the current count so we can try again */
                        container->devcnt = -1;
@@ -353,6 +361,23 @@ static void manage_container(struct mdstat_ent *mdstat,
        }
 }
 
+static int disk_init_and_add(struct mdinfo *disk, struct mdinfo *clone,
+                            struct active_array *aa)
+{
+       if (!disk || !clone)
+               return -1;
+
+       *disk = *clone;
+       disk->recovery_fd = sysfs_open(aa->devnum, disk->sys_name, "recovery_start");
+       disk->state_fd = sysfs_open(aa->devnum, disk->sys_name, "state");
+       disk->prev_state = read_dev_state(disk->state_fd);
+       disk->curr_state = disk->prev_state;
+       disk->next = aa->info.devs;
+       aa->info.devs = disk;
+
+       return 0;
+}
+
 static void manage_member(struct mdstat_ent *mdstat,
                          struct active_array *a)
 {
@@ -376,8 +401,9 @@ static void manage_member(struct mdstat_ent *mdstat,
 
        if (a->check_degraded) {
                struct metadata_update *updates = NULL;
-               struct mdinfo *newdev;
+               struct mdinfo *newdev = NULL;
                struct active_array *newa;
+               struct mdinfo *d;
 
                a->check_degraded = 0;
 
@@ -385,34 +411,39 @@ static void manage_member(struct mdstat_ent *mdstat,
                 * to check.
                 */
                newdev = a->container->ss->activate_spare(a, &updates);
-               if (newdev) {
-                       struct mdinfo *d;
-                       /* Cool, we can add a device or several. */
-                       newa = duplicate_aa(a);
-                       /* suspend recovery - maybe not needed */
-
-                       /* Add device to array and set offset/size/slot.
-                        * and open files for each newdev */
-                       for (d = newdev; d ; d = d->next) {
-                               struct mdinfo *newd;
-                               if (sysfs_add_disk(&newa->info, d, 0) < 0)
-                                       continue;
-                               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");
-                               newd->prev_state
-                                       = read_dev_state(newd->state_fd);
-                               newd->curr_state = newd->prev_state;
+               if (!newdev)
+                       return;
+
+               newa = duplicate_aa(a);
+               if (!newa)
+                       goto out;
+               /* Cool, we can add a device or several. */
+
+               /* Add device to array and set offset/size/slot.
+                * and open files for each newdev */
+               for (d = newdev; d ; d = d->next) {
+                       struct mdinfo *newd;
+
+                       newd = malloc(sizeof(*newd));
+                       if (!newd)
+                               continue;
+                       if (sysfs_add_disk(&newa->info, d, 0) < 0) {
+                               free(newd);
+                               continue;
                        }
-                       queue_metadata_update(updates);
-                       replace_array(a->container, a, newa);
-                       sysfs_set_str(&a->info, NULL, "sync_action", "recover");
+                       disk_init_and_add(newd, d, newa);
+               }
+               queue_metadata_update(updates);
+               updates = NULL;
+               replace_array(a->container, a, newa);
+               sysfs_set_str(&a->info, NULL, "sync_action", "recover");
+ out:
+               while (newdev) {
+                       d = newdev->next;
+                       free(newdev);
+                       newdev = d;
                }
+               free_updates(&updates);
        }
 }
 
@@ -492,16 +523,7 @@ static void manage_new(struct mdstat_ent *mdstat,
                        if (i == di->disk.raid_disk)
                                break;
 
-               if (di && newd) {
-                       memcpy(newd, di, sizeof(*newd));
-
-                       newd->state_fd = sysfs_open(new->devnum,
-                                                   newd->sys_name,
-                                                   "state");
-
-                       newd->prev_state = read_dev_state(newd->state_fd);
-                       newd->curr_state = newd->prev_state;
-               } else {
+               if (disk_init_and_add(newd, di, new) != 0) {
                        if (newd)
                                free(newd);
 
@@ -511,18 +533,14 @@ static void manage_new(struct mdstat_ent *mdstat,
                                new->container = NULL;
                                break;
                        }
-                       continue;
                }
-               sprintf(newd->sys_name, "rd%d", i);
-               newd->next = new->info.devs;
-               new->info.devs = newd;
        }
 
        new->action_fd = sysfs_open(new->devnum, NULL, "sync_action");
        new->info.state_fd = sysfs_open(new->devnum, NULL, "array_state");
        new->resync_start_fd = sysfs_open(new->devnum, NULL, "resync_start");
        new->metadata_fd = sysfs_open(new->devnum, NULL, "metadata_version");
-       get_resync_start(new);
+       new->sync_completed_fd = sysfs_open(new->devnum, NULL, "sync_completed");
        dprintf("%s: inst: %d action: %d state: %d\n", __func__, atoi(inst),
                new->action_fd, new->info.state_fd);
 
@@ -654,14 +672,10 @@ 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 {
 
@@ -679,15 +693,6 @@ void do_manager(struct supertype *container)
 
                        read_sock(container);
 
-                       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);
                }
                remove_old();
@@ -699,12 +704,9 @@ void do_manager(struct supertype *container)
                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 (update_queue == NULL)
+                       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);