[linux-lvm] Changing device numbers.

Bas list at showme.wox.org
Wed Mar 14 06:13:17 UTC 2001


----- Original Message -----
From: Andreas Dilger <adilger at turbolinux.com>
To: <linux-lvm at sistina.com>
Sent: dinsdag 13 maart 2001 12:55
Subject: Re: [linux-lvm] Changing device numbers.


> Bas writes:
> > Because since I removed a couple of LVs and created a few, lilo seems to
> > have some trouble when it's told that root=/dev/rootvg/root. (this
number
> > has changed). Plus I think it looks a lot "nicer" ...
>
> You have two significant problems:
>
> 1) The most important problem is that it is IMPOSSIBLE for LILO to boot
>    from a striped LV (or MD RAID 0 for that matter).  No matter what you
>    do, this will not be fixed, because the BIOS cannot handle a kernel
>    image on multiple disks.

To avoid miscommunication: the LV is striped across 2 disks. I'm not using
RAID
or anything like that. To be more specific: I used lvcreate -i2 -I 4 -L
(size) -n (name) (vgname).  The kernel image is on /boot, which is (the
only) "normal" partition.

> 2) The next problem is that LILO doesn't support booting from an LV (yet).
>    I posted a patch to lvm-devel with a fix for LILO, and if you are using
>    the current CVS LVM kernel patch, you _can_ boot from an LV, but not
>    a striped LV.

>
> 3) No matter what you do with LVM, you still need to follow the
limitations
>    that LILO already has - BIOS accessible drive, use "lba32" option for
>    kernel images above 1024 cylinders, etc.  LILO _should_ give you a
>    warning or error if these are broken, even with LVM.  However, with an
>    LVM /boot partition, it is not always clear how things are layed out
>    on disk (or at least less so than with DOS partitions).
>
> "Niceness" has nothing to do with it.  LILO is complaining about not
> recognizing device "58:15" (or whatever), but it would also complain about
> device "58:0" until you apply the LILO patch.  After that, it will work no
> matter what you do, as long as LILO is happy with where the kernel is
> physically located on disk.

Why does it work when I manually type "root=/dev/rootvg/root"  ?

> Here is the LILO patch again.  The LVM patch is in beta6.  If you use it
> with anything older than beta3, it will crash your system.

Just for my understanding: if I use this patch, I will not have to use an
initrd anymore ?

> Cheers, Andreas
>
> PS - it would be interesting if you tried a patched LILO on your current
>      setup (with striped LV) before you fix it.  I want to know if checks
>      for a kernel over multiple devices is working (geo->base_dev test).
> ==========================================================================
> diff -ru lilo-21.6.1/geometry.c lilo-21.6.1a/geometry.c
> --- lilo-21.6.1/geometry.c Sat Dec 16 15:09:21 2000
> +++ lilo-21.6.1a/geometry.c Wed Mar  7 23:30:10 2001
> @@ -39,6 +39,18 @@
>  #endif
>  #endif
>
> +struct lv_bmap {
> +    __u32 lv_block;
> +    __u16 lv_dev;
> +};
> +
> +#ifndef LV_BMAP
> +#define LV_BMAP _IOWR(0xfe, 0x30, 1)
> +#endif
> +#ifndef LVM_GET_IOP_VERSION
> +#define LVM_GET_IOP_VERSION _IOR(0xfe, 0x98, 1)
> +#endif
> +
>  #ifndef HDIO_GETGEO
>  #define HDIO_GETGEO HDIO_REQ
>  #endif
> @@ -265,6 +277,39 @@
>  }
>
>
> +void lvm_bmap(struct lv_bmap *lbm)
> +{
> +    DEVICE dev;
> +    static int lvmfd = -1;
> +    static dev_t last_dev = 0;
> +
> +    if (lbm->lv_dev != last_dev) {
> + char lvm_char[] = "/dev/lvm";
> + unsigned short iop;
> +
> + if (lvmfd != -1)
> +     close(lvmfd);
> +
> + if ((lvmfd = open(lvm_char, lbm->lv_dev, O_RDONLY)) < 0)
> +     die("can't open LVM char device %s\n", lvm_char);
> +
> + if (ioctl(lvmfd, LVM_GET_IOP_VERSION, &iop) < 0)
> +     die("LVM_GET_IOP_VERSION failed on %s\n", lvm_char);
> +
> + if (iop < 10)
> +     die("LVM IOP %d not supported for booting\n", iop);
> + close(lvmfd);
> +
> + lvmfd = dev_open(&dev, lbm->lv_dev, O_RDONLY);
> + if (lvmfd < 0)
> +     die("can't open LVM block device %#x\n", lbm->lv_dev);
> +    }
> +    if (ioctl(lvmfd, LV_BMAP, lbm) < 0) {
> + perror(__FUNCTION__);
> + pdie("LV_BMAP error or ioctl unsupported, can't have image in LVM.\n");
> +    }
> +}
> +
>  void geo_query_dev(GEOMETRY *geo,int device,int all)
>  {
>      DEVICE dev;
> @@ -421,6 +472,28 @@
>      DT_ENTRY *walk;
>      int inherited,keep_cyls;
>
> +    /*
> +     * Find underlying device (PV) for LVM.  It is OK if the underlying
> +     * PV is really an MD RAID1 device, because the geometry of the RAID1
> +     * device is exactly the same as the underlying disk, so FIBMAP and
> +     * LV_BMAP will return the correct block numbers regardless of MD.
> +     */
> +    if (MAJOR(device) == MAJOR_LVM)
> +    {
> + struct lv_bmap lbmA, lbmB;
> +
> +#define DIFF 10
> + lbmA.lv_dev = lbmB.lv_dev = device;
> + lbmA.lv_block = 0;
> + lbmB.lv_block = DIFF;
> +
> + lvm_bmap(&lbmA);
> + lvm_bmap(&lbmB);
> + if (lbmB.lv_block - lbmA.lv_block != DIFF)
> +     die("This version of LVM does not support boot LVs");
> + device = geo->base_dev = lbmA.lv_dev;
> +    }
> +    /* Find underlying device for MD RAID */
>      if (MAJOR(device) == MD_MAJOR) {
>          char mdxxx[11];
>   int md_fd, pass;
> @@ -523,7 +592,8 @@
>      if (fstat(geo->fd,&st) < 0) die("fstat %s: %s",name,strerror(errno));
>      if (!S_ISREG(st.st_mode) && !S_ISBLK(st.st_mode))
>   die("%s: neither a reg. file nor a block dev.",name);
> -    geo_get(geo,S_ISREG(st.st_mode) ? st.st_dev : st.st_rdev,user_dev,1);
> +    geo->dev = S_ISREG(st.st_mode) ? st.st_dev : st.st_rdev;
> +    geo_get(geo, geo->dev, user_dev, 1);
>      geo->file = S_ISREG(st.st_mode);
>      geo->boot = 0;
>  #ifndef FIGETBSZ
> @@ -549,16 +619,15 @@
>  int geo_open_boot(GEOMETRY *geo,char *name)
>  {
>      struct stat st;
> -    dev_t dev;
>
>      if (stat(name,&st) < 0) die("stat %s: %s",name,strerror(errno));
>      if (!S_ISREG(st.st_mode) && !S_ISBLK(st.st_mode))
>   die("%s: neither a reg. file nor a block dev.",name);
> -    dev = S_ISREG(st.st_mode) ? st.st_dev : st.st_rdev;
> -    if (MAJOR(dev) == MAJOR_FD) geo->fd = 0;
> +    geo->dev = S_ISREG(st.st_mode) ? st.st_dev : st.st_rdev;
> +    if (MAJOR(geo->dev) == MAJOR_FD) geo->fd = 0;
>      else if ((geo->fd = open(name,O_NOACCESS)) < 0)
>       die("open %s: %s",name,strerror(errno));
> -    geo_get(geo,dev,-1,0);
> +    geo_get(geo, geo->dev, -1, 0);
>      geo->file = S_ISREG(st.st_mode);
>      geo->boot = 1;
>      geo->spb = 1;
> @@ -596,6 +667,18 @@
>   if (ioctl(geo->fd,FIBMAP,&block) < 0) pdie("ioctl FIBMAP");
>   if (!block) {
>       return 0;
>   }
> +    }
> +    if (MAJOR(geo->dev) == MAJOR_LVM) {
> + struct lv_bmap lbm;
> +
> + lbm.lv_dev = geo->dev;
> + lbm.lv_block = block;
> +
> + lvm_bmap(&lbm);
> + if (lbm.lv_dev != geo->base_dev)
> +     die("LVM boot LV cannot be on multiple PVs\n");
> + block = lbm.lv_block;
>      }
>      sector = block*geo->spb+((offset/SECTOR_SIZE) % geo->spb);
>      sector += geo->start;
> diff -ru lilo-21.6.1/geometry.h lilo-21.6.1a/geometry.h
> --- lilo-21.6.1/geometry.h Sat Nov  6 14:09:40 1999
> +++ lilo-21.6.1a/geometry.h Wed Mar  7 23:20:30 2001
> @@ -16,6 +16,7 @@
>      int spb; /* sectors per block */
>      int fd,file;
>      int boot; /* non-zero after geo_open_boot */
> +    dev_t dev, base_dev;
>  } GEOMETRY;
>
>  typedef struct _dt_entry {
> diff -ru lilo-21.6.1/lilo.h lilo-21.6.1a/lilo.h
> --- lilo-21.6.1/lilo.h Thu Sep 21 17:18:50 2000
> +++ lilo-21.6.1a/lilo.h Tue Jan 23 14:49:59 2001
> @@ -41,6 +41,7 @@
>  #define MAJOR_DAC960 48 /* First Mylex DAC960 PCI RAID controller */
>  #define MAJOR_IDE5 55 /* IDE on fifth interface */
>  #define MAJOR_IDE6 57 /* IDE on sixth interface */
> +#define MAJOR_LVM 58 /* Logical Volume Manager devices */
>  #define COMPAQ_SMART2_MAJOR 72 /* First Smart/2 Major */
>
>  #define MAX_IMAGES      ((SECTOR_SIZE*2-2)/sizeof(IMAGE_DESCR))
>     /* maximum number of images */
> --
> Andreas Dilger  \ "If a man ate a pound of pasta and a pound of antipasto,
>                  \  would they cancel out, leaving him still hungry?"
> http://www-mddsp.enel.ucalgary.ca/People/adilger/               -- Dogbert
> _______________________________________________
> linux-lvm mailing list
> linux-lvm at sistina.com
> http://lists.sistina.com/mailman/listinfo/linux-lvm




More information about the linux-lvm mailing list