]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - managemon.c
Merge branch 'master' into devel-3.2
[thirdparty/mdadm.git] / managemon.c
index 19effe44d5920fc19abdaa003f14dda2add06efd..ebd9b73ff2024aa6e50d7737f8800bca376381f9 100644 (file)
@@ -112,12 +112,16 @@ 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);
        close(aa->resync_start_fd);
+       close(aa->metadata_fd);
+       close(aa->sync_completed_fd);
 }
 
 static void free_aa(struct active_array *aa)
@@ -274,7 +278,7 @@ static void add_disk_to_container(struct supertype *st, struct mdinfo *sd)
         */
        st2 = dup_super(st);
        if (st2->ss->load_super(st2, dfd, NULL) == 0) {
-               st2->ss->getinfo_super(st, &info);
+               st2->ss->getinfo_super(st, &info, NULL);
                if (st->ss->compare_super(st, st2) == 0 &&
                    info.disk.raid_disk >= 0) {
                        /* Looks like a good member of array.
@@ -313,7 +317,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;
@@ -359,6 +363,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)
 {
@@ -375,12 +396,20 @@ static void manage_member(struct mdstat_ent *mdstat,
         * trying to find and assign a spare.
         * We do that whenever the monitor tells us too.
         */
+       char buf[64];
+       int frozen;
+
        // FIXME
        a->info.array.raid_disks = mdstat->raid_disks;
-       a->info.array.chunk_size = mdstat->chunk_size;
        // MORE
 
-       if (a->check_degraded) {
+       /* honor 'frozen' */
+       if (sysfs_get_str(&a->info, NULL, "metadata_version", buf, sizeof(buf)) > 0)
+               frozen = buf[9] == '-';
+       else
+               frozen = 1; /* can't read metadata_version assume the worst */
+
+       if (a->check_degraded && !frozen) {
                struct metadata_update *updates = NULL;
                struct mdinfo *newdev = NULL;
                struct active_array *newa;
@@ -412,14 +441,7 @@ static void manage_member(struct mdstat_ent *mdstat,
                                free(newd);
                                continue;
                        }
-                       *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;
+                       disk_init_and_add(newd, d, newa);
                }
                queue_metadata_update(updates);
                updates = NULL;
@@ -499,7 +521,7 @@ static void manage_new(struct mdstat_ent *mdstat,
 
        new->container = container;
 
-       inst = &mdstat->metadata_version[10+strlen(container->devname)+1];
+       inst = to_subarray(mdstat, container->devname);
 
        new->info.array = mdi->array;
        new->info.component_size = mdi->component_size;
@@ -511,16 +533,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);
 
@@ -530,18 +543,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);
 
@@ -657,7 +666,13 @@ void read_sock(struct supertype *container)
                /* read and validate the message */
                if (receive_message(fd, &msg, tmo) == 0) {
                        handle_message(container, &msg);
-                       if (ack(fd, tmo) < 0)
+                       if (msg.len == 0) {
+                               /* ping reply with version */
+                               msg.buf = Version;
+                               msg.len = strlen(Version) + 1;
+                               if (send_message(fd, &msg, tmo) < 0)
+                                       terminate = 1;
+                       } else if (ack(fd, tmo) < 0)
                                terminate = 1;
                } else
                        terminate = 1;
@@ -673,14 +688,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 {
 
@@ -698,21 +709,6 @@ void do_manager(struct supertype *container)
 
                        read_sock(container);
 
-                       if (container->sock < 0 || socket_hup_requested) {
-                               /* If this fails, we hope it already exists
-                                * pid file lives in /var/run/mdadm/mdXX.pid
-                                */
-                               mkdir("/var", 0600);
-                               mkdir("/var/run", 0600);
-                               mkdir("/var/run/mdadm", 0600);
-                               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();
@@ -724,12 +720,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);