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