summaryrefslogtreecommitdiff
path: root/Grow.c
diff options
context:
space:
mode:
authorLabun, Marcin <Marcin.Labun@intel.com>2011-10-31 11:29:46 +1100
committerNeilBrown <neilb@suse.de>2011-10-31 11:29:46 +1100
commit81219e70f2a9be7292046860ea15528fe5854cab (patch)
tree6e964755844055702ee3e40385df3853dac9b3cb /Grow.c
parentdb7fdfe422a7d280b1fae999cb72b20b0e58756c (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 'Grow.c')
-rw-r--r--Grow.c75
1 files changed, 75 insertions, 0 deletions
diff --git a/Grow.c b/Grow.c
index 93a69fde..13825a2b 100644
--- a/Grow.c
+++ b/Grow.c
@@ -1357,6 +1357,36 @@ static int reshape_container(char *container, char *devname,
char *backup_file,
int quiet, int restart, int freeze_reshape);
+/*
+ * helper routine to check metadata reshape avalability
+ * 1. Do not "grow" arrays with volume activation blocked
+ * 2. do not reshape containers with container reshape blocked
+ *
+ * IN:
+ * subarray - array name or NULL for container wide reshape
+ * content - md device info from container_content
+ * OUT:
+ * 0 - block reshape
+ */
+static int check_reshape(char *subarray, struct mdinfo *content)
+{
+ char *ep;
+ unsigned int idx;
+
+ if (!subarray) {
+ if (content->array.state & (1<<MD_SB_BLOCK_CONTAINER_RESHAPE))
+ return 0;
+ } else {
+ /* do not "grow" arrays with volume activation blocked */
+ idx = strtoul(subarray, &ep, 10);
+ if (*ep == '\0'
+ && content->container_member == (int) idx
+ && (content->array.state & (1<<MD_SB_BLOCK_VOLUME)))
+ return 0;
+ }
+ return 1;
+}
+
int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
long long size,
int level, char *layout_str, int chunksize, int raid_disks,
@@ -1467,6 +1497,32 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
return 1;
}
+ /* check if operation is supported for metadata handler */
+ if (st->ss->container_content) {
+ struct mdinfo *cc = NULL;
+ struct mdinfo *content = NULL;
+
+ cc = st->ss->container_content(st, subarray);
+ for (content = cc; content ; content = content->next) {
+ int allow_reshape;
+
+ /* check if reshape is allowed based on metadata
+ * indications stored in content.array.status
+ */
+ allow_reshape = check_reshape(subarray, content);
+ if (!allow_reshape) {
+ fprintf(stderr, Name
+ " cannot reshape arrays in"
+ " container with unsupported"
+ " metadata: %s(%s)\n",
+ devname, container_buf);
+ sysfs_free(cc);
+ free(subarray);
+ return 1;
+ }
+ }
+ sysfs_free(cc);
+ }
if (mdmon_running(container_dev))
st->update_tail = &st->updates;
}
@@ -3723,9 +3779,28 @@ int Grow_continue_command(char *devname, int fd,
cc = st->ss->container_content(st, NULL);
for (content = cc; content ; content = content->next) {
char *array;
+ int allow_reshape;
if (content->reshape_active == 0)
continue;
+ /* The decision about array or container wide
+ * reshape is taken in Grow_continue based
+ * content->reshape_active state, therefore we
+ * need to check_reshape based on
+ * reshape_active and subarray name
+ */
+ allow_reshape =
+ check_reshape((content->reshape_active == CONTAINER_RESHAPE)? NULL : subarray,
+ content);
+ if (!allow_reshape) {
+ fprintf(stderr, Name
+ ": cannot continue reshape of an array"
+ " in container with unsupported"
+ " metadata: %s(%s)\n",
+ devname, buf);
+ ret_val = 1;
+ goto Grow_continue_command_exit;
+ }
array = strchr(content->text_version+1, '/')+1;
mdstat = mdstat_by_subdev(array, container_dev);