[dmraid] Fixes for IMSM data corruption

Heinz Mauelshagen mauelsha at fedoraproject.org
Thu Nov 4 15:02:55 UTC 2010


commit a2244439e8b2c7f61094ac1f013881f17b6b04bd
Author: Heinz.Mauelshagen <heinzm at redhat.com>
Date:   Thu Nov 4 16:02:37 2010 +0100

    Fixes for IMSM data corruption

 ..._19-enabling_registration_degraded_volume.patch |  176 ++++++++++++++++
 bz626417_20-cleanup_some_compilation_warning.patch |   63 ++++++
 ...ption_that_postpones_any_metadata_updates.patch |  215 ++++++++++++++++++++
 ...ssage_after_unsuccessful_vol_registration.patch |   14 ++
 ...ring_activation_volume_marked_for_rebuild.patch |   88 ++++++++
 dmraid.spec                                        |   14 ++-
 6 files changed, 569 insertions(+), 1 deletions(-)
---
diff --git a/bz626417_19-enabling_registration_degraded_volume.patch b/bz626417_19-enabling_registration_degraded_volume.patch
new file mode 100644
index 0000000..d6f3c92
--- /dev/null
+++ b/bz626417_19-enabling_registration_degraded_volume.patch
@@ -0,0 +1,176 @@
+--- a/lib/events/libdmraid-events-isw.c	
++++ a/lib/events/libdmraid-events-isw.c	
+@@ -308,6 +308,7 @@ static void __dso_dev_copy(struct dso_raid_dev *dst, struct dso_raid_dev *src)
+ 	strcpy(dst->name, src->name);
+ 	strcpy(dst->major_minor, src->major_minor);
+ 	dst->port = src->port;
++	dst->active = src->active;
+ }
+ 
+ /* Copy a struct dso_raid_dev. */
+@@ -316,7 +317,7 @@ static void _dso_dev_copy(struct dso_raid_set *rs, struct dso_raid_dev *dst)
+ 	struct dso_raid_dev *src = rs->devs + rs->num_devs - 1;
+ 
+ 	if (rs->num_devs < 0)
+-		syslog(LOG_ERR, "Programatic error: num_devs < o");
++		syslog(LOG_ERR, "Programatic error: num_devs < 0");
+ 
+ 	if (src != dst)
+ 		__dso_dev_copy(dst, src);
+@@ -595,7 +596,7 @@ static int _get_sysfs_major_minor(const char *d_name, char *major_minor,
+  * Retrieve device properties for @dev_name from sysfs
+  * (major:minor and port number) into @dev.
+  *
+- * Return 0 for failure, 0 for success.
++ * Return 1 for failure, 0 for success.
+  */
+ /* FIXME: straighten this by using libsysfs ? */
+ static int _set_raid_dev_properties(const char *dev_name,
+@@ -611,11 +612,11 @@ static int _set_raid_dev_properties(const char *dev_name,
+ 
+ 	/* Get major:minor of this RAID device. */
+ 	if (_get_sysfs_major_minor(dev_name, dev->major_minor, log_type))
+-		return -ENOENT;
++		return 1;
+ 
+ 	dir_entries = _scandir(sys_scsi_path, &dir_ent, _scandir_dot_filter);
+ 	if (dir_entries < 0)
+-		return -ENOENT;
++		return 1;
+ 
+ 	/* Remember length of initial sysfs path. */
+ 	strcpy(path, sys_scsi_path);
+@@ -788,8 +789,8 @@ static struct dso_raid_set *_add_raid_dev(struct dso_raid_set *rs,
+ 			grown_raid_set->devs + grown_raid_set->num_devs - 1;
+ 
+ 		if (_set_raid_dev_properties(d_name, dev, log_type)) {
+-			dm_free(grown_raid_set);
+-			return NULL;
++			/* Unable to get device properties - reset them to initial values */
++			_dso_dev_init(dev);
+ 		}
+ 	}
+ 
+@@ -915,11 +916,9 @@ static struct dso_raid_set *_get_slave_devices(const char *rs_name,
+ 
+ 		/* Append to RAID sets list of RAID devices. */
+ 		rs = _add_raid_dev(rs, rs_name, d_name, log_type);
+-		if (!rs)
+-			break;
++		_check_raid_dev_active(d_name, rs->devs + rs->num_devs - 1);
+ 
+ 		dm_free(dir_ent[i]);
+-		_check_raid_dev_active(d_name, rs->devs + rs->num_devs - 1);
+ 	}
+ 
+ 	_destroy_dirent(dir_ent, i, dir_entries);
+@@ -957,6 +956,7 @@ static struct dso_raid_set *_create_raid_set(const char *rs_name,
+ 	struct dm_task *dmt;
+ 	struct dm_info dev_info;
+ 	struct dirent *dent, **dir_ent;
++	struct dso_raid_dev *dev = NULL;
+ 
+ 	/* Get device Info. */
+ 	dmt = dm_task_create(DM_DEVICE_INFO);
+@@ -1007,6 +1007,15 @@ static struct dso_raid_set *_create_raid_set(const char *rs_name,
+ 		free(dent);
+ 	}
+ 
++	 /* Check if all devices are avaliable */
++	for (dev = rs->devs, i = 0; i < rs->num_devs; i++, dev++) {
++	    	/* If there is no major:minor number device is missing */
++		if (*dev->major_minor == '\0') {
++			/* Replace failed device with last device in set; reduce num_devs. */
++			_dso_dev_copy(rs, dev);
++		}
++	}
++	
+ 	return rs;
+ }
+ 
+@@ -1292,13 +1301,13 @@ static enum disk_state_type _process_raid45_event(struct dm_task *dmt,
+ 
+ 	dev_status_str = args[num_devs + 1];
+ 
+-	/* Consistency check on num_devs and status chars. */
+-	i = _get_num_devs_from_status(dev_status_str);
+-	if (i != num_devs)
+-		goto err;
++	/* check if is it rebuilding in progress */
++	if (strchr(dev_status_str, 'i'))
++	    return D_FAILURE_NOSYNC;
+ 
++	syslog(LOG_INFO, "dev_status_str= %s", dev_status_str);
+ 	/* Check for bad raid45 devices. */
+-	for (i = 0, p = dev_status_str; i < rs->num_devs; i++) {
++	for (i = 0, p = dev_status_str; i <= rs->num_devs; i++) {
+ 		/* Skip past any non active/dead identifiers. */
+ 		dead = *(p++) == 'D';
+ 		while (*p && *p != 'A' && *p != 'D')
+@@ -1318,7 +1327,8 @@ static enum disk_state_type _process_raid45_event(struct dm_task *dmt,
+ 			/* Copy last device in set; reduce num_devs. */
+ 			_dso_dev_copy(rs, dev);
+ 			ret = D_FAILURE_DISK;
+-		}
++		} else 
++		    ret = D_FAILURE_NOSYNC;
+ 	}
+ 
+ 	return ret;
+--- a/lib/register/dmreg.c	
++++ a/lib/register/dmreg.c	
+@@ -374,6 +374,7 @@ static int _dm_raid_state(char *dev_name)
+ 				/* Skip past raid45 target chars. */
+ 				if (status[i] != 'p' &&
+ 				    status[i] != 'i' &&
++				    status[i] != 'D' &&
+ 				    status[i] != 'A')
+ 					errors++;
+ 			}
+@@ -422,17 +423,34 @@ static int _validate_dev_and_dso_names(char *dev_name, char *dso_name)
+ 	return (dso_name && _dm_valid_dso(dso_name)) ? 1 : 0;
+ }
+ 
++/*
++ * Function removes unnecassary path to the DSO library
++ * (leaves only library name)
++ */
++char * dso_lib_name_prepare(char * dso_path) 
++{
++	char *ptr = NULL;
++	char *lib_name = dso_path;
++
++	while (ptr = strchr(lib_name, '/'))
++	    lib_name = ptr + 1;
++	
++	return lib_name;
++}
++
+ /* Register a device to be monitored for events. */
+ /* FIXME: correct dev_name vs. _dm_raid_state() check of device. */
+ int dm_register_device(char *dev_name, char *dso_name)
+ {	
+-	int errors, pending,
+-	    ret = _validate_dev_and_dso_names(dev_name, dso_name);
++	int errors, pending,ret;
++	char *dso_lib_name = dso_lib_name_prepare(dso_name);
++	
++	ret= _validate_dev_and_dso_names(dev_name, dso_lib_name);
+ 
+ 	if (ret)
+ 		return ret;
+ 
+-	if (dm_monitored_events(&pending, dev_name, dso_name)) {
++	if (dm_monitored_events(&pending, dev_name, dso_lib_name)) {
+ 		printf("ERROR: device \"%s\" %s\n", dev_name,
+ 		       pending ? "has a registration event pending" :
+ 				 "is already being monitored");
+@@ -452,7 +470,7 @@ int dm_register_device(char *dev_name, char *dso_name)
+ 		return 1;
+ 	}
+ 
+-	if (_dm_set_events(EVENTS_REGISTER, dev_name, dso_name)) {
++	if (_dm_set_events(EVENTS_REGISTER, dev_name, dso_lib_name)) {
+ 		printf("ERROR:  Unable to register a device mapper "
+ 		       "event handler for device \"%s\"\n", dev_name);
+ 		return 1;
diff --git a/bz626417_20-cleanup_some_compilation_warning.patch b/bz626417_20-cleanup_some_compilation_warning.patch
new file mode 100644
index 0000000..228ecb1
--- /dev/null
+++ b/bz626417_20-cleanup_some_compilation_warning.patch
@@ -0,0 +1,63 @@
+--- a/lib/events/libdmraid-events-isw.c	
++++ a/lib/events/libdmraid-events-isw.c	
+@@ -101,13 +101,12 @@ enum rebuild_type { REBUILD_START, REBUILD_END };
+ static const char *default_dmraid_events_lib = "libdmraid-events.so";
+ static const char *sys_dm_dm = "dm-";
+ static const char *sys_block_path = "/sys/block/";
+-static const char *sys_dm_path = "/sys/block/dm-";
++//static const char *sys_dm_path = "/sys/block/dm-";
+ static const char *sys_scsi_path = "/sys/class/scsi_device/";
+ static const char *sys_slaves_dir = "/slaves";
+ static const char *sys_scsi_dev_blk = "/device/block";
+ static const char sys_scsi_dev_blk_delims[] = { '/', ':' };
+ static const char *sys_dev_dir = "/dev";
+-static const char *syslog_ident = "libdmraid-events";
+ 
+ /* Logging. */
+ enum log_type { LOG_NAMES, LOG_PORTS, LOG_OPEN_FAILURE, LOG_NONE };
+@@ -1534,7 +1533,7 @@ int register_device(const char *rs_name, const char *uuid,
+ 	/* FIXME: need to run first to get syslog() to work. */
+ 	_check_sgpio();
+ 
+-	rs_name = basename(rs_name);
++	rs_name = basename((char *)rs_name);
+ 
+ 	/* Check for double registration attempt. */
+ 	pthread_mutex_lock(&_register_mutex);
+@@ -1595,7 +1594,7 @@ int unregister_device(const char *rs_name, const char *uuid,
+ {
+ 	struct dso_raid_set *prev, *rs;
+ 
+-	rs_name = basename(rs_name);
++	rs_name = basename((char *)rs_name);
+ 
+ 	pthread_mutex_lock(&_register_mutex);
+ 
+--- a/lib/format/ataraid/isw.c	
++++ a/lib/format/ataraid/isw.c	
+@@ -1250,7 +1250,7 @@ static int
+ isw_metadata_handler(struct lib_context *lc, enum handler_commands command,
+ 		     struct handler_info *info, void *context)
+ {
+-	int idx, ret = 0;
++	int ret = 0;
+ 	struct raid_set *rs = context;
+ 	struct raid_dev *rd = list_entry(rs->devs.next, struct raid_dev, devs);
+ 	struct isw *isw, *new_isw;
+--- a/lib/register/dmreg.c	
++++ a/lib/register/dmreg.c	
+@@ -427,12 +427,12 @@ static int _validate_dev_and_dso_names(char *dev_name, char *dso_name)
+  * Function removes unnecassary path to the DSO library
+  * (leaves only library name)
+  */
+-char * dso_lib_name_prepare(char * dso_path) 
++char *dso_lib_name_prepare(char *dso_path) 
+ {
+ 	char *ptr = NULL;
+ 	char *lib_name = dso_path;
+ 
+-	while (ptr = strchr(lib_name, '/'))
++	while ((ptr = strchr(lib_name, '/')) != NULL)
+ 	    lib_name = ptr + 1;
+ 	
+ 	return lib_name;
diff --git a/bz626417_21-add_option_that_postpones_any_metadata_updates.patch b/bz626417_21-add_option_that_postpones_any_metadata_updates.patch
new file mode 100644
index 0000000..e899599
--- /dev/null
+++ b/bz626417_21-add_option_that_postpones_any_metadata_updates.patch
@@ -0,0 +1,215 @@
+diff --git a/include/dmraid/lib_context.h b/include/dmraid/lib_context.h
+index c2e16e6..c2b3c4d 100644
+--- a/include/dmraid/lib_context.h
++++ b/include/dmraid/lib_context.h
+@@ -46,7 +46,8 @@ enum lc_options {
+ 	LC_CREATE,
+ 	LC_REBUILD_SET,
+ 	LC_REBUILD_DISK,
+-	LC_HOT_SPARE_SET,	/* Add new options below this one ! */
++	LC_HOT_SPARE_SET,	
++	LC_DEFER_UPDATE,	/* Add new options below this one ! */
+ 	LC_OPTIONS_SIZE,	/* Must be the last enumerator. */
+ };
+ 
+@@ -67,6 +68,7 @@ enum lc_options {
+ #define	OPT_CREATE(lc)		(lc_opt(lc, LC_CREATE))
+ #define OPT_HOT_SPARE_SET(lc)	(lc_opt(lc, LC_HOT_SPARE_SET))
+ #define OPT_REBUILD_DISK(lc)	(lc_opt(lc, LC_REBUILD_DISK))
++#define OPT_DEFER_UPDATE(lc)	(lc_opt(lc, LC_DEFER_UPDATE))
+ 
+ /* Return option value. */
+ #define	OPT_STR(lc, o)		(lc->options[o].arg.str)
+@@ -76,6 +78,7 @@ enum lc_options {
+ #define	OPT_STR_PARTCHAR(lc)	OPT_STR(lc, LC_PARTCHAR)
+ #define OPT_STR_HOT_SPARE_SET(lc)	OPT_STR(lc, LC_HOT_SPARE_SET)
+ #define OPT_STR_REBUILD_DISK(lc)	OPT_STR(lc, LC_REBUILD_DISK)
++#define OPT_STR_DEFER_UPDATE(lc)	OPT_STR(lc, LC_DEFER_UPDATE)
+ 
+ struct lib_version {
+ 	const char *text;
+diff --git a/lib/metadata/reconfig.c b/lib/metadata/reconfig.c
+index 73f7604..19768a9 100644
+--- a/lib/metadata/reconfig.c
++++ b/lib/metadata/reconfig.c
+@@ -249,9 +249,9 @@ add_dev_to_raid(struct lib_context *lc, struct raid_set *rs,
+ 			strncat(lib_name, ".so", 3);
+ 		} else
+ 			goto err;
+-
++		
+ 		/* Check registration */
+-		if (!dm_monitored_events(&pending, sub_rs->name, lib_name)) {
++		if (!dm_monitored_events(&pending, sub_rs->name, lib_name) && !OPT_DEFER_UPDATE(lc)) {
+ 			/* If NOT registered update metadata to OK state. */
+ 			if (check_rd->fmt->metadata_handler)
+ 				check_rd->fmt->metadata_handler(lc, UPDATE_REBUILD_STATE, NULL, (void *) rs);
+diff --git a/man/dmraid.8 b/man/dmraid.8
+index b4de737..62a6091 100644
+--- a/man/dmraid.8
++++ b/man/dmraid.8
+@@ -11,6 +11,7 @@ dmraid \- discover, configure and activate software (ATA)RAID
+  [-Z|--rm_partitions]
+  [--separator SEPARATOR]
+  [-t|--test]
++ [-u|--update_defer]
+  [RAID-set...]
+ 
+ .B dmraid
+@@ -38,6 +39,7 @@ dmraid \- discover, configure and activate software (ATA)RAID
+  {-R| --rebuild}
+  RAID-set
+  [device-path]
++ [-u|--update_defer]
+ 
+ .B dmraid
+  {-x| --remove}
+@@ -118,7 +120,14 @@ underlying the set, ie if sda is part of the set, remove sda1, sda2, etc.
+ This prevents applications from directly accessiong the disks bypassing dmraid.
+ RAID set names given on command line don't need to be fully specified
+ (eg, "dmraid -ay sil" would activate all discovered Silicon Image Medley
+-RAID sets).
++RAID sets). Option 
++.B -u
++defers metadata update in case of rebuild is triggered parallelly with activation.
++Awoids metadata update to "OK" state if volume is not registered to the event
++monitoring. 
++Useful if volume is activating at early stage of booting process when registration
++to the event monitoring is impossible.
++
+ 
+ .TP
+ .I {-b|--block_devices} [device-path...]
+@@ -208,7 +217,11 @@ Use CHAR as the separator between the device name and the partition number.
+ .I {-R| --rebuild} RAID-set [device-path]
+ Rebuild raid array after a drive has failed and a new drive is added. 
+ For Intel chipset based systems, there are two methods in which a new drive 
+-is added to the system.
++is added to the system. Option
++.B -u
++defers metadata update in case of rebuild is triggered. 
++Awoids metadata update to "OK" state if volume is not registered to the event
++monitoring. 
+ 
+ 1. Using OROM to identify a new drive
+     During system reboot, enter OROM and mark the new drive as the rebuild drive.  
+diff --git a/tools/commands.c b/tools/commands.c
+index 4c71ae1..a3c77d2 100644
+--- a/tools/commands.c
++++ b/tools/commands.c
+@@ -30,7 +30,7 @@ int add_dev_to_array(struct lib_context *lc, struct raid_set *rs,
+ /*
+  * Command line options.
+  */
+-static char const *short_opts = "a:hipP:"
++static char const *short_opts = "a:hipP:u"
+ #ifndef	DMRAID_MINI
+ 	"bc::dDEf:glxM:"
+ #ifdef	DMRAID_NATIVE_LOG
+@@ -46,6 +46,7 @@ static struct option long_opts[] = {
+ 	{"format", required_argument, NULL, 'f'},
+ 	{"partchar", required_argument, NULL, 'P'},
+ 	{"no_partitions", no_argument, NULL, 'p'},
++	{"update_defer", no_argument, NULL, 'u'},
+ # ifndef DMRAID_MINI
+ 	{"block_devices", no_argument, NULL, 'b'},
+ 	{"display_columns", optional_argument, NULL, 'c'},
+@@ -197,6 +198,15 @@ check_part_separator(struct lib_context *lc, int arg)
+ 	return lc_stralloc_opt(lc, LC_PARTCHAR, optarg) ? 1 : 0;
+ }
+ 
++/* Defer any mtadata updates in case of volume activation 
++ * at early stage of OS boot */
++static int
++defer_update(struct lib_context *lc, int arg)
++{
++    	lc_inc_opt(lc, arg);
++	return 1;
++}
++
+ /* Display help information */
+ static int
+ help(struct lib_context *lc, int arg)
+@@ -211,6 +221,7 @@ help(struct lib_context *lc, int arg)
+ 		  "\t[-P|--partchar CHAR]\n"
+ 		  "\t[-p|--no_partitions]\n"
+ 		  "\t[-Z|--rm_partitions]\n"
++		  "\t[-d|--update_defer]\n"
+ 		  "\t[--separator SEPARATOR]\n" "\t[RAID-set...]\n", c);
+ 	log_print(lc, "%s\t{-h|--help}\n", c);
+ 	log_print(lc, "%s\t{-V/--version}\n", c);
+@@ -219,11 +230,12 @@ help(struct lib_context *lc, int arg)
+ 	log_print(lc,
+ 		  "* = [-d|--debug]... [-v|--verbose]... [-i|--ignorelocking]\n");
+ 	log_print(lc,
+-		  "%s\t{-a|--activate} {y|n|yes|no} *\n"
++		  "%s\t{-a|--activate} {y|n|yes|no} \n"
+ 		  "\t[-f|--format FORMAT[,FORMAT...]]\n"
+ 		  "\t[-P|--partchar CHAR]\n" "\t[-p|--no_partitions]\n"
+ 		  "\t[--separator SEPARATOR]\n" "\t[-t|--test]\n"
+-		  "\t[-Z|--rm_partitions] [RAID-set...]\n", c);
++		  "\t[-Z|--rm_partitions] [RAID-set...]\n"
++		  "\t[-u|--update_defer]", c);
+ 	log_print(lc,
+ 		  "%s\t{-b|--block_devices} *\n"
+ 		  "\t[-c|--display_columns][FIELD[,FIELD...]]...\n"
+@@ -255,7 +267,8 @@ help(struct lib_context *lc, int arg)
+ 		  "\t[--str[i[de]] [0-9]...[kK][bB]]\n"
+ 		  "\t{--disk[s] \"device-path[, device-path...\"}\n", c);
+ 	log_print(lc, "%s\t{-x|--remove RAID-set} \n");
+-	log_print(lc, "%s\t{-R|--rebuild} RAID-set [drive_name]\n", c);
++	log_print(lc, "%s\t{-R|--rebuild} RAID-set [drive_name]\n"
++		  "\t[-u|--update_defer]", c);
+ 	log_print(lc, "%s\t[{-f|--format FORMAT}]\n"
+ 		  "\t{-S|--spare [RAID-set]} \n"
+ 		  "\t{-M|--media \"device-path\"}\n", c);
+@@ -285,6 +298,19 @@ static struct actions actions[] = {
+ 	 0,
+ 	 },
+ 
++	/* Defer metadata update */
++	{'u',
++	 UNDEF,
++	 UNDEF,
++	 ACTIVATE | REBUILD
++#ifndef DMRAID_MINI
++	 | DBG | TEST | VERBOSE
++#endif
++	 , NO_ARGS,
++	 defer_update,
++	 LC_DEFER_UPDATE,
++	 },
++
+ 	/* Format option. */
+ 	{'f',
+ 	 FORMAT,
+@@ -726,7 +752,7 @@ handle_args(struct lib_context *lc, int argc, char ***argv)
+ 		if (o == 'C') {
+ 			*argv += optind - 1;
+ 			return 1;
+-		} else if (o == 'R' && argc == 4) {
++		} else if (o == 'R' && (argc == 4 || argc == 5)) {
+ 			if (*(*argv + optind))
+ 				save_drive_name(lc, *(*argv + optind));
+ 		}
+@@ -744,7 +770,7 @@ handle_args(struct lib_context *lc, int argc, char ***argv)
+ 		ret = check_actions_arguments(lc);
+ 
+ 	*argv += optind;
+-	if (argc == 4 && lc->options[LC_REBUILD_SET].opt)
++	if ((argc == 4 || argc == 5) && lc->options[LC_REBUILD_SET].opt)
+ 		*argv += 1;
+ 
+ 	return ret;
+@@ -871,7 +897,7 @@ struct prepost prepost[] = {
+ 	 0,
+ 	 activate_or_deactivate_sets,
+ 	 },
+-
++	
+ #ifndef DMRAID_MINI
+ 	/* Display block devices. */
+ 	{BLOCK_DEVICES,
+-- 
+1.7.0.4
+
diff --git a/bz626417_8-faulty_message_after_unsuccessful_vol_registration.patch b/bz626417_8-faulty_message_after_unsuccessful_vol_registration.patch
new file mode 100644
index 0000000..18a633a
--- /dev/null
+++ b/bz626417_8-faulty_message_after_unsuccessful_vol_registration.patch
@@ -0,0 +1,14 @@
+--- a/daemons/dmeventd/dmeventd.c	
++++ a/daemons/dmeventd/dmeventd.c	
+@@ -969,8 +969,10 @@ static int _register_for_event(struct message_data *message_data)
+ 	if (!(thread = _lookup_thread_status(message_data))) {
+ 		_unlock_mutex();
+ 
+-		if (!(ret = _do_register_device(thread_new)))
++		if (!_do_register_device(thread_new)) {
++			ret = -1;
+ 			goto out;
++		}
+ 
+ 		thread = thread_new;
+ 		thread_new = NULL;
diff --git a/bz635995-data_corruption_during_activation_volume_marked_for_rebuild.patch b/bz635995-data_corruption_during_activation_volume_marked_for_rebuild.patch
new file mode 100644
index 0000000..2a902e1
--- /dev/null
+++ b/bz635995-data_corruption_during_activation_volume_marked_for_rebuild.patch
@@ -0,0 +1,88 @@
+--- a/lib/activate/activate.c	
++++ a/lib/activate/activate.c	
+@@ -370,7 +370,10 @@ get_dm_devs(struct raid_set *rs, int valid)
+ 	return ret + get_rds(rs, valid);
+ }
+ 
+-/* Retrieve number of drive to rebuild from metadata format handler. */
++/* Retrieve number of drive to rebuild from metadata format handler.
++ *
++ * Returns number of drive to rebuild or -1 if there is no drive to rebuild
++ */
+ static int
+ get_rebuild_drive(struct lib_context *lc, struct raid_set *rs,
+ 		  struct handler_info *info)
+@@ -378,25 +381,23 @@ get_rebuild_drive(struct lib_context *lc, struct raid_set *rs,
+ 	/* Initialize drive to rebuild invalid. */
+ 	info->data.i32 = -1;
+ 
+-	if (lc->options[LC_REBUILD_SET].opt) {
+-		struct raid_dev *rd;
++	struct raid_dev *rd;
+ 
+-		if (list_empty(&rs->devs))
+-			LOG_ERR(lc, 0, "RAID set has no devices!");
++	if (list_empty(&rs->devs))
++		LOG_ERR(lc, 0, "RAID set has no devices!");
+ 
+-		rd = list_entry(rs->devs.next, typeof(*rd), devs);
+-		if (rd->fmt->metadata_handler) {
+-			if (!rd->
+-			    fmt->metadata_handler(lc, GET_REBUILD_DRIVE_NO,
+-						  info, rs))
+-				LOG_ERR(lc, 0, "Can't get rebuild drive #!");
+-		} else
+-			LOG_ERR(lc, 0,
+-				"Can't rebuild w/o metadata_handler for %s",
+-				rd->fmt->name);
+-	}
++	rd = list_entry(rs->devs.next, typeof(*rd), devs);
++	if (rd->fmt->metadata_handler) {
++		if (!rd->
++		    fmt->metadata_handler(lc, GET_REBUILD_DRIVE_NO,
++					  info, rs))
++			LOG_ERR(lc, 0, "Can't get rebuild drive #!");
++	} else
++		LOG_ERR(lc, 0,
++			"Can't rebuild w/o metadata_handler for %s",
++			rd->fmt->name);
+ 
+-	return 1;
++	return info->data.i32;
+ }
+ 
+ /* Return true if RAID set needs rebuilding. */
+@@ -458,7 +459,7 @@ dm_raid1(struct lib_context *lc, char **table, struct raid_set *rs)
+ 	 */
+ 	need_sync = rs_need_sync(rs);
+ 	rebuild_drive.data.i32 = -1;
+-	if (need_sync && !get_rebuild_drive(lc, rs, &rebuild_drive))
++	if (need_sync && get_rebuild_drive(lc, rs, &rebuild_drive) < 0)
+ 		return 0;
+ 
+ 	if (!_dm_raid1_bol(lc, table, rs, sectors, mirrors, need_sync))
+@@ -540,7 +541,7 @@ _dm_raid45_bol(struct lib_context *lc, char **table, struct raid_set *rs,
+ 
+ 	/* Get drive as rebuild target. */
+ 	rebuild_drive.data.i32 = -1;
+-	if (need_sync && !get_rebuild_drive(lc, rs, &rebuild_drive))
++	if (need_sync && get_rebuild_drive(lc, rs, &rebuild_drive) < 0)
+ 		return 0;
+ 
+ 	return p_fmt(lc, table, "0 %U %s core 2 %u %s %s 1 %u %u %d",
+--- a/lib/format/ataraid/isw.c	
++++ a/lib/format/ataraid/isw.c	
+@@ -1302,11 +1302,9 @@ isw_metadata_handler(struct lib_context *lc, enum handler_commands command,
+ 	case GET_REBUILD_DRIVE_NO:
+ 		rd = list_entry(rs->devs.next, typeof(*rd), devs);
+ 		isw = META(rd, isw);
+-		idx = rd_idx_by_name(isw, lc->options[LC_REBUILD_SET].arg.str);
+-		if (idx < 0)
+-			return 0;
+ 
+-		dev = raiddev(isw, idx);
++		/* Get disk to rebuild index form metadata stored on first disk */
++		dev = raiddev(isw, 0);
+ 		disk = isw->disk;
+ 
+ 		if (info) {
diff --git a/dmraid.spec b/dmraid.spec
index 483e669..4402d02 100644
--- a/dmraid.spec
+++ b/dmraid.spec
@@ -7,7 +7,7 @@
 Summary: dmraid (Device-mapper RAID tool and library)
 Name: dmraid
 Version: 1.0.0.rc16
-Release: 12%{?dist}
+Release: 13%{?dist}
 License: GPLv2+
 Group: System Environment/Base
 URL: http://people.redhat.com/heinzm/sw/dmraid
@@ -33,6 +33,12 @@ Patch6: move_pattern_file_to_var.patch
 Patch7: libversion.patch
 Patch8: libversion-display.patch
 
+Patch9: bz635995-data_corruption_during_activation_volume_marked_for_rebuild.patch
+# Patch10: bz626417_8-faulty_message_after_unsuccessful_vol_registration.patch
+Patch11: bz626417_19-enabling_registration_degraded_volume.patch
+Patch12: bz626417_20-cleanup_some_compilation_warning.patch
+Patch13: bz626417_21-add_option_that_postpones_any_metadata_updates.patch
+
 %description
 DMRAID supports RAID device discovery, RAID set activation, creation,
 removal, rebuild and display of properties for ATARAID/DDF1 metadata on
@@ -81,6 +87,12 @@ Device failure reporting has to be activated manually by activating the
 %patch7 -p1
 %patch8 -p1
 
+%patch9 -p1
+# %patch10 -p1
+%patch11 -p1
+%patch12 -p1
+%patch13 -p1
+
 %build
 %define _libdir /%{_lib}
 


More information about the scm-commits mailing list