[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