*/
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.
* 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;
}
}
+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)
{
* 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;
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;
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;
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->recovery_fd = sysfs_open(new->devnum,
- newd->sys_name,
- "recovery_start");
-
- 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);
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");
+ 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);
/* 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;
{
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 (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();
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);