summaryrefslogtreecommitdiff
path: root/managemon.c
diff options
context:
space:
mode:
authorLabun, Marcin <Marcin.Labun@intel.com>2011-03-15 15:09:31 +1100
committerNeilBrown <neilb@suse.de>2011-03-15 15:09:31 +1100
commit258c3e921b5efae10116857971a9a2bfbfe99d4b (patch)
tree1dea3736020172e2b678b99036a1d7d0a4f2ef4a /managemon.c
parent33b0edd78ad33207434f2944e81a09a91ddafd10 (diff)
IMSM: Fix problem in mdmon monitor of using removed disk in imsm container.
Manager thread shall pass the information to monitor thread (mdmon) that some devices are removed from container. Otherwise, monitor (mdmon) might use such devices (spares) to rebuild the array that has gone degraded. This problem happens for imsm containers, since a list of the container disks is maintained in intel_super structure. When array goes degraded, the list is searched to find a spare disks to start rebuild. Without this fix the rebuild could be stared on the spare device that was a member of the container, but has been removed from it. New super type function handler has been introduced to prepare metadata format specific information about removed devices. int (*remove_from_super)(struct supertype *st, mdu_disk_info_t *dinfo) The message prepared in remove_from_super is later processed by process_update handler in monitor thread. Signed-off-by: Marcin Labun <marcin.labun@intel.com> Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'managemon.c')
-rw-r--r--managemon.c39
1 files changed, 36 insertions, 3 deletions
diff --git a/managemon.c b/managemon.c
index 26ff1877..49c90346 100644
--- a/managemon.c
+++ b/managemon.c
@@ -297,12 +297,44 @@ static void add_disk_to_container(struct supertype *st, struct mdinfo *sd)
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.
*/
@@ -334,6 +366,7 @@ static void manage_container(struct mdstat_ent *mdstat,
if (!found) {
cd = *cdp;
*cdp = (*cdp)->next;
+ remove_disk_from_container(container, cd);
free(cd);
} else
cdp = &(*cdp)->next;