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)
st->update_tail = NULL;
}
+/*
+ * Create and queue update structure about the removed disks.
+ * The update is prepared by super type handler and passed to the monitor
+ * thread.
+ */
+static void remove_disk_from_container(struct supertype *st, struct mdinfo *sd)
+{
+ struct metadata_update *update = NULL;
+ mdu_disk_info_t dk = {
+ .number = -1,
+ .major = sd->disk.major,
+ .minor = sd->disk.minor,
+ .raid_disk = -1,
+ .state = 0,
+ };
+ /* nothing to do if super type handler does not support
+ * remove disk primitive
+ */
+ if (!st->ss->remove_from_super)
+ return;
+ dprintf("%s: remove %d:%d from container\n",
+ __func__, sd->disk.major, sd->disk.minor);
+
+ st->update_tail = &update;
+ st->ss->remove_from_super(st, &dk);
+ st->ss->write_init_super(st);
+ queue_metadata_update(update);
+ st->update_tail = NULL;
+}
+
static void manage_container(struct mdstat_ent *mdstat,
struct supertype *container)
{
- /* The only thing of interest here is if a new device
- * has been added to the container. We add it to the
- * array ignoring any metadata on it.
+ /* Of interest here are:
+ * - if a new device has been added to the container, we
+ * add it to the array ignoring any metadata on it.
+ * - if a device has been removed from the container, we
+ * remove it from the device list and update the metadata.
* FIXME should we look for compatible metadata and take hints
* about spare assignment.... probably not.
*/
if (!found) {
cd = *cdp;
*cdp = (*cdp)->next;
+ remove_disk_from_container(container, cd);
free(cd);
} else
cdp = &(*cdp)->next;
* 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;
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;
/* 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;