All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] raid0<->raid10 takeover for imsm metadata
@ 2011-01-17 15:42 Krzysztof Wojcik
  2011-01-17 15:42 ` [PATCH 1/4] Add raid10 -> raid0 takeover support Krzysztof Wojcik
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ messages in thread
From: Krzysztof Wojcik @ 2011-01-17 15:42 UTC (permalink / raw)
  To: neilb
  Cc: linux-raid, wojciech.neubauer, adam.kwolek, dan.j.williams,
	ed.ciechanowski

The following series implements raid0 <-> raid10 takeover support
for imsm metadata format.
It includes corrections according last code review notes.

---

Krzysztof Wojcik (4):
      Add raid10 -> raid0 takeover support
      raid0->raid10 takeover- create metadata update
      raid0->raid10 takeover- allocate memory for added disks
      raid0->raid10 takeover- process metadata update


 Grow.c        |    1 
 super-intel.c |  201 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 201 insertions(+), 1 deletions(-)

-- 
Krzysztof Wojcik

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/4] Add raid10 -> raid0 takeover support
  2011-01-17 15:42 [PATCH 0/4] raid0<->raid10 takeover for imsm metadata Krzysztof Wojcik
@ 2011-01-17 15:42 ` Krzysztof Wojcik
  2011-01-26  0:58   ` Neil Brown
  2011-01-17 15:42 ` [PATCH 2/4] raid0->raid10 takeover- create metadata update Krzysztof Wojcik
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 8+ messages in thread
From: Krzysztof Wojcik @ 2011-01-17 15:42 UTC (permalink / raw)
  To: neilb
  Cc: linux-raid, wojciech.neubauer, adam.kwolek, dan.j.williams,
	ed.ciechanowski

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 <krzysztof.wojcik@intel.com>
---
 Grow.c        |    1 +
 super-intel.c |   98 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 98 insertions(+), 1 deletions(-)

diff --git a/Grow.c b/Grow.c
index ad13d6e..c4125ea 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 334e0f4..86b365d 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,15 @@ struct geo_params {
 	int raid_disks;
 };
 
