Blame SOURCES/bz626417_19-enabling_registration_degraded_volume.patch

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