[linux-lvm] [patch] lvm2 and md component devices

Luca Berra bluca at comedia.it
Sun Jan 25 16:14:01 UTC 2004


At the moment lvm2 scans devices according to filters in lvm.conf
There is also provisioning to ignore md component device if an md device
is found with the same uuid.

This approach becomes a problem when the md device is not activated and
the _unwary_ user did not set up a filter in lvm.conf.

The attached patch aims to fix this issue in a way that should be
transparent to the user.

It modifies _find_labeller in lib/label/label.c to look for md
superblock signature in the component device and ignore the device if
found.

In order to achieve this i had to modify lib/device/dev-io.c to use
lseek64 in place of lseek (i don't think there is any advantage in using
_llseek).

It build and works as expected on my test system (mandrake cooker), but
i would like some comments on it.

I did not remove yet the check for duplicate pv and md in
lib/cache/lvmcache.c and lib/format1/disk-rep.c, but i believe it can be
removed if my patch is ok.

Forcing the user zero the md superblock (using mdadm) before using the
device as a pv does not seem a bad side-effect.

Regards,
L.

-- 
Luca Berra -- bluca at comedia.it
        Communication Media & Services S.r.l.
 /"\
 \ /     ASCII RIBBON CAMPAIGN
  X        AGAINST HTML MAIL
 / \
-------------- next part --------------
--- LVM2.2.00.08/lib/device/dev-io.c.skipmd	2004-01-24 19:11:29.000000000 +0100
+++ LVM2.2.00.08/lib/device/dev-io.c	2004-01-25 02:24:50.056433529 +0100
@@ -41,11 +41,9 @@
 #  endif
 #endif
 
-
-/* FIXME Use _llseek for 64-bit
-_syscall5(int,  _llseek,  uint,  fd, ulong, hi, ulong, lo, loff_t *, res, uint, wh);
- if (_llseek((unsigned) fd, (ulong) (offset >> 32), (ulong) (offset & 0xFFFFFFFF), &pos, SEEK_SET) < 0) { 
-*/
+#ifndef __dietlibc__
+extern __off64_t lseek64 __P ((int __fd, __off64_t __offset, int __whence));
+#endif
 
 static LIST_INIT(_open_devices);
 
@@ -76,7 +74,7 @@
 		return 0;
 	}
 
-	if (lseek(fd, (off_t) where->start, SEEK_SET) < 0) {
+	if (lseek64(fd, where->start, SEEK_SET) < 0LL) {
 		log_sys_error("lseek", dev_name(where->dev));
 		return 0;
 	}
@@ -318,7 +316,7 @@
 #endif
 
 	if ((flags & O_CREAT) && !(flags & O_TRUNC)) {
-		dev->end = lseek(dev->fd, (off_t) 0, SEEK_END);
+		dev->end = lseek64(dev->fd, 0, SEEK_END);
 	}
 
 	list_add(&_open_devices, &dev->open_list);
--- LVM2.2.00.08/lib/label/label.c.skipmd	2003-08-26 23:12:05.000000000 +0200
+++ LVM2.2.00.08/lib/label/label.c	2004-01-25 02:22:05.309194536 +0100
@@ -98,6 +98,11 @@
 	return NULL;
 }
 
+#define MD_SB_MAGIC     0xa92b4efc
+#define MD_RESERVED_BYTES       (64 * 1024)
+#define MD_RESERVED_SECTORS     (MD_RESERVED_BYTES / SECTOR_SIZE)
+#define MD_NEW_SIZE_SECTORS(x)      ((x & ~(MD_RESERVED_SECTORS - 1)) - MD_RESERVED_SECTORS)
+
 static struct labeller *_find_labeller(struct device *dev, char *buf,
 				       uint64_t *label_sector)
 {
@@ -108,12 +113,26 @@
 	uint64_t sector;
 	int found = 0;
 	char readbuf[LABEL_SCAN_SIZE];
+	uint32_t md_magic;
 
 	if (!dev_open(dev)) {
 		stack;
 		return NULL;
 	}
 
+	/* check if it is an md component device */
+	dev_get_size(dev, &sector);
+	if (sector > MD_RESERVED_SECTORS*2) {
+		sector = MD_NEW_SIZE_SECTORS(sector);
+		sector *= SECTOR_SIZE; 
+		if (dev_read(dev, sector, sizeof(uint32_t), &md_magic)) {
+			if (md_magic == MD_SB_MAGIC) {
+				log_very_verbose("%s: Skipping md component device", dev_name(dev));
+				goto out;
+			}
+		}
+	}
+
 	if (!dev_read(dev, UINT64_C(0), LABEL_SCAN_SIZE, readbuf)) {
 		log_debug("%s: Failed to read label area", dev_name(dev));
 		goto out;


More information about the linux-lvm mailing list