diff options
author | Dan Williams <dan.j.williams@intel.com> | 2010-11-23 05:00:54 +0100 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2010-11-23 05:00:54 +0100 |
commit | bc77ed535db05fc4b5b46f20dc4c27893f01610d (patch) | |
tree | 92a86d4a598897adc3815935120a39ab1d26bc1b /managemon.c | |
parent | Provide a mdstat_ent to subarray helper (diff) | |
download | mdadm-bc77ed535db05fc4b5b46f20dc4c27893f01610d.tar.xz mdadm-bc77ed535db05fc4b5b46f20dc4c27893f01610d.zip |
block monitor: freeze spare assignment for external arrays
In order to support reshape and atomic removal of spares from containers
we need to prevent mdmon from activating spares. In the reshape case we
additionally need to freeze sync_action while the reshape transaction is
initiated with the kernel and recorded in the metadata.
When reshaping a raid0 array we need to freeze the array *before* it is
transitioned to a redundant raid level. Since sync_action does not exist
at this point we extend the '-' prefix of a subarray string to flag
mdmon not to activate spares.
Mdadm needs to be reasonably certain that the version of mdmon in the
system honors this 'freeze' indication. If mdmon is not already active
then we assume the version that gets started is the same as the mdadm
version. Otherwise, we check the version of mdmon as returned by the
extended ping_monitor() operation. This is to catch cases where mdadm
is upgraded in the filesystem, but mdmon started in the initramfs is
from a previous release.
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'managemon.c')
-rw-r--r-- | managemon.c | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/managemon.c b/managemon.c index fbf61888..8915522d 100644 --- a/managemon.c +++ b/managemon.c @@ -394,12 +394,21 @@ 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; @@ -656,7 +665,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; |