+enum takeover_direction {
+	R10_TO_R0,
+	R0_TO_R10
+};
+struct imsm_update_takeover {
+	enum imsm_update_type type;
+	int subarray;
+	enum takeover_direction direction;
+};
 
 struct imsm_update_reshape {
 	enum imsm_update_type type;
@@ -5802,6 +5812,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;
+	struct intel_dev *dv;
+
+	for (dv = super->devlist; dv; dv = dv->next)
+		if (dv->index == (unsigned int)u->subarray) {
+			dev = dv->dev;
+			break;
+	}
+
+	if (dev == NULL)
+		return 0;
+
+	map = get_imsm_map(dev, 0);
+
+	if (u->direction == R10_TO_R0) {
+		/* iterate through devices to mark removed disks as spare */
+		for (dm = super->disks; dm; dm = dm->next) {
+			if (dm->disk.status & FAILED_DISK) {
+				int idx = dm->index;
+				/* update indexes on the disk list */
+				for (du = super->disks; du; du = du->next)
+					if (du->index > idx)
+						du->index--;
+				/* mark as spare disk */
+				dm->disk.status = SPARE_DISK;
+				dm->index = -1;
+			}
+		}
+
+		/* update map */
+		map->num_members = map->num_members / 2;
+		map->map_state = IMSM_T_STATE_NORMAL;
+		map->num_domains = 1;
+		map->raid_level = 0;
+		map->failed_disk_num = -1;
+	}
+
+	/* update disk order table */
+	for (du = super->disks; du; du = du->next)
+		if (du->index >= 0)
+			set_imsm_ord_tbl_ent(map, du->index, du->index);
+
+	return 1;
+}
+
 static void imsm_process_update(struct supertype *st,
 			        struct metadata_update *update)
 {
@@ -5844,6 +5904,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(
@@ -6691,6 +6758,35 @@ 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;
+
+	u = malloc(sizeof(struct imsm_update_takeover));
+	if (u == NULL)
+		return 1;
+
+	u->type = update_takeover;
+	u->subarray = super->current_vol;
+
+	/* 10->0 transition */
+	if (geo->level == 0)
+		u->direction = R10_TO_R0;
+
+	/* 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;
+}
+
 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)
@@ -6772,7 +6868,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;


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 2/4] raid0->raid10 takeover- create metadata update
  2011-01-17 15:42 [PATCH 0/4] raid0<->raid10 takeover for imsm metadata Krzysztof Wojcik
  2011-01-17 15:42 ` [PATCH 1/4] Add raid10 -> raid0 takeover support Krzysztof Wojcik
@ 2011-01-17 15:42 ` Krzysztof Wojcik
  2011-01-17 15:43 ` [PATCH 3/4] raid0->raid10 takeover- allocate memory for added disks Krzysztof Wojcik
  2011-01-17 15:43 ` [PATCH 4/4] raid0->raid10 takeover- process metadata update Krzysztof Wojcik
  3 siblings, 0 replies; 8+ messages in thread
From: Krzysztof Wojcik @ 2011-01-17 15:42 UTC (permalink / raw)
  To: neilb
  Cc: linux-raid, wojciech.neubauer, adam.kwolek, dan.j.williams,
	ed.ciechanowski

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 <krzysztof.wojcik@intel.com>
---
 super-intel.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/super-intel.c b/super-intel.c
index 86b365d..3ba9962 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -6774,6 +6774,10 @@ int imsm_takeover(struct supertype *st, struct geo_params *geo)
 	if (geo->level == 0)
 		u->direction = R10_TO_R0;
 
+	/* 0->10 transition */
+	if (geo->level == 10)
+		u->direction = R0_TO_R10;
+
 	/* update metadata locally */
 	imsm_update_metadata_locally(st, u,
 					sizeof(struct imsm_update_takeover));


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 3/4] raid0->raid10 takeover- allocate memory for added disks
  2011-01-17 15:42 [PATCH 0/4] raid0<->raid10 takeover for imsm metadata Krzysztof Wojcik
  2011-01-17 15:42 ` [PATCH 1/4] Add raid10 -> raid0 takeover support Krzysztof Wojcik
  2011-01-17 15:42 ` [PATCH 2/4] raid0->raid10 takeover- create metadata update Krzysztof Wojcik
@ 2011-01-17 15:43 ` Krzysztof Wojcik
  2011-01-17 15:43 ` [PATCH 4/4] raid0->raid10 takeover- process metadata update Krzysztof Wojcik
  3 siblings, 0 replies; 8+ messages in thread
From: Krzysztof Wojcik @ 2011-01-17 15:43 UTC (permalink / raw)
  To: neilb
  Cc: linux-raid, wojciech.neubauer, adam.kwolek, dan.j.williams,
	ed.ciechanowski

Allocate memory will be used in process_update.
For raid0->raid10 takeover operation number of disks doubles
so we should allocate memory for additional disks
and one imsm_dev structure with extended order table.

Signed-off-by: Krzysztof Wojcik <krzysztof.wojcik@intel.com>
---
 super-intel.c |   48 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 48 insertions(+), 0 deletions(-)

diff --git a/super-intel.c b/super-intel.c
index 3ba9962..3b2a273 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -6231,6 +6231,54 @@ 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;
+			struct imsm_dev *dev = get_imsm_dev(super, u->subarray);
+			struct imsm_map *map = get_imsm_map(dev, 0);
+			int num_members = map->num_members;
+			void *space;
+			int size, i;
+			int err = 0;
+			/* allocate memory for added disks */
+			for (i = 0; i < num_members; i++) {
+				size = sizeof(struct dl);
+				space = malloc(size);
+				if (!space) {
+					err++;
+					goto update_takeover_exit;
+				}
+				*tail = space;
+				tail = space;
+				*tail = NULL;
+			}
+			/* allocate memory for new device */
+			size = sizeof_imsm_dev(super->devlist->dev, 0) +
+				(num_members * sizeof(__u32));
+			space = malloc(size);
+			if (!space) {
+				err++;
+				goto update_takeover_exit;
+			}
+			*tail = space;
+			tail = space;
+			*tail = NULL;
+update_takeover_exit:
+			if (!err) {
+				len = disks_to_mpb_size(num_members * 2);
+			} else {
+				/* if allocation didn't success, free buffer */
+				while (update->space_list) {
+					void **sp = update->space_list;
+					update->space_list = *sp;
+					free(sp);
+				}
+			}
+		}
+
+		break;
+	}
 	case update_reshape_container_disks: {
 		/* Every raid device in the container is about to
 		 * gain some more devices, and we will enter a


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 4/4] raid0->raid10 takeover- process metadata update
  2011-01-17 15:42 [PATCH 0/4] raid0<->raid10 takeover for imsm metadata Krzysztof Wojcik
                   ` (2 preceding siblings ...)
  2011-01-17 15:43 ` [PATCH 3/4] raid0->raid10 takeover- allocate memory for added disks Krzysztof Wojcik
@ 2011-01-17 15:43 ` Krzysztof Wojcik
  3 siblings, 0 replies; 8+ messages in thread
From: Krzysztof Wojcik @ 2011-01-17 15:43 UTC (permalink / raw)
  To: neilb
  Cc: linux-raid, wojciech.neubauer, adam.kwolek, dan.j.williams,
	ed.ciechanowski

Implementation of raid0->raid10 takeover metadata update
at process_update level.
- We are using memory prievously alocated in prepare_update to
create two dummy disks will be inserted in the metadata and
new imsm_dev structure with expanded disk order table.
- Update indexes in disk list
- Update metadata map
- Update disk order table

Signed-off-by: Krzysztof Wojcik <krzysztof.wojcik@intel.com>
---
 super-intel.c |   59 +++++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 55 insertions(+), 4 deletions(-)

diff --git a/super-intel.c b/super-intel.c
index 3b2a273..e284a4a 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -5813,12 +5813,15 @@ update_reshape_exit:
 }
 
 static int apply_takeover_update(struct imsm_update_takeover *u,
-				struct intel_super *super)
+				struct intel_super *super,
+				void ***space_list)
 {
 	struct imsm_dev *dev = NULL;
+	struct intel_dev *dv;
+	struct imsm_dev *dev_new;
 	struct imsm_map *map;
 	struct dl *dm, *du;
-	struct intel_dev *dv;
+	int i;
 
 	for (dv = super->devlist; dv; dv = dv->next)
 		if (dv->index == (unsigned int)u->subarray) {
@@ -5845,7 +5848,6 @@ static int apply_takeover_update(struct imsm_update_takeover *u,
 				dm->index = -1;
 			}
 		}
-
 		/* update map */
 		map->num_members = map->num_members / 2;
 		map->map_state = IMSM_T_STATE_NORMAL;
@@ -5854,10 +5856,59 @@ static int apply_takeover_update(struct imsm_update_takeover *u,
 		map->failed_disk_num = -1;
 	}
 
+	if (u->direction == R0_TO_R10) {
+		void **space;
+		/* update slots in current disk list */
+		for (dm = super->disks; dm; dm = dm->next) {
+			if (dm->index >= 0)
+				dm->index *= 2;
+		}
+		/* create new *missing* disks */
+		for (i = 0; i < map->num_members; i++) {
+			space = *space_list;
+			if (!space)
+				continue;
+			*space_list = *space;
+			du = (void *)space;
+			memcpy(du, super->disks, sizeof(*du));
+			du->disk.status = FAILED_DISK;
+			du->disk.scsi_id = 0;
+			du->fd = -1;
+			du->minor = 0;
+			du->major = 0;
+			du->index = (i * 2) + 1;
+			sprintf((char *)du->disk.serial,
+				" MISSING_%d", du->index);
+			sprintf((char *)du->serial,
+				"MISSING_%d", du->index);
+			du->next = super->missing;
+			super->missing = du;
+		}
+		/* create new dev and map */
+		space = *space_list;
+		if (!space)
+			return 0;
+		*space_list = *space;
+		dev_new = (void *)space;
+		memcpy(dev_new, dev, sizeof(*dev));
+		/* update new map */
+		map = get_imsm_map(dev_new, 0);
+		map->failed_disk_num = map->num_members;
+		map->num_members = map->num_members * 2;
+		map->map_state = IMSM_T_STATE_NORMAL;
+		map->num_domains = 2;
+		map->raid_level = 1;
+		/* replace dev<->dev_new */
+		dv->dev = dev_new;
+	}
 	/* update disk order table */
 	for (du = super->disks; du; du = du->next)
 		if (du->index >= 0)
 			set_imsm_ord_tbl_ent(map, du->index, du->index);
+	for (du = super->missing; du; du = du->next)
+		if (du->index >= 0)
+			set_imsm_ord_tbl_ent(map, du->index,
+						du->index | IMSM_ORD_REBUILD);
 
 	return 1;
 }
@@ -5906,7 +5957,7 @@ static void imsm_process_update(struct supertype *st,
 	switch (type) {
 	case update_takeover: {
 		struct imsm_update_takeover *u = (void *)update->buf;
-		if (apply_takeover_update(u, super))
+		if (apply_takeover_update(u, super, &update->space_list))
 			super->updates_pending++;
 		break;
 	}


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/4] Add raid10 -> raid0 takeover support
  2011-01-17 15:42 ` [PATCH 1/4] Add raid10 -> raid0 takeover support Krzysztof Wojcik
@ 2011-01-26  0:58   ` Neil Brown
  2011-01-26 11:34     ` Wojcik, Krzysztof
  0 siblings, 1 reply; 8+ messages in thread
From: Neil Brown @ 2011-01-26  0:58 UTC (permalink / raw)
  To: Krzysztof Wojcik
  Cc: linux-raid, wojciech.neubauer, adam.kwolek, dan.j.williams,
	ed.ciechanowski

On Mon, 17 Jan 2011 16:42:43 +0100
Krzysztof Wojcik <krzysztof.wojcik@intel.com> 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().

I've applied this, but I'm not sure that I like it.

I don't think mdadm needs to send a metadata update for 10->0
conversion.
It should:
 - fail all the devices that aren't wanted
 - remove them
 - mdmon notices and updates the metadata
 - mdadm changes the level to RAID0
 - mdmon notices and updates the metadata.

Currently mdmon doesn't monitor 'level', but it could and probably
should.
However in the interest of forward progress I won't insist on that for
now.

Other problems:

> 
> Signed-off-by: Krzysztof Wojcik <krzysztof.wojcik@intel.com>
> ---
>  Grow.c        |    1 +
>  super-intel.c |   98
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files
> changed, 98 insertions(+), 1 deletions(-)
> 
> diff --git a/Grow.c b/Grow.c
> index ad13d6e..c4125ea 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);

Why is this here??? EVERY change should be justified in the notes at
the top!!!!!!!


>  	}
>  
>  	info.array = array;
> diff --git a/super-intel.c b/super-intel.c
> index 334e0f4..86b365d 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,15 @@ struct geo_params {
>  	int raid_disks;
>  };
>  
> +enum takeover_direction {
> +	R10_TO_R0,
> +	R0_TO_R10
> +};
> +struct imsm_update_takeover {
> +	enum imsm_update_type type;
> +	int subarray;
> +	enum takeover_direction direction;
> +};
>  
>  struct imsm_update_reshape {
>  	enum imsm_update_type type;
> @@ -5802,6 +5812,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;
> +	struct intel_dev *dv;
> +
> +	for (dv = super->devlist; dv; dv = dv->next)
> +		if (dv->index == (unsigned int)u->subarray) {
> +			dev = dv->dev;
> +			break;
> +	}
> +
> +	if (dev == NULL)
> +		return 0;
> +
> +	map = get_imsm_map(dev, 0);
> +
> +	if (u->direction == R10_TO_R0) {
> +		/* iterate through devices to mark removed disks as
> spare */
> +		for (dm = super->disks; dm; dm = dm->next) {
> +			if (dm->disk.status & FAILED_DISK) {
> +				int idx = dm->index;
> +				/* update indexes on the disk list */
> +				for (du = super->disks; du; du =
> du->next)
> +					if (du->index > idx)
> +						du->index--;
> +				/* mark as spare disk */
> +				dm->disk.status = SPARE_DISK;
> +				dm->index = -1;

This looks like it is probably wrong, but I'm not exactly sure what it
is trying to do so I cannot be sure.
In particular the changes to 'index' seem to be based on some
assumption that are not necessarily true.
Could you please explain exactly what this is trying to achieve?

> +			}
> +		}
> +
> +		/* update map */
> +		map->num_members = map->num_members / 2;
> +		map->map_state = IMSM_T_STATE_NORMAL;
> +		map->num_domains = 1;

I'm confused by this 'num_domains' thing.  Could you please explain
it for me.  The term "parity domains" is meaningless to me in this
context.

Thanks,
NeilBrown



> +		map->raid_level = 0;
> +		map->failed_disk_num = -1;
> +	}
> +
> +	/* update disk order table */
> +	for (du = super->disks; du; du = du->next)
> +		if (du->index >= 0)
> +			set_imsm_ord_tbl_ent(map, du->index,
> du->index); +
> +	return 1;
> +}
> +
>  static void imsm_process_update(struct supertype *st,
>  			        struct metadata_update *update)
>  {
> @@ -5844,6 +5904,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(
> @@ -6691,6 +6758,35 @@ 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;
> +
> +	u = malloc(sizeof(struct imsm_update_takeover));
> +	if (u == NULL)
> +		return 1;
> +
> +	u->type = update_takeover;
> +	u->subarray = super->current_vol;
> +
> +	/* 10->0 transition */
> +	if (geo->level == 0)
> +		u->direction = R10_TO_R0;
> +
> +	/* 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;
> +}
> +
>  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)
> @@ -6772,7 +6868,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;


^ permalink raw reply	[flat|nested] 8+ messages in thread

* RE: [PATCH 1/4] Add raid10 -> raid0 takeover support
  2011-01-26  0:58   ` Neil Brown
@ 2011-01-26 11:34     ` Wojcik, Krzysztof
  2011-01-27  3:23       ` Neil Brown
  0 siblings, 1 reply; 8+ messages in thread
From: Wojcik, Krzysztof @ 2011-01-26 11:34 UTC (permalink / raw)
  To: Neil Brown
  Cc: linux-raid, Neubauer, Wojciech, Kwolek, Adam, Williams, Dan J,
	Ciechanowski, Ed



> -----Original Message-----
> From: Neil Brown [mailto:neilb@suse.de]
> Sent: Wednesday, January 26, 2011 1:59 AM
> To: Wojcik, Krzysztof
> Cc: linux-raid@vger.kernel.org; Neubauer, Wojciech; Kwolek, Adam;
> Williams, Dan J; Ciechanowski, Ed
> Subject: Re: [PATCH 1/4] Add raid10 -> raid0 takeover support
> 
> On Mon, 17 Jan 2011 16:42:43 +0100
> Krzysztof Wojcik <krzysztof.wojcik@intel.com> 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().
> 
> I've applied this, but I'm not sure that I like it.
> 
> I don't think mdadm needs to send a metadata update for 10->0
> conversion.
> It should:
>  - fail all the devices that aren't wanted
>  - remove them
>  - mdmon notices and updates the metadata
>  - mdadm changes the level to RAID0
>  - mdmon notices and updates the metadata.
> 
> Currently mdmon doesn't monitor 'level', but it could and probably
> should.
> However in the interest of forward progress I won't insist on that for
> now.
Ok. Thanks for patch applying.
In the future we can consider to change
> 
> Other problems:
> 
> >
> > Signed-off-by: Krzysztof Wojcik <krzysztof.wojcik@intel.com>
> > ---
> >  Grow.c        |    1 +
> >  super-intel.c |   98
> > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files
> > changed, 98 insertions(+), 1 deletions(-)
> >
> > diff --git a/Grow.c b/Grow.c
> > index ad13d6e..c4125ea 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);
> 
> Why is this here??? EVERY change should be justified in the notes at
> the top!!!!!!!
> 
> 
> >  	}
> >
> >  	info.array = array;
> > diff --git a/super-intel.c b/super-intel.c
> > index 334e0f4..86b365d 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,15 @@ struct geo_params {
> >  	int raid_disks;
> >  };
> >
> > +enum takeover_direction {
> > +	R10_TO_R0,
> > +	R0_TO_R10
> > +};
> > +struct imsm_update_takeover {
> > +	enum imsm_update_type type;
> > +	int subarray;
> > +	enum takeover_direction direction;
> > +};
> >
> >  struct imsm_update_reshape {
> >  	enum imsm_update_type type;
> > @@ -5802,6 +5812,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;
> > +	struct intel_dev *dv;
> > +
> > +	for (dv = super->devlist; dv; dv = dv->next)
> > +		if (dv->index == (unsigned int)u->subarray) {
> > +			dev = dv->dev;
> > +			break;
> > +	}
> > +
> > +	if (dev == NULL)
> > +		return 0;
> > +
> > +	map = get_imsm_map(dev, 0);
> > +
> > +	if (u->direction == R10_TO_R0) {
> > +		/* iterate through devices to mark removed disks as
> > spare */
> > +		for (dm = super->disks; dm; dm = dm->next) {
> > +			if (dm->disk.status & FAILED_DISK) {
> > +				int idx = dm->index;
> > +				/* update indexes on the disk list */
> > +				for (du = super->disks; du; du =
> > du->next)
> > +					if (du->index > idx)
> > +						du->index--;
> > +				/* mark as spare disk */
> > +				dm->disk.status = SPARE_DISK;
> > +				dm->index = -1;
> 
> This looks like it is probably wrong, but I'm not exactly sure what it
> is trying to do so I cannot be sure.
> In particular the changes to 'index' seem to be based on some
> assumption that are not necessarily true.
> Could you please explain exactly what this is trying to achieve?
When we remove disks from array, indexes of existing disks have to be updated to remove gaps between disks- if greater than removed disk index it should be decreased
Example:
1. Raid10:
Disk 1: index 0
Disk 2: index 1
Disk 3: index 2
Disk 4: index 3
2. Disk 2 and 4 have been removed
RAID10:
Disk 1: index 0
Disk 2(removed): index 1
Disk 3: index 2
Disk 4(removed): index 3
3. Level has been changed to "0"
RAID0:
Disk 1: index 0
Disk 2: index -1
Disk 3: index 1
Disk 4: index -1
4. At the end we have following layout:
RAID0:
Disk 1: index 0
Disk 2: index 1


> 
> > +			}
> > +		}
> > +
> > +		/* update map */
> > +		map->num_members = map->num_members / 2;
> > +		map->map_state = IMSM_T_STATE_NORMAL;
> > +		map->num_domains = 1;
> 
> I'm confused by this 'num_domains' thing.  Could you please explain
> it for me.  The term "parity domains" is meaningless to me in this
> context.
"num_domains" is used to distinguish level 10 and level 1:
For level 1:
	Level= 1
	Num_domains= 1
For level 10:
	Level= 1
	Num_domains= 2

For other levels (0, 5) num_domains= 1.

> 
> Thanks,
> NeilBrown
> 
> 
> 
> > +		map->raid_level = 0;
> > +		map->failed_disk_num = -1;
> > +	}
> > +
> > +	/* update disk order table */
> > +	for (du = super->disks; du; du = du->next)
> > +		if (du->index >= 0)
> > +			set_imsm_ord_tbl_ent(map, du->index,
> > du->index); +
> > +	return 1;
> > +}
> > +
> >  static void imsm_process_update(struct supertype *st,
> >  			        struct metadata_update *update)
> >  {
> > @@ -5844,6 +5904,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(
> > @@ -6691,6 +6758,35 @@ 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;
> > +
> > +	u = malloc(sizeof(struct imsm_update_takeover));
> > +	if (u == NULL)
> > +		return 1;
> > +
> > +	u->type = update_takeover;
> > +	u->subarray = super->current_vol;
> > +
> > +	/* 10->0 transition */
> > +	if (geo->level == 0)
> > +		u->direction = R10_TO_R0;
> > +
> > +	/* 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;
> > +}
> > +
> >  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)
> > @@ -6772,7 +6868,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;


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/4] Add raid10 -> raid0 takeover support
  2011-01-26 11:34     ` Wojcik, Krzysztof
@ 2011-01-27  3:23       ` Neil Brown
  0 siblings, 0 replies; 8+ messages in thread
From: Neil Brown @ 2011-01-27  3:23 UTC (permalink / raw)
  To: Wojcik, Krzysztof
  Cc: linux-raid, Neubauer, Wojciech, Kwolek, Adam, Williams, Dan J,
	Ciechanowski, Ed

On Wed, 26 Jan 2011 11:34:08 +0000
"Wojcik, Krzysztof" <krzysztof.wojcik@intel.com> wrote:

> 
> 
> > -----Original Message-----
> > From: Neil Brown [mailto:neilb@suse.de]
> > Sent: Wednesday, January 26, 2011 1:59 AM
> > To: Wojcik, Krzysztof
> > Cc: linux-raid@vger.kernel.org; Neubauer, Wojciech; Kwolek, Adam;
> > Williams, Dan J; Ciechanowski, Ed
> > Subject: Re: [PATCH 1/4] Add raid10 -> raid0 takeover support
> > 
> > On Mon, 17 Jan 2011 16:42:43 +0100
> > Krzysztof Wojcik <krzysztof.wojcik@intel.com> 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().
> > 
> > I've applied this, but I'm not sure that I like it.
> > 
> > I don't think mdadm needs to send a metadata update for 10->0
> > conversion.
> > It should:
> >  - fail all the devices that aren't wanted
> >  - remove them
> >  - mdmon notices and updates the metadata
> >  - mdadm changes the level to RAID0
> >  - mdmon notices and updates the metadata.
> > 
> > Currently mdmon doesn't monitor 'level', but it could and probably
> > should.
> > However in the interest of forward progress I won't insist on that
> > for now.
> Ok. Thanks for patch applying.
> In the future we can consider to change
> > 
> > Other problems:
> > 
> > >
> > > Signed-off-by: Krzysztof Wojcik <krzysztof.wojcik@intel.com>
> > > ---
> > >  Grow.c        |    1 +
> > >  super-intel.c |   98
> > > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files
> > > changed, 98 insertions(+), 1 deletions(-)
> > >
> > > diff --git a/Grow.c b/Grow.c
> > > index ad13d6e..c4125ea 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);
> > 
> > Why is this here??? EVERY change should be justified in the notes at
> > the top!!!!!!!
> > 
> > 
> > >  	}
> > >
> > >  	info.array = array;
> > > diff --git a/super-intel.c b/super-intel.c
> > > index 334e0f4..86b365d 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,15 @@ struct geo_params {
> > >  	int raid_disks;
> > >  };
> > >
> > > +enum takeover_direction {
> > > +	R10_TO_R0,
> > > +	R0_TO_R10
> > > +};
> > > +struct imsm_update_takeover {
> > > +	enum imsm_update_type type;
> > > +	int subarray;
> > > +	enum takeover_direction direction;
> > > +};
> > >
> > >  struct imsm_update_reshape {
> > >  	enum imsm_update_type type;
> > > @@ -5802,6 +5812,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;
> > > +	struct intel_dev *dv;
> > > +
> > > +	for (dv = super->devlist; dv; dv = dv->next)
> > > +		if (dv->index == (unsigned int)u->subarray) {
> > > +			dev = dv->dev;
> > > +			break;
> > > +	}
> > > +
> > > +	if (dev == NULL)
> > > +		return 0;
> > > +
> > > +	map = get_imsm_map(dev, 0);
> > > +
> > > +	if (u->direction == R10_TO_R0) {
> > > +		/* iterate through devices to mark removed disks
> > > as spare */
> > > +		for (dm = super->disks; dm; dm = dm->next) {
> > > +			if (dm->disk.status & FAILED_DISK) {
> > > +				int idx = dm->index;
> > > +				/* update indexes on the disk
> > > list */
> > > +				for (du = super->disks; du; du =
> > > du->next)
> > > +					if (du->index > idx)
> > > +						du->index--;
> > > +				/* mark as spare disk */
> > > +				dm->disk.status = SPARE_DISK;
> > > +				dm->index = -1;
> > 
> > This looks like it is probably wrong, but I'm not exactly sure what
> > it is trying to do so I cannot be sure.
> > In particular the changes to 'index' seem to be based on some
> > assumption that are not necessarily true.
> > Could you please explain exactly what this is trying to achieve?
> When we remove disks from array, indexes of existing disks have to be
> updated to remove gaps between disks- if greater than removed disk
> index it should be decreased Example: 1. Raid10:
> Disk 1: index 0
> Disk 2: index 1
> Disk 3: index 2
> Disk 4: index 3
> 2. Disk 2 and 4 have been removed
> RAID10:
> Disk 1: index 0
> Disk 2(removed): index 1
> Disk 3: index 2
> Disk 4(removed): index 3
> 3. Level has been changed to "0"
> RAID0:
> Disk 1: index 0
> Disk 2: index -1
> Disk 3: index 1
> Disk 4: index -1
> 4. At the end we have following layout:
> RAID0:
> Disk 1: index 0
> Disk 2: index 1

And does this work if the devices are in a different order, or if some
are missing?
It would make more sense to divide-by-2 the indexes of the devices that
you want to keep.


> 
> 
> > 
> > > +			}
> > > +		}
> > > +
> > > +		/* update map */
> > > +		map->num_members = map->num_members / 2;
> > > +		map->map_state = IMSM_T_STATE_NORMAL;
> > > +		map->num_domains = 1;
> > 
> > I'm confused by this 'num_domains' thing.  Could you please explain
> > it for me.  The term "parity domains" is meaningless to me in this
> > context.
> "num_domains" is used to distinguish level 10 and level 1:
> For level 1:
> 	Level= 1
> 	Num_domains= 1
> For level 10:
> 	Level= 1
> 	Num_domains= 2
> 
> For other levels (0, 5) num_domains= 1.

It would be great if you could include that in the code somewhere as a
comment, as the numbers seem to be entirely arbitrary and not follow
any clear pattern.

Thanks.
NeilBrown


> 
> > 
> > Thanks,
> > NeilBrown
> > 
> > 
> > 
> > > +		map->raid_level = 0;
> > > +		map->failed_disk_num = -1;
> > > +	}
> > > +
> > > +	/* update disk order table */
> > > +	for (du = super->disks; du; du = du->next)
> > > +		if (du->index >= 0)
> > > +			set_imsm_ord_tbl_ent(map, du->index,
> > > du->index); +
> > > +	return 1;
> > > +}
> > > +
> > >  static void imsm_process_update(struct supertype *st,
> > >  			        struct metadata_update *update)
> > >  {
> > > @@ -5844,6 +5904,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(
> > > @@ -6691,6 +6758,35 @@ 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;
> > > +
> > > +	u = malloc(sizeof(struct imsm_update_takeover));
> > > +	if (u == NULL)
> > > +		return 1;
> > > +
> > > +	u->type = update_takeover;
> > > +	u->subarray = super->current_vol;
> > > +
> > > +	/* 10->0 transition */
> > > +	if (geo->level == 0)
> > > +		u->direction = R10_TO_R0;
> > > +
> > > +	/* 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;
> > > +}
> > > +
> > >  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) @@ -6772,7 +6868,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;


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2011-01-27  3:23 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-01-17 15:42 [PATCH 0/4] raid0<->raid10 takeover for imsm metadata Krzysztof Wojcik
2011-01-17 15:42 ` [PATCH 1/4] Add raid10 -> raid0 takeover support Krzysztof Wojcik
2011-01-26  0:58   ` Neil Brown
2011-01-26 11:34     ` Wojcik, Krzysztof
2011-01-27  3:23       ` Neil Brown
2011-01-17 15:42 ` [PATCH 2/4] raid0->raid10 takeover- create metadata update Krzysztof Wojcik
2011-01-17 15:43 ` [PATCH 3/4] raid0->raid10 takeover- allocate memory for added disks Krzysztof Wojcik
2011-01-17 15:43 ` [PATCH 4/4] raid0->raid10 takeover- process metadata update Krzysztof Wojcik

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.