--- 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;