|
|
41b6f0 |
--- a/lib/events/libdmraid-events-isw.c
|
|
|
41b6f0 |
+++ a/lib/events/libdmraid-events-isw.c
|
|
|
41b6f0 |
@@ -308,6 +308,7 @@ static void __dso_dev_copy(struct dso_raid_dev *dst, struct dso_raid_dev *src)
|
|
|
41b6f0 |
strcpy(dst->name, src->name);
|
|
|
41b6f0 |
strcpy(dst->major_minor, src->major_minor);
|
|
|
41b6f0 |
dst->port = src->port;
|
|
|
41b6f0 |
+ dst->active = src->active;
|
|
|
41b6f0 |
}
|
|
|
41b6f0 |
|
|
|
41b6f0 |
/* Copy a struct dso_raid_dev. */
|
|
|
41b6f0 |
@@ -316,7 +317,7 @@ static void _dso_dev_copy(struct dso_raid_set *rs, struct dso_raid_dev *dst)
|
|
|
41b6f0 |
struct dso_raid_dev *src = rs->devs + rs->num_devs - 1;
|
|
|
41b6f0 |
|
|
|
41b6f0 |
if (rs->num_devs < 0)
|
|
|
41b6f0 |
- syslog(LOG_ERR, "Programatic error: num_devs < o");
|
|
|
41b6f0 |
+ syslog(LOG_ERR, "Programatic error: num_devs < 0");
|
|
|
41b6f0 |
|
|
|
41b6f0 |
if (src != dst)
|
|
|
41b6f0 |
__dso_dev_copy(dst, src);
|
|
|
41b6f0 |
@@ -595,7 +596,7 @@ static int _get_sysfs_major_minor(const char *d_name, char *major_minor,
|
|
|
41b6f0 |
* Retrieve device properties for @dev_name from sysfs
|
|
|
41b6f0 |
* (major:minor and port number) into @dev.
|
|
|
41b6f0 |
*
|
|
|
41b6f0 |
- * Return 0 for failure, 0 for success.
|
|
|
41b6f0 |
+ * Return 1 for failure, 0 for success.
|
|
|
41b6f0 |
*/
|
|
|
41b6f0 |
/* FIXME: straighten this by using libsysfs ? */
|
|
|
41b6f0 |
static int _set_raid_dev_properties(const char *dev_name,
|
|
|
41b6f0 |
@@ -611,11 +612,11 @@ static int _set_raid_dev_properties(const char *dev_name,
|
|
|
41b6f0 |
|
|
|
41b6f0 |
/* Get major:minor of this RAID device. */
|
|
|
41b6f0 |
if (_get_sysfs_major_minor(dev_name, dev->major_minor, log_type))
|
|
|
41b6f0 |
- return -ENOENT;
|
|
|
41b6f0 |
+ return 1;
|
|
|
41b6f0 |
|
|
|
41b6f0 |
dir_entries = _scandir(sys_scsi_path, &dir_ent, _scandir_dot_filter);
|
|
|
41b6f0 |
if (dir_entries < 0)
|
|
|
41b6f0 |
- return -ENOENT;
|
|
|
41b6f0 |
+ return 1;
|
|
|
41b6f0 |
|
|
|
41b6f0 |
/* Remember length of initial sysfs path. */
|
|
|
41b6f0 |
strcpy(path, sys_scsi_path);
|
|
|
41b6f0 |
@@ -788,8 +789,8 @@ static struct dso_raid_set *_add_raid_dev(struct dso_raid_set *rs,
|
|
|
41b6f0 |
grown_raid_set->devs + grown_raid_set->num_devs - 1;
|
|
|
41b6f0 |
|
|
|
41b6f0 |
if (_set_raid_dev_properties(d_name, dev, log_type)) {
|
|
|
41b6f0 |
- dm_free(grown_raid_set);
|
|
|
41b6f0 |
- return NULL;
|
|
|
41b6f0 |
+ /* Unable to get device properties - reset them to initial values */
|
|
|
41b6f0 |
+ _dso_dev_init(dev);
|
|
|
41b6f0 |
}
|
|
|
41b6f0 |
}
|
|
|
41b6f0 |
|
|
|
41b6f0 |
@@ -915,11 +916,9 @@ static struct dso_raid_set *_get_slave_devices(const char *rs_name,
|
|
|
41b6f0 |
|
|
|
41b6f0 |
/* Append to RAID sets list of RAID devices. */
|
|
|
41b6f0 |
rs = _add_raid_dev(rs, rs_name, d_name, log_type);
|
|
|
41b6f0 |
- if (!rs)
|
|
|
41b6f0 |
- break;
|
|
|
41b6f0 |
+ _check_raid_dev_active(d_name, rs->devs + rs->num_devs - 1);
|
|
|
41b6f0 |
|
|
|
41b6f0 |
dm_free(dir_ent[i]);
|
|
|
41b6f0 |
- _check_raid_dev_active(d_name, rs->devs + rs->num_devs - 1);
|
|
|
41b6f0 |
}
|
|
|
41b6f0 |
|
|
|
41b6f0 |
_destroy_dirent(dir_ent, i, dir_entries);
|
|
|
41b6f0 |
@@ -957,6 +956,7 @@ static struct dso_raid_set *_create_raid_set(const char *rs_name,
|
|
|
41b6f0 |
struct dm_task *dmt;
|
|
|
41b6f0 |
struct dm_info dev_info;
|
|
|
41b6f0 |
struct dirent *dent, **dir_ent;
|
|
|
41b6f0 |
+ struct dso_raid_dev *dev = NULL;
|
|
|
41b6f0 |
|
|
|
41b6f0 |
/* Get device Info. */
|
|
|
41b6f0 |
dmt = dm_task_create(DM_DEVICE_INFO);
|
|
|
41b6f0 |
@@ -1007,6 +1007,15 @@ static struct dso_raid_set *_create_raid_set(const char *rs_name,
|
|
|
41b6f0 |
free(dent);
|
|
|
41b6f0 |
}
|
|
|
41b6f0 |
|
|
|
41b6f0 |
+ /* Check if all devices are avaliable */
|
|
|
41b6f0 |
+ for (dev = rs->devs, i = 0; i < rs->num_devs; i++, dev++) {
|
|
|
41b6f0 |
+ /* If there is no major:minor number device is missing */
|
|
|
41b6f0 |
+ if (*dev->major_minor == '\0') {
|
|
|
41b6f0 |
+ /* Replace failed device with last device in set; reduce num_devs. */
|
|
|
41b6f0 |
+ _dso_dev_copy(rs, dev);
|
|
|
41b6f0 |
+ }
|
|
|
41b6f0 |
+ }
|
|
|
41b6f0 |
+
|
|
|
41b6f0 |
return rs;
|
|
|
41b6f0 |
}
|
|
|
41b6f0 |
|
|
|
41b6f0 |
@@ -1292,13 +1301,13 @@ static enum disk_state_type _process_raid45_event(struct dm_task *dmt,
|
|
|
41b6f0 |
|
|
|
41b6f0 |
dev_status_str = args[num_devs + 1];
|
|
|
41b6f0 |
|
|
|
41b6f0 |
- /* Consistency check on num_devs and status chars. */
|
|
|
41b6f0 |
- i = _get_num_devs_from_status(dev_status_str);
|
|
|
41b6f0 |
- if (i != num_devs)
|
|
|
41b6f0 |
- goto err;
|
|
|
41b6f0 |
+ /* check if is it rebuilding in progress */
|
|
|
41b6f0 |
+ if (strchr(dev_status_str, 'i'))
|
|
|
41b6f0 |
+ return D_FAILURE_NOSYNC;
|
|
|
41b6f0 |
|
|
|
41b6f0 |
+ syslog(LOG_INFO, "dev_status_str= %s", dev_status_str);
|
|
|
41b6f0 |
/* Check for bad raid45 devices. */
|
|
|
41b6f0 |
- for (i = 0, p = dev_status_str; i < rs->num_devs; i++) {
|
|
|
41b6f0 |
+ for (i = 0, p = dev_status_str; i <= rs->num_devs; i++) {
|
|
|
41b6f0 |
/* Skip past any non active/dead identifiers. */
|
|
|
41b6f0 |
dead = *(p++) == 'D';
|
|
|
41b6f0 |
while (*p && *p != 'A' && *p != 'D')
|
|
|
41b6f0 |
@@ -1318,7 +1327,8 @@ static enum disk_state_type _process_raid45_event(struct dm_task *dmt,
|
|
|
41b6f0 |
/* Copy last device in set; reduce num_devs. */
|
|
|
41b6f0 |
_dso_dev_copy(rs, dev);
|
|
|
41b6f0 |
ret = D_FAILURE_DISK;
|
|
|
41b6f0 |
- }
|
|
|
41b6f0 |
+ } else
|
|
|
41b6f0 |
+ ret = D_FAILURE_NOSYNC;
|
|
|
41b6f0 |
}
|
|
|
41b6f0 |
|
|
|
41b6f0 |
return ret;
|
|
|
41b6f0 |
--- a/lib/register/dmreg.c
|
|
|
41b6f0 |
+++ a/lib/register/dmreg.c
|
|
|
41b6f0 |
@@ -374,6 +374,7 @@ static int _dm_raid_state(char *dev_name)
|
|
|
41b6f0 |
/* Skip past raid45 target chars. */
|
|
|
41b6f0 |
if (status[i] != 'p' &&
|
|
|
41b6f0 |
status[i] != 'i' &&
|
|
|
41b6f0 |
+ status[i] != 'D' &&
|
|
|
41b6f0 |
status[i] != 'A')
|
|
|
41b6f0 |
errors++;
|
|
|
41b6f0 |
}
|
|
|
41b6f0 |
@@ -422,17 +423,34 @@ static int _validate_dev_and_dso_names(char *dev_name, char *dso_name)
|
|
|
41b6f0 |
return (dso_name && _dm_valid_dso(dso_name)) ? 1 : 0;
|
|
|
41b6f0 |
}
|
|
|
41b6f0 |
|
|
|
41b6f0 |
+/*
|
|
|
41b6f0 |
+ * Function removes unnecassary path to the DSO library
|
|
|
41b6f0 |
+ * (leaves only library name)
|
|
|
41b6f0 |
+ */
|
|
|
41b6f0 |
+char * dso_lib_name_prepare(char * dso_path)
|
|
|
41b6f0 |
+{
|
|
|
41b6f0 |
+ char *ptr = NULL;
|
|
|
41b6f0 |
+ char *lib_name = dso_path;
|
|
|
41b6f0 |
+
|
|
|
41b6f0 |
+ while (ptr = strchr(lib_name, '/'))
|
|
|
41b6f0 |
+ lib_name = ptr + 1;
|
|
|
41b6f0 |
+
|
|
|
41b6f0 |
+ return lib_name;
|
|
|
41b6f0 |
+}
|
|
|
41b6f0 |
+
|
|
|
41b6f0 |
/* Register a device to be monitored for events. */
|
|
|
41b6f0 |
/* FIXME: correct dev_name vs. _dm_raid_state() check of device. */
|
|
|
41b6f0 |
int dm_register_device(char *dev_name, char *dso_name)
|
|
|
41b6f0 |
{
|
|
|
41b6f0 |
- int errors, pending,
|
|
|
41b6f0 |
- ret = _validate_dev_and_dso_names(dev_name, dso_name);
|
|
|
41b6f0 |
+ int errors, pending,ret;
|
|
|
41b6f0 |
+ char *dso_lib_name = dso_lib_name_prepare(dso_name);
|
|
|
41b6f0 |
+
|
|
|
41b6f0 |
+ ret= _validate_dev_and_dso_names(dev_name, dso_lib_name);
|
|
|
41b6f0 |
|
|
|
41b6f0 |
if (ret)
|
|
|
41b6f0 |
return ret;
|
|
|
41b6f0 |
|
|
|
41b6f0 |
- if (dm_monitored_events(&pending, dev_name, dso_name)) {
|
|
|
41b6f0 |
+ if (dm_monitored_events(&pending, dev_name, dso_lib_name)) {
|
|
|
41b6f0 |
printf("ERROR: device \"%s\" %s\n", dev_name,
|
|
|
41b6f0 |
pending ? "has a registration event pending" :
|
|
|
41b6f0 |
"is already being monitored");
|
|
|
41b6f0 |
@@ -452,7 +470,7 @@ int dm_register_device(char *dev_name, char *dso_name)
|
|
|
41b6f0 |
return 1;
|
|
|
41b6f0 |
}
|
|
|
41b6f0 |
|
|
|
41b6f0 |
- if (_dm_set_events(EVENTS_REGISTER, dev_name, dso_name)) {
|
|
|
41b6f0 |
+ if (_dm_set_events(EVENTS_REGISTER, dev_name, dso_lib_name)) {
|
|
|
41b6f0 |
printf("ERROR: Unable to register a device mapper "
|
|
|
41b6f0 |
"event handler for device \"%s\"\n", dev_name);
|
|
|
41b6f0 |
return 1;
|