[PATCH 0/6] Add raid0<->raid10 takeover support for imsm metadata
[PATCH 0/6] Add raid0<->raid10 takeover support for imsm metadata
am 13.01.2011 16:32:18 von krzysztof.wojcik
The following series implements raid0<->raid10 takeover support
for imsm metadata format.
It contains also some fixes for generic takeover flow.
---
Krzysztof Wojcik (6):
Define imsm_analyze_change function
Set reshape.after.data_disks for raid0<->raid10 takeover
Unfreeze for non re-striping transitions
Add raid10 -> raid0 takeover support
raid0->raid10 takeover- create metadata update
raid0->raid10 takeover- allocate memory for added disks
Grow.c | 5 +
super-intel.c | 289 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 282 insertions(+), 12 deletions(-)
--
Krzyszto Wojcik
--
To unsubscribe from this list: send the line "unsubscribe linux-raid" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/6] Unfreeze for non re-striping transitions
am 13.01.2011 16:32:44 von krzysztof.wojcik
For non re-striping transitions array must be unfrozen
before end of processing.
Signed-off-by: Krzysztof Wojcik
---
Grow.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/Grow.c b/Grow.c
index 47a8fb8..c0f9419 100644
--- a/Grow.c
+++ b/Grow.c
@@ -1751,7 +1751,7 @@ static int reshape_array(char *container, int cfd, int fd, char *devname,
printf("chunk size for %s set to %d\n",
devname, info->array.chunk_size);
}
-
+ unfreeze(st);
return rv;
}
--
To unsubscribe from this list: send the line "unsubscribe linux-raid" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 4/6] Add raid10 -> raid0 takeover support
am 13.01.2011 16:32:52 von krzysztof.wojcik
The patch introduces takeover form level 10 to level 0 for imsm
metadata. This patch contains procedures connected with preparing
and applying metadata update during 10 -> 0 takeover.
When performing takeover 10->0 mdmon should update the external
metadata (due to disk slot and level changes).
To achieve that mdadm calls reshape_super() and prepare
the "update_takeover" metadata update type.
Prepared update is processed by mdmon in process_update().
Signed-off-by: Krzysztof Wojcik
---
Grow.c | 1
super-intel.c | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 126 insertions(+), 1 deletions(-)
diff --git a/Grow.c b/Grow.c
index c0f9419..e1ec01c 100644
--- a/Grow.c
+++ b/Grow.c
@@ -1463,6 +1463,7 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
rv = 1;
goto release;
}
+ ping_monitor(container);
}
info.array = array;
diff --git a/super-intel.c b/super-intel.c
index c12ba74..7d2d777 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -299,6 +299,7 @@ enum imsm_update_type {
update_rename_array,
update_add_remove_disk,
update_reshape_container_disks,
+ update_takeover
};
struct imsm_update_activate_spare {
@@ -319,6 +320,17 @@ struct geo_params {
int raid_disks;
};
+#define TAKEOVER_DISKS 2
+enum takeover_direction {
+ R10_TO_R0,
+ R0_TO_R10
+};
+struct imsm_update_takeover {
+ enum imsm_update_type type;
+ int subarray;
+ enum takeover_direction direction;
+ int disks[TAKEOVER_DISKS];
+};
struct imsm_update_reshape {
enum imsm_update_type type;
@@ -5793,6 +5805,56 @@ update_reshape_exit:
return ret_val;
}
+static int apply_takeover_update(struct imsm_update_takeover *u,
+ struct intel_super *super)
+{
+ struct imsm_dev *dev = NULL;
+ struct imsm_map *map;
+ struct dl *dm, *du;
+ int *tab;
+ int i;
+
+ dev = get_imsm_dev(super, u->subarray);
+
+ if (dev == NULL)
+ return 0;
+
+ map = get_imsm_map(dev, 0);
+ tab = (int *)&map->disk_ord_tbl;
+
+ if (u->direction == R10_TO_R0) {
+ /* iterate through devices to mark removed disks as spare */
+ for (i = 0; i < TAKEOVER_DISKS; i++) {
+ for (dm = super->disks; dm; dm = dm->next) {
+ if (((unsigned int)dm->major != major(u->disks[i])) ||
+ ((unsigned int)dm->minor != minor(u->disks[i])))
+ continue;
+ for (du = super->disks; du; du = du->next)
+ if ((du->index > dm->index) && (du->index > 0))
+ du->index--;
+ dm->disk.status = SPARE_DISK;
+ dm->index = -1;
+ }
+ }
+ /* update disk order table */
+ i = 0;
+ for (du = super->disks; du; du = du->next) {
+ if (du->index >= 0) {
+ tab[du->index] = i;
+ i++;
+ }
+ }
+ /* update map */
+ map->num_members = 2;
+ map->map_state = IMSM_T_STATE_NORMAL;
+ map->num_domains = 1;
+ map->raid_level = 0;
+ map->failed_disk_num = -1;
+ }
+
+ return 1;
+}
+
static void imsm_process_update(struct supertype *st,
struct metadata_update *update)
{
@@ -5835,6 +5897,13 @@ static void imsm_process_update(struct supertype *st,
mpb = super->anchor;
switch (type) {
+ case update_takeover: {
+ struct imsm_update_takeover *u = (void *)update->buf;
+ if (apply_takeover_update(u, super))
+ super->updates_pending++;
+ break;
+ }
+
case update_reshape_container_disks: {
struct imsm_update_reshape *u = (void *)update->buf;
if (apply_reshape_container_disks_update(
@@ -6682,6 +6751,61 @@ analyse_change_exit:
return change;
}
+int imsm_takeover(struct supertype *st, struct geo_params *geo)
+{
+ struct intel_super *super = st->sb;
+ struct imsm_update_takeover *u;
+ struct mdinfo *info;
+ struct mdinfo *newdi;
+ struct dl *dl;
+ int i, fd;
+ int found = 0;
+ char buf[PATH_MAX];
+
+ sprintf(buf, "/dev/md%i", geo->dev_id);
+ fd = open(buf, O_RDONLY);
+ if (!fd) {
+ fprintf(stderr, Name "Cannot open %s", buf);
+ return 1;
+ }
+ info = sysfs_read(fd, 0, GET_LEVEL|GET_VERSION|GET_DEVS|GET_STATE);
+ if (!info) {
+ fprintf(stderr, Name "Cannot load sysfs information for %s (%i)",
+ geo->dev_name, geo->dev_id);
+ return 1;
+ }
+
+ u = malloc(sizeof(struct imsm_update_takeover));
+ if (u == NULL)
+ return 1;
+
+ u->type = update_takeover;
+ u->subarray = super->current_vol;
+
+ /* 10->0 transition - mark disks to remove */
+ if (geo->level == 0) {
+ u->direction = R10_TO_R0;
+ i = 0;
+ for (dl = super->disks; dl; dl = dl->next) {
+ found = 0;
+ for (newdi = info->devs; newdi; newdi = newdi->next) {
+ if ((dl->major != newdi->disk.major) ||
+ (dl->minor != newdi->disk.minor) ||
+ (newdi->disk.raid_disk < 0))
+ continue;
+ found = 1;
+ break;
+ }
+ /* if disk not found, mark it for remove */
+ if ((found == 0) && (!(dl->disk.status & SPARE_DISK)))
+ u->disks[i++] = makedev(dl->major, dl->minor);
+ }
+ }
+
+ append_metadata_update(st, u, sizeof(struct imsm_update_takeover));
+ return 0;
+}
+
static int imsm_reshape_super(struct supertype *st, long long size, int level,
int layout, int chunksize, int raid_disks,
char *backup, char *dev, int verbose)
@@ -6763,7 +6887,7 @@ static int imsm_reshape_super(struct supertype *st, long long size, int level,
change = imsm_analyze_change(st, &geo);
switch (change) {
case CH_TAKEOVER:
- ret_val = 0;
+ ret_val = imsm_takeover(st, &geo);
break;
case CH_CHUNK_MIGR:
ret_val = 0;
--
To unsubscribe from this list: send the line "unsubscribe linux-raid" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 5/6] raid0->raid10 takeover- create metadata update
am 13.01.2011 16:33:00 von krzysztof.wojcik
Create metadata update for raid0 -> raid10 takeover.
Because we have no mdmon running for raid0 we have to
update metadata using local update mechanism
Signed-off-by: Krzysztof Wojcik
---
super-intel.c | 14 +++++++++++++-
1 files changed, 13 insertions(+), 1 deletions(-)
diff --git a/super-intel.c b/super-intel.c
index 7d2d777..63bd2d2 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -6802,7 +6802,19 @@ int imsm_takeover(struct supertype *st, struct geo_params *geo)
}
}
- append_metadata_update(st, u, sizeof(struct imsm_update_takeover));
+ /* 0->10 transition- nothing to do here
+ * all work will be done in prepare_update, process_update */
+ if (geo->level == 10)
+ u->direction = R0_TO_R10;
+
+ /* update metadata locally */
+ imsm_update_metadata_locally(st, u, sizeof(struct imsm_update_takeover));
+ /* and possibly remotely */
+ if (st->update_tail)
+ append_metadata_update(st, u, sizeof(struct imsm_update_takeover));
+ else
+ free(u);
+
return 0;
}
--
To unsubscribe from this list: send the line "unsubscribe linux-raid" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 6/6] raid0->raid10 takeover- allocate memory for added disks
am 13.01.2011 16:33:09 von krzysztof.wojcik
Allocate memory necessary to add new dummy disks
in process_update.
Signed-off-by: Krzysztof Wojcik
---
super-intel.c | 18 ++++++++++++++++++
1 files changed, 18 insertions(+), 0 deletions(-)
diff --git a/super-intel.c b/super-intel.c
index 63bd2d2..a7d7d08 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -6224,6 +6224,24 @@ static void imsm_prepare_update(struct supertype *st,
size_t len = 0;
switch (type) {
+ case update_takeover: {
+ struct imsm_update_takeover *u = (void *)update->buf;
+ if (u->direction == R0_TO_R10) {
+ void **tail = (void**)&update->space_list;
+ void *space;
+ int size = sizeof_imsm_dev(super->devlist->dev, 0) +
+ (TAKEOVER_DISKS * sizeof(__u32));
+ space = malloc(size);
+ if (!space)
+ break;
+ *tail = space;
+ tail = space;
+ *tail = NULL;
+
+ len = disks_to_mpb_size(TAKEOVER_DISKS * 2);
+ }
+ break;
+ }
case update_reshape_container_disks: {
/* Every raid device in the container is about to
* gain some more devices, and we will enter a
--
To unsubscribe from this list: send the line "unsubscribe linux-raid" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/6] Define imsm_analyze_change function
am 17.01.2011 03:02:51 von NeilBrown
On Thu, 13 Jan 2011 16:32:27 +0100 Krzysztof Wojcik
wrote:
> Function intended to use for single volume migration.
> Function analyze transition and validate if it is supported.
>
> Signed-off-by: Krzysztof Wojcik
Applied, thanks.
Though I reformatted it a bit.
NeilBrown
> ---
> super-intel.c | 135 ++++++++++++++++++++++++++++++++++++++++++++++++++++-----
> 1 files changed, 124 insertions(+), 11 deletions(-)
>
> diff --git a/super-intel.c b/super-intel.c
> index 4cbb070..c12ba74 100644
> --- a/super-intel.c
> +++ b/super-intel.c
> @@ -6576,16 +6576,110 @@ static void imsm_update_metadata_locally(struct supertype *st,
> }
> }
>
> -/********************************************************** *********************
> +/********************************************************** *****************
> * Function: imsm_analyze_change
> -* Description: Function analyze and validate change for single volume migration
> +* Description: Function analyze change for single volume
> +* and validate if transition is supported
> * Parameters: Geometry parameters, supertype structure
> * Returns: Operation type code on success, -1 if fail
> -*********************************************************** *********************/
> -enum imsm_reshape_type imsm_analyze_change(
> - struct supertype *st, struct geo_params *geo)
> +*********************************************************** *****************/
> +enum imsm_reshape_type imsm_analyze_change(struct supertype *st,
> + struct geo_params *geo)
> {
> - return -1;
> + struct mdinfo info;
> + int change = -1;
> + int check_devs = 0;
> +
> + getinfo_super_imsm_volume(st, &info, NULL);
> +
> + if ((geo->level != info.array.level) &&
> + (geo->level >= 0) &&
> + (geo->level != UnSet)) {
> + switch (info.array.level) {
> + case 0:
> + if (geo->level == 5) {
> + change = CH_LEVEL_MIGRATION;
> + check_devs = 1;
> + }
> + if (geo->level == 10) {
> + change = CH_TAKEOVER;
> + check_devs = 1;
> + }
> + break;
> + case 5:
> + if (geo->level != 0)
> + change = CH_LEVEL_MIGRATION;
> + break;
> + case 10:
> + if (geo->level == 0) {
> + change = CH_TAKEOVER;
> + check_devs = 1;
> + }
> + break;
> + }
> + if (change == -1) {
> + fprintf(stderr, Name " Error. Level Migration from %d to %d "\
> + "not supported!\n", info.array.level, geo->level);
> + goto analyse_change_exit;
> + }
> + } else {
> + geo->level = info.array.level;
> + }
> +
> + if ((geo->layout != info.array.layout)
> + && ((geo->layout != UnSet) && (geo->layout != -1))) {
> + change = CH_LEVEL_MIGRATION;
> + if ((info.array.layout == 0) && (info.array.level == 5)
> + && (geo->layout == 5)) {
> + /* reshape 5 -> 4 */
> + } else if ((info.array.layout == 5)
> + && (info.array.level == 5)
> + && (geo->layout == 0)) {
> + /* reshape 4 -> 5 */
> + geo->layout = 0;
> + geo->level = 5;
> + } else {
> + fprintf(stderr, Name " Error. Layout Migration from %d to %d "\
> + "not supported!\n", info.array.layout, geo->layout);
> + change = -1;
> + goto analyse_change_exit;
> + }
> + } else {
> + geo->layout = info.array.layout;
> + }
> +
> + if ((geo->chunksize > 0) && (geo->chunksize != UnSet)
> + && (geo->chunksize != info.array.chunk_size)) {
> + change = CH_CHUNK_MIGR;
> + } else {
> + geo->chunksize = info.array.chunk_size;
> + }
> +
> + if (!validate_geometry_imsm(st,
> + geo->level,
> + geo->layout,
> + geo->raid_disks,
> + (geo->chunksize / 1024),
> + geo->size,
> + 0, 0, 1))
> + change = -1;
> +
> + if (check_devs) {
> + struct intel_super *super = st->sb;
> + struct imsm_super *mpb = super->anchor;
> +
> + if (mpb->num_raid_devs > 1) {
> + fprintf(stderr, Name " Error. Cannot perform operation on %s"\
> + "- for this operation it MUST be single "\
> + "array in container\n",
> + geo->dev_name);
> + change = -1;
> + }
> + }
> +
> +analyse_change_exit:
> +
> + return change;
> }
>
> static int imsm_reshape_super(struct supertype *st, long long size, int level,
> @@ -6649,18 +6743,37 @@ static int imsm_reshape_super(struct supertype *st, long long size, int level,
> * - chunk size migration
> * - migration: raid5 -> raid0; raid0 -> raid5
> */
> - int change;
> + struct intel_super *super = st->sb;
> + struct intel_dev *dev = super->devlist;
> + int change, devnum;
> dprintf("imsm: info: Volume operation\n");
> + /* find requested device */
> + while (dev) {
> + imsm_find_array_minor_by_subdev(dev->index, st->container_dev, &devnum);
> + if (devnum == geo.dev_id)
> + break;
> + dev = dev->next;
> + }
> + if (dev == NULL) {
> + fprintf(stderr, Name " Cannot find %s (%i) subarray\n",
> + geo.dev_name, geo.dev_id);
> + goto exit_imsm_reshape_super;
> + }
> + super->current_vol = dev->index;
> change = imsm_analyze_change(st, &geo);
> switch (change) {
> case CH_TAKEOVER:
> - break;
> + ret_val = 0;
> + break;
> case CH_CHUNK_MIGR:
> - break;
> + ret_val = 0;
> + break;
> case CH_LEVEL_MIGRATION:
> - break;
> + ret_val = 0;
> + break;
> + default:
> + ret_val = 1;
> }
> - ret_val = 0;
> }
>
> exit_imsm_reshape_super:
--
To unsubscribe from this list: send the line "unsubscribe linux-raid" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/6] Set reshape.after.data_disks for raid0<->raid10takeover
am 17.01.2011 03:03:05 von NeilBrown
On Thu, 13 Jan 2011 16:32:35 +0100 Krzysztof Wojcik
wrote:
> reshape.after.data_disks field must be initiated
> for raid0<->rai10 transition.
> Instead calculated spares_needed variable in reshape_array
> function has random value.
>
> Signed-off-by: Krzysztof Wojcik
> ---
> Grow.c | 2 ++
> 1 files changed, 2 insertions(+), 0 deletions(-)
>
> diff --git a/Grow.c b/Grow.c
> index 763287b..47a8fb8 100644
> --- a/Grow.c
> +++ b/Grow.c
> @@ -966,6 +966,7 @@ char *analyse_change(struct mdinfo *info, struct reshape *re)
> re->level = 0;
> re->parity = 0;
> re->before.data_disks = new_disks;
> + re->after.data_disks = re->before.data_disks;
> re->before.layout = 0;
> re->backup_blocks = 0;
> return NULL;
> @@ -1003,6 +1004,7 @@ char *analyse_change(struct mdinfo *info, struct reshape *re)
> re->parity = 0;
> re->before.data_disks = (info->array.raid_disks +
> info->delta_disks);
> + re->after.data_disks = re->before.data_disks;
> re->before.layout = info->new_layout;
> re->backup_blocks = 0;
> return NULL;
apply, thanks.
NeilBrown
--
To unsubscribe from this list: send the line "unsubscribe linux-raid" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 3/6] Unfreeze for non re-striping transitions
am 17.01.2011 03:04:08 von NeilBrown
On Thu, 13 Jan 2011 16:32:44 +0100 Krzysztof Wojcik
wrote:
> For non re-striping transitions array must be unfrozen
> before end of processing.
>
> Signed-off-by: Krzysztof Wojcik
> ---
> Grow.c | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/Grow.c b/Grow.c
> index 47a8fb8..c0f9419 100644
> --- a/Grow.c
> +++ b/Grow.c
> @@ -1751,7 +1751,7 @@ static int reshape_array(char *container, int cfd, int fd, char *devname,
> printf("chunk size for %s set to %d\n",
> devname, info->array.chunk_size);
> }
> -
> + unfreeze(st);
> return rv;
> }
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-raid" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
I already had an unfreeze in there, condition on 'forked', how I think yours
is more correct - I don't want the condition there.
Applied thanks,
NeilBrown
--
To unsubscribe from this list: send the line "unsubscribe linux-raid" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 4/6] Add raid10 -> raid0 takeover support
am 17.01.2011 03:06:38 von NeilBrown
On Thu, 13 Jan 2011 16:32:52 +0100 Krzysztof Wojcik
wrote:
> The patch introduces takeover form level 10 to level 0 for imsm
> metadata. This patch contains procedures connected with preparing
> and applying metadata update during 10 -> 0 takeover.
> When performing takeover 10->0 mdmon should update the external
> metadata (due to disk slot and level changes).
> To achieve that mdadm calls reshape_super() and prepare
> the "update_takeover" metadata update type.
> Prepared update is processed by mdmon in process_update().
You are using sysfs_read inside super-intel again. That is the wrong thing
to do for the same reasons as last time.
And I'm not very comfortable about sending a list of devices to delete from
mdadm to mdmon.
I would think that mdadm would simply fail/remove the devices from the array,
then tell mdmon to update the metadata. It would see which ones are still
working and construct the RAID0 out of those.
NeilBrown
>
> Signed-off-by: Krzysztof Wojcik
> ---
> Grow.c | 1
> super-intel.c | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 126 insertions(+), 1 deletions(-)
>
> diff --git a/Grow.c b/Grow.c
> index c0f9419..e1ec01c 100644
> --- a/Grow.c
> +++ b/Grow.c
> @@ -1463,6 +1463,7 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
> rv = 1;
> goto release;
> }
> + ping_monitor(container);
> }
>
> info.array = array;
> diff --git a/super-intel.c b/super-intel.c
> index c12ba74..7d2d777 100644
> --- a/super-intel.c
> +++ b/super-intel.c
> @@ -299,6 +299,7 @@ enum imsm_update_type {
> update_rename_array,
> update_add_remove_disk,
> update_reshape_container_disks,
> + update_takeover
> };
>
> struct imsm_update_activate_spare {
> @@ -319,6 +320,17 @@ struct geo_params {
> int raid_disks;
> };
>
> +#define TAKEOVER_DISKS 2
> +enum takeover_direction {
> + R10_TO_R0,
> + R0_TO_R10
> +};
> +struct imsm_update_takeover {
> + enum imsm_update_type type;
> + int subarray;
> + enum takeover_direction direction;
> + int disks[TAKEOVER_DISKS];
> +};
>
> struct imsm_update_reshape {
> enum imsm_update_type type;
> @@ -5793,6 +5805,56 @@ update_reshape_exit:
> return ret_val;
> }
>
> +static int apply_takeover_update(struct imsm_update_takeover *u,
> + struct intel_super *super)
> +{
> + struct imsm_dev *dev = NULL;
> + struct imsm_map *map;
> + struct dl *dm, *du;
> + int *tab;
> + int i;
> +
> + dev = get_imsm_dev(super, u->subarray);
> +
> + if (dev == NULL)
> + return 0;
> +
> + map = get_imsm_map(dev, 0);
> + tab = (int *)&map->disk_ord_tbl;
> +
> + if (u->direction == R10_TO_R0) {
> + /* iterate through devices to mark removed disks as spare */
> + for (i = 0; i < TAKEOVER_DISKS; i++) {
> + for (dm = super->disks; dm; dm = dm->next) {
> + if (((unsigned int)dm->major != major(u->disks[i])) ||
> + ((unsigned int)dm->minor != minor(u->disks[i])))
> + continue;
> + for (du = super->disks; du; du = du->next)
> + if ((du->index > dm->index) && (du->index > 0))
> + du->index--;
> + dm->disk.status = SPARE_DISK;
> + dm->index = -1;
> + }
> + }
> + /* update disk order table */
> + i = 0;
> + for (du = super->disks; du; du = du->next) {
> + if (du->index >= 0) {
> + tab[du->index] = i;
> + i++;
> + }
> + }
> + /* update map */
> + map->num_members = 2;
> + map->map_state = IMSM_T_STATE_NORMAL;
> + map->num_domains = 1;
> + map->raid_level = 0;
> + map->failed_disk_num = -1;
> + }
> +
> + return 1;
> +}
> +
> static void imsm_process_update(struct supertype *st,
> struct metadata_update *update)
> {
> @@ -5835,6 +5897,13 @@ static void imsm_process_update(struct supertype *st,
> mpb = super->anchor;
>
> switch (type) {
> + case update_takeover: {
> + struct imsm_update_takeover *u = (void *)update->buf;
> + if (apply_takeover_update(u, super))
> + super->updates_pending++;
> + break;
> + }
> +
> case update_reshape_container_disks: {
> struct imsm_update_reshape *u = (void *)update->buf;
> if (apply_reshape_container_disks_update(
> @@ -6682,6 +6751,61 @@ analyse_change_exit:
> return change;
> }
>
> +int imsm_takeover(struct supertype *st, struct geo_params *geo)
> +{
> + struct intel_super *super = st->sb;
> + struct imsm_update_takeover *u;
> + struct mdinfo *info;
> + struct mdinfo *newdi;
> + struct dl *dl;
> + int i, fd;
> + int found = 0;
> + char buf[PATH_MAX];
> +
> + sprintf(buf, "/dev/md%i", geo->dev_id);
> + fd = open(buf, O_RDONLY);
> + if (!fd) {
> + fprintf(stderr, Name "Cannot open %s", buf);
> + return 1;
> + }
> + info = sysfs_read(fd, 0, GET_LEVEL|GET_VERSION|GET_DEVS|GET_STATE);
> + if (!info) {
> + fprintf(stderr, Name "Cannot load sysfs information for %s (%i)",
> + geo->dev_name, geo->dev_id);
> + return 1;
> + }
> +
> + u = malloc(sizeof(struct imsm_update_takeover));
> + if (u == NULL)
> + return 1;
> +
> + u->type = update_takeover;
> + u->subarray = super->current_vol;
> +
> + /* 10->0 transition - mark disks to remove */
> + if (geo->level == 0) {
> + u->direction = R10_TO_R0;
> + i = 0;
> + for (dl = super->disks; dl; dl = dl->next) {
> + found = 0;
> + for (newdi = info->devs; newdi; newdi = newdi->next) {
> + if ((dl->major != newdi->disk.major) ||
> + (dl->minor != newdi->disk.minor) ||
> + (newdi->disk.raid_disk < 0))
> + continue;
> + found = 1;
> + break;
> + }
> + /* if disk not found, mark it for remove */
> + if ((found == 0) && (!(dl->disk.status & SPARE_DISK)))
> + u->disks[i++] = makedev(dl->major, dl->minor);
> + }
> + }
> +
> + append_metadata_update(st, u, sizeof(struct imsm_update_takeover));
> + return 0;
> +}
> +
> static int imsm_reshape_super(struct supertype *st, long long size, int level,
> int layout, int chunksize, int raid_disks,
> char *backup, char *dev, int verbose)
> @@ -6763,7 +6887,7 @@ static int imsm_reshape_super(struct supertype *st, long long size, int level,
> change = imsm_analyze_change(st, &geo);
> switch (change) {
> case CH_TAKEOVER:
> - ret_val = 0;
> + ret_val = imsm_takeover(st, &geo);
> break;
> case CH_CHUNK_MIGR:
> ret_val = 0;
--
To unsubscribe from this list: send the line "unsubscribe linux-raid" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html