This patch allows EVMS to correctly discover LVM volumes created with old
versions of the Sistina LVM tools (0.8x), and fixes a segfault in the engine
when trying to discover those volumes.

Index: Plugins/lvmregmgr/lvm_groups.c
===================================================================
RCS file: /chillywilly/CVS_Root/evms-1.2.0-cvs-root/engine/Plugins/lvmregmgr/lvm_groups.c,v
retrieving revision 1.37
retrieving revision 1.38
diff -u -r1.37 -r1.38
--- Plugins/lvmregmgr/lvm_groups.c	2002/09/11 18:13:21	1.37
+++ Plugins/lvmregmgr/lvm_groups.c	2002/11/26 14:12:17	1.38
@@ -76,9 +76,8 @@
 
 	// Array of LVM lv_disk_t structures. This will hold all the LV
 	// metadata for this group.
-	new_group->lv_array = lvm_engine->engine_alloc((MAX_LV+2) * sizeof(lv_disk_t));
-	new_group->lv_array = lvm_engine->engine_alloc(round_up((MAX_LV+2) * sizeof(lv_disk_t), EVMS_VSECTOR_SIZE));
-	if ( ! new_group->lv_array ) {
+	new_group->lv_array_disk = lvm_engine->engine_alloc(EVMS_LVM_MAX_LV_METADATA_SIZE);
+	if ( ! new_group->lv_array_disk ) {
 		LOG_CRITICAL("Memory error creating LV metadata for container %s\n", vg_name);
 		lvm_deallocate_volume_group(new_group);
 		RETURN(NULL);
@@ -125,9 +124,9 @@
 	}
 
 	// Delete the array of lv_disk_t structs
-	if ( group->lv_array ) {
-		lvm_engine->engine_free(group->lv_array);
-		group->lv_array = NULL;
+	if ( group->lv_array_disk ) {
+		lvm_engine->engine_free(group->lv_array_disk);
+		group->lv_array_disk = NULL;
 	}
 
 	// Delete all logical volumes.
Index: Plugins/lvmregmgr/lvm_io.c
===================================================================
RCS file: /chillywilly/CVS_Root/evms-1.2.0-cvs-root/engine/Plugins/lvmregmgr/lvm_io.c,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -r1.31 -r1.32
--- Plugins/lvmregmgr/lvm_io.c	2002/01/25 20:15:06	1.31
+++ Plugins/lvmregmgr/lvm_io.c	2002/11/26 14:12:17	1.32
@@ -536,12 +536,16 @@
 
 			segment	= group->pv_list[i]->segment;
 			pv	= group->pv_list[i]->pv;
-			rc = READ(segment, bytes_to_sectors(pv->lv_on_disk.base),
-				bytes_to_sectors(pv->lv_on_disk.size), group->lv_array);
+			rc = READ(segment,
+				  pv->lv_on_disk.base >> EVMS_VSECTOR_SIZE_SHIFT,
+				  bytes_to_sectors(min(pv->lv_on_disk.size, EVMS_LVM_MAX_LV_METADATA_SIZE)),
+				  group->lv_array_disk);
 			if (rc) {
 				LOG_SERIOUS("Error reading LV metadata from object %s\n", segment->name);
 				continue;
 			}
+			group->lv_array = (lv_disk_t*)(((unsigned long)group->lv_array_disk) +
+						       (pv->lv_on_disk.base & (EVMS_VSECTOR_SIZE - 1)));
 
 			// Endian conversion of LV metadata.
 			lvm_endian_convert_lvs(group);
@@ -577,8 +581,9 @@
 
 	// Endian-conversion is done outside this function as an optimization.
 
-	if ( WRITE(segment, bytes_to_sectors(pv->lv_on_disk.base),
-			bytes_to_sectors(pv->lv_on_disk.size), group->lv_array) ) {
+	if ( WRITE(segment, pv->lv_on_disk.base >> EVMS_VSECTOR_SIZE_SHIFT,
+		   bytes_to_sectors(min(pv->lv_on_disk.size, EVMS_LVM_MAX_LV_METADATA_SIZE)),
+		   group->lv_array_disk) ) {
 		LOG_SERIOUS("Error writing LV array to object %s\n", segment->name);
 		RETURN(EIO);
 	}
Index: Plugins/lvmregmgr/lvmregmgr.h
===================================================================
RCS file: /chillywilly/CVS_Root/evms-1.2.0-cvs-root/engine/Plugins/lvmregmgr/lvmregmgr.h,v
retrieving revision 1.50
retrieving revision 1.51
diff -u -r1.50 -r1.51
--- Plugins/lvmregmgr/lvmregmgr.h	2002/09/11 18:13:22	1.50
+++ Plugins/lvmregmgr/lvmregmgr.h	2002/11/26 14:12:17	1.51
@@ -30,6 +30,7 @@
 #define LVM_DEV_DIRECTORY		"lvm/"
 #define EVMS_LVM_PV_REMOVE_IOCTL	0x01
 #define EVMS_LVM_SNAPSHOT_STAT_IOCTL	0x02
+#define EVMS_LVM_MAX_LV_METADATA_SIZE	round_up((MAX_LV+2)*sizeof(lv_disk_t), EVMS_VSECTOR_SIZE) // in bytes
 
 typedef u_int8_t boolean;
 
@@ -322,6 +323,7 @@
 	unsigned char		* uuid_list[MAX_PV+1];	// Array of UUIDs of the PVs in this group
 	lvm_logical_volume_t	* volume_list[MAX_LV+1];// Array of logical volumes exported from this group
 	lv_disk_t		* lv_array;		// The entire array of LVs stored on each PV in this VG
+	lv_disk_t		* lv_array_disk;
 	lvm_logical_volume_t	* freespace;		// The volume representing the freespace in this group
 	geometry_t		geometry;		// Keep track of max sector and block sizes for this group.
 	int			pv_count;		// Number of PVs/segments found on this VG
Index: Plugins/lvmregmgr/lvm_groups.c
===================================================================
RCS file: /chillywilly/CVS_Root/evms-1.2.0-cvs-root/engine/Plugins/lvmregmgr/lvm_groups.c,v
retrieving revision 1.38
retrieving revision 1.39
diff -u -r1.38 -r1.39
--- Plugins/lvmregmgr/lvm_groups.c	2002/11/26 14:12:17	1.38
+++ Plugins/lvmregmgr/lvm_groups.c	2002/12/03 20:18:48	1.39
@@ -83,6 +83,12 @@
 		RETURN(NULL);
 	}
 
+	// For newly created groups, we are always going to make sure the LV
+	// array is properly aligned on disk, so we can set lv_array to be
+	// lv_array_disk. For discovered groups, this value will simply be
+	// over-written when we read in the LV array from disk.
+	new_group->lv_array = new_group->lv_array_disk;
+
 	// Initialize the remaining group fields.
 	new_group->container->plugin		= lvm_plugin;
 	new_group->container->flags		= 0;
