[linux-lvm] LVM support for LILO

Andi Kleen ak at suse.de
Fri Sep 8 14:25:25 UTC 2000


On Thu, Sep 07, 2000 at 05:44:03PM -0600, Andreas Dilger wrote:
> Yes, please send me a copy...

Sorry for the delay. I cleaned the patch a bit up and appended it. I also
noticed that I sent you the wrong version of the kernel patch earlier, the
patched lilo needs the ioctl on the character device (the patch I sent adds
it to the block device, because I used that first). I appended a new
kernel patch against 2.2.16 + LVM 0.9 and a patch against lilo 21.5. Again
a warning, the lilo patch is not really tested and may just break.


-Andi

-------------- next part --------------
diff -ur lilo-21.5/geometry.c lilo-21.5-work/geometry.c
--- lilo-21.5/geometry.c	Sat Jul 15 22:33:06 2000
+++ lilo-21.5-work/geometry.c	Fri Aug 11 14:02:21 2000
@@ -30,6 +30,18 @@
 #define HDIO_GETGEO HDIO_REQ
 #endif
 
+#define LV_BMAP   _IOWR ( 0xfe, 0x51, 1)
+#ifndef MAJOR
+#define MAJOR(x) (((x) >> 8) & 0xff) 
+#endif
+#define LVM_MAJOR 58
+
+typedef unsigned short kernel_dev_t; 
+
+typedef struct lv_bmap {
+    ulong lv_block;
+    kernel_dev_t lv_dev;           
+} lv_bmap_t;
 
 typedef struct _st_buf {
     struct _st_buf *next;
@@ -40,6 +52,7 @@
 DT_ENTRY *disktab = NULL;
 int old_disktab = 0;
 
+int lvmbmap(dev_t dev, unsigned block, dev_t *curdev);
 
 void geo_init(char *name)
 {
@@ -408,7 +421,9 @@
     DT_ENTRY *walk;
     int inherited,keep_cyls;
 
-    if (MAJOR(device) == MD_MAJOR) {
+    switch (MAJOR(device)) { 
+    case MD_MAJOR:
+    {
         char mdxxx[11];
 	int md_fd, pass;
 	md_array_info_t md_array_info;
@@ -433,7 +448,19 @@
 	    }
 	}
 	close(md_fd);
+	break;	
     }
+    case LVM_MAJOR:
+    {
+	dev_t realdev = 0;	
+	int blk = lvmbmap(device,1,&realdev);
+
+	if (!blk) 
+		pdie("cannot find underlying LVM PV");
+	device = realdev;
+	break;	
+    } 
+    } 
     for (walk = disktab; walk; walk = walk->next)
 	if (walk->device == device) break;
     inherited = !walk && !old_disktab;
@@ -549,6 +576,7 @@
     geo->file = S_ISREG(st.st_mode);
     geo->boot = 1;
     geo->spb = 1;
+    geo->dev = st.st_dev; 
     return geo->fd;
 }
 
@@ -559,6 +587,36 @@
 }
 
 
+int lvmbmap(dev_t dev, unsigned block, dev_t *curdev)
+{
+	static int lvmfd = -1; 
+	lv_bmap_t bm; 
+
+	if (lvmfd < 0) {
+		lvmfd = open("/dev/lvm", O_RDWR); 
+		if (lvmfd < 0) pdie("open of /dev/lvm");
+	}	
+	bm.lv_dev = dev;
+	bm.lv_block = block;
+	
+	if (bm.lv_dev != dev) 
+		pdie("glibc dev_t does not match kernel_dev_t"); 
+ 
+	if (ioctl(lvmfd, LV_BMAP, &bm) < 0) 
+		return 0; 
+	
+	if (!(*curdev)) 
+		*curdev = bm.lv_dev;
+	else if (*curdev != bm.lv_dev) {   
+		/* FIXME: should check if they're really on different
+		   BIOS devices */ 
+		pdie("LVM boot file over multiple PVs"); 
+	}
+
+	return bm.lv_block; 
+}
+
+
 #ifndef FIBMAP
 #define FIBMAP BMAP_IOCTL
 #endif
@@ -576,6 +634,11 @@
     if (geo->file) {
 	if (ioctl(geo->fd,FIBMAP,&block) < 0) pdie("ioctl FIBMAP");
 	if (!block) return 0;
+
+	if (MAJOR(geo->dev) == LVM_MAJOR) { 
+		block = lvmbmap(geo->dev, block, &geo->curdev); 
+		if (!block) return 0; 
+	} 
     }
     sector = block*geo->spb+((offset/SECTOR_SIZE) % geo->spb);
     sector += geo->start;
diff -ur lilo-21.5/geometry.h lilo-21.5-work/geometry.h
--- lilo-21.5/geometry.h	Sat Nov  6 22:09:40 1999
+++ lilo-21.5-work/geometry.h	Thu Aug 10 17:57:37 2000
@@ -16,6 +16,9 @@
     int spb; /* sectors per block */
     int fd,file;
     int boot; /* non-zero after geo_open_boot */
+    dev_t dev; 
+    dev_t curdev;
+    int delayed;
 } GEOMETRY;
 
 typedef struct _dt_entry {
Binary files lilo-21.5/lilo.o and lilo-21.5-work/lilo.o differ
Binary files lilo-21.5/map.o and lilo-21.5-work/map.o differ
-------------- next part --------------
--- include/linux/lvm.h.LVBMAP	Fri Sep  1 17:40:55 2000
+++ include/linux/lvm.h	Fri Sep  8 13:11:58 2000
@@ -355,6 +355,10 @@
 
 /* lock the logical volume manager */
 #define	LVM_LOCK_LVM            _IO ( 0xfe, 0x100)
+
+/* bmap, argument lv_bmap_t */
+#define LV_BMAP		_IOWR ( 0xfe, 0x51, 1)
+
 /* END ioctls */
 
 
@@ -534,7 +538,10 @@
    ulong    new_pe;
 } le_remap_req_t;
 
-
+typedef struct lv_bmap {
+    ulong lv_block;
+    dev_t lv_dev;	    
+} lv_bmap_t;
 
 /*
  * Structure Logical Volume (LV) Version 1
--- drivers/block/lvm.c.LVBMAP	Mon Aug 28 15:04:34 2000
+++ drivers/block/lvm.c	Fri Sep  8 15:59:53 2000
@@ -1025,6 +1025,10 @@
          }
          return 0;
 
+	case LV_BMAP:
+		/* turn logical block into (dev_t, block). non privileged. */ 
+		return lvm_user_bmap(inode, (struct lv_bmap *) arg);  		
+		break; 
 
       default:
          printk ( KERN_WARNING
@@ -1076,6 +1080,28 @@
  *
  ********************************************************************/
 
+static int lvm_user_bmap(struct inode *inode, struct lv_bmap *user_result) 
+{ 
+	struct buffer_head bh; 
+	unsigned long block; 
+	int err;
+
+	if (get_user(block, &user_result->lv_block)) 
+		return -EFAULT; 	
+
+	memset(&bh,0,sizeof bh); 
+	bh.b_size = 512; /* XXX */ 
+	bh.b_rsector = block;
+	bh.b_dev = bh.b_rdev = inode->i_dev;
+	if ((err=lvm_map(&bh, READ)) < 0)  {
+		printk("lvm map failed: %d\n", err); 
+		return -EINVAL; 
+	}	
+
+	return put_user(  kdev_t_to_nr(bh.b_rdev), &user_result->lv_dev) ||
+		put_user(bh.b_rsector, &user_result->lv_block) ? -EFAULT : 0;
+} 
+
 /*
  * block device open routine
  */


More information about the linux-lvm mailing list