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 /sysfs.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 'sysfs.c')
-rw-r--r-- | sysfs.c | 33 |
1 files changed, 33 insertions, 0 deletions
@@ -435,6 +435,17 @@ int sysfs_uevent(struct mdinfo *sra, char *event) return 0; } +int sysfs_attribute_available(struct mdinfo *sra, struct mdinfo *dev, char *name) +{ + char fname[50]; + struct stat st; + + sprintf(fname, "/sys/block/%s/md/%s/%s", + sra->sys_name, dev?dev->sys_name:"", name); + + return stat(fname, &st) == 0; +} + int sysfs_get_fd(struct mdinfo *sra, struct mdinfo *dev, char *name) { @@ -789,6 +800,28 @@ int sysfs_unique_holder(int devnum, long rdev) return found; } +int sysfs_freeze_array(struct mdinfo *sra) +{ + /* Try to freeze resync/rebuild on this array/container. + * Return -1 if the array is busy, + * return -2 container cannot be frozen, + * return 0 if this kernel doesn't support 'frozen' + * return 1 if it worked. + */ + char buf[20]; + + if (!sysfs_attribute_available(sra, NULL, "sync_action")) + return 1; /* no sync_action == frozen */ + if (sysfs_get_str(sra, NULL, "sync_action", buf, 20) <= 0) + return 0; + if (strcmp(buf, "idle\n") != 0 && + strcmp(buf, "frozen\n") != 0) + return -1; + if (sysfs_set_str(sra, NULL, "sync_action", "frozen") < 0) + return 0; + return 1; +} + #ifndef MDASSEMBLE static char *clean_states[] = { |