diff options
author | Labun, Marcin <Marcin.Labun@intel.com> | 2011-10-31 11:29:46 +1100 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2011-10-31 11:29:46 +1100 |
commit | 81219e70f2a9be7292046860ea15528fe5854cab (patch) | |
tree | 6e964755844055702ee3e40385df3853dac9b3cb /Incremental.c | |
parent | db7fdfe422a7d280b1fae999cb72b20b0e58756c (diff) |
kill-subarray: fix, IMSM cannot kill-subarray with unsupported metadata
container_content retrieves volume information from disks in the
container. For unsupported volumes the function was not returning
mdinfo. When all volumes were unsupported the function was returning
NULL pointer to block actions on the volumes. Therefore, such volumes
were not activated in Incremental and Assembly. As side effect they
also could not be deleted using kill-subarray since "kill" function
requires to obtain a valid mdinfo from container_content.
This patch fixes the kill-subarray problem by allowing to obtain
mdinfo of all volumes types including unsupported and introducing new
array.status flags.
There are following changes:
1. Added MD_SB_BLOCK_VOLUME for blocking an array, other arrays in the
container can be activated.
2. Added MD_SB_BLOCK_CONTAINER_RESHAPE block container wide reshapes
(like changing disk numbers in arrays).
3. IMSM container_content handler is to load mdinfo for all volumes
and set both blocking flags in array.state field in mdinfo of
unsupported volumes. In case of some errors, all volumes can be
affected. Only blocked array is not activated (also reshaped as
result). The container wide reshapes are also blocked since by
metadata definition they require modifications of both arrays.
4. Incremental_container and Assemble functions check array.state and
do not activate volumes with blocking bits set.
5. assemble_container_content is changed to check container wide reshapes
before activating reshapes of assembled containers.
6. Grow_reshape and Grow_continue_command checks blocking bits
before starting reshapes or continueing (-G --continue) reshapes.
7. kill-subarray ignores array.state info and can remove requested array.
Signed-off-by: Marcin Labun <marcin.labun@intel.com>
Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'Incremental.c')
-rw-r--r-- | Incremental.c | 32 |
1 files changed, 23 insertions, 9 deletions
diff --git a/Incremental.c b/Incremental.c index c21c9714..98a3a746 100644 --- a/Incremental.c +++ b/Incremental.c @@ -1446,6 +1446,8 @@ static int Incremental_container(struct supertype *st, char *devname, struct map_ent *smp; int suuid[4]; int sfd; + int ra_blocked = 0; + int ra_all = 0; st->ss->getinfo_super(st, &info, NULL); @@ -1473,21 +1475,26 @@ static int Incremental_container(struct supertype *st, char *devname, trustworthy = FOREIGN; list = st->ss->container_content(st, NULL); - /* do not assemble arrays that might have bad blocks */ - if (list && list->array.state & (1<<MD_SB_BBM_ERRORS)) { - fprintf(stderr, Name ": BBM log found in metadata. " - "Cannot activate array(s).\n"); - /* free container data and exit */ - sysfs_free(list); - return 2; - } - + /* when nothing to activate - quit */ + if (list == NULL) + return 0; + if (map_lock(&map)) + fprintf(stderr, Name ": failed to get exclusive lock on " + "mapfile\n"); for (ra = list ; ra ; ra = ra->next) { int mdfd; char chosen_name[1024]; struct map_ent *mp; struct mddev_ident *match = NULL; + ra_all++; + /* do not activate arrays blocked by metadata handler */ + if (ra->array.state & (1 << MD_SB_BLOCK_VOLUME)) { + fprintf(stderr, Name ": Cannot activate array %s in %s.\n", + ra->text_version, devname); + ra_blocked++; + continue; + } mp = map_by_uuid(&map, ra->uuid); if (mp) { @@ -1566,6 +1573,13 @@ static int Incremental_container(struct supertype *st, char *devname, close(mdfd); } + /* don't move spares to container with volume being activated + when all volumes are blocked */ + if (ra_all == ra_blocked) { + map_unlock(&map); + return 0; + } + /* Now move all suitable spares from spare container */ domains = domain_from_array(list, st->ss->name); memcpy(suuid, uuid_zero, sizeof(int[4])); |