Sophie

Sophie

distrib > Mandriva > 10.2 > x86_64 > by-pkgid > d2c6371ee78bcfbb8107b569c44c3d07 > files > 8

evms-2.5.1-6mdk.src.rpm

diff -Nua evms-2.5.1/plugins/md/md_discover.c engine2/plugins/md/md_discover.c
--- evms-2.5.1/plugins/md/md_discover.c	2005-01-19 10:08:53.000000000 -0600
+++ engine2/plugins/md/md_discover.c	2005-02-10 23:39:43.000000000 -0600
@@ -570,6 +570,23 @@
 		goto out;
 	}
 
+	for (i=0; i<md_info.nr_disks && !rc; i++) {
+		d.number = i;
+		rc = md_ioctl_get_disk_info(region, &d);
+		if (rc) {
+			LOG_WARNING("Can't get info for disk[%d].\n", i);
+			rc = 0;
+			continue;
+		}
+		member = md_volume_find_member_from_major_minor(vol, d.major, d.minor);
+		if (member && (member->dev_number != d.number)) {
+			LOG_WARNING("The kernel said disk(%d:%d) is at index[%d].\n",
+				    d.major, d.minor, d.number);
+			member->dev_number = d.number;
+			EngFncs->sort_list(vol->members, md_volume_sort_members, NULL);
+		}
+	}
+
 	md_volume_get_super_info(vol, &sb_info);
 	if (md_info.raid_disks != sb_info.raid_disks) {
 		if (vol->flags & MD_ARRAY_RESIZE_PENDING) {
@@ -724,9 +741,27 @@
 			/* This disk is not in the MD volume. */
 			if (d.state & (1<<MD_DISK_REMOVED)) {
 				LOG_DEBUG("Disk[%d] was removed.\n", d.number);
+			} else if (d.state & (1<<MD_DISK_FAULTY)) {
+			       length = sprintf(message_buffer,
+						_("%s region %s contains a failed disk with major %d and minor %d."
+						  "  The Kernel MD driver still has a reference to this disk."
+						  "  However, EVMS did not find MD superblock on this disk.\n\n"
+						  "  Would you like to request the kernel to release the reference to this disk?\n"),
+						level_to_string(md_info.level), vol->name, 
+						d.major, d.minor);
+			
+				if (md_get_yes_no_response(message_buffer) == TRUE) {
+					md_ioctl_hot_remove_disk(region, makedev(d.major, d.minor));
+				}
+
 			} else {
-				LOG_MD_BUG();
-				rc = EINVAL;
+				LOG_WARNING("Missing disk[%d] info:"
+					    " raid_disk(%d), major(%d), minor(%d) state(0x%08X).\n",
+					    d.number, d.raid_disk, d.major, d.minor, d.state);
+				if (EngFncs->is_2_4_kernel() == FALSE) {
+					LOG_MD_BUG();
+					rc = EINVAL;
+				}
 			}
 		}
 	}
diff -Nua evms-2.5.1/plugins/md/md.h engine2/plugins/md/md.h
--- evms-2.5.1/plugins/md/md.h	2005-01-20 09:30:47.000000000 -0600
+++ engine2/plugins/md/md.h	2005-02-10 23:39:43.000000000 -0600
@@ -357,10 +357,12 @@
 int find_disk_in_active_region(storage_object_t *region, int major, int minor);
 md_member_t *md_find_member(int major, int minor);
 md_member_t * md_volume_find_member(md_volume_t *vol, int dev_number);
+md_member_t * md_volume_find_member_from_major_minor(md_volume_t *vol, int major, int minor);
 
 //int find_empty_slot(mdp_super_t *sb);
 int md_fix_dev_major_minor(md_volume_t * vol, boolean do_msg);
 boolean follow_up_mark_faulty(md_volume_t *volume, storage_object_t *faulty);
+boolean md_get_yes_no_response(char *question);
 
 md_volume_t * md_allocate_volume(void);
 void md_free_volume(md_volume_t *vol);
diff -Nua evms-2.5.1/plugins/md/md_info.c engine2/plugins/md/md_info.c
--- evms-2.5.1/plugins/md/md_info.c	2005-01-16 23:50:21.000000000 -0600
+++ engine2/plugins/md/md_info.c	2005-02-10 22:19:39.000000000 -0600
@@ -60,7 +60,7 @@
 	}
 	
 	if (region->flags & SOFLAG_ACTIVE) {
-		rc = md_analyze_active_region(vol);
+		md_analyze_active_region(vol);
 	}
 
 	info_entries = NUM_VOLUME_INFO_ENTRIES + EngFncs->list_count(vol->members);
@@ -70,7 +70,6 @@
 	info = EngFncs->engine_alloc(sizeof(extended_info_array_t) +
 				     sizeof(extended_info_t) * info_entries);
 	if (info != NULL) {
-		info->count = info_entries;
 		cur_info = info->info;
 
 		cur_info->name = EngFncs->engine_strdup("name");
@@ -126,7 +125,7 @@
 				}
 				strcat(message_buffer, _("Active"));
 			}
-			if (vol->flags & MD_ARRAY_SYNCING) {
+			if (md_is_recovery_running(vol->region)) {
 				if (message_buffer[0] != '\0') {
 					strcat(message_buffer, ", ");
 				}
@@ -289,7 +288,7 @@
 	int info_count = 0;
 	char buf[64];
 
-	sprintf(buf, _("number %d"), info->number);
+	sprintf(buf, "number %d", info->number);
 	cur_info->name = EngFncs->engine_strdup(buf);
 	cur_info->title = EngFncs->engine_strdup(_("Number"));
 	cur_info->desc = EngFncs->engine_strdup(_("Disk number in the array"));
@@ -302,7 +301,7 @@
 	cur_info->group.group_number = 0;
 	cur_info->group.group_level = 0;
 	cur_info->group.group_name = NULL;
-	cur_info->flags = EVMS_EINFO_FLAGS_MORE_INFO_AVAILABLE;
+	cur_info->flags = 0;
 	cur_info++;
 	info_count++;
 
@@ -414,7 +413,7 @@
 	}
 	
 	// If none of the flags are set, it must be a spare disk.
-	if (message_buffer[0] == '\0') {
+	if (buffer[0] == '\0') {
 		strcpy(buffer, _("Spare"));
 	}
 
@@ -476,10 +475,40 @@
 
 	int rc = 0;
 	extended_info_array_t * info;
+	extended_info_t *cur_info;
+	char buf[64];
+
+	LOG_ENTRY();
 
-	info = EngFncs->engine_alloc(sizeof(extended_info_array_t) + sizeof(extended_info_t) * NUM_DISK_INFO_ENTRIES);
+	info = EngFncs->engine_alloc(sizeof(extended_info_array_t) + sizeof(extended_info_t) * (NUM_DISK_INFO_ENTRIES + 1));
 	if (info != NULL) {
+
 		info->count = get_member_disk_info(member, info->info);
+
+		if (info->count != NUM_DISK_INFO_ENTRIES) {
+			LOG_MD_BUG();
+			EngFncs->engine_free(info);
+			return EINVAL;
+		}
+
+		cur_info = &info->info[info->count];
+
+		sprintf(buf, "superblock_child_object_%d", member->dev_number);
+		cur_info->name = EngFncs->engine_strdup(buf);
+		cur_info->title = EngFncs->engine_strdup(_("Superblock Index"));
+		cur_info->desc = EngFncs->engine_strdup(_("Superblock information on the child object"));
+		cur_info->type = EVMS_Type_Unsigned_Int32;
+		cur_info->unit = EVMS_Unit_None;
+		cur_info->format = EVMS_Format_Normal;
+		cur_info->value.ui32 = member->dev_number;
+		cur_info->collection_type = EVMS_Collection_None;
+		cur_info->collection.list = NULL;
+		cur_info->group.group_number = 0;
+		cur_info->group.group_level = 0;
+		cur_info->group.group_name = NULL;
+		cur_info->flags = EVMS_EINFO_FLAGS_MORE_INFO_AVAILABLE;
+
+		info->count++;
 		*info_array = info;
 	} else {
 		LOG_CRITICAL("Error getting memory for an extended_info_array./n");
@@ -494,10 +523,40 @@
 {
 	int rc = 0;
 	extended_info_array_t * info;
+	extended_info_t *cur_info;
+	char buf[64];
 
-	info = EngFncs->engine_alloc(sizeof(extended_info_array_t) + sizeof(extended_info_t) * NUM_DISK_INFO_ENTRIES);
+	LOG_ENTRY();
+
+	info = EngFncs->engine_alloc(sizeof(extended_info_array_t) + sizeof(extended_info_t) * (NUM_DISK_INFO_ENTRIES + 1));
 	if (info != NULL) {
+		
 		info->count = get_superblock_disk_info(member->vol, member->dev_number, info->info);
+
+		if (info->count != NUM_DISK_INFO_ENTRIES) {
+			LOG_MD_BUG();
+			EngFncs->engine_free(info);
+			return EINVAL;
+		}
+
+		cur_info = &info->info[info->count];
+
+		sprintf(buf, "superblock_stale_object_%d", member->dev_number);
+		cur_info->name = EngFncs->engine_strdup(buf);
+		cur_info->title = EngFncs->engine_strdup(_("Superblock Index"));
+		cur_info->desc = EngFncs->engine_strdup(_("Superblock information on the stale object"));
+		cur_info->type = EVMS_Type_Unsigned_Int32;
+		cur_info->unit = EVMS_Unit_None;
+		cur_info->format = EVMS_Format_Normal;
+		cur_info->value.ui32 = member->dev_number;
+		cur_info->collection_type = EVMS_Collection_None;
+		cur_info->collection.list = NULL;
+		cur_info->group.group_number = 0;
+		cur_info->group.group_level = 0;
+		cur_info->group.group_name = NULL;
+		cur_info->flags = EVMS_EINFO_FLAGS_MORE_INFO_AVAILABLE;
+
+		info->count++;
 		*info_array = info;
 	} else {
 		LOG_CRITICAL("Error getting memory for an extended_info_array./n");
@@ -512,32 +571,26 @@
 /*
  * md_get_superblock_info
  *
- * if child_index is -1, the master superblock will be used.
+ * if member is NULL, the master superblock will be used.
  */
 static int md_get_superblock_info(
 	md_volume_t *vol,
-	int child_index,
+	md_member_t *member,
 	extended_info_array_t ** info_array )
 {
 	extended_info_array_t * info;
 	extended_info_t *cur_info;
 	int info_entries;
 	md_super_info_t super;
-	md_member_t *member;
 	int i;
 
-	if (child_index == -1) {
+	LOG_ENTRY();
+
+	if (member == NULL) {
 		// Request to display volume's master superblock information
 		md_volume_get_super_info(vol, &super);
 	} else {
-		member = md_volume_find_member(vol, child_index);
-		if (member) {
-			LOG_CRITICAL("Could not locate member index %d in %s.\n",
-				     child_index, vol->name);
-			md_member_get_super_info(member, &super);
-		} else {
-			return EINVAL;
-		}
+		md_member_get_super_info(member, &super);
 	}
 
 	info_entries = NUM_SUPER_INFO_ENTRIES + super.nr_disks*NUM_DISK_INFO_ENTRIES;
@@ -546,6 +599,7 @@
 				     sizeof(extended_info_t) * info_entries);
 	if (info == NULL) {
 		LOG_CRITICAL("Error getting memory for an extended_info_array.\n");
+		LOG_EXIT_INT(ENOMEM);
 		return ENOMEM;
 	}
 	cur_info = info->info;
@@ -1002,6 +1056,9 @@
 	int rc = 0;
 	int idx = -1;
 	md_member_t *member;
+	list_element_t iter;
+
+	LOG_ENTRY();
 
 	if (!name) {
 		// Default case. Return all basic info about the region.
@@ -1010,7 +1067,11 @@
 	else if ( ! strncmp(name, "child_object", 12) ) {
                 // "Extra" information about the child's superblock
 		idx = atoi(name + 12);
-		member = md_volume_find_member(vol, idx);
+		LIST_FOR_EACH(vol->members, iter, member) {
+			if ((member->dev_number == idx) && !(member->flags & MD_MEMBER_STALE)) {
+				break;
+			}
+		}
 		if (member) {
 			rc = md_get_child_disk_info(member, info_array);
 		} else {
@@ -1023,6 +1084,11 @@
                 // "Extra" information about the stale disk's superblock
 		idx = atoi(name + 12);
 		member = md_volume_find_member(vol, idx);
+		LIST_FOR_EACH(vol->members, iter, member) {
+			if ((member->dev_number == idx) && (member->flags & MD_MEMBER_STALE)) {
+				break;
+			}
+		}
 		if (member) {
 			rc = md_get_stale_disk_info(member, info_array);
 		} else {
@@ -1031,11 +1097,20 @@
 			return EINVAL;
 		}
 	}
-	else if ( ! strncmp(name, "number", 6) ) {
-                // "Extra" information about a disk in the array
-		idx = atoi(name + 6);
-		if (idx >= 0) {
-			rc = md_get_superblock_info(vol, idx, info_array);
+	else if ( ! strncmp(name, "superblock", 10) ) {
+                // "Extra" information about the master superblock
+		rc = md_get_superblock_info(vol, NULL, info_array);
+	}	
+	else if ( ! strncmp(name, "superblock_child_object_", 24) ) {
+                // "Extra" information about the child superblock
+		idx = atoi(name + 24);
+		LIST_FOR_EACH(vol->members, iter, member) {
+			if ((member->dev_number == idx) && !(member->flags & MD_MEMBER_STALE)) {
+				break;
+			}
+		}
+		if (member) {
+			rc = md_get_superblock_info(vol, member, info_array);
 		}
 		else {
 			LOG_ERROR("No support for extra region information about \"%s\"\n", name);
@@ -1043,9 +1118,22 @@
 			return EINVAL;
 		}
 	}
-	else if ( ! strncmp(name, "superblock", 10) ) {
-                // "Extra" information about the master superblock
-		rc = md_get_superblock_info(vol, -1, info_array);
+	else if ( ! strncmp(name, "superblock_stale_object_", 24) ) {
+                // "Extra" information about the stale superblock
+		idx = atoi(name + 24);
+		LIST_FOR_EACH(vol->members, iter, member) {
+			if ((member->dev_number == idx) && (member->flags & MD_MEMBER_STALE)) {
+				break;
+			}
+		}
+		if (member) {
+			rc = md_get_superblock_info(vol, member, info_array);
+		}
+		else {
+			LOG_ERROR("No support for extra region information about \"%s\"\n", name);
+			LOG_EXIT_INT(EINVAL);
+			return EINVAL;
+		}
 	}
 	else {
 		LOG_ERROR("No support for extra region information about \"%s\"\n", name);
diff -Nua evms-2.5.1/plugins/md/md_io.c engine2/plugins/md/md_io.c
--- evms-2.5.1/plugins/md/md_io.c	2005-01-16 23:50:21.000000000 -0600
+++ engine2/plugins/md/md_io.c	2005-02-11 17:00:14.000000000 -0600
@@ -97,6 +97,13 @@
 	int rc = 0, fd;
 	LOG_ENTRY();
 
+	if (obj->dev_major == MD_MAJOR) {
+		LOG_DEBUG("%s (%d:%d) is an MD device, skip flushing buffer cache.\n",
+			  obj->name, obj->dev_major, obj->dev_minor);
+		LOG_EXIT_INT(0);
+		return 0;
+	}
+
 	fd = EngFncs->open_object(obj, O_RDONLY);
 	if (fd <= 0) {
 		LOG_DEBUG("Unable to open object %s to send ioctl\n", obj->name);
diff -Nua evms-2.5.1/plugins/md/md_main.c engine2/plugins/md/md_main.c
--- evms-2.5.1/plugins/md/md_main.c	2005-01-20 09:30:47.000000000 -0600
+++ engine2/plugins/md/md_main.c	2005-02-10 23:39:56.000000000 -0600
@@ -669,6 +669,14 @@
 	return 0;
 }
 
+boolean md_get_yes_no_response(char *question)
+{
+	int    answer = 0;
+	char * choice_text[3] = { _("Yes"), _("No"), NULL };
+	QUESTION(&answer, choice_text, question);
+	return (answer == 0) ? TRUE : FALSE;
+}
+
 boolean follow_up_mark_faulty(md_volume_t *volume, storage_object_t *faulty)
 {
 	int    answer = 0;
@@ -809,6 +817,23 @@
 	return NULL;
 }
 
+md_member_t * md_volume_find_member_from_major_minor(md_volume_t *vol, int major, int minor)
+{
+	list_element_t iter;
+	md_member_t *member;
+
+	LOG_ENTRY();
+	LIST_FOR_EACH(vol->members, iter, member) {
+		if ((member->obj->dev_major == major) && 
+		    (member->obj->dev_minor == minor)) {
+			LOG_EXIT_PTR(member);
+			return member;
+		}
+	}
+	LOG_EXIT_PTR(NULL);
+	return NULL;
+}
+
 md_member_t * md_volume_find_member(md_volume_t *vol, int dev_number)
 {
 	list_element_t iter;
@@ -1809,6 +1834,7 @@
 	evms_md_ioctl_parm_t parm;
 	mdu_disk_info_t info;
 	md_member_t *member;
+	int kernel_idx;
 	
 	LOG_ENTRY();
 	
@@ -1829,7 +1855,6 @@
 	/*
 	 * Removing a faulty disk which is still in the array
 	 */
-	int kernel_idx;
 	kernel_idx = find_disk_in_active_region(vol->region,
 						faulty->dev_major,
 						faulty->dev_minor);
diff -Nua evms-2.5.1/plugins/md/md_super.c engine2/plugins/md/md_super.c
--- evms-2.5.1/plugins/md/md_super.c	2005-01-19 06:25:00.000000000 -0600
+++ engine2/plugins/md/md_super.c	2005-02-10 16:12:21.000000000 -0600
@@ -145,7 +145,7 @@
 			goto queue_corrupt_message;
 		}
 		
-		if ( (1 << ffz(~(chunksize_in_bytes))) != chunksize_in_bytes) {
+		if ( (1 << (ffs(chunksize_in_bytes)-1)) != chunksize_in_bytes) {
 			length = sprintf(message_buffer,
 					 _("%s region %s is corrupt."
 					   "  The chunk size (%d bytes) is not a power of 2."),
@@ -2909,6 +2909,7 @@
 		return -1;
 	}
 	member->vol->sb_func->get_sb_disk_info(member, &info);
+	LOG_EXIT_INT(info.raid_disk);
 	return info.raid_disk;
 }
 
diff -Nua evms-2.5.1/plugins/md/raid1_mgr.c engine2/plugins/md/raid1_mgr.c
--- evms-2.5.1/plugins/md/raid1_mgr.c	2005-01-18 21:33:09.000000000 -0600
+++ engine2/plugins/md/raid1_mgr.c	2005-02-05 17:31:07.000000000 -0600
@@ -768,6 +768,7 @@
 static int raid1_create_region(md_volume_t * vol, list_anchor_t output_list, boolean final_call)
 {
 	int rc = 0;
+	int length;
 	storage_object_t * region;
 
 	LOG_ENTRY();
@@ -781,9 +782,12 @@
 	if (!vol->active_disks) {
 		if (final_call) {
 			vol->flags |= MD_CORRUPT;
-			LOG_CRITICAL("Volume %s does not have any active disks."
-				    "  This is final discovery call, the volume is corrupt.\n",
-				    vol->name);
+			length = sprintf(message_buffer,
+					 _("RAID1 region %s is corrupt. "
+					   "  The number of raid disks for a full functional array is %d."
+					   "  The number of active disks is %d."),
+					 vol->name, vol->raid_disks, vol->active_disks);
+			md_queue_corrupt_message(vol->personality, message_buffer, length);
 		} else {
 			LOG_DEBUG("Volume %s does not have any active disks, delaying discovery.\n",
 				  vol->name);