[PATCH 00/21] Series short description
[PATCH 00/21] Series short description
am 23.11.2010 13:39:38 von adam.kwolek
This patch series bases on previously sent patch series: array/container freezing by Dan Williams, and my and Maciej Trela's patches for OLCE and check pointing for external metadata.
This patch series implements:
1. Patches 0001 to 0018 : fixes for freezing, OLCE and check pointing
2. Patches 0018 to 0021 : implements new migration features for external metadata:
- Migration raid0 to raid5
- Migration raid5 to raid0
- Chunk size migration
We are planning in the few days add fixes for raid10 <-> raid0 takeover also.
Migration feature reuses code flow introduced for OLCE (Online Capacity Expansion) and uses the same grow/reshape flow in mdadm/mdmon.
Migration is executed in the following way:
1. mdadm: reshape_super() prepares metadata update and sends it to mdmon
2. mdadm: waits for reshape array state
3. monitor: receives metadata update and applies it.
4. monitor: metadata update triggers managemon.
5. managemon: updates array (md) configuration and starts reshape
6. mdadm: finds that reshape is started and continues it using check pointing
7. mdadm: reshape is finished and manage_reshape() finalizes array:
- Sets array size as is given in metadata
- Performs takeover to raid0 if necessary
In current patches placement of manage_reshape() function call was changed.
It is moved to end of array processing to use common code form Grow.c for external metadata reshape case
(we do not need to duplicate existing code) as it would do the same things as code for native metadata.
New manage_reshape() placement causes a few things to do in implementation only and simplifees code.
Migrations command line:
1. Execute migration raid0->raid5:
mdadm - -grow /dev/md/array_name -level 5 -layout=left-asymmetric
This converts n-disks raid0 array to (n+1)-disks raid5 array. Additional raid5 array disk is user from spares pool
2. Execute migration raid5->raid0:
mdadm - -grow /dev/md/array_name -level 0
This converts n-disks raid5 array to n-disks raid0 array.
3. Execute chunk size migration
mdadm - -grow /dev/md/array_name -chunk N
where N is ne chunk size value
In current patch series testing of 'experimental' flag was changes according to Neil's suggestion, as I've found it useable for my testing purposes.
The rest of comments to already reviewed patches (OLCE/check pointing) will be implemented in next step.
---
Adam Kwolek (21):
Migration: Chunk size migration
Migration raid0->raid5
Migration: raid5->raid0
imsm: Use geo structure
Change manage_reshape() placement
FIX: Start mdmon after changing level
FIX: Checkpointing: Enable checkpointing for non-growing migrations
FIX: Level field can be NULL
imsm Fix: Core during rebuild on array details read
WORKAROUND: md reports idle state during reshape start
FIX: Honor !reshape state on wait_reshape() entry
FIX: Unfreeze not only container for external metadata
FIX: Cannot exit monitor after takeover
imsm: FIX: Continue expansion after -As command
imsm: FIX: Reshape Cancel message on 2nd array doesn't work correctly
imsm: FIX: Guard size setting
FIX: Allow for reshape without backup file
FIX: Use MDADM_EXPERIMENTAL environment variable
imsm: FIX: imsm_check_reshape_conditions change ret_val
imsm: Change some debug output information
imsm: Remove unnecessary code
mdadm/mdadm/Detail.c | 1
mdadm/mdadm/Grow.c | 178 ++++++++----
mdadm/mdadm/Makefile | 6
mdadm/mdadm/managemon.c | 113 ++++++-
mdadm/mdadm/mdadm.h | 7
mdadm/mdadm/mdmon.h | 4
mdadm/mdadm/mdstat.c | 2
mdadm/mdadm/monitor.c | 11 +
mdadm/mdadm/msg.c | 5
mdadm/mdadm/restripe.c | 1
mdadm/mdadm/super-intel.c | 693 +++++++++++++++++++++++++++++++++------------
mdadm/mdadm/util.c | 88 +++++-
12 files changed, 830 insertions(+), 279 deletions(-)
--
Signature
--
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 01/21] imsm: Remove unnecessary code
am 23.11.2010 13:39:46 von adam.kwolek
Remove unused or not necessary/not used/redundant code
Signed-off-by: Adam Kwolek
---
mdadm/mdadm/super-intel.c | 40 ++++++++++++----------------------------
1 files changed, 12 insertions(+), 28 deletions(-)
diff --git a/mdadm/mdadm/super-intel.c b/mdadm/mdadm/super-intel.c
index 5cd3ba1..1248612 100644
--- a/mdadm/mdadm/super-intel.c
+++ b/mdadm/mdadm/super-intel.c
@@ -6997,7 +6997,6 @@ struct imsm_update_reshape *imsm_create_metadata_update_for_reshape(struct super
struct mdinfo *spares = NULL;
int i;
unsigned long long array_blocks;
- unsigned long long array_blocks_current;
int used_disks;
int delta_disks = 0;
struct dl *new_disks;
@@ -7056,7 +7055,6 @@ struct imsm_update_reshape *imsm_create_metadata_update_for_reshape(struct super
struct imsm_map *new_map2;
int idx;
- u->devnum = -1;
new_map = NULL;
imsm_copy_dev(upd_devs, old_dev);
new_map = get_imsm_map(upd_devs, 0);
@@ -7165,11 +7163,8 @@ calculate_size_only:
/* round array size down to closest MB
*/
array_blocks = (array_blocks >> SECT_PER_MB_SHIFT) << SECT_PER_MB_SHIFT;
- array_blocks_current = (((unsigned long long)((struct imsm_dev *)upd_devs)->size_high) << 32)
- + ((struct imsm_dev *)upd_devs)->size_low;
((struct imsm_dev *)(upd_devs))->size_low = __cpu_to_le32((__u32)array_blocks);
((struct imsm_dev *)(upd_devs))->size_high = __cpu_to_le32((__u32)(array_blocks >> 32));
-
/* finalize update */
ret_val = u;
}
@@ -7247,13 +7242,12 @@ exit_get_volume_for_olce:
int imsm_reshape_super(struct supertype *st, long long size, int level,
int layout, int chunksize, int raid_disks,
- char *backup, char*dev, int verbouse)
+ char *backup, char *dev, int verbouse)
{
int ret_val = 1;
struct mdinfo *sra = NULL;
int fd = -1;
char buf[PATH_MAX];
- char *devname = NULL;
dprintf("imsm: reshape_super called().\n");
dprintf("\tfor level : %i\n", level);
@@ -7264,13 +7258,7 @@ int imsm_reshape_super(struct supertype *st, long long size, int level,
return ret_val;
}
- devname = devnum2devname(st->devnum);
- if (devname == NULL) {
- dprintf("imsm: Error: imsm_reshape_super(): cannot get device name.\n");
- return ret_val;
- }
-
- snprintf(buf, PATH_MAX, "/dev/%s", devname);
+ snprintf(buf, PATH_MAX, "/dev/md%i", st->devnum);
fd = open(buf , O_RDONLY | O_DIRECT);
if (fd < 0) {
dprintf("imsm: cannot open device\n");
@@ -7371,9 +7359,6 @@ imsm_reshape_super_exit:
sysfs_free(sra);
if (fd >= 0)
close(fd);
- if (devname)
- free(devname);
-
dprintf("imsm: reshape_super Exit code = %i\n", ret_val);
return ret_val;
}
@@ -7725,28 +7710,29 @@ int imsm_grow_manage_size(struct supertype *st, struct mdinfo *sra)
struct mdinfo *info = NULL;
unsigned long long size;
int container_fd;
- int dn;
/* finalize current volume reshape
* for external meta size has to be managed by mdadm
* read size set in meta and put it to md when
* reshape is finished.
- *
- * for takeovered array, return to original raid level
*/
- if (sra == NULL)
+ if (sra == NULL) {
+ dprintf("Error: imsm_grow_manage_size(): sra == NULL\n");
goto exit_grow_manage_size_ext_meta;
+ }
wait_reshape(sra);
/* reshape has finished, update md size
* get per-device size and multiply by data disks
*/
- dn = devname2devnum(sra->text_version + 1);
- container_fd = open_dev(dn);
- if (container_fd < 0)
+ container_fd = open_dev(st->devnum);
+ if (container_fd < 0) {
+ dprintf("Error: imsm_grow_manage_size(): container_fd == 0\n");
goto exit_grow_manage_size_ext_meta;
- st->ss->load_super(st, container_fd, NULL);
+ }
+ if (st->loaded_container)
+ st->ss->load_super(st, container_fd, NULL);
info = sysfs_read(container_fd, 0, GET_LEVEL|GET_VERSION|GET_DEVS|GET_STATE);
close(container_fd);
if (info == NULL) {
@@ -7756,8 +7742,6 @@ int imsm_grow_manage_size(struct supertype *st, struct mdinfo *sra)
st->ss->getinfo_super(st, info);
size = info->custom_array_size/2;
sysfs_set_num(sra, NULL, "array_size", size);
-
- /* for takeovered array return to original raid level */
ret_val = 1;
exit_grow_manage_size_ext_meta:
@@ -8116,7 +8100,7 @@ int imsm_manage_container_reshape(struct supertype *st)
continue;
}
} else {
- dprintf("Reshape is broken (cannot read sync_complete)\n");
+ dprintf("Reshape is broken (cannot read sync_complete)\n");
dprintf("Array level is: %i\n", info->array.level);
ret_val = 1;
close(fd2);
--
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 02/21] imsm: Change some debug output information
am 23.11.2010 13:39:54 von adam.kwolek
Change debug information to more useful, correct spelling errors.
Signed-off-by: Adam Kwolek
---
mdadm/mdadm/super-intel.c | 18 ++++++++++--------
1 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/mdadm/mdadm/super-intel.c b/mdadm/mdadm/super-intel.c
index 1248612..f628c2c 100644
--- a/mdadm/mdadm/super-intel.c
+++ b/mdadm/mdadm/super-intel.c
@@ -6962,7 +6962,7 @@ struct mdinfo *get_spares_imsm(int devnum)
goto abort;
}
if (ret_val->array.spare_disks == 0) {
- dprintf("imsm: ERROR: No available spares.\n");
+ fprintf(stderr, Name": imsm: ERROR: No available spares.\n");
free(ret_val);
ret_val = NULL;
goto abort;
@@ -7003,7 +7003,7 @@ struct imsm_update_reshape *imsm_create_metadata_update_for_reshape(struct super
int device_size;
void *upd_devs;
- dprintf("insm imsm_update_metadata_for_reshape(enter)\n");
+ dprintf("imsm imsm_update_metadata_for_reshape(enter)\n");
if ((raid_disks < super->anchor->num_disks) ||
(raid_disks == UnSet))
@@ -7261,7 +7261,7 @@ int imsm_reshape_super(struct supertype *st, long long size, int level,
snprintf(buf, PATH_MAX, "/dev/md%i", st->devnum);
fd = open(buf , O_RDONLY | O_DIRECT);
if (fd < 0) {
- dprintf("imsm: cannot open device\n");
+ dprintf("imsm: cannot open device %s\n", buf);
goto imsm_reshape_super_exit;
}
@@ -7710,6 +7710,7 @@ int imsm_grow_manage_size(struct supertype *st, struct mdinfo *sra)
struct mdinfo *info = NULL;
unsigned long long size;
int container_fd;
+ unsigned long long current_size = 0;
/* finalize current volume reshape
* for external meta size has to be managed by mdadm
@@ -7741,6 +7742,8 @@ int imsm_grow_manage_size(struct supertype *st, struct mdinfo *sra)
}
st->ss->getinfo_super(st, info);
size = info->custom_array_size/2;
+ sysfs_get_ll(sra, NULL, "array_size", ¤t_size);
+ dprintf("imsm_grow_manage_size(): current size is %llu, set size to %llu\n", current_size, size);
sysfs_set_num(sra, NULL, "array_size", size);
ret_val = 1;
@@ -7985,14 +7988,14 @@ int imsm_manage_container_reshape(struct supertype *st)
* for single vlolume reshape exit only and reuse Grow_reshape() code
*/
if (st->subarray[0] != 0) {
- dprintf("imsm: manage_reshape() current volume: %s\n", st->subarray);
- dprintf("imsm: manage_reshape() detects volume reshape (devnum = %i), exit.\n", st->devnum);
+ dprintf("imsm: imsm_manage_container_reshape() current volume: %s\n", st->subarray);
+ dprintf("imsm: imsm_manage_container_reshape() detects volume reshape (devnum = %i), exit.\n", st->devnum);
return ret_val;
}
devname = devnum2devname(st->devnum);
if (devname == NULL) {
- dprintf("imsm: Error: imsm_manage_reshape(): cannot get device name.\n");
+ dprintf("imsm: Error: imsm_manage_container_reshape(): cannot get device name.\n");
return ret_val;
}
@@ -8198,8 +8201,7 @@ int imsm_manage_reshape(struct supertype *st, char *backup)
* for single vlolume reshape exit only and reuse Grow_reshape() code
*/
if (st->subarray[0] != 0) {
- dprintf("imsm: manage_reshape() current volume: %s\n", st->subarray);
- dprintf("imsm: manage_reshape() detects volume reshape (devnum = %i), exit.\n", st->devnum);
+ dprintf("imsm: manage_reshape() current volume: %s (devnum = %i)\n", st->subarray, st->devnum);
return ret_val;
}
ret_val = imsm_manage_container_reshape(st);
--
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 03/21] imsm: FIX: imsm_check_reshape_conditions change ret_val
am 23.11.2010 13:40:02 von adam.kwolek
Put information to return variable (ret_val) in more clear way.
manage_reshape will always unfreeze container
and this will not base on return value as it has to be always unfrozen,
on success and on error.
Signed-off-by: Adam Kwolek
---
mdadm/mdadm/super-intel.c | 12 +++++++-----
1 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/mdadm/mdadm/super-intel.c b/mdadm/mdadm/super-intel.c
index f628c2c..b58eb5f 100644
--- a/mdadm/mdadm/super-intel.c
+++ b/mdadm/mdadm/super-intel.c
@@ -7969,7 +7969,7 @@ exit_imsm_check_reshape_conditions:
int imsm_manage_container_reshape(struct supertype *st)
{
- int ret_val = 0;
+ int ret_val = 1;
char buf[PATH_MAX];
struct intel_super *super = st->sb;
struct imsm_super *mpb = super->anchor;
@@ -8028,12 +8028,10 @@ int imsm_manage_container_reshape(struct supertype *st)
find_array_minor(info2.name, 1, ¤t_array);
if (current_array < 0) {
dprintf("imsm. Error.Cannot get first array.\n");
- ret_val = 1;
goto imsm_manage_container_reshape_exit;
}
if (imsm_check_reshape_conditions(fd, st, current_array)) {
dprintf("imsm. Error. Wrong reshape conditions.\n");
- ret_val = 1;
goto imsm_manage_container_reshape_exit;
}
raid_disks = info2.array.raid_disks;
@@ -8128,6 +8126,7 @@ int imsm_manage_container_reshape(struct supertype *st)
close(fd2);
if (ret_val) {
dprintf("Reshape is broken (cannot reshape)\n");
+ ret_val = 1;
goto imsm_manage_container_reshape_exit;
}
current_array = -1;
@@ -8156,6 +8155,7 @@ int imsm_manage_container_reshape(struct supertype *st)
if (imsm_check_reshape_conditions(fd, st, current_array)) {
dprintf("imsm. Error. Wrong reshape conditions.\n");
+ ret_val = 1;
current_array = -1;
}
} else
@@ -8205,8 +8205,10 @@ int imsm_manage_reshape(struct supertype *st, char *backup)
return ret_val;
}
ret_val = imsm_manage_container_reshape(st);
- if (ret_val)
- unfreeze_container(st);
+ /* unfreeze on error and success
+ * for any result this is end of work
+ */
+ unfreeze_container(st);
return ret_val;
}
--
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 04/21] FIX: Use MDADM_EXPERIMENTAL environment variable
am 23.11.2010 13:40:09 von adam.kwolek
Instead 'EXPERIMENTAL' compilation flag, use 'MDADM_EXPERIMENTAL'
environment variable to enable features.
Function experimental was put to util.c for reuse.
Signed-off-by: Adam Kwolek
---
mdadm/mdadm/mdadm.h | 1 +
mdadm/mdadm/super-intel.c | 18 ++----------------
mdadm/mdadm/util.c | 10 ++++++++++
3 files changed, 13 insertions(+), 16 deletions(-)
diff --git a/mdadm/mdadm/mdadm.h b/mdadm/mdadm/mdadm.h
index c722475..844c354 100644
--- a/mdadm/mdadm/mdadm.h
+++ b/mdadm/mdadm/mdadm.h
@@ -970,6 +970,7 @@ extern int read_attr(char *buf, int len, int fd);
extern int read_dev_state(int fd);
extern int find_array_minor(char *text_version, int external, int *minor);
extern int find_array_minor2(char *text_version, int external, int *minor);
+extern inline int experimental(void);
extern void free_line(char *line);
extern int match_oneof(char *devices, char *devname);
diff --git a/mdadm/mdadm/super-intel.c b/mdadm/mdadm/super-intel.c
index b58eb5f..1005595 100644
--- a/mdadm/mdadm/super-intel.c
+++ b/mdadm/mdadm/super-intel.c
@@ -195,16 +195,6 @@ struct bbm_log {
static char *map_state_str[] = { "normal", "uninitialized", "degraded", "failed" };
#endif
-static inline int experimental(void)
-{
-#ifdef EXPERIMENTAL
- return 1;
-#else
- fprintf(stderr, Name "(IMSM): To use this feature EXPERIMENTAL compilation flag has to be used.\n");
- return 0;
-#endif
-}
-
#define UNIT_SRC_NORMAL 0 /* Source data for curr_migr_unit must
* be recovered using srcMap */
#define UNIT_SRC_IN_CP_AREA 1 /* Source data for curr_migr_unit has
@@ -7253,10 +7243,8 @@ int imsm_reshape_super(struct supertype *st, long long size, int level,
dprintf("\tfor level : %i\n", level);
dprintf("\tfor raid_disks : %i\n", raid_disks);
- if (experimental() == 0) {
- dprintf("imsm: Error: Operation not supported without EXPERIMENTAL compilaton flag.\n");
+ if (experimental() == 0)
return ret_val;
- }
snprintf(buf, PATH_MAX, "/dev/md%i", st->devnum);
fd = open(buf , O_RDONLY | O_DIRECT);
@@ -8192,10 +8180,8 @@ int imsm_manage_reshape(struct supertype *st, char *backup)
dprintf("imsm: manage_reshape() called\n");
- if (experimental() == 0) {
- dprintf("imsm: Error: Operation not supported without EXPERIMENTAL compilaton flag.\n");
+ if (experimental() == 0)
return ret_val;
- }
/* verify reshape conditions
* for single vlolume reshape exit only and reuse Grow_reshape() code
diff --git a/mdadm/mdadm/util.c b/mdadm/mdadm/util.c
index 58ba6f0..d176ec0 100644
--- a/mdadm/mdadm/util.c
+++ b/mdadm/mdadm/util.c
@@ -2010,3 +2010,13 @@ int find_array_minor2(char *text_version, int external, int *minor)
}
return result;
}
+
+inline int experimental(void)
+{
+ if (check_env("MDADM_EXPERIMENTAL"))
+ return 1;
+ else {
+ fprintf(stderr, Name "(IMSM): To use this feature MDADM_EXPERIMENTAL enviroment variable has to defined.\n");
+ 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 05/21] FIX: Allow for reshape without backup file
am 23.11.2010 13:40:17 von adam.kwolek
When reshape process is guarded by metadata specific checkpointing,
backup file is no longer necessary.
Remove backup file requirement from mdadm command line when reshape_super
and manage reshape_super are defined for external metadata case.
Signed-off-by: Adam Kwolek
---
mdadm/mdadm/Grow.c | 25 +++++++++++++++++--------
1 files changed, 17 insertions(+), 8 deletions(-)
diff --git a/mdadm/mdadm/Grow.c b/mdadm/mdadm/Grow.c
index 2cabb94..127e535 100644
--- a/mdadm/mdadm/Grow.c
+++ b/mdadm/mdadm/Grow.c
@@ -1586,6 +1586,11 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
goto release;
}
if (backup_file == NULL) {
+ int backup_file_required_for_external;
+
+ backup_file_required_for_external = st->ss->external &&
+ st->ss->reshape_super && st->ss->manage_reshape;
+
if (st->ss->external && !st->ss->manage_reshape) {
fprintf(stderr, Name ": %s Grow operation not supported by %s metadata\n",
devname, st->ss->name);
@@ -1593,10 +1598,12 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
break;
}
if (ndata <= odata) {
- fprintf(stderr, Name ": %s: Cannot grow - need backup-file\n",
- devname);
- rv = 1;
- break;
+ if (!backup_file_required_for_external) {
+ fprintf(stderr, Name ": %s: Cannot grow - need backup-file\n",
+ devname);
+ rv = 1;
+ break;
+ }
} else if (sra->array.spare_disks == 0) {
fprintf(stderr, Name ": %s: Cannot grow - need a spare or "
"backup-file to backup critical section\n",
@@ -1605,10 +1612,12 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
break;
}
if (d == array.raid_disks) {
- fprintf(stderr, Name ": %s: No spare device for backup\n",
- devname);
- rv = 1;
- break;
+ if (!backup_file_required_for_external) {
+ fprintf(stderr, Name ": %s: No spare device for backup\n",
+ devname);
+ rv = 1;
+ break;
+ }
}
} else {
/* need to check backup file is large enough */
--
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 06/21] imsm: FIX: Guard size setting
am 23.11.2010 13:40:25 von adam.kwolek
Function imsm_num_data_members() can return 0 when error condition
occurs. This would cause set 0 array size in metadata to 0 also.
This patch puts guard for array size modification in such case.
Signed-off-by: Adam Kwolek
---
mdadm/mdadm/super-intel.c | 18 ++++++++++--------
1 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/mdadm/mdadm/super-intel.c b/mdadm/mdadm/super-intel.c
index 1005595..3ff26c5 100644
--- a/mdadm/mdadm/super-intel.c
+++ b/mdadm/mdadm/super-intel.c
@@ -7149,14 +7149,16 @@ calculate_size_only:
*/
if (new_map != NULL) {
used_disks = imsm_num_data_members(upd_devs, 0);
- array_blocks = new_map->blocks_per_member * used_disks;
- /* round array size down to closest MB
- */
- array_blocks = (array_blocks >> SECT_PER_MB_SHIFT) << SECT_PER_MB_SHIFT;
- ((struct imsm_dev *)(upd_devs))->size_low = __cpu_to_le32((__u32)array_blocks);
- ((struct imsm_dev *)(upd_devs))->size_high = __cpu_to_le32((__u32)(array_blocks >> 32));
- /* finalize update */
- ret_val = u;
+ if (used_disks) {
+ array_blocks = new_map->blocks_per_member * used_disks;
+ /* round array size down to closest MB
+ */
+ array_blocks = (array_blocks >> SECT_PER_MB_SHIFT) << SECT_PER_MB_SHIFT;
+ ((struct imsm_dev *)(upd_devs))->size_low = __cpu_to_le32((__u32)array_blocks);
+ ((struct imsm_dev *)(upd_devs))->size_high = __cpu_to_le32((__u32)(array_blocks >> 32));
+ /* finalize update */
+ ret_val = u;
+ }
}
exit_imsm_create_metadata_update_for_reshape:
--
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 07/21] imsm: FIX: Reshape Cancel message on 2nd array doesn"t
am 23.11.2010 13:40:33 von adam.kwolek
During Online Capacity Expansion on container with 2 arrays, when 2nd
volume reshape fails, cancel message is generated.
Cancel message should not remove disks from disks list when they are used
in other volume already. Size stored in metadata has to be roll-backed
to initial value when disks are removed array configuration.
Signed-off-by: Adam Kwolek
---
mdadm/mdadm/super-intel.c | 53 ++++++++++++++++++++++++++++++++++++---------
1 files changed, 42 insertions(+), 11 deletions(-)
diff --git a/mdadm/mdadm/super-intel.c b/mdadm/mdadm/super-intel.c
index 3ff26c5..96892ec 100644
--- a/mdadm/mdadm/super-intel.c
+++ b/mdadm/mdadm/super-intel.c
@@ -5795,11 +5795,15 @@ update_reshape_exit:
struct imsm_update_reshape *u = (void *)update->buf;
struct active_array *a;
int inst;
+ int i;
struct imsm_dev *dev;
+ struct imsm_dev *devi;
struct imsm_map *map_1;
struct imsm_map *map_2;
int reshape_delta_disks ;
struct dl *curr_disk;
+ int used_disks;
+ unsigned long long array_blocks;
dprintf("imsm: process_update() for update_reshape_cancel for device %i\n", u->devnum);
@@ -5821,9 +5825,28 @@ update_reshape_exit:
dev = get_imsm_dev(super, inst);
map_1 = get_imsm_map(dev, 0);
map_2 = get_imsm_map(dev, 1);
+ if (map_2 == NULL)
+ break;
reshape_delta_disks = map_1->num_members - map_2->num_members;
dprintf("\t\tRemove %i device(s) from configuration.\n", reshape_delta_disks);
+ /* when cancel was applied during reshape of second volume, we need disks for first
+ * array reshaped previously, find the smallest delta_disks to remove
+ */
+ i = 0;
+ devi = get_imsm_dev(super, i);
+ while (devi) {
+ struct imsm_map *mapi = get_imsm_map(devi, 0);
+ int delta_disks = map_1->num_members - mapi->num_members;
+ if ((i != inst) &&
+ (delta_disks < reshape_delta_disks) &&
+ (delta_disks >= 0))
+ reshape_delta_disks = delta_disks;
+ i++;
+ devi = get_imsm_dev(super, i);
+ }
+ /* remove disks
+ */
if (reshape_delta_disks > 0) {
/* reverse device(s) back to spares
*/
@@ -5839,18 +5862,26 @@ update_reshape_exit:
}
curr_disk = curr_disk->next;
}
-
- /* roll back maps and migration
- */
- memcpy(map_1, map_2, sizeof_imsm_map(map_2));
- /* reconfigure map_2 and perform migration end
- */
- map_2 = get_imsm_map(dev, 1);
- memcpy(map_2, map_1, sizeof_imsm_map(map_1));
- end_migration(dev, map_1->map_state);
-
- super->updates_pending++;
}
+ /* roll back maps and migration
+ */
+ memcpy(map_1, map_2, sizeof_imsm_map(map_2));
+ /* reconfigure map_2 and perform migration end
+ */
+ map_2 = get_imsm_map(dev, 1);
+ memcpy(map_2, map_1, sizeof_imsm_map(map_1));
+ end_migration(dev, map_1->map_state);
+ /* array size rollback
+ */
+ used_disks = imsm_num_data_members(dev, 0);
+ array_blocks = map_1->blocks_per_member * used_disks;
+ /* round array size down to closest MB
+ */
+ array_blocks = (array_blocks >> SECT_PER_MB_SHIFT) << SECT_PER_MB_SHIFT;
+ dev->size_low = __cpu_to_le32((__u32)array_blocks);
+ dev->size_high = __cpu_to_le32((__u32)(array_blocks >> 32));
+
+ super->updates_pending++;
break;
}
case update_level: {
--
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 08/21] imsm: FIX: Continue expansion after -As command
am 23.11.2010 13:40:41 von adam.kwolek
When Online Capacity Expansion is run for 2 volumes on container
and during first reshape reboot occurs, -As mdadm command fill finish
reshape on first volume only. Having 2 arrays in container built
on different disks will violate IMSM compatibility with windows.
To resolve this we have to have ability to finish Expansion for second array also.
This should be done by execution the same container mdadm command.
mdadm should finish work and prepare container that will be compatible with Windows IMSM software.
During running the same command on container, mdadm should:
1. Correct size in md for first volume (finished already)
2. Continue reshape for second volume.
Signed-off-by: Adam Kwolek
---
mdadm/mdadm/Makefile | 6 ++-
mdadm/mdadm/mdadm.h | 4 +-
mdadm/mdadm/super-intel.c | 90 +++++++++++++++++++++++++++++++++++++--------
mdadm/mdadm/util.c | 78 +++++++++++++++++++++++++++++++++------
4 files changed, 144 insertions(+), 34 deletions(-)
diff --git a/mdadm/mdadm/Makefile b/mdadm/mdadm/Makefile
index 2162039..7e2a058 100644
--- a/mdadm/mdadm/Makefile
+++ b/mdadm/mdadm/Makefile
@@ -112,17 +112,17 @@ SRCS = mdadm.c config.c mdstat.c ReadMe.c util.c Manage.c Assemble.c Build.c \
MON_OBJS = mdmon.o monitor.o managemon.o util.o mdstat.o sysfs.o config.o \
Kill.o sg_io.o dlink.o ReadMe.o super0.o super1.o super-intel.o \
super-ddf.o sha1.o crc32.o msg.o bitmap.o \
- platform-intel.o probe_roms.o Grow.o restripe.o
+ platform-intel.o probe_roms.o Grow.o restripe.o mapfile.o
MON_SRCS = mdmon.c monitor.c managemon.c util.c mdstat.c sysfs.c config.c \
Kill.c sg_io.c dlink.c ReadMe.c super0.c super1.c super-intel.c \
super-ddf.c sha1.c crc32.c msg.c bitmap.c \
- platform-intel.c probe_roms.c Grow.c restripe.c
+ platform-intel.c probe_roms.c Grow.c restripe.c mapfile.c
STATICSRC = pwgr.c
STATICOBJS = pwgr.o
-ASSEMBLE_SRCS := mdassemble.c Assemble.c Manage.c config.c dlink.c util.c \
+ASSEMBLE_SRCS := mdassemble.c Assemble.c Manage.c config.c dlink.c util.c mapfile.c\
super0.c super1.c super-ddf.c super-intel.c sha1.c crc32.c sg_io.c mdstat.c \
platform-intel.c probe_roms.c sysfs.c
ASSEMBLE_AUTO_SRCS := mdopen.c
diff --git a/mdadm/mdadm/mdadm.h b/mdadm/mdadm/mdadm.h
index 844c354..ddff47a 100644
--- a/mdadm/mdadm/mdadm.h
+++ b/mdadm/mdadm/mdadm.h
@@ -968,8 +968,8 @@ extern int devname_matches(char *name, char *match);
extern struct mddev_ident_s *conf_match(struct mdinfo *info, struct supertype *st);
extern int read_attr(char *buf, int len, int fd);
extern int read_dev_state(int fd);
-extern int find_array_minor(char *text_version, int external, int *minor);
-extern int find_array_minor2(char *text_version, int external, int *minor);
+extern int find_array_minor(char *text_version, int external, int container, int *minor);
+extern int find_array_minor2(char *text_version, int external, int container, int *minor);
extern inline int experimental(void);
extern void free_line(char *line);
diff --git a/mdadm/mdadm/super-intel.c b/mdadm/mdadm/super-intel.c
index 96892ec..945cc94 100644
--- a/mdadm/mdadm/super-intel.c
+++ b/mdadm/mdadm/super-intel.c
@@ -1748,7 +1748,7 @@ static void getinfo_super_imsm_volume(struct supertype *st, struct mdinfo *info)
/* fill sys_name field
*/
- if (find_array_minor2(info->text_version, 1, &minor) == 0)
+ if (find_array_minor2(info->text_version, 1, st->devnum, &minor) == 0)
sprintf(info->sys_name, "md%i", minor);
/* fill delta_disks field
@@ -1911,7 +1911,7 @@ static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info)
}
/* fill sys_name field
*/
- if (find_array_minor2(info->text_version, 1, &minor) == 0)
+ if (find_array_minor2(info->text_version, 1, st->devnum, &minor) == 0)
sprintf(info->sys_name, "md%i", minor);
}
@@ -6266,6 +6266,7 @@ static void imsm_prepare_update(struct supertype *st,
dprintf("imsm: No passed device.\n");
break;
}
+ dprintf("imsm: reshape delta disks is = %i\n", u->reshape_delta_disks);
if (u->reshape_delta_disks < 0)
break;
u->update_prepared = 1;
@@ -6804,6 +6805,7 @@ int imsm_reshape_is_allowed_on_container(struct supertype *st,
char buf[PATH_MAX];
int fd = -1;
int device_num = -1;
+ int devices_that_can_grow = 0;
dprintf("imsm: imsm_reshape_is_allowed_on_container(ENTER): st->devnum = (%i)\n", st->devnum);
@@ -6830,6 +6832,12 @@ int imsm_reshape_is_allowed_on_container(struct supertype *st,
while (device_num > -1) {
int result;
int minor;
+ unsigned long long array_blocks;
+ struct imsm_map *map = NULL;
+ struct imsm_dev *dev = NULL;
+ struct intel_super *super = NULL;
+ int used_disks;
+
dprintf("imsm: checking device_num: %i\n", device_num);
sprintf(st->subarray, "%i", device_num);
@@ -6841,8 +6849,12 @@ int imsm_reshape_is_allowed_on_container(struct supertype *st,
*/
dprintf("imsm: error: superblock is NULL during container operation\n");
} else {
- dprintf("imsm: no more devices to check\n");
- ret_val = 1;
+ dprintf("imsm: no more devices to check, number of forund devices: %i\n",
+ devices_that_can_grow);
+ /* check if any device in container can be groved
+ */
+ if (devices_that_can_grow)
+ ret_val = 1;
/* restore superblock, for last device not loaded */
sprintf(st->subarray, "%i", 0);
st->ss->load_super(st, fd, NULL);
@@ -6856,13 +6868,40 @@ int imsm_reshape_is_allowed_on_container(struct supertype *st,
}
st->ss->getinfo_super(st, info);
- if (raid_disks <= info->array.raid_disks) {
+ if (raid_disks < info->array.raid_disks) {
/* we work on container for Online Capacity Expansion
* only so raid_disks has to grow
*/
dprintf("imsm: for container operation raid disks increase is required\n");
break;
}
+ /* check if size is set corectly
+ * wrong conditions could happend when previous reshape wes interrupted
+ */
+ super = st->sb;
+ dev = get_imsm_dev(super, device_num);
+ if (dev == NULL) {
+ dprintf("cannot get imsm device\n");
+ ret_val = 0;
+ break;
+ }
+ map = get_imsm_map(dev, 0);
+ if (dev == NULL) {
+ dprintf("cannot get imsm device map\n");
+ ret_val = 0;
+ break;
+ }
+ used_disks = imsm_num_data_members(dev, 0);
+ dprintf("read raid_disks =%i\n", used_disks);
+ array_blocks = map->blocks_per_member * used_disks;
+ /* round array size down to closest MB
+ */
+ array_blocks = (array_blocks >> SECT_PER_MB_SHIFT) << SECT_PER_MB_SHIFT;
+ if (sysfs_set_num(info, NULL, "array_size", array_blocks/2) < 0)
+ dprintf("cannot set array size to %llu\n", array_blocks/2);
+
+ if (raid_disks > info->array.raid_disks)
+ devices_that_can_grow++;
if ((info->array.level != 0) &&
(info->array.level != 5)) {
@@ -6884,14 +6923,25 @@ int imsm_reshape_is_allowed_on_container(struct supertype *st,
/* all raid5 and raid0 volumes in container
* has to be ready for Online Capacity Expansion
*/
- result = find_array_minor2(info->text_version, st->ss->external, &minor);
+ result = find_array_minor2(info->text_version, st->ss->external, st->devnum, &minor);
if (result < 0) {
dprintf("imsm: cannot find array\n");
break;
}
sprintf(info->sys_name, "md%i", minor);
if (sysfs_get_str(info, NULL, "array_state", buf, 20) <= 0) {
- dprintf("imsm: for container operation wrong array state\n");
+ dprintf("imsm: cannot read array state\n");
+ break;
+ }
+ if ((strncmp(buf, "clean", 5) != 0) &&
+ (strncmp(buf, "clear", 5) != 0) &&
+ (strncmp(buf, "active", 6) != 0)) {
+ int index = strlen(buf) - 1;
+
+ if (index < 0)
+ index = 0;
+ *(buf + index) = 0;
+ fprintf(stderr, "imsm: Error: Array %s is not in proper state (current state: %s). Cannot continue.\n", info->sys_name, buf);
break;
}
if (info->array.level > 0) {
@@ -6953,7 +7003,7 @@ struct mdinfo *get_spares_imsm(int devnum)
goto abort;
}
sprintf(buf, "/md%i/0", devnum);
- find_result = find_array_minor2(buf, 1, &devnum);
+ find_result = find_array_minor2(buf, 1, devnum, &devnum);
if (find_result < 0) {
dprintf("imsm: ERROR: Cannot find array.\n");
goto abort;
@@ -7024,7 +7074,7 @@ struct imsm_update_reshape *imsm_create_metadata_update_for_reshape(struct super
int device_size;
void *upd_devs;
- dprintf("imsm imsm_update_metadata_for_reshape(enter)\n");
+ dprintf("imsm imsm_update_metadata_for_reshape(enter) raid_disks = %i\n", raid_disks);
if ((raid_disks < super->anchor->num_disks) ||
(raid_disks == UnSet))
@@ -7070,7 +7120,7 @@ struct imsm_update_reshape *imsm_create_metadata_update_for_reshape(struct super
if (old_dev == NULL)
break;
- find_array_minor((char *)old_dev->volume, 1, &devnum);
+ find_array_minor((char *)old_dev->volume, 1, st->devnum, &devnum);
if (devnum == imsm_volume) {
__u8 to_state;
struct imsm_map *new_map2;
@@ -7081,6 +7131,7 @@ struct imsm_update_reshape *imsm_create_metadata_update_for_reshape(struct super
new_map = get_imsm_map(upd_devs, 0);
old_disk_number = new_map->num_members;
new_map->num_members = raid_disks;
+ u->reshape_delta_disks = new_map->num_members - old_disk_number;
/* start migration on new device
* it puts second map there also
*/
@@ -7105,7 +7156,7 @@ struct imsm_update_reshape *imsm_create_metadata_update_for_reshape(struct super
}
}
- if (u->reshape_delta_disks == 0) {
+ if (delta_disks <= 0) {
dprintf("imsm: reshape without grow (disk add).\n");
/* finalize update */
goto calculate_size_only;
@@ -7297,7 +7348,7 @@ int imsm_reshape_super(struct supertype *st, long long size, int level,
array = get_volume_for_olce(st, raid_disks);
if (array) {
int devnum = -1;
- find_array_minor(array, 1, &devnum);
+ find_array_minor(array, 1, st->devnum, &devnum);
if (devnum > 0) {
dprintf("imsm: Preparing metadata update for: %s\n", array);
@@ -7908,7 +7959,7 @@ int imsm_check_reshape_conditions(int fd, struct supertype *st, int current_arra
}
st->ss->getinfo_super(st, info);
- find_array_minor(info->name, 1, &temp_array);
+ find_array_minor(info->name, 1, st->devnum, &temp_array);
if (temp_array != current_array) {
if (temp_array < 0) {
ret_val = -1;
@@ -7919,6 +7970,11 @@ int imsm_check_reshape_conditions(int fd, struct supertype *st, int current_arra
continue;
}
+ if (sysfs_get_str(info, NULL, "raid_disks", buf, sizeof(buf)) < 0) {
+ dprintf("cannot get raid_disks\n");
+ ret_val = 1;
+ break;
+ }
/* sync_max should be always set to 0
*/
if (sysfs_get_str(info, NULL, "sync_max", buf, sizeof(buf)) < 0) {
@@ -7967,7 +8023,7 @@ int imsm_check_reshape_conditions(int fd, struct supertype *st, int current_arra
sysfs_free(info);
info = NULL;
if (wrong_slots_counter != 0) {
- dprintf("Slost for correction %i.\n", wrong_slots_counter);
+ dprintf("Slots for correction %i.\n", wrong_slots_counter);
ret_val = 1;
goto exit_imsm_check_reshape_conditions;
}
@@ -8046,7 +8102,7 @@ int imsm_manage_container_reshape(struct supertype *st)
info2.devs = NULL;
st->ss->getinfo_super(st, &info2);
current_array = -1;
- find_array_minor(info2.name, 1, ¤t_array);
+ find_array_minor(info2.name, 1, st->devnum, ¤t_array);
if (current_array < 0) {
dprintf("imsm. Error.Cannot get first array.\n");
goto imsm_manage_container_reshape_exit;
@@ -8077,7 +8133,7 @@ int imsm_manage_container_reshape(struct supertype *st)
info2.devs = NULL;
st->ss->getinfo_super(st, &info2);
dprintf("Checking slots for device %s\n", info2.sys_name);
- find_array_minor(info2.name, 1, &temp_array);
+ find_array_minor(info2.name, 1, st->devnum, &temp_array);
if (temp_array == current_array)
break;
}
@@ -8158,7 +8214,7 @@ int imsm_manage_container_reshape(struct supertype *st)
dprintf("imsm: next volume to reshape is: %s\n", array);
info2.devs = NULL;
st->ss->getinfo_super(st, &info2);
- find_array_minor(info2.name, 1, ¤t_array);
+ find_array_minor(info2.name, 1, st->devnum, ¤t_array);
if (current_array > -1) {
/* send next array update
*/
diff --git a/mdadm/mdadm/util.c b/mdadm/mdadm/util.c
index d176ec0..60b9e0a 100644
--- a/mdadm/mdadm/util.c
+++ b/mdadm/mdadm/util.c
@@ -1947,8 +1947,9 @@ int path2devnum(char *pth)
return dev_num;
}
-
-int find_array_minor(char *text_version, int external, int *minor)
+extern void map_read(struct map_ent **map);
+extern void map_free(struct map_ent *map);
+int find_array_minor(char *text_version, int external, int container, int *minor)
{
int i;
char path[PATH_MAX];
@@ -1957,6 +1958,65 @@ int find_array_minor(char *text_version, int external, int *minor)
if (minor == NULL)
return -2;
+ snprintf(path, PATH_MAX, "/dev/md/%s", text_version);
+ i = path2devnum(path);
+ if (i > -1) {
+ *minor = i;
+ return 0;
+ }
+
+ i = path2devnum(text_version);
+ if (i > -1) {
+ *minor = i;
+ return 0;
+ }
+
+ if (container > 0) {
+ struct map_ent *map = NULL;
+ struct map_ent *m;
+ char cont[PATH_MAX];
+
+ snprintf(cont, PATH_MAX, "/md%i/", container);
+ map_read(&map);
+ for (m = map; m; m = m->next) {
+ int index;
+ unsigned int len = 0;
+ char buf[PATH_MAX];
+
+ /* array have belongs to proper container
+ */
+ if (strncmp(cont, m->metadata, 6) != 0)
+ continue;
+ /* begin of array name in map have to be the same
+ * as array name in metadata
+ */
+ if (strncmp(m->path, path, strlen(path)) != 0)
+ continue;
+ /* array name has to be followed by '_' char
+ */
+ len = strlen(path);
+ if (*(m->path + len) != '_')
+ continue;
+ /* then we have to have valid index
+ */
+ len++;
+ if (strlen(m->path + len) <= 0)
+ continue;
+ /* index has to be las position in array name
+ */
+ index = atoi(m->path + strlen(path) + 1);
+ snprintf(buf, PATH_MAX, "%i", index);
+ len += strlen(buf);
+ if (len != strlen(m->path))
+ continue;
+ dprintf("Found %s device based on mdadm maps\n", m->path);
+ *minor = m->devnum;
+ map_free(map);
+ return 0;
+ }
+ map_free(map);
+ }
+
for (i = 127; i >= 0; i--) {
char buf[PATH_MAX];
@@ -1968,7 +2028,7 @@ int find_array_minor(char *text_version, int external, int *minor)
if (external) {
char *version = strchr(buf, ':');
if (version && strcmp(version + 1,
- text_version))
+ text_version))
continue;
} else {
if (strcmp(buf, text_version))
@@ -1979,25 +2039,19 @@ int find_array_minor(char *text_version, int external, int *minor)
}
}
- snprintf(path, PATH_MAX, "/dev/md/%s", text_version);
- i = path2devnum(path);
- if (i > -1) {
- *minor = i;
- return 0;
- }
return -1;
}
/* find_array_minor2 looks for frozen devices also
*/
-int find_array_minor2(char *text_version, int external, int *minor)
+int find_array_minor2(char *text_version, int external, int container, int *minor)
{
int result;
char buf[PATH_MAX];
strcpy(buf, text_version);
- result = find_array_minor(text_version, external, minor);
+ result = find_array_minor(text_version, external, container, minor);
if (result < 0) {
/* try to find frozen array also
*/
@@ -2006,7 +2060,7 @@ int find_array_minor2(char *text_version, int external, int *minor)
strcpy(buf, text_version);
*buf = '-';
- result = find_array_minor(buf, external, minor);
+ result = find_array_minor(buf, external, container, minor);
}
return result;
}
--
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 09/21] FIX: Cannot exit monitor after takeover
am 23.11.2010 13:40:49 von adam.kwolek
When performing backward takeover to raid0 monitor cannot exit
for single raid0 array configuration.
Monitor is locked by communication (ping_manager()) after unfreeze()
Do not ping manager for raid0 array as they shouldn't be monitored.
Signed-off-by: Adam Kwolek
---
mdadm/mdadm/msg.c | 5 +++--
1 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/mdadm/mdadm/msg.c b/mdadm/mdadm/msg.c
index 7f0b66e..f413824 100644
--- a/mdadm/mdadm/msg.c
+++ b/mdadm/mdadm/msg.c
@@ -414,11 +414,12 @@ void unblock_monitor(char *container, const int unfreeze)
if (!is_container_member(e, container))
continue;
sysfs_free(sra);
- sra = sysfs_read(-1, e->devnum, GET_VERSION);
+ sra = sysfs_read(-1, e->devnum, GET_VERSION|GET_LEVEL);
if (unblock_subarray(sra, unfreeze))
fprintf(stderr, Name ": Failed to unfreeze %s\n", e->dev);
}
- ping_monitor(container);
+ if (sra && sra->array.level > 0)
+ ping_monitor(container);
sysfs_free(sra);
free_mdstat(ent);
--
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 10/21] FIX: Unfreeze not only container for external metadata
am 23.11.2010 13:40:57 von adam.kwolek
Unfreeze for external metadata case should unfreeze arrays and container,
not only container as so far. Unfreeze() function doesn't know
what the changes to configuration was made so far, and if arrays
are pulled from frozen state in md.
Unfreeze() has to make sure by performing array unfreeze that all arrays
are not frozen and then unblock monitor.
Signed-off-by: Adam Kwolek
---
mdadm/mdadm/Grow.c | 18 ++++++++----------
1 files changed, 8 insertions(+), 10 deletions(-)
diff --git a/mdadm/mdadm/Grow.c b/mdadm/mdadm/Grow.c
index 127e535..9b1c4c5 100644
--- a/mdadm/mdadm/Grow.c
+++ b/mdadm/mdadm/Grow.c
@@ -491,16 +491,14 @@ static void unfreeze(struct supertype *st, int frozen)
return;
if (st->ss->external)
- return unfreeze_container(st);
- else {
- struct mdinfo *sra = sysfs_read(-1, st->devnum, GET_VERSION);
-
- if (sra)
- sysfs_set_str(sra, NULL, "sync_action", "idle");
- else
- fprintf(stderr, Name ": failed to unfreeze array\n");
- sysfs_free(sra);
- }
+ unfreeze_container(st);
+
+ struct mdinfo *sra = sysfs_read(-1, st->devnum, GET_VERSION);
+ if (sra)
+ sysfs_set_str(sra, NULL, "sync_action", "idle");
+ else
+ fprintf(stderr, Name ": failed to unfreeze array\n");
+ sysfs_free(sra);
}
void wait_reshape(struct mdinfo *sra)
--
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 11/21] FIX: Honor !reshape state on wait_reshape() entry
am 23.11.2010 13:41:05 von adam.kwolek
When wait_reshape() function starts it can occurs that reshape is finished already,
before wait_reshape() start. This can lead to wait for change state inside this function for a long time.
To avoid this before wait we should test if finish conditions are not reached already.
Signed-off-by: Adam Kwolek
---
mdadm/mdadm/Grow.c | 9 ++++++---
1 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/mdadm/mdadm/Grow.c b/mdadm/mdadm/Grow.c
index 9b1c4c5..f56613f 100644
--- a/mdadm/mdadm/Grow.c
+++ b/mdadm/mdadm/Grow.c
@@ -506,17 +506,20 @@ void wait_reshape(struct mdinfo *sra)
int fd = sysfs_get_fd(sra, NULL, "sync_action");
char action[20];
- do {
+ if (sysfs_fd_get_str(fd, action, 20) < 0) {
+ close(fd);
+ return;
+ }
+ while (strncmp(action, "reshape", 7) == 0) {
fd_set rfds;
FD_ZERO(&rfds);
FD_SET(fd, &rfds);
select(fd+1, NULL, NULL, &rfds, NULL);
-
if (sysfs_fd_get_str(fd, action, 20) < 0) {
close(fd);
return;
}
- } while (strncmp(action, "reshape", 7) == 0);
+ }
}
static int reshape_super(struct supertype *st, long long size, int level,
--
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 12/21] WORKAROUND: md reports idle state during reshape start
am 23.11.2010 13:41:16 von adam.kwolek
md reports reshape->idle->reshape states transition on reshape start, so reshape finalization is wrongly indicated.
Finalize reshape when we have any progress only,
When reshape is really started, idle state causes reshape finalization as usually.
Signed-off-by: Adam Kwolek
---
mdadm/mdadm/monitor.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/mdadm/mdadm/monitor.c b/mdadm/mdadm/monitor.c
index f8ddba7..4cd634d 100644
--- a/mdadm/mdadm/monitor.c
+++ b/mdadm/mdadm/monitor.c
@@ -332,7 +332,8 @@ static int read_and_act(struct active_array *a)
/* finalize reshape detection
*/
if ((a->curr_action != reshape) &&
- (a->prev_action == reshape)) {
+ (a->prev_action == reshape) &&
+ (a->info.reshape_progress > 2)) {
/* set zero to allow for future rebuilds
*/
a->reshape_delta_disks = RESHAPE_NOT_ACTIVE;
--
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 13/21] imsm Fix: Core during rebuild on array details read
am 23.11.2010 13:41:24 von adam.kwolek
When rebuild/reshape is in progress, executing mdadm for read array details causes core dump.
This is due to not initialized devices list pointer in getinfo_super() call.
Initializing it to NULL value allows code to detect such situation.
Signed-off-by: Adam Kwolek
---
mdadm/mdadm/Detail.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/mdadm/mdadm/Detail.c b/mdadm/mdadm/Detail.c
index 1f2dbf2..b355199 100644
--- a/mdadm/mdadm/Detail.c
+++ b/mdadm/mdadm/Detail.c
@@ -140,6 +140,7 @@ int Detail(char *dev, int brief, int export, int test, char *homehost)
close(fd2);
if (err)
continue;
+ info.devs = NULL;
st->ss->getinfo_super(st, &info);
if (array.raid_disks != 0 && /* container */
--
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 14/21] FIX: Level field can be NULL
am 23.11.2010 13:41:32 von adam.kwolek
When array changes its shape/level or array is about closing
level field in mdstat can be NULL. This causes core dump in mdmon.
Patch introduces guard in code for this situation.
Signed-off-by: Adam Kwolek
---
mdadm/mdadm/mdstat.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/mdadm/mdadm/mdstat.c b/mdadm/mdadm/mdstat.c
index aecd1d4..1f818b1 100644
--- a/mdadm/mdadm/mdstat.c
+++ b/mdadm/mdadm/mdstat.c
@@ -291,6 +291,8 @@ struct mdstat_ent *mdstat_read(int hold, int start)
int mdstat_to_level(struct mdstat_ent *ms)
{
+ if (ms->level == NULL)
+ return LEVEL_UNSUPPORTED;
if (strncmp(ms->level, "raid0", 5) == 0)
return 0;
else if (strncmp(ms->level, "raid10", 6) == 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 15/21] FIX: Checkpointing: Enable checkpointing for
am 23.11.2010 13:41:39 von adam.kwolek
For non growing migration case, there are several errors in checkpointing:
1. Write offset was computed incorrectly based on old disk number.
This causes checkpointing to stop working
(suspend_lo value was wrong calculated and cannot be saved in sysfs).
2. Checkpointing cannot start due to wrong sync_completed value reported by md
on reshape start. md reports value 2 instead 0.
3. Layout value for raid0 causes that geo_map() returns error.
Signed-off-by: Adam Kwolek
---
mdadm/mdadm/Grow.c | 2 +-
mdadm/mdadm/monitor.c | 8 +++++++-
mdadm/mdadm/restripe.c | 1 +
3 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/mdadm/mdadm/Grow.c b/mdadm/mdadm/Grow.c
index f56613f..3747f76 100644
--- a/mdadm/mdadm/Grow.c
+++ b/mdadm/mdadm/Grow.c
@@ -2280,7 +2280,7 @@ int grow_backup_ext(struct supertype *st, struct mdinfo *sra,
if (sra->new_level == 6)
new_odata--;
- write_offset = offset * 512 * odata;
+ write_offset = offset * 512 * new_odata;
bytes_per_unit = sra->new_chunk * new_odata;
if (chunk > sra->new_chunk)
bytes_per_unit *= (chunk / sra->new_chunk);
diff --git a/mdadm/mdadm/monitor.c b/mdadm/mdadm/monitor.c
index 4cd634d..a37cd93 100644
--- a/mdadm/mdadm/monitor.c
+++ b/mdadm/mdadm/monitor.c
@@ -248,8 +248,14 @@ static int read_and_act(struct active_array *a)
if (safe_sync_max >= a->info.component_size)
sysfs_set_str(&a->info, NULL, "sync_max", "max");
- else
+ else {
+ /* Workarround:
+ * sometimes md reports sync_completed == 2 but in fact it is 0
+ */
+ if ((new_sync_completed == 2) && (safe_sync_max == 0))
+ safe_sync_max = 2;
sysfs_set_num(&a->info, NULL, "sync_max", safe_sync_max);
+ }
} else {
sysfs_set_num(&a->info, NULL, "sync_max", a->grow_sync_max);
}
diff --git a/mdadm/mdadm/restripe.c b/mdadm/mdadm/restripe.c
index 7add7ce..3b16ad8 100644
--- a/mdadm/mdadm/restripe.c
+++ b/mdadm/mdadm/restripe.c
@@ -45,6 +45,7 @@ static int geo_map(int block, unsigned long long stripe, int raid_disks,
switch(level*100 + layout) {
case 000:
+ case 000 + ALGORITHM_PARITY_N: /* layout has no matter for raid0 */
case 400:
case 400 + ALGORITHM_PARITY_N:
case 500 + ALGORITHM_PARITY_N:
--
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 16/21] FIX: Start mdmon after changing level
am 23.11.2010 13:41:47 von adam.kwolek
When level is changing from not monitored (raid0) to monitored level
mdmon should be run. This is common situation, so code from super-intel.c
has to be moved to Grow.c
Signed-off-by: Adam Kwolek
---
mdadm/mdadm/Grow.c | 8 ++++++++
mdadm/mdadm/super-intel.c | 11 -----------
2 files changed, 8 insertions(+), 11 deletions(-)
diff --git a/mdadm/mdadm/Grow.c b/mdadm/mdadm/Grow.c
index 3747f76..66a2303 100644
--- a/mdadm/mdadm/Grow.c
+++ b/mdadm/mdadm/Grow.c
@@ -1241,6 +1241,14 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
rv = 1;
goto release;
}
+ /* before sending update make sure that for external metadata
+ * and after changing raid level mdmon is running
+ */
+ if (st->ss->external && !mdmon_running(st->container_dev) &&
+ level > 0) {
+ start_mdmon(st->container_dev);
+ ping_monitor(container);
+ }
sync_metadata(st);
}
}
diff --git a/mdadm/mdadm/super-intel.c b/mdadm/mdadm/super-intel.c
index 945cc94..7481126 100644
--- a/mdadm/mdadm/super-intel.c
+++ b/mdadm/mdadm/super-intel.c
@@ -7410,17 +7410,6 @@ int imsm_reshape_super(struct supertype *st, long long size, int level,
ret_val = 0;
goto imsm_reshape_super_exit;
}
- /* if raid0 was takeovered by any other
- * personality start mdmon */
- if (sra->array.level == 0) {
- char *dname = devnum2devname(dn);
- if (!mdmon_running(dn))
- start_mdmon(dn);
- if (dname) {
- ping_monitor(dname);
- free(dname);
- }
- }
ret_val = 0;
}
sysfs_free(sra);
--
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 17/21] Change manage_reshape() placement
am 23.11.2010 13:41:55 von adam.kwolek
After reshape_super() call manage_reshape() should do the same things
as grow_reshape() for native metadata case (for execution on array).
The difference is on reshape finish only, when md finishes his work.
For external metadata size is managed externally from md point of view,
so specific to metadata action is required there.
This causes moving manage_reshape() placement to add necessary actions only
to common flow and not duplicate current code.
Signed-off-by: Adam Kwolek
---
mdadm/mdadm/Grow.c | 23 +++++++++++++----------
1 files changed, 13 insertions(+), 10 deletions(-)
diff --git a/mdadm/mdadm/Grow.c b/mdadm/mdadm/Grow.c
index 66a2303..eaa10c1 100644
--- a/mdadm/mdadm/Grow.c
+++ b/mdadm/mdadm/Grow.c
@@ -1730,14 +1730,6 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
break;
}
- if (st->ss->external) {
- /* metadata handler takes it from here */
- ping_manager(container);
- st->ss->manage_reshape(st, backup_file);
- frozen = 0;
- break;
- }
-
/* set up the backup-super-block. This requires the
* uuid from the array.
*/
@@ -1808,6 +1800,15 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
d - odisks, fdlist+odisks, offsets+odisks);
if (backup_file && done)
unlink(backup_file);
+
+ /* manage/finalize reshape in metadata specific way
+ */
+ close(fd);
+ if (st->ss->external && st->ss->manage_reshape) {
+ st->ss->manage_reshape(st, backup_file);
+ break;
+ }
+
if (level != UnSet && level != array.level) {
/* We need to wait for the reshape to finish
* (which will have happened unless odata < ndata)
@@ -1818,8 +1819,10 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
if (c == NULL)
exit(0);/* not possible */
- if (odata < ndata)
- wait_reshape(sra);
+ /* child process has always wait for reshape finish
+ * to perform unfreeze
+ */
+ wait_reshape(sra);
err = sysfs_set_str(sra, NULL, "level", c);
if (err)
fprintf(stderr, Name ": %s: could not set level to %s\n",
--
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 18/21] imsm: Use geo structure
am 23.11.2010 13:42:03 von adam.kwolek
For passing parameters use geo structures.
Add function (update_geometry()) to update geometry structure.
Signed-off-by: Krysztof Wojcik
Signed-off-by: Adam Kwolek
---
mdadm/mdadm/super-intel.c | 271 +++++++++++++++++++++++++++++++++------------
1 files changed, 199 insertions(+), 72 deletions(-)
diff --git a/mdadm/mdadm/super-intel.c b/mdadm/mdadm/super-intel.c
index 7481126..113c3bb 100644
--- a/mdadm/mdadm/super-intel.c
+++ b/mdadm/mdadm/super-intel.c
@@ -329,6 +329,16 @@ struct imsm_update_activate_spare {
struct imsm_update_activate_spare *next;
};
+struct geo_params {
+ int dev_id;
+ char *dev_name;
+ long long size;
+ int level;
+ int layout;
+ int chunksize;
+ int raid_disks;
+};
+
struct imsm_update_reshape {
enum imsm_update_type type;
@@ -6797,8 +6807,7 @@ static int update_level_imsm(struct supertype *st, struct mdinfo *info,
}
int imsm_reshape_is_allowed_on_container(struct supertype *st,
- long long size, int level, int layout,
- int chunksize, int raid_disks)
+ struct geo_params *geo)
{
int ret_val = 0;
struct mdinfo *info = NULL;
@@ -6809,8 +6818,9 @@ int imsm_reshape_is_allowed_on_container(struct supertype *st,
dprintf("imsm: imsm_reshape_is_allowed_on_container(ENTER): st->devnum = (%i)\n", st->devnum);
- if ((size != -1) || (level != UnSet) ||
- (layout != UnSet) || (chunksize != 0)) {
+ if (geo == NULL ||
+ (geo->size != -1) || (geo->level != UnSet) ||
+ (geo->layout != UnSet) || (geo->chunksize != 0)) {
dprintf("imsm: Container operation is allowed for raid disks number change only.\n");
return ret_val;
}
@@ -6823,7 +6833,7 @@ int imsm_reshape_is_allowed_on_container(struct supertype *st,
return ret_val;
}
- if (raid_disks == UnSet) {
+ if (geo->raid_disks == UnSet) {
dprintf("imsm: for container operation raid disks change is required\n");
goto exit_imsm_reshape_is_allowed_on_container;
}
@@ -6868,7 +6878,7 @@ int imsm_reshape_is_allowed_on_container(struct supertype *st,
}
st->ss->getinfo_super(st, info);
- if (raid_disks < info->array.raid_disks) {
+ if (geo->raid_disks < info->array.raid_disks) {
/* we work on container for Online Capacity Expansion
* only so raid_disks has to grow
*/
@@ -6892,7 +6902,8 @@ int imsm_reshape_is_allowed_on_container(struct supertype *st,
break;
}
used_disks = imsm_num_data_members(dev, 0);
- dprintf("read raid_disks =%i\n", used_disks);
+ dprintf("read raid_disks = %i\n", used_disks);
+ dprintf("read requested disks = %i\n", geo->raid_disks);
array_blocks = map->blocks_per_member * used_disks;
/* round array size down to closest MB
*/
@@ -6900,7 +6911,7 @@ int imsm_reshape_is_allowed_on_container(struct supertype *st,
if (sysfs_set_num(info, NULL, "array_size", array_blocks/2) < 0)
dprintf("cannot set array size to %llu\n", array_blocks/2);
- if (raid_disks > info->array.raid_disks)
+ if (geo->raid_disks > info->array.raid_disks)
devices_that_can_grow++;
if ((info->array.level != 0) &&
@@ -6913,9 +6924,9 @@ int imsm_reshape_is_allowed_on_container(struct supertype *st,
/* check for platform support for this raid level configuration
*/
struct intel_super *super = st->sb;
- if (!is_raid_level_supported(super->orom, info->array.level, raid_disks)) {
+ if (!is_raid_level_supported(super->orom, info->array.level, geo->raid_disks)) {
dprintf("platform does not support raid%d with %d disk%s\n",
- info->array.level, raid_disks, raid_disks > 1 ? "s" : "");
+ info->array.level, geo->raid_disks, geo->raid_disks > 1 ? "s" : "");
break;
}
}
@@ -7051,6 +7062,106 @@ abort:
return ret_val;
}
+/********************************************************** *******************
+ * Function: update_geometry
+ * Description: Prepares imsm volume map update in case of volume reshape
+ * Returns: 0 on success, -1 if fail
+ * ************************************************************ ***************/
+int update_geometry(struct supertype *st,
+ struct geo_params *geo)
+{
+ int fd = -1, ret_val = -1;
+ struct mdinfo *sra = NULL;
+ char buf[PATH_MAX];
+ char supported = 1;
+
+ snprintf(buf, PATH_MAX, "/dev/md%i", geo->dev_id);
+ fd = open(buf , O_RDONLY | O_DIRECT);
+ if (fd < 0) {
+ dprintf("imsm: cannot open device\n");
+ return -1;
+ }
+
+ sra = sysfs_read(fd, 0, GET_DISKS | GET_LAYOUT | GET_CHUNK | GET_SIZE | GET_LEVEL | GET_DEVS);
+ if (!sra) {
+ dprintf("imsm: Cannot get mdinfo!\n");
+ goto update_geometry_exit;
+ }
+
+ if (sra->devs == NULL) {
+ dprintf("imsm: Cannot load device information.\n");
+ goto update_geometry_exit;
+ }
+ /* is size change possible??? */
+ if (((unsigned long long)geo->size != sra->devs->component_size) && (geo->size != UnSet) && (geo->size > 0)) {
+ geo->size = sra->devs->component_size;
+ dprintf("imsm: Change the array size not supported in imsm!\n");
+ goto update_geometry_exit;
+ }
+
+ if ((geo->level != sra->array.level) && (geo->level >= 0) && (geo->level != UnSet)) {
+ switch (sra->array.level) {
+ case 0:
+ if (geo->level != 5)
+ supported = 0;
+ break;
+ case 5:
+ if (geo->level != 0)
+ supported = 0;
+ break;
+ case 1:
+ if ((geo->level != 5) || (geo->level != 0))
+ supported = 0;
+ break;
+ case 10:
+ if (geo->level != 5)
+ supported = 0;
+ break;
+ default:
+ supported = 0;
+ break;
+ }
+ if (!supported) {
+ dprintf("imsm: Error. Level Migration from %d to %d not supported!\n", sra->array.level, geo->level);
+ goto update_geometry_exit;
+ }
+ } else {
+ geo->level = sra->array.level;
+ }
+
+ if ((geo->layout != sra->array.layout) && ((geo->layout != UnSet) && (geo->layout != -1))) {
+ if ((sra->array.layout == 0) && (sra->array.level == 5) && (geo->layout == 5)) {
+ /* reshape 5 -> 4 */
+ geo->raid_disks++;
+ } else if ((sra->array.layout == 5) && (sra->array.level == 5) && (geo->layout == 0)) {
+ /* reshape 4 -> 5 */
+ geo->layout = 0;
+ geo->level = 5;
+ } else {
+ dprintf("imsm: Error. Layout Migration from %d to %d not supported!\n", sra->array.layout, geo->layout);
+ ret_val = -1;
+ goto update_geometry_exit;
+ }
+ }
+
+ if ((geo->chunksize == 0) || (geo->chunksize == UnSet))
+ geo->chunksize = sra->array.chunk_size;
+
+ if (!validate_geometry_imsm(st, geo->level, geo->layout, geo->raid_disks,
+ geo->chunksize, geo->size,
+ 0, 0, 1))
+ goto update_geometry_exit;
+
+ ret_val = 0;
+
+update_geometry_exit:
+ sysfs_free(sra);
+ if (fd > -1)
+ close(fd);
+
+ return ret_val;
+}
+
/*********************************************************** *******************
* function: imsm_create_metadata_update_for_reshape
* Function creates update for whole IMSM container.
@@ -7058,7 +7169,7 @@ abort:
* when reshape will be triggered and md sets slot numbers.
* Slot numbers in metadata will be updated with stage_2 update
************************************************************ ******************/
-struct imsm_update_reshape *imsm_create_metadata_update_for_reshape(struct supertype *st, int raid_disks, int imsm_volume)
+struct imsm_update_reshape *imsm_create_metadata_update_for_reshape(struct supertype *st, struct geo_params *geo)
{
struct imsm_update_reshape *ret_val = NULL;
struct intel_super *super = st->sb;
@@ -7074,12 +7185,12 @@ struct imsm_update_reshape *imsm_create_metadata_update_for_reshape(struct super
int device_size;
void *upd_devs;
- dprintf("imsm imsm_update_metadata_for_reshape(enter) raid_disks = %i\n", raid_disks);
+ dprintf("imsm imsm_update_metadata_for_reshape(enter) raid_disks = %i\n", geo->raid_disks);
- if ((raid_disks < super->anchor->num_disks) ||
- (raid_disks == UnSet))
- raid_disks = super->anchor->num_disks;
- delta_disks = raid_disks - super->anchor->num_disks;
+ if ((geo->raid_disks < super->anchor->num_disks) ||
+ (geo->raid_disks == UnSet))
+ geo->raid_disks = super->anchor->num_disks;
+ delta_disks = geo->raid_disks - super->anchor->num_disks;
/* size of all update data without anchor */
update_memory_size = sizeof(struct imsm_update_reshape);
@@ -7088,7 +7199,7 @@ struct imsm_update_reshape *imsm_create_metadata_update_for_reshape(struct super
*/
device_size = sizeof(struct imsm_dev);
device_size += sizeof(struct imsm_map);
- device_size += 2*(raid_disks - 1) * sizeof(__u32);
+ device_size += 2 * (geo->raid_disks - 1) * sizeof(__u32);
update_memory_size += device_size * super->anchor->num_raid_devs;
if (delta_disks > 1) {
@@ -7121,7 +7232,7 @@ struct imsm_update_reshape *imsm_create_metadata_update_for_reshape(struct super
break;
find_array_minor((char *)old_dev->volume, 1, st->devnum, &devnum);
- if (devnum == imsm_volume) {
+ if (devnum == geo->dev_id) {
__u8 to_state;
struct imsm_map *new_map2;
int idx;
@@ -7130,7 +7241,7 @@ struct imsm_update_reshape *imsm_create_metadata_update_for_reshape(struct super
imsm_copy_dev(upd_devs, old_dev);
new_map = get_imsm_map(upd_devs, 0);
old_disk_number = new_map->num_members;
- new_map->num_members = raid_disks;
+ new_map->num_members = geo->raid_disks;
u->reshape_delta_disks = new_map->num_members - old_disk_number;
/* start migration on new device
* it puts second map there also
@@ -7150,7 +7261,7 @@ struct imsm_update_reshape *imsm_create_metadata_update_for_reshape(struct super
for (idx = new_map2->num_members; idx < new_map->num_members; idx++)
set_imsm_ord_tbl_ent(new_map, idx, idx);
}
- u->devnum = imsm_volume;
+ u->devnum = geo->dev_id;
break;
}
}
@@ -7322,10 +7433,20 @@ int imsm_reshape_super(struct supertype *st, long long size, int level,
struct mdinfo *sra = NULL;
int fd = -1;
char buf[PATH_MAX];
+ struct geo_params geo;
+
+ memset(&geo, sizeof (struct geo_params), 0);
+
+ geo.dev_name = dev;
+ geo.size = size;
+ geo.level = level;
+ geo.layout = layout;
+ geo.chunksize = chunksize;
+ geo.raid_disks = raid_disks;
dprintf("imsm: reshape_super called().\n");
- dprintf("\tfor level : %i\n", level);
- dprintf("\tfor raid_disks : %i\n", raid_disks);
+ dprintf("\tfor level : %i\n", geo.level);
+ dprintf("\tfor raid_disks : %i\n", geo.raid_disks);
if (experimental() == 0)
return ret_val;
@@ -7341,38 +7462,44 @@ int imsm_reshape_super(struct supertype *st, long long size, int level,
* on container level we can do almost everything */
if (st->subarray[0] == 0) {
/* check for delta_disks > 0 and supported raid levels 0 and 5 only in container */
- if (imsm_reshape_is_allowed_on_container(st, size, level, layout, chunksize, raid_disks)) {
+ if (imsm_reshape_is_allowed_on_container(st, &geo)) {
struct imsm_update_reshape *u;
char *array;
- array = get_volume_for_olce(st, raid_disks);
+ array = get_volume_for_olce(st, geo.raid_disks);
if (array) {
- int devnum = -1;
- find_array_minor(array, 1, st->devnum, &devnum);
- if (devnum > 0) {
+ find_array_minor(array, 1, st->devnum, &geo.dev_id);
+ if (geo.dev_id > 0) {
dprintf("imsm: Preparing metadata update for: %s\n", array);
st->update_tail = &st->updates;
- u = imsm_create_metadata_update_for_reshape(st, raid_disks, devnum);
+ u = imsm_create_metadata_update_for_reshape(st, &geo);
if (u) {
ret_val = 0;
append_metadata_update(st, u, u->update_memory_size);
- }
- }
+ } else
+ dprintf("imsm: Cannot prepare update\n");
+ } else
+ dprintf("imsm: Cannot find array in container\n");
free(array);
}
- }
+ } else
+ dprintf("imsm: Operation is not allowed on container\n");
if (ret_val)
unfreeze_container(st);
*st->subarray = 0;
goto imsm_reshape_super_exit;
- }
+ } else
+ dprintf("imsm: not a container operation\n");
+
+ geo.dev_id = -1;
+ find_array_minor(geo.dev_name, 1, st->devnum, &geo.dev_id);
/* we have volume so takeover can be performed for single volume only
*/
- if ((size == -1) && (layout == UnSet) && (raid_disks == 0) && (level != UnSet)) {
-
+ if ((geo.size == -1) && (geo.layout == UnSet) && (geo.raid_disks == 0) && (geo.level != UnSet) &&
+ (geo.dev_id > -1)) {
/* ok - this is takeover */
int container_fd;
int dn;
@@ -7400,9 +7527,9 @@ int imsm_reshape_super(struct supertype *st, long long size, int level,
* to/from different than raid10 level
* if source level is raid0 mdmon is sterted only
*/
- if (((level == 10) || (sra->array.level == 10) || (sra->array.level == 0)) &&
- (level != sra->array.level) &&
- (level > 0)) {
+ if (((geo.level == 10) || (sra->array.level == 10) || (sra->array.level == 0)) &&
+ (geo.level != sra->array.level) &&
+ (geo.level > 0)) {
st->update_tail = &st->updates;
err = update_level_imsm(st, sra, sra->name, 0, 0, NULL);
if (err != 0) {
@@ -8039,17 +8166,17 @@ int imsm_manage_container_reshape(struct supertype *st)
char buf[PATH_MAX];
struct intel_super *super = st->sb;
struct imsm_super *mpb = super->anchor;
- char *devname;
int fd;
struct mdinfo *info = NULL;
struct mdinfo info2;
int validate_fd;
- int current_array;
- int delta_disks, raid_disks;
+ int delta_disks;
+ struct geo_params geo;
#ifdef DEBUG
int i;
#endif
+ memset(&geo, sizeof (struct geo_params), 0);
/* verify reshape conditions
* for single vlolume reshape exit only and reuse Grow_reshape() code
*/
@@ -8059,24 +8186,23 @@ int imsm_manage_container_reshape(struct supertype *st)
return ret_val;
}
- devname = devnum2devname(st->devnum);
- if (devname == NULL) {
- dprintf("imsm: Error: imsm_manage_container_reshape(): cannot get device name.\n");
+ geo.dev_name = devnum2devname(st->devnum);
+ if (geo.dev_name == NULL) {
+ dprintf("imsm: Error: imsm_manage_reshape(): cannot get device name.\n");
return ret_val;
}
- snprintf(buf, PATH_MAX, "/dev/%s", devname);
+ snprintf(buf, PATH_MAX, "/dev/%s", geo.dev_name);
fd = open(buf , O_RDONLY | O_DIRECT);
if (fd < 0) {
dprintf("imsm: cannot open device\n");
- free(devname);
- return ret_val;
+ goto imsm_manage_container_reshape_exit;
}
/* send pings to roll managemon and monitor
*/
- ping_manager(devname);
- ping_monitor(devname);
+ ping_manager(geo.dev_name);
+ ping_monitor(geo.dev_name);
#ifdef DEBUG
/* device list for reshape
@@ -8090,22 +8216,22 @@ int imsm_manage_container_reshape(struct supertype *st)
info2.devs = NULL;
st->ss->getinfo_super(st, &info2);
- current_array = -1;
- find_array_minor(info2.name, 1, st->devnum, ¤t_array);
- if (current_array < 0) {
+ geo.dev_id = -1;
+ find_array_minor(info2.name, 1, st->devnum, &geo.dev_id);
+ if (geo.dev_id < 0) {
dprintf("imsm. Error.Cannot get first array.\n");
goto imsm_manage_container_reshape_exit;
}
- if (imsm_check_reshape_conditions(fd, st, current_array)) {
+ if (imsm_check_reshape_conditions(fd, st, geo.dev_id)) {
dprintf("imsm. Error. Wrong reshape conditions.\n");
goto imsm_manage_container_reshape_exit;
}
- raid_disks = info2.array.raid_disks;
+ geo.raid_disks = info2.array.raid_disks;
dprintf("Container is ready for reshape ...\n");
switch (fork()) {
case 0:
fprintf(stderr, Name ": Child forked to run and monitor reshape\n");
- while (current_array > -1) {
+ while (geo.dev_id > -1) {
int fd2 = -1;
int i;
int temp_array = -1;
@@ -8123,11 +8249,11 @@ int imsm_manage_container_reshape(struct supertype *st)
st->ss->getinfo_super(st, &info2);
dprintf("Checking slots for device %s\n", info2.sys_name);
find_array_minor(info2.name, 1, st->devnum, &temp_array);
- if (temp_array == current_array)
+ if (temp_array == geo.dev_id)
break;
}
snprintf(buf, PATH_MAX, "/dev/%s", info2.sys_name);
- dprintf("Prepare to reshape for device %s (md%i)\n", info2.sys_name, current_array);
+ dprintf("Prepare to reshape for device %s (md%i)\n", info2.sys_name, geo.dev_id);
fd2 = open(buf, O_RDWR | O_DIRECT);
if (fd2 < 0) {
dprintf("Reshape is broken (cannot open array)\n");
@@ -8160,7 +8286,7 @@ int imsm_manage_container_reshape(struct supertype *st)
/* or this array was already reshaped */
(strncmp(buf, "none", 4) == 0)) {
dprintf("Skip this array, sync_completed is %s\n", buf);
- current_array = -1;
+ geo.dev_id = -1;
sysfs_free(info);
info = NULL;
close(fd2);
@@ -8176,10 +8302,10 @@ int imsm_manage_container_reshape(struct supertype *st)
snprintf(buf, PATH_MAX, "/dev/md/%s", info2.name);
info->delta_disks = info2.delta_disks;
- delta_disks = info->array.raid_disks - raid_disks;
- raid_disks = info->array.raid_disks;
+ delta_disks = info->array.raid_disks - geo.raid_disks;
+ geo.raid_disks = info->array.raid_disks;
if (info->array.level == 4) {
- raid_disks--;
+ geo.raid_disks--;
delta_disks--;
}
@@ -8195,37 +8321,37 @@ int imsm_manage_container_reshape(struct supertype *st)
ret_val = 1;
goto imsm_manage_container_reshape_exit;
}
- current_array = -1;
+ geo.dev_id = -1;
sprintf(st->subarray, "%i", 0);
- array = get_volume_for_olce(st, raid_disks);
+ array = get_volume_for_olce(st, geo.raid_disks);
if (array) {
struct imsm_update_reshape *u;
dprintf("imsm: next volume to reshape is: %s\n", array);
info2.devs = NULL;
st->ss->getinfo_super(st, &info2);
- find_array_minor(info2.name, 1, st->devnum, ¤t_array);
- if (current_array > -1) {
+ find_array_minor(info2.name, 1, st->devnum, &geo.dev_id);
+ if (geo.dev_id > -1) {
/* send next array update
*/
- dprintf("imsm: Preparing metadata update for: %s (md%i)\n", array, current_array);
+ dprintf("imsm: Preparing metadata update for: %s (md%i)\n", array, geo.dev_id);
st->update_tail = &st->updates;
- u = imsm_create_metadata_update_for_reshape(st, raid_disks, current_array);
+ u = imsm_create_metadata_update_for_reshape(st, &geo);
if (u) {
u->reshape_delta_disks = delta_disks;
append_metadata_update(st, u, u->update_memory_size);
flush_metadata_updates(st);
/* send pings to roll managemon and monitor
*/
- ping_manager(devname);
- ping_monitor(devname);
+ ping_manager(geo.dev_name);
+ ping_monitor(geo.dev_name);
- if (imsm_check_reshape_conditions(fd, st, current_array)) {
+ if (imsm_check_reshape_conditions(fd, st, geo.dev_id)) {
dprintf("imsm. Error. Wrong reshape conditions.\n");
ret_val = 1;
- current_array = -1;
+ geo.dev_id = -1;
}
} else
- current_array = -1;
+ geo.dev_id = -1;
}
free(array);
}
@@ -8244,10 +8370,11 @@ int imsm_manage_container_reshape(struct supertype *st)
}
imsm_manage_container_reshape_exit:
- free(devname);
sysfs_free(info);
if (fd > -1)
close(fd);
+ if (geo.dev_name)
+ free(geo.dev_name);
return ret_val;
}
--
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 19/21] Migration: raid5->raid0
am 23.11.2010 13:42:11 von adam.kwolek
Add implementation for migration from raid5 to raid0 in one step.
For this migration case (and others for external metadata case)
flow used for Expansion is used. This causes update array parameters
in managemon based on sent metadata update. To do this uptate md parameters
in Grow.c has to be disabled for external metadata case.
In Grow.c instead starting reshape for external metadata case
wait_reshape_start_ext() function is introduced.
Function waits for reshape start initialized by managemon after setting
array parameter as for Expansion case.
In managemon was added subarray_set_num_man() function.
It is similar to function that exists in Grow.c except 2 things:
1. it uses different way to "ping" monitor
2. it tries to set raid_disks more than 2 times as we are more sure that monitor works
during processing in managemon context
For imsm raid level parameters flow from mdadm (via metadata update)
to managemon was added.
Signed-off-by: Adam Kwolek
---
mdadm/mdadm/Grow.c | 93 ++++++++++++++++++++++--------
mdadm/mdadm/managemon.c | 107 ++++++++++++++++++++++++++++++----
mdadm/mdadm/mdadm.h | 2 +
mdadm/mdadm/mdmon.h | 3 +
mdadm/mdadm/super-intel.c | 141 +++++++++++++++++++++++++++++++++++++--------
5 files changed, 283 insertions(+), 63 deletions(-)
diff --git a/mdadm/mdadm/Grow.c b/mdadm/mdadm/Grow.c
index eaa10c1..5347847 100644
--- a/mdadm/mdadm/Grow.c
+++ b/mdadm/mdadm/Grow.c
@@ -1699,28 +1699,32 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
break;
}
} else {
- /* set them all just in case some old 'new_*' value
- * persists from some earlier problem
+ /* set parametes here only if managemon is not responsible for this
*/
- int err = err; /* only used if rv==1, and always set if
- * rv==1, so initialisation not needed,
- * despite gcc warning
- */
- if (sysfs_set_num(sra, NULL, "chunk_size", nchunk) < 0)
- rv = 1, err = errno;
- if (!rv && sysfs_set_num(sra, NULL, "layout", nlayout) < 0)
- rv = 1, err = errno;
- if (!rv && sysfs_set_num(sra, NULL, "raid_disks", ndisks) < 0)
- rv = 1, err = errno;
- if (rv) {
- fprintf(stderr, Name ": Cannot set device shape for %s\n",
- devname);
- if (get_linux_version() < 2006030)
- fprintf(stderr, Name ": linux 2.6.30 or later required\n");
- if (err == EBUSY &&
- (array.state & (1<
- fprintf(stderr, " Bitmap must be removed before shape can be changed\n");
- break;
+ if ((st->ss->external == 0) || (st->ss->reshape_super == NULL)) {
+ /* set them all just in case some old 'new_*' value
+ * persists from some earlier problem
+ */
+ int err = err; /* only used if rv==1, and always set if
+ * rv==1, so initialisation not needed,
+ * despite gcc warning
+ */
+ if (sysfs_set_num(sra, NULL, "chunk_size", nchunk) < 0)
+ rv = 1, err = errno;
+ if (!rv && sysfs_set_num(sra, NULL, "layout", nlayout) < 0)
+ rv = 1, err = errno;
+ if (!rv && sysfs_set_num(sra, NULL, "raid_disks", ndisks) < 0)
+ rv = 1, err = errno;
+ if (rv) {
+ fprintf(stderr, Name ": Cannot set device shape for %s\n",
+ devname);
+ if (get_linux_version() < 2006030)
+ fprintf(stderr, Name ": linux 2.6.30 or later required\n");
+ if (err == EBUSY &&
+ (array.state & (1<
+ fprintf(stderr, " Bitmap must be removed before shape can be changed\n");
+ break;
+ }
}
}
@@ -2199,6 +2203,42 @@ int wait_reshape_completed_ext(struct supertype *st,
return 0;
}
+int wait_reshape_start_ext(struct supertype *st, struct mdinfo *sra)
+{
+#define WAIT_FOR_RESHAPE_START 20
+ int wait_time = WAIT_FOR_RESHAPE_START;
+ int ret_val = -1;
+ char *container = devnum2devname(st->devnum);
+
+ if (container == NULL) {
+ dprintf("wait_reshape_start_ext: cannot find container.\n");
+ return ret_val;
+ }
+ ping_manager(container);
+ ping_monitor(container);
+ while (wait_time) {
+ char action[20];
+ dprintf("wait_reshape_start_ext Waiting for reshape state (%i) ...\n", WAIT_FOR_RESHAPE_START - wait_time + 1);
+ if (sysfs_get_str(sra, NULL, "sync_action", action, 20) < 0) {
+ dprintf("Error: wait_reshape_start_ext cannot read sync_action\n");
+ break;
+ }
+ dprintf("wait_reshape_start_ext: read from sysfs: %s\n", action);
+ if (strncmp(action, "reshape", 7) == 0) {
+ dprintf("wait_reshape_start_ext: reshape started.\n");
+ ret_val = 0;
+ break;
+ }
+ ping_manager(container);
+ ping_monitor(container);
+ sleep(1);
+ wait_time--;
+ }
+
+ free(container);
+ return ret_val;
+}
+
void send_resync_max_to_mdmon(struct supertype *st,
struct mdinfo *sra,
unsigned long long resync_max)
@@ -2437,10 +2477,13 @@ static int child_same_size_ext(struct supertype *st, int afd, struct mdinfo *sra
sysfs_get_ll(sra, NULL, "sync_speed_min", &speed);
sysfs_set_num(sra, NULL, "sync_speed_min", 200000);
- /* Start the reshape - give a chance to update the metadata */
- sysfs_set_num(sra, NULL, "sync_max", 0);
- sysfs_set_str(sra, NULL, "sync_action", "reshape");
- flush_metadata_updates(st);
+ /* wait reshape is starteb by managemon
+ * - give a chance to update the metadata */
+ if (wait_reshape_start_ext(st, sra)) {
+ dprintf("Error: Reshape not started\n");
+ free(buf);
+ return -1;
+ }
size = sra->component_size / (chunk/512);
while (start < size) {
diff --git a/mdadm/mdadm/managemon.c b/mdadm/mdadm/managemon.c
index 2c7be12..8b2d73c 100644
--- a/mdadm/mdadm/managemon.c
+++ b/mdadm/mdadm/managemon.c
@@ -109,6 +109,8 @@
#include
#include
+extern char *map_num(mapping_t *map, int num);
+
static void close_aa(struct active_array *aa)
{
struct mdinfo *d;
@@ -380,6 +382,43 @@ static int disk_init_and_add(struct mdinfo *disk, struct mdinfo *clone,
return 0;
}
+int subarray_set_num_man(char *container, struct mdinfo *sra, char *name, int n)
+{
+ /* when dealing with external metadata subarrays we need to be
+ * prepared to handle EAGAIN. The kernel may need to wait for
+ * mdmon to mark the array active so the kernel can handle
+ * allocations/writeback when preparing the reshape action
+ * (md_allow_write()). We temporarily disable safe_mode_delay
+ * to close a race with the array_state going clean before the
+ * next write to raid_disks / stripe_cache_size
+ */
+ char safe[50];
+ int rc;
+#define MANAGEMON_COUNTER 20
+ int counter = MANAGEMON_COUNTER;
+
+ /* only 'raid_disks' and 'stripe_cache_size' trigger md_allow_write */
+ if (strcmp(name, "raid_disks") != 0 &&
+ strcmp(name, "stripe_cache_size") != 0)
+ return sysfs_set_num(sra, NULL, name, n);
+
+ rc = sysfs_get_str(sra, NULL, "safe_mode_delay", safe, sizeof(safe));
+ if (rc <= 0)
+ return -1;
+ sysfs_set_num(sra, NULL, "safe_mode_delay", 0);
+ rc = sysfs_set_num(sra, NULL, name, n);
+ while ((rc < 0) && counter) {
+ counter--;
+ dprintf("managemon: Try to set %s to value %i (%i time(s)).\n", name, n, MANAGEMON_COUNTER - counter);
+ wakeup_monitor();
+ usleep(250000);
+ rc = sysfs_set_num(sra, NULL, name, n);
+ }
+ sysfs_set_str(sra, NULL, "safe_mode_delay", safe);
+ return rc;
+}
+
+
static void manage_member(struct mdstat_ent *mdstat,
struct active_array *a)
{
@@ -431,17 +470,17 @@ static void manage_member(struct mdstat_ent *mdstat,
struct mdinfo *newdev = NULL;
struct mdinfo *d;
int delta_disks = a->reshape_delta_disks;
+ int status_ok = 1;
- newdev = a->container->ss->reshape_array(a, RESHAPE_IN_PROGRESS, &updates);
+ newa = duplicate_aa(a);
+ if (newa == NULL) {
+ a->reshape_delta_disks = RESHAPE_NOT_ACTIVE;
+ goto reshape_out;
+ }
+ newdev = newa->container->ss->reshape_array(newa, RESHAPE_IN_PROGRESS, &updates);
if (newdev) {
- int status_ok = 1;
- newa = duplicate_aa(a);
- if (newa == NULL)
- goto reshape_out;
-
for (d = newdev; d ; d = d->next) {
struct mdinfo *newd;
-
newd = malloc(sizeof(*newd));
if (!newd) {
status_ok = 0;
@@ -456,11 +495,41 @@ static void manage_member(struct mdstat_ent *mdstat,
}
disk_init_and_add(newd, d, newa);
}
- /* go with reshape
+ }
+ if (newa->reshape_delta_disks == RESHAPE_IN_PROGRESS) {
+ /* set reshape parametars
*/
- if (status_ok)
+ if (status_ok) {
+ dprintf("managemon: set sync_max to 0\n");
if (sysfs_set_num(&newa->info, NULL, "sync_max", 0) < 0)
status_ok = 0;
+ }
+
+ if (status_ok && newa->reshape_raid_disks) {
+ dprintf("managemon: set raid_disks to %i\n", newa->reshape_raid_disks);
+ if (subarray_set_num_man(a->container->devname, &newa->info, "raid_disks", newa->reshape_raid_disks))
+ status_ok = 0;
+ }
+
+ if (status_ok && newa->reshape_level > -1) {
+ char *c = map_num(pers, newa->reshape_level);
+ if (c == NULL)
+ status_ok = 0;
+ else {
+ dprintf("managemon: set level to %s\n", c);
+ if (sysfs_set_str(&newa->info, NULL, "level", c) < 0)
+ status_ok = 0;
+ }
+ }
+
+ if (status_ok && newa->reshape_layout >= 0) {
+ dprintf("managemon: set layout to %i\n", newa->reshape_layout);
+ if (sysfs_set_num(&newa->info, NULL, "layout", newa->reshape_layout) < 0)
+ status_ok = 0;
+ }
+
+ /* go with reshape
+ */
if (status_ok && sysfs_set_str(&newa->info, NULL, "sync_action", "reshape") == 0) {
/* reshape executed
*/
@@ -475,7 +544,10 @@ static void manage_member(struct mdstat_ent *mdstat,
newa->old_data_disks--;
if (newa->info.array.level == 6)
newa->old_data_disks--;
- newa->new_data_disks = newa->info.array.raid_disks + delta_disks;
+ if (newa->reshape_raid_disks > 0)
+ newa->new_data_disks = newa->reshape_raid_disks;
+ else
+ newa->new_data_disks = newa->info.array.raid_disks + delta_disks;
if (level == 4)
newa->new_data_disks--;
if (level == 5)
@@ -487,28 +559,35 @@ static void manage_member(struct mdstat_ent *mdstat,
replace_array(a->container, a, newa);
a = newa;
+ newa = NULL;
} else {
/* on problems cancelupdate
*/
- free_aa(newa);
free_updates(&updates);
updates = NULL;
- a->container->ss->reshape_array(a, RESHAPE_CANCEL_REQUEST, &updates);
- sysfs_set_str(&a->info, NULL, "sync_action", "idle");
+ a->reshape_delta_disks = RESHAPE_NOT_ACTIVE;
}
}
+reshape_out:
+ if (a->reshape_delta_disks == RESHAPE_NOT_ACTIVE) {
+ dprintf("Cancel reshape.\n");
+ a->container->ss->reshape_array(a, RESHAPE_CANCEL_REQUEST, &updates);
+ sysfs_set_str(&a->info, NULL, "sync_action", "idle");
+ }
dprintf("Send metadata update for reshape.\n");
queue_metadata_update(updates);
updates = NULL;
wakeup_monitor();
-reshape_out:
+
while (newdev) {
d = newdev->next;
free(newdev);
newdev = d;
}
free_updates(&updates);
+ if (newa)
+ free_aa(newa);
}
}
diff --git a/mdadm/mdadm/mdadm.h b/mdadm/mdadm/mdadm.h
index ddff47a..32db716 100644
--- a/mdadm/mdadm/mdadm.h
+++ b/mdadm/mdadm/mdadm.h
@@ -429,6 +429,8 @@ extern int sysfs_attr_match(const char *attr, const char *str);
extern int sysfs_match_word(const char *word, char **list);
extern int sysfs_set_str(struct mdinfo *sra, struct mdinfo *dev,
char *name, char *val);
+extern int sysfs_get_ll(struct mdinfo *sra, struct mdinfo *dev,
+ char *name, unsigned long long *val);
extern int sysfs_set_num(struct mdinfo *sra, struct mdinfo *dev,
char *name, unsigned long long val);
extern int sysfs_uevent(struct mdinfo *sra, char *event);
diff --git a/mdadm/mdadm/mdmon.h b/mdadm/mdadm/mdmon.h
index 8362dbd..18bd780 100644
--- a/mdadm/mdadm/mdmon.h
+++ b/mdadm/mdadm/mdmon.h
@@ -59,6 +59,9 @@ struct active_array {
#define RESHAPE_CANCEL_REQUEST (RESHAPE_IN_PROGRESS-1)
int reshape_delta_disks;
+ int reshape_raid_disks;
+ int reshape_level;
+ int reshape_layout;
unsigned long long grow_sync_max; /* sync_max from mdadm Grow */
enum reshape_wait waiting_for; /* we can wait for grow backup event
or for md reshape completed */
diff --git a/mdadm/mdadm/super-intel.c b/mdadm/mdadm/super-intel.c
index 113c3bb..f874f2f 100644
--- a/mdadm/mdadm/super-intel.c
+++ b/mdadm/mdadm/super-intel.c
@@ -344,6 +344,9 @@ struct imsm_update_reshape {
enum imsm_update_type type;
int update_memory_size;
int reshape_delta_disks;
+ int reshape_raid_disks;
+ int reshape_level;
+ int reshape_layout;
int disks_count;
int spares_in_update;
int devnum;
@@ -5684,6 +5687,7 @@ static void imsm_process_update(struct supertype *st,
__u32 new_mpb_size;
int new_disk_num;
struct intel_dev *current_dev;
+ struct imsm_dev *new_dev;
dprintf("imsm: imsm_process_update() for update_reshape [u->update_prepared = %i]\n", u->update_prepared);
if ((u->update_prepared == -1) ||
@@ -5741,11 +5745,12 @@ static void imsm_process_update(struct supertype *st,
}
/* find current dev in intel_super
*/
- dprintf("\t\tLooking for volume %s\n", (char *)u->devs_mem.dev->volume);
+ new_dev = (struct imsm_dev *)((void *)u + u->upd_devs_offset);
+ dprintf("\t\tLooking for volume %s\n", (char *)new_dev->volume);
current_dev = super->devlist;
while (current_dev) {
if (strcmp((char *)current_dev->dev->volume,
- (char *)u->devs_mem.dev->volume) == 0)
+ (char *)new_dev->volume) == 0)
break;
current_dev = current_dev->next;
}
@@ -5764,7 +5769,13 @@ static void imsm_process_update(struct supertype *st,
/* set reshape_delta_disks
*/
a->reshape_delta_disks = u->reshape_delta_disks;
-
+ a->reshape_raid_disks = u->reshape_raid_disks;
+ a->reshape_level = u->reshape_level;
+ a->reshape_layout = u->reshape_layout;
+ if (a->reshape_level == 0) {
+ a->reshape_level = 5;
+ a->reshape_layout = 5;
+ }
/* Clear migration record */
memset(super->migr_rec, 0, sizeof(struct migr_record));
@@ -6280,12 +6291,7 @@ static void imsm_prepare_update(struct supertype *st,
if (u->reshape_delta_disks < 0)
break;
u->update_prepared = 1;
- if (u->reshape_delta_disks == 0) {
- /* for non growing reshape buffers sizes are not affected
- * but check some parameters
- */
- break;
- }
+
/* count HDDs
*/
u->disks_count = 0;
@@ -7215,6 +7221,9 @@ struct imsm_update_reshape *imsm_create_metadata_update_for_reshape(struct super
}
u->reshape_delta_disks = delta_disks;
u->update_prepared = -1;
+ u->reshape_raid_disks = 0;
+ u->reshape_level = -1;
+ u->reshape_layout = -1;
u->update_memory_size = update_memory_size;
u->type = update_reshape;
u->spares_in_update = 0;
@@ -7262,6 +7271,18 @@ struct imsm_update_reshape *imsm_create_metadata_update_for_reshape(struct super
set_imsm_ord_tbl_ent(new_map, idx, idx);
}
u->devnum = geo->dev_id;
+ /* case for reshape without grow */
+ if (u->reshape_delta_disks == 0) {
+ dprintf("imsm: reshape prepate metadata for volume= %d, index= %d\n", geo->dev_id, i);
+ if (update_geometry(st, geo) == -1) {
+ dprintf("imsm: ERROR: Cannot prepare update for volume map!\n");
+ ret_val = NULL;
+ goto exit_imsm_create_metadata_update_for_reshape;
+ } else {
+ new_map->raid_level = geo->level;
+ new_map->blocks_per_strip = geo->chunksize / 512;
+ }
+ }
break;
}
}
@@ -7433,6 +7454,7 @@ int imsm_reshape_super(struct supertype *st, long long size, int level,
struct mdinfo *sra = NULL;
int fd = -1;
char buf[PATH_MAX];
+ int delta_disks = -1;
struct geo_params geo;
memset(&geo, sizeof (struct geo_params), 0);
@@ -7493,6 +7515,13 @@ int imsm_reshape_super(struct supertype *st, long long size, int level,
} else
dprintf("imsm: not a container operation\n");
+ sra = sysfs_read(fd, 0, GET_VERSION | GET_LEVEL | GET_LAYOUT |
+ GET_DISKS | GET_DEVS | GET_CHUNK | GET_SIZE);
+ if (sra == NULL) {
+ fprintf(stderr, Name ": Cannot read sysfs info (imsm)\n");
+ goto imsm_reshape_super_exit;
+ }
+
geo.dev_id = -1;
find_array_minor(geo.dev_name, 1, st->devnum, &geo.dev_id);
@@ -7505,12 +7534,6 @@ int imsm_reshape_super(struct supertype *st, long long size, int level,
int dn;
int err;
- sra = sysfs_read(fd, 0, GET_VERSION | GET_LEVEL |
- GET_LAYOUT | GET_DISKS | GET_DEVS);
- if (sra == NULL) {
- fprintf(stderr, Name ": Cannot read sysfs info (imsm)\n");
- goto imsm_reshape_super_exit;
- }
dn = devname2devnum(sra->text_version + 1);
container_fd = open_dev_excl(dn);
if (container_fd < 0) {
@@ -7538,11 +7561,49 @@ int imsm_reshape_super(struct supertype *st, long long size, int level,
goto imsm_reshape_super_exit;
}
ret_val = 0;
+ goto imsm_reshape_super_exit;
}
- sysfs_free(sra);
- sra = NULL;
}
+ /* this is not takeover
+ * continue volume check - proceed if delta_disk is zero only
+ */
+ if (geo.raid_disks > 0 && geo.raid_disks != UnSet)
+ delta_disks = geo.raid_disks - sra->array.raid_disks;
+ else
+ delta_disks = 0;
+ dprintf("imsm: imsm_reshape_super() called on array when delta disks = %i\n", delta_disks);
+ if (delta_disks == 0) {
+ struct imsm_update_reshape *u;
+ st->update_tail = &st->updates;
+ dprintf("imsm: imsm_reshape_super(): raid_disks not changed for volume reshape. Reshape allowed.\n");
+
+ if (find_array_minor(geo.dev_name, 1, st->devnum, &geo.dev_id) > -1) {
+ u = imsm_create_metadata_update_for_reshape(st, &geo);
+ if (u) {
+ if (geo.raid_disks > raid_disks)
+ u->reshape_raid_disks = geo.raid_disks;
+ u->reshape_level = geo.level;
+ u->reshape_layout = geo.layout;
+ ret_val = 0;
+ append_metadata_update(st, u, u->update_memory_size);
+ }
+ }
+ goto imsm_reshape_super_exit;
+ } else {
+ char *devname = devnum2devname(st->devnum);
+ char *devtoprint = devname;
+
+ if (devtoprint == NULL)
+ devtoprint = "Device";
+ fprintf(stderr, Name
+ ": %s cannot be reshaped. Command has to be executed on container.\n",
+ devtoprint);
+ if (devname)
+ free(devname);
+ }
+
+
imsm_reshape_super_exit:
sysfs_free(sra);
if (fd >= 0)
@@ -7829,7 +7890,8 @@ struct mdinfo *imsm_reshape_array(struct active_array *a, int request_type,
if (a->reshape_delta_disks == 0) {
dprintf("array parameters has to be changed\n");
- /* TBD */
+ a->reshape_delta_disks = RESHAPE_IN_PROGRESS;
+ return disk_list;
}
if (a->reshape_delta_disks > 0) {
dprintf("grow is detected.\n");
@@ -7850,20 +7912,18 @@ struct mdinfo *imsm_reshape_array(struct active_array *a, int request_type,
imsm_reshape_array_exit:
if (u == NULL) {
dprintf("imsm: send update update_reshape_cancel\n");
+ a->reshape_delta_disks = RESHAPE_NOT_ACTIVE;
sysfs_set_str(&a->info, NULL, "sync_action", "idle");
imsm_grow_array_remove_devices_on_cancel(a);
u = (struct imsm_update_reshape *)calloc(1, sizeof(struct imsm_update_reshape));
- if (u) {
+ if (u)
u->type = update_reshape_cancel;
- a->reshape_delta_disks = RESHAPE_NOT_ACTIVE;
- }
}
if (u) {
/* post any prepared update
*/
u->devnum = a->devnum;
-
u->update_memory_size = sizeof(struct imsm_update_reshape);
u->reshape_delta_disks = a->reshape_delta_disks;
u->update_prepared = 1;
@@ -7876,11 +7936,11 @@ imsm_reshape_array_exit:
mu->next = *updates;
*updates = mu;
} else {
+ a->reshape_delta_disks = RESHAPE_NOT_ACTIVE;
free(u);
u = NULL;
}
}
- a->reshape_delta_disks = RESHAPE_NOT_ACTIVE;
if ((disk_list) && (u == NULL)) {
while (disk_list) {
@@ -8026,7 +8086,8 @@ int imsm_child_grow(struct supertype *st, char *devname, int validate_fd, struct
void return_to_raid0(struct mdinfo *sra)
{
- if (sra->array.level == 4) {
+ if ((sra->array.level == 4) ||
+ (sra->array.level == 0)) {
dprintf("Execute backward takeover to raid0\n");
sysfs_set_str(sra, NULL, "level", "raid0");
}
@@ -8392,7 +8453,38 @@ int imsm_manage_reshape(struct supertype *st, char *backup)
* for single vlolume reshape exit only and reuse Grow_reshape() code
*/
if (st->subarray[0] != 0) {
+ char buf[PATH_MAX];
+ int fd;
+
dprintf("imsm: manage_reshape() current volume: %s (devnum = %i)\n", st->subarray, st->devnum);
+
+ snprintf(buf, PATH_MAX, "/dev/md%i", st->devnum);
+ fd = open(buf , O_RDWR | O_DIRECT);
+ if (fd > -1) {
+ struct mdinfo *info;
+ struct mdinfo sra;
+
+ sra.devs = NULL;
+ st->ss->getinfo_super(st, &sra);
+ /* wait for reshape finish
+ * and manage array size based on metadata information
+ */
+ imsm_grow_manage_size(st, &sra);
+
+ /* for level == 4: execute takeover to raid0 */
+ info = sysfs_read(fd, 0, GET_VERSION | GET_LEVEL | GET_DEVS | GET_LAYOUT);
+ if (info) {
+ /* curently md doesn't support direct translation from raid5 to raid4
+ * it has be done via raid5 layout5
+ */
+ if ((info->array.level == 5) &&
+ (info->array.layout == 5))
+ info->array.level = 4;
+ return_to_raid0(info);
+ sysfs_free(info);
+ }
+ close(fd);
+ }
return ret_val;
}
ret_val = imsm_manage_container_reshape(st);
@@ -8460,3 +8552,4 @@ struct superswitch super_imsm = {
.prepare_update = imsm_prepare_update,
#endif /* MDASSEMBLE */
};
+
--
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 20/21] Migration raid0->raid5
am 23.11.2010 13:42:20 von adam.kwolek
Add implementation for migration from raid0 to raid5 in one step.
For imsm raid level parameters flow from mdadm (vi metadata update) to managemon was added.
Block takeover for this migration case (update_reshape is used only)
For migration on container (OLCE) reinitialize variables that are changed
by single array reshape case.
Signed-off-by: Adam Kwolek
---
mdadm/mdadm/super-intel.c | 53 +++++++++++++++++++++++++++++++++++++++++----
1 files changed, 48 insertions(+), 5 deletions(-)
diff --git a/mdadm/mdadm/super-intel.c b/mdadm/mdadm/super-intel.c
index f874f2f..0b553bc 100644
--- a/mdadm/mdadm/super-intel.c
+++ b/mdadm/mdadm/super-intel.c
@@ -5335,7 +5335,7 @@ static void imsm_sync_metadata(struct supertype *container)
{
struct intel_super *super = container->sb;
- if (!super->updates_pending)
+ if (!super || !super->updates_pending)
return;
write_super_imsm(container, 0);
@@ -7193,6 +7193,13 @@ struct imsm_update_reshape *imsm_create_metadata_update_for_reshape(struct super
dprintf("imsm imsm_update_metadata_for_reshape(enter) raid_disks = %i\n", geo->raid_disks);
+ if (super == NULL || super->anchor == NULL) {
+ dprintf("Error: imsm_create_metadata_update_for_reshape(): null pointers on input\n");
+ dprintf("\t\t super = %p\n", super);
+ if (super)
+ dprintf("\t\t super->anchor = %p\n", super->anchor);
+ return ret_val;
+ }
if ((geo->raid_disks < super->anchor->num_disks) ||
(geo->raid_disks == UnSet))
geo->raid_disks = super->anchor->num_disks;
@@ -7271,8 +7278,11 @@ struct imsm_update_reshape *imsm_create_metadata_update_for_reshape(struct super
set_imsm_ord_tbl_ent(new_map, idx, idx);
}
u->devnum = geo->dev_id;
- /* case for reshape without grow */
- if (u->reshape_delta_disks == 0) {
+ /* case for reshape without grow
+ * or grow is level change effect
+ */
+ if ((u->reshape_delta_disks == 0) ||
+ ((new_map->raid_level != geo->level) && (geo->level != UnSet))) {
dprintf("imsm: reshape prepate metadata for volume= %d, index= %d\n", geo->dev_id, i);
if (update_geometry(st, geo) == -1) {
dprintf("imsm: ERROR: Cannot prepare update for volume map!\n");
@@ -7534,6 +7544,13 @@ int imsm_reshape_super(struct supertype *st, long long size, int level,
int dn;
int err;
+ /* takeover raid0->raid5 doesn't need meta update
+ * this can be handled by migrations if necessary
+ */
+ if ((geo.level == 5) && (sra->array.level == 5)) {
+ ret_val = 0;
+ goto imsm_reshape_super_exit;
+ }
dn = devname2devnum(sra->text_version + 1);
container_fd = open_dev_excl(dn);
if (container_fd < 0) {
@@ -7570,8 +7587,10 @@ int imsm_reshape_super(struct supertype *st, long long size, int level,
*/
if (geo.raid_disks > 0 && geo.raid_disks != UnSet)
delta_disks = geo.raid_disks - sra->array.raid_disks;
- else
+ else {
delta_disks = 0;
+ geo.raid_disks = sra->array.raid_disks;
+ }
dprintf("imsm: imsm_reshape_super() called on array when delta disks = %i\n", delta_disks);
if (delta_disks == 0) {
struct imsm_update_reshape *u;
@@ -7579,7 +7598,26 @@ int imsm_reshape_super(struct supertype *st, long long size, int level,
dprintf("imsm: imsm_reshape_super(): raid_disks not changed for volume reshape. Reshape allowed.\n");
if (find_array_minor(geo.dev_name, 1, st->devnum, &geo.dev_id) > -1) {
- u = imsm_create_metadata_update_for_reshape(st, &geo);
+ struct supertype *st2 = NULL;
+ struct supertype *st_tmp = st;
+ if (st->sb == NULL) {
+ close(fd);
+ /* open container
+ */
+ snprintf(buf, PATH_MAX, "/dev/md%i", st->container_dev);
+ dprintf("imsm: open device %s\n", buf);
+ fd = open(buf , O_RDWR | O_DIRECT);
+ if (fd < 0) {
+ dprintf("imsm: cannot open device %s\n", buf);
+ goto imsm_reshape_super_exit;
+ }
+ st2 = super_by_fd(fd);
+ st->ss->load_super(st2, fd, NULL);
+ if (st2)
+ st_tmp = st2;
+ }
+
+ u = imsm_create_metadata_update_for_reshape(st_tmp, &geo);
if (u) {
if (geo.raid_disks > raid_disks)
u->reshape_raid_disks = geo.raid_disks;
@@ -7587,7 +7625,10 @@ int imsm_reshape_super(struct supertype *st, long long size, int level,
u->reshape_layout = geo.layout;
ret_val = 0;
append_metadata_update(st, u, u->update_memory_size);
+
}
+ if (st2)
+ st->ss->free_super(st2);
}
goto imsm_reshape_super_exit;
} else {
@@ -8396,6 +8437,8 @@ int imsm_manage_container_reshape(struct supertype *st)
*/
dprintf("imsm: Preparing metadata update for: %s (md%i)\n", array, geo.dev_id);
st->update_tail = &st->updates;
+ geo.size = UnSet;
+ geo.level = UnSet;
u = imsm_create_metadata_update_for_reshape(st, &geo);
if (u) {
u->reshape_delta_disks = delta_disks;
--
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 21/21] Migration: Chunk size migration
am 23.11.2010 13:42:28 von adam.kwolek
Add implementation for chunk size migration for external metadata.
Update works using array parameters update in managemon. Reshape is started by managemon also.
mdadm waits for reshape array state instead starting reshape process.
For imsm chunk size parameter flow, from mdadm (via metadata update) to managemon was added.
Signed-off-by: Adam Kwolek
---
mdadm/mdadm/managemon.c | 6 ++++++
mdadm/mdadm/mdmon.h | 1 +
mdadm/mdadm/super-intel.c | 4 ++++
3 files changed, 11 insertions(+), 0 deletions(-)
diff --git a/mdadm/mdadm/managemon.c b/mdadm/mdadm/managemon.c
index 8b2d73c..860354a 100644
--- a/mdadm/mdadm/managemon.c
+++ b/mdadm/mdadm/managemon.c
@@ -522,6 +522,12 @@ static void manage_member(struct mdstat_ent *mdstat,
}
}
+ if (status_ok && newa->reshape_chunk_size > 0) {
+ dprintf("managemon: set chunk_size to %i\n", newa->reshape_chunk_size);
+ if (sysfs_set_num(&newa->info, NULL, "chunk_size", newa->reshape_chunk_size) < 0)
+ status_ok = 0;
+ }
+
if (status_ok && newa->reshape_layout >= 0) {
dprintf("managemon: set layout to %i\n", newa->reshape_layout);
if (sysfs_set_num(&newa->info, NULL, "layout", newa->reshape_layout) < 0)
diff --git a/mdadm/mdadm/mdmon.h b/mdadm/mdadm/mdmon.h
index 18bd780..cf8c1f2 100644
--- a/mdadm/mdadm/mdmon.h
+++ b/mdadm/mdadm/mdmon.h
@@ -62,6 +62,7 @@ struct active_array {
int reshape_raid_disks;
int reshape_level;
int reshape_layout;
+ int reshape_chunk_size;
unsigned long long grow_sync_max; /* sync_max from mdadm Grow */
enum reshape_wait waiting_for; /* we can wait for grow backup event
or for md reshape completed */
diff --git a/mdadm/mdadm/super-intel.c b/mdadm/mdadm/super-intel.c
index 0b553bc..2d61df4 100644
--- a/mdadm/mdadm/super-intel.c
+++ b/mdadm/mdadm/super-intel.c
@@ -347,6 +347,7 @@ struct imsm_update_reshape {
int reshape_raid_disks;
int reshape_level;
int reshape_layout;
+ int reshape_chunk_size;
int disks_count;
int spares_in_update;
int devnum;
@@ -5776,6 +5777,7 @@ static void imsm_process_update(struct supertype *st,
a->reshape_level = 5;
a->reshape_layout = 5;
}
+ a->reshape_chunk_size = u->reshape_chunk_size;
/* Clear migration record */
memset(super->migr_rec, 0, sizeof(struct migr_record));
@@ -7231,6 +7233,7 @@ struct imsm_update_reshape *imsm_create_metadata_update_for_reshape(struct super
u->reshape_raid_disks = 0;
u->reshape_level = -1;
u->reshape_layout = -1;
+ u->reshape_chunk_size = -1;
u->update_memory_size = update_memory_size;
u->type = update_reshape;
u->spares_in_update = 0;
@@ -7623,6 +7626,7 @@ int imsm_reshape_super(struct supertype *st, long long size, int level,
u->reshape_raid_disks = geo.raid_disks;
u->reshape_level = geo.level;
u->reshape_layout = geo.layout;
+ u->reshape_chunk_size = geo.chunksize;
ret_val = 0;
append_metadata_update(st, u, u->update_memory_size);
--
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 00/21] Series short description
am 24.11.2010 06:04:48 von NeilBrown
On Tue, 23 Nov 2010 13:39:38 +0100
Adam Kwolek wrote:
> This patch series bases on previously sent patch series: array/container freezing by Dan Williams, and my and Maciej Trela's patches for OLCE and check pointing for external metadata.
> This patch series implements:
> 1. Patches 0001 to 0018 : fixes for freezing, OLCE and check pointing
> 2. Patches 0018 to 0021 : implements new migration features for external metadata:
> - Migration raid0 to raid5
> - Migration raid5 to raid0
> - Chunk size migration
I'm afraid this series isn't much use to me.
It appears to be intended to apply after the previous set of 31 patches you
posted. However I haven't applied any of those. I responded to the first 6
explaining why each was either wrong, unacceptable, or not explained well
enough for me to review it properly, and I just stopped at 6.
So for example,
[PATCH 04/21] FIX: Use MDADM_EXPERIMENTAL environment variable
is of no use to me as I never applied the patch that it tried to fix.
I could probably pick out the patches that can still apply, but I'd rather
not have to.
Please send a set of patches against my devel-3.6 branch with any 'fixes' to
your own patches already merged back into those patches.
Then I will apply as much as I can, and explain was is need to make any other
acceptable.
Thanks,
NeilBrown
>
> We are planning in the few days add fixes for raid10 <-> raid0 takeover also.
>
> Migration feature reuses code flow introduced for OLCE (Online Capacity Expansion) and uses the same grow/reshape flow in mdadm/mdmon.
> Migration is executed in the following way:
> 1. mdadm: reshape_super() prepares metadata update and sends it to mdmon
> 2. mdadm: waits for reshape array state
> 3. monitor: receives metadata update and applies it.
> 4. monitor: metadata update triggers managemon.
> 5. managemon: updates array (md) configuration and starts reshape
> 6. mdadm: finds that reshape is started and continues it using check pointing
> 7. mdadm: reshape is finished and manage_reshape() finalizes array:
> - Sets array size as is given in metadata
> - Performs takeover to raid0 if necessary
>
> In current patches placement of manage_reshape() function call was changed.
> It is moved to end of array processing to use common code form Grow.c for external metadata reshape case
> (we do not need to duplicate existing code) as it would do the same things as code for native metadata.
> New manage_reshape() placement causes a few things to do in implementation only and simplifees code.
>
> Migrations command line:
> 1. Execute migration raid0->raid5:
> mdadm - -grow /dev/md/array_name -level 5 -layout=left-asymmetric
>
> This converts n-disks raid0 array to (n+1)-disks raid5 array. Additional raid5 array disk is user from spares pool
>
> 2. Execute migration raid5->raid0:
> mdadm - -grow /dev/md/array_name -level 0
>
> This converts n-disks raid5 array to n-disks raid0 array.
> 3. Execute chunk size migration
> mdadm - -grow /dev/md/array_name -chunk N
>
> where N is ne chunk size value
>
> In current patch series testing of 'experimental' flag was changes according to Neil's suggestion, as I've found it useable for my testing purposes.
> The rest of comments to already reviewed patches (OLCE/check pointing) will be implemented in next step.
>
>
> ---
>
> Adam Kwolek (21):
> Migration: Chunk size migration
> Migration raid0->raid5
> Migration: raid5->raid0
> imsm: Use geo structure
> Change manage_reshape() placement
> FIX: Start mdmon after changing level
> FIX: Checkpointing: Enable checkpointing for non-growing migrations
> FIX: Level field can be NULL
> imsm Fix: Core during rebuild on array details read
> WORKAROUND: md reports idle state during reshape start
> FIX: Honor !reshape state on wait_reshape() entry
> FIX: Unfreeze not only container for external metadata
> FIX: Cannot exit monitor after takeover
> imsm: FIX: Continue expansion after -As command
> imsm: FIX: Reshape Cancel message on 2nd array doesn't work correctly
> imsm: FIX: Guard size setting
> FIX: Allow for reshape without backup file
> FIX: Use MDADM_EXPERIMENTAL environment variable
> imsm: FIX: imsm_check_reshape_conditions change ret_val
> imsm: Change some debug output information
> imsm: Remove unnecessary code
>
>
> mdadm/mdadm/Detail.c | 1
> mdadm/mdadm/Grow.c | 178 ++++++++----
> mdadm/mdadm/Makefile | 6
> mdadm/mdadm/managemon.c | 113 ++++++-
> mdadm/mdadm/mdadm.h | 7
> mdadm/mdadm/mdmon.h | 4
> mdadm/mdadm/mdstat.c | 2
> mdadm/mdadm/monitor.c | 11 +
> mdadm/mdadm/msg.c | 5
> mdadm/mdadm/restripe.c | 1
> mdadm/mdadm/super-intel.c | 693 +++++++++++++++++++++++++++++++++------------
> mdadm/mdadm/util.c | 88 +++++-
> 12 files changed, 830 insertions(+), 279 deletions(-)
>
--
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