grub-devel.gnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] Install to LVM PVs
@ 2013-09-25 12:39 Gabriel de Perthuis
  2013-09-26  8:53 ` Vladimir 'φ-coder/phcoder' Serbinenko
  0 siblings, 1 reply; 24+ messages in thread
From: Gabriel de Perthuis @ 2013-09-25 12:39 UTC (permalink / raw)
  To: grub-devel

Hello,
This patch lets grub install to a reserved area in LVM physical volumes.
These bootloader areas can be created with LVM 2.02.99 and the
--bootloaderareasize argument to pvcreate and vgconvert.
I tested it in QEMU, installing to and booting a disk that contains a PV
and no partition table.


=== modified file 'grub-core/disk/lvm.c'
--- grub-core/disk/lvm.c	2012-06-25 15:52:20 +0000
+++ grub-core/disk/lvm.c	2013-09-25 11:03:21 +0000
@@ -95,6 +95,38 @@
     }
 }
 
+static struct grub_lvm_pv_header *
+grub_lvm_get_pvh(grub_disk_t disk, char buf[static GRUB_LVM_LABEL_SIZE])
+{
+  struct grub_lvm_label_header *lh = (struct grub_lvm_label_header *) buf;
+  unsigned int i;
+
+  /* Search for label. */
+  for (i = 0; i < GRUB_LVM_LABEL_SCAN_SECTORS; i++)
+    {
+      if (grub_disk_read (disk, i, 0, GRUB_LVM_LABEL_SIZE, buf))
+	return NULL;
+
+      if ((! grub_strncmp ((char *)lh->id, GRUB_LVM_LABEL_ID,
+			   sizeof (lh->id)))
+	  && (! grub_strncmp ((char *)lh->type, GRUB_LVM_LVM2_LABEL,
+			      sizeof (lh->type))))
+	break;
+    }
+
+  /* Return if we didn't find a label. */
+  if (i == GRUB_LVM_LABEL_SCAN_SECTORS)
+    {
+#ifdef GRUB_UTIL
+      grub_util_info ("no LVM signature found");
+#endif
+      return NULL;
+    }
+
+  return (struct grub_lvm_pv_header *) (buf + grub_le_to_cpu32(lh->offset_xl));
+}
+
+
 static struct grub_diskfilter_vg * 
 grub_lvm_detect (grub_disk_t disk,
 		 struct grub_diskfilter_pv_id *id,
@@ -102,11 +134,10 @@
 {
   grub_err_t err;
   grub_uint64_t mda_offset, mda_size;
-  char buf[GRUB_LVM_LABEL_SIZE];
   char vg_id[GRUB_LVM_ID_STRLEN+1];
   char pv_id[GRUB_LVM_ID_STRLEN+1];
+  char buf[GRUB_LVM_LABEL_SIZE];
   char *metadatabuf, *p, *q, *vgname;
-  struct grub_lvm_label_header *lh = (struct grub_lvm_label_header *) buf;
   struct grub_lvm_pv_header *pvh;
   struct grub_lvm_disk_locn *dlocn;
   struct grub_lvm_mda_header *mdah;
@@ -115,30 +146,9 @@
   struct grub_diskfilter_vg *vg;
   struct grub_diskfilter_pv *pv;
 
-  /* Search for label. */
-  for (i = 0; i < GRUB_LVM_LABEL_SCAN_SECTORS; i++)
-    {
-      err = grub_disk_read (disk, i, 0, sizeof(buf), buf);
-      if (err)
-	goto fail;
-
-      if ((! grub_strncmp ((char *)lh->id, GRUB_LVM_LABEL_ID,
-			   sizeof (lh->id)))
-	  && (! grub_strncmp ((char *)lh->type, GRUB_LVM_LVM2_LABEL,
-			      sizeof (lh->type))))
-	break;
-    }
-
-  /* Return if we didn't find a label. */
-  if (i == GRUB_LVM_LABEL_SCAN_SECTORS)
-    {
-#ifdef GRUB_UTIL
-      grub_util_info ("no LVM signature found");
-#endif
-      goto fail;
-    }
-
-  pvh = (struct grub_lvm_pv_header *) (buf + grub_le_to_cpu32(lh->offset_xl));
+  pvh = grub_lvm_get_pvh(disk, buf);
+  if (! pvh)
+    goto fail;
 
   for (i = 0, j = 0; i < GRUB_LVM_ID_LEN; i++)
     {
@@ -151,7 +161,7 @@
   dlocn = pvh->disk_areas_xl;
 
   dlocn++;
-  /* Is it possible to have multiple data/metadata areas? I haven't
+  /* Is it possible to have multiple data areas? I haven't
      seen devices that have it. */
   if (dlocn->offset)
     {
@@ -746,6 +756,88 @@
   return NULL;
 }
 
+#ifdef GRUB_UTIL
+int
+grub_util_is_lvm(grub_disk_t disk)
+{
+  struct grub_diskfilter_pv_id id;
+  struct grub_diskfilter_vg *vg;
+  grub_disk_addr_t start_sector;
+  vg = grub_lvm_detect(disk, &id, &start_sector);
+  if (! vg)
+    return 0;
+  /* don't free the vg, it's held by grub_diskfilter_vg_register */
+  grub_free(id.uuid);
+  return 1;
+}
+
+grub_err_t
+grub_util_lvm_embed (struct grub_disk *disk, unsigned int *nsectors,
+		     unsigned int max_nsectors,
+		     grub_embed_type_t embed_type,
+		     grub_disk_addr_t **sectors)
+{
+  char buf[GRUB_LVM_LABEL_SIZE];
+  struct grub_lvm_pv_header *pvh;
+  struct grub_lvm_pv_header_ext *pvh_ext;
+  struct grub_diskfilter_pv *pv = NULL;
+  struct grub_diskfilter_vg *vg = NULL;
+  struct grub_lvm_disk_locn *dlocn;
+  grub_uint64_t ba_offset, ba_size, ba_start_sector;
+  unsigned int i;
+
+  if (embed_type != GRUB_EMBED_PCBIOS)
+    return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+		       "LVM curently supports only PC-BIOS embedding");
+  if (disk->partition)
+    return grub_error (GRUB_ERR_BUG, "disk isn't LVM");
+  pv = grub_diskfilter_get_pv_from_disk (disk, &vg);
+  if (! pv)
+    return grub_error (GRUB_ERR_BUG, "disk isn't LVM");
+
+  pvh = grub_lvm_get_pvh(disk, buf);
+  if (! pvh)
+    return grub_error (GRUB_ERR_BUG, "disk isn't LVM");
+
+  dlocn = pvh->disk_areas_xl;
+
+  /* skip past the data area list */
+  while (dlocn->offset)
+    dlocn++;
+  dlocn++;
+  /* and the metadata area list */
+  while (dlocn->offset)
+    dlocn++;
+  dlocn++;
+
+  pvh_ext = (struct grub_lvm_pv_header_ext*)dlocn;
+  if (! pvh_ext->version_xl)
+    return grub_error (GRUB_ERR_BUG, "LVM PV doesn't have a bootloader area");
+
+  dlocn = pvh_ext->disk_areas_xl;
+  ba_offset = grub_le_to_cpu64 (dlocn->offset);
+  ba_size = grub_le_to_cpu64 (dlocn->size);
+  if (! (ba_offset && ba_size))
+    return grub_error (GRUB_ERR_BUG, "LVM PV doesn't have a bootloader area");
+  /* could be worked around with extra arithmetic if this actually happens */
+  if (ba_offset % GRUB_DISK_SECTOR_SIZE)
+    return grub_error (
+      GRUB_ERR_BUG, "LVM bootloader area is improperly aligned");
+  ba_start_sector = ba_offset / GRUB_DISK_SECTOR_SIZE;
+
+  *nsectors = ba_size / GRUB_DISK_SECTOR_SIZE;
+  if (*nsectors > max_nsectors)
+    *nsectors = max_nsectors;
+
+  *sectors = grub_malloc (*nsectors * sizeof (**sectors));
+  if (!*sectors)
+    return grub_errno;
+  for (i = 0; i < *nsectors; i++)
+    (*sectors)[i] = ba_start_sector + i;
+
+  return GRUB_ERR_NONE;
+}
+#endif
 \f
 
 static struct grub_diskfilter grub_lvm_dev = {

=== modified file 'include/grub/diskfilter.h'
--- include/grub/diskfilter.h	2012-06-25 15:36:50 +0000
+++ include/grub/diskfilter.h	2013-09-25 08:59:05 +0000
@@ -75,6 +75,9 @@
 #ifdef GRUB_UTIL
   char **partmaps;
 #endif
+  /* Optional bootloader embedding area */
+  grub_uint64_t ba_offset;
+  grub_uint64_t ba_size;
 };
 
 struct grub_diskfilter_lv {

=== modified file 'include/grub/emu/hostdisk.h'
--- include/grub/emu/hostdisk.h	2013-08-22 14:50:12 +0000
+++ include/grub/emu/hostdisk.h	2013-09-25 07:59:06 +0000
@@ -44,9 +44,16 @@
 char *
 grub_util_get_ldm (grub_disk_t disk, grub_disk_addr_t start);
 int
+grub_util_is_lvm (grub_disk_t disk);
+int
 grub_util_is_ldm (grub_disk_t disk);
 #ifdef GRUB_UTIL
 grub_err_t
+grub_util_lvm_embed (struct grub_disk *disk, unsigned int *nsectors,
+		     unsigned int max_nsectors,
+		     grub_embed_type_t embed_type,
+		     grub_disk_addr_t **sectors);
+grub_err_t
 grub_util_ldm_embed (struct grub_disk *disk, unsigned int *nsectors,
 		     unsigned int max_nsectors,
 		     grub_embed_type_t embed_type,

=== modified file 'include/grub/lvm.h'
--- include/grub/lvm.h	2012-01-29 13:28:01 +0000
+++ include/grub/lvm.h	2013-09-25 08:32:31 +0000
@@ -62,6 +62,13 @@
   struct grub_lvm_disk_locn disk_areas_xl[0];	/* Two lists */
 } __attribute__ ((packed));
 
+struct grub_lvm_pv_header_ext {
+  grub_uint32_t version_xl;
+  grub_uint32_t flags_xl;
+  /* NULL-terminated list of bootloader embedding areas */
+  struct grub_lvm_disk_locn disk_areas_xl[0];
+} __attribute__ ((packed));
+
 #define GRUB_LVM_FMTT_MAGIC "\040\114\126\115\062\040\170\133\065\101\045\162\060\116\052\076"
 #define GRUB_LVM_FMTT_VERSION 1
 #define GRUB_LVM_MDA_HEADER_SIZE 512

=== modified file 'util/grub-setup.c'
--- util/grub-setup.c	2013-04-04 06:55:06 +0000
+++ util/grub-setup.c	2013-09-25 11:31:47 +0000
@@ -387,7 +387,7 @@
       .container = dest_dev->disk->partition,
       .multiple_partmaps = 0
     };
-    int is_ldm;
+    int is_ldm, is_lvm;
     grub_err_t err;
     grub_disk_addr_t *sectors;
     int i;
@@ -411,8 +411,9 @@
       grub_errno = GRUB_ERR_NONE;
 
     is_ldm = grub_util_is_ldm (dest_dev->disk);
+    is_lvm = grub_util_is_lvm (dest_dev->disk);
 
-    if (fs_probe)
+    if (!is_lvm && fs_probe)
       {
 	if (!fs && !ctx.dest_partmap)
 	  grub_util_error (_("unable to identify a filesystem in %s; safety check can't be performed"),
@@ -459,7 +460,7 @@
 
     free (tmp_img);
     
-    if (! ctx.dest_partmap && ! fs && !is_ldm)
+    if (! ctx.dest_partmap && ! fs && !is_ldm && !is_lvm)
       {
 	grub_util_warn ("%s", _("Attempting to install GRUB to a partitionless disk or to a partition.  This is a BAD idea."));
 	goto unable_to_embed;
@@ -492,7 +493,10 @@
       maxsec = ((0x78000 - GRUB_KERNEL_I386_PC_LINK_ADDR)
 		>> GRUB_DISK_SECTOR_BITS);
 
-    if (is_ldm)
+    if (is_lvm)
+      err = grub_util_lvm_embed (dest_dev->disk, &nsec, maxsec,
+				 GRUB_EMBED_PCBIOS, &sectors);
+    else if (is_ldm)
       err = grub_util_ldm_embed (dest_dev->disk, &nsec, maxsec,
 				 GRUB_EMBED_PCBIOS, &sectors);
     else if (ctx.dest_partmap)
@@ -588,7 +592,7 @@
 
   if (dest_dev->disk->dev->id != root_dev->disk->dev->id)
     grub_util_error ("%s", _("embedding is not possible, but this is required for "
-			     "RAID and LVM install"));
+			     "RAID install"));
 
   {
     grub_fs_t fs;




^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH] Install to LVM PVs
  2013-09-25 12:39 [PATCH] Install to LVM PVs Gabriel de Perthuis
@ 2013-09-26  8:53 ` Vladimir 'φ-coder/phcoder' Serbinenko
  2013-09-27 10:39   ` Gabriel de Perthuis
  0 siblings, 1 reply; 24+ messages in thread
From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2013-09-26  8:53 UTC (permalink / raw)
  To: The development of GNU GRUB

[-- Attachment #1: Type: text/plain, Size: 10367 bytes --]

On 25.09.2013 14:39, Gabriel de Perthuis wrote:
> Hello,
> This patch lets grub install to a reserved area in LVM physical volumes.
> These bootloader areas can be created with LVM 2.02.99 and the
> --bootloaderareasize argument to pvcreate and vgconvert.
> I tested it in QEMU, installing to and booting a disk that contains a PV
> and no partition table.
> 
This is not how the use of this area was imagined. There are couple of
subtleties which your patch didn't take in account.
Currently there is joint developpement with LVM guys but it wasn't
published yet.
> 
> === modified file 'grub-core/disk/lvm.c'
> --- grub-core/disk/lvm.c	2012-06-25 15:52:20 +0000
> +++ grub-core/disk/lvm.c	2013-09-25 11:03:21 +0000
> @@ -95,6 +95,38 @@
>      }
>  }
>  
> +static struct grub_lvm_pv_header *
> +grub_lvm_get_pvh(grub_disk_t disk, char buf[static GRUB_LVM_LABEL_SIZE])
> +{
> +  struct grub_lvm_label_header *lh = (struct grub_lvm_label_header *) buf;
> +  unsigned int i;
> +
> +  /* Search for label. */
> +  for (i = 0; i < GRUB_LVM_LABEL_SCAN_SECTORS; i++)
> +    {
> +      if (grub_disk_read (disk, i, 0, GRUB_LVM_LABEL_SIZE, buf))
> +	return NULL;
> +
> +      if ((! grub_strncmp ((char *)lh->id, GRUB_LVM_LABEL_ID,
> +			   sizeof (lh->id)))
> +	  && (! grub_strncmp ((char *)lh->type, GRUB_LVM_LVM2_LABEL,
> +			      sizeof (lh->type))))
> +	break;
> +    }
> +
> +  /* Return if we didn't find a label. */
> +  if (i == GRUB_LVM_LABEL_SCAN_SECTORS)
> +    {
> +#ifdef GRUB_UTIL
> +      grub_util_info ("no LVM signature found");
> +#endif
> +      return NULL;
> +    }
> +
> +  return (struct grub_lvm_pv_header *) (buf + grub_le_to_cpu32(lh->offset_xl));
> +}
> +
> +
>  static struct grub_diskfilter_vg * 
>  grub_lvm_detect (grub_disk_t disk,
>  		 struct grub_diskfilter_pv_id *id,
> @@ -102,11 +134,10 @@
>  {
>    grub_err_t err;
>    grub_uint64_t mda_offset, mda_size;
> -  char buf[GRUB_LVM_LABEL_SIZE];
>    char vg_id[GRUB_LVM_ID_STRLEN+1];
>    char pv_id[GRUB_LVM_ID_STRLEN+1];
> +  char buf[GRUB_LVM_LABEL_SIZE];
>    char *metadatabuf, *p, *q, *vgname;
> -  struct grub_lvm_label_header *lh = (struct grub_lvm_label_header *) buf;
>    struct grub_lvm_pv_header *pvh;
>    struct grub_lvm_disk_locn *dlocn;
>    struct grub_lvm_mda_header *mdah;
> @@ -115,30 +146,9 @@
>    struct grub_diskfilter_vg *vg;
>    struct grub_diskfilter_pv *pv;
>  
> -  /* Search for label. */
> -  for (i = 0; i < GRUB_LVM_LABEL_SCAN_SECTORS; i++)
> -    {
> -      err = grub_disk_read (disk, i, 0, sizeof(buf), buf);
> -      if (err)
> -	goto fail;
> -
> -      if ((! grub_strncmp ((char *)lh->id, GRUB_LVM_LABEL_ID,
> -			   sizeof (lh->id)))
> -	  && (! grub_strncmp ((char *)lh->type, GRUB_LVM_LVM2_LABEL,
> -			      sizeof (lh->type))))
> -	break;
> -    }
> -
> -  /* Return if we didn't find a label. */
> -  if (i == GRUB_LVM_LABEL_SCAN_SECTORS)
> -    {
> -#ifdef GRUB_UTIL
> -      grub_util_info ("no LVM signature found");
> -#endif
> -      goto fail;
> -    }
> -
> -  pvh = (struct grub_lvm_pv_header *) (buf + grub_le_to_cpu32(lh->offset_xl));
> +  pvh = grub_lvm_get_pvh(disk, buf);
> +  if (! pvh)
> +    goto fail;
>  
>    for (i = 0, j = 0; i < GRUB_LVM_ID_LEN; i++)
>      {
> @@ -151,7 +161,7 @@
>    dlocn = pvh->disk_areas_xl;
>  
>    dlocn++;
> -  /* Is it possible to have multiple data/metadata areas? I haven't
> +  /* Is it possible to have multiple data areas? I haven't
>       seen devices that have it. */
>    if (dlocn->offset)
>      {
> @@ -746,6 +756,88 @@
>    return NULL;
>  }
>  
> +#ifdef GRUB_UTIL
> +int
> +grub_util_is_lvm(grub_disk_t disk)
> +{
> +  struct grub_diskfilter_pv_id id;
> +  struct grub_diskfilter_vg *vg;
> +  grub_disk_addr_t start_sector;
> +  vg = grub_lvm_detect(disk, &id, &start_sector);
> +  if (! vg)
> +    return 0;
> +  /* don't free the vg, it's held by grub_diskfilter_vg_register */
> +  grub_free(id.uuid);
> +  return 1;
> +}
> +
> +grub_err_t
> +grub_util_lvm_embed (struct grub_disk *disk, unsigned int *nsectors,
> +		     unsigned int max_nsectors,
> +		     grub_embed_type_t embed_type,
> +		     grub_disk_addr_t **sectors)
> +{
> +  char buf[GRUB_LVM_LABEL_SIZE];
> +  struct grub_lvm_pv_header *pvh;
> +  struct grub_lvm_pv_header_ext *pvh_ext;
> +  struct grub_diskfilter_pv *pv = NULL;
> +  struct grub_diskfilter_vg *vg = NULL;
> +  struct grub_lvm_disk_locn *dlocn;
> +  grub_uint64_t ba_offset, ba_size, ba_start_sector;
> +  unsigned int i;
> +
> +  if (embed_type != GRUB_EMBED_PCBIOS)
> +    return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
> +		       "LVM curently supports only PC-BIOS embedding");
> +  if (disk->partition)
> +    return grub_error (GRUB_ERR_BUG, "disk isn't LVM");
> +  pv = grub_diskfilter_get_pv_from_disk (disk, &vg);
> +  if (! pv)
> +    return grub_error (GRUB_ERR_BUG, "disk isn't LVM");
> +
> +  pvh = grub_lvm_get_pvh(disk, buf);
> +  if (! pvh)
> +    return grub_error (GRUB_ERR_BUG, "disk isn't LVM");
> +
> +  dlocn = pvh->disk_areas_xl;
> +
> +  /* skip past the data area list */
> +  while (dlocn->offset)
> +    dlocn++;
> +  dlocn++;
> +  /* and the metadata area list */
> +  while (dlocn->offset)
> +    dlocn++;
> +  dlocn++;
> +
> +  pvh_ext = (struct grub_lvm_pv_header_ext*)dlocn;
> +  if (! pvh_ext->version_xl)
> +    return grub_error (GRUB_ERR_BUG, "LVM PV doesn't have a bootloader area");
> +
> +  dlocn = pvh_ext->disk_areas_xl;
> +  ba_offset = grub_le_to_cpu64 (dlocn->offset);
> +  ba_size = grub_le_to_cpu64 (dlocn->size);
> +  if (! (ba_offset && ba_size))
> +    return grub_error (GRUB_ERR_BUG, "LVM PV doesn't have a bootloader area");
> +  /* could be worked around with extra arithmetic if this actually happens */
> +  if (ba_offset % GRUB_DISK_SECTOR_SIZE)
> +    return grub_error (
> +      GRUB_ERR_BUG, "LVM bootloader area is improperly aligned");
> +  ba_start_sector = ba_offset / GRUB_DISK_SECTOR_SIZE;
> +
> +  *nsectors = ba_size / GRUB_DISK_SECTOR_SIZE;
> +  if (*nsectors > max_nsectors)
> +    *nsectors = max_nsectors;
> +
> +  *sectors = grub_malloc (*nsectors * sizeof (**sectors));
> +  if (!*sectors)
> +    return grub_errno;
> +  for (i = 0; i < *nsectors; i++)
> +    (*sectors)[i] = ba_start_sector + i;
> +
> +  return GRUB_ERR_NONE;
> +}
> +#endif
>  \f
>  
>  static struct grub_diskfilter grub_lvm_dev = {
> 
> === modified file 'include/grub/diskfilter.h'
> --- include/grub/diskfilter.h	2012-06-25 15:36:50 +0000
> +++ include/grub/diskfilter.h	2013-09-25 08:59:05 +0000
> @@ -75,6 +75,9 @@
>  #ifdef GRUB_UTIL
>    char **partmaps;
>  #endif
> +  /* Optional bootloader embedding area */
> +  grub_uint64_t ba_offset;
> +  grub_uint64_t ba_size;
>  };
>  
>  struct grub_diskfilter_lv {
> 
> === modified file 'include/grub/emu/hostdisk.h'
> --- include/grub/emu/hostdisk.h	2013-08-22 14:50:12 +0000
> +++ include/grub/emu/hostdisk.h	2013-09-25 07:59:06 +0000
> @@ -44,9 +44,16 @@
>  char *
>  grub_util_get_ldm (grub_disk_t disk, grub_disk_addr_t start);
>  int
> +grub_util_is_lvm (grub_disk_t disk);
> +int
>  grub_util_is_ldm (grub_disk_t disk);
>  #ifdef GRUB_UTIL
>  grub_err_t
> +grub_util_lvm_embed (struct grub_disk *disk, unsigned int *nsectors,
> +		     unsigned int max_nsectors,
> +		     grub_embed_type_t embed_type,
> +		     grub_disk_addr_t **sectors);
> +grub_err_t
>  grub_util_ldm_embed (struct grub_disk *disk, unsigned int *nsectors,
>  		     unsigned int max_nsectors,
>  		     grub_embed_type_t embed_type,
> 
> === modified file 'include/grub/lvm.h'
> --- include/grub/lvm.h	2012-01-29 13:28:01 +0000
> +++ include/grub/lvm.h	2013-09-25 08:32:31 +0000
> @@ -62,6 +62,13 @@
>    struct grub_lvm_disk_locn disk_areas_xl[0];	/* Two lists */
>  } __attribute__ ((packed));
>  
> +struct grub_lvm_pv_header_ext {
> +  grub_uint32_t version_xl;
> +  grub_uint32_t flags_xl;
> +  /* NULL-terminated list of bootloader embedding areas */
> +  struct grub_lvm_disk_locn disk_areas_xl[0];
> +} __attribute__ ((packed));
> +
>  #define GRUB_LVM_FMTT_MAGIC "\040\114\126\115\062\040\170\133\065\101\045\162\060\116\052\076"
>  #define GRUB_LVM_FMTT_VERSION 1
>  #define GRUB_LVM_MDA_HEADER_SIZE 512
> 
> === modified file 'util/grub-setup.c'
> --- util/grub-setup.c	2013-04-04 06:55:06 +0000
> +++ util/grub-setup.c	2013-09-25 11:31:47 +0000
> @@ -387,7 +387,7 @@
>        .container = dest_dev->disk->partition,
>        .multiple_partmaps = 0
>      };
> -    int is_ldm;
> +    int is_ldm, is_lvm;
>      grub_err_t err;
>      grub_disk_addr_t *sectors;
>      int i;
> @@ -411,8 +411,9 @@
>        grub_errno = GRUB_ERR_NONE;
>  
>      is_ldm = grub_util_is_ldm (dest_dev->disk);
> +    is_lvm = grub_util_is_lvm (dest_dev->disk);
>  
> -    if (fs_probe)
> +    if (!is_lvm && fs_probe)
>        {
>  	if (!fs && !ctx.dest_partmap)
>  	  grub_util_error (_("unable to identify a filesystem in %s; safety check can't be performed"),
> @@ -459,7 +460,7 @@
>  
>      free (tmp_img);
>      
> -    if (! ctx.dest_partmap && ! fs && !is_ldm)
> +    if (! ctx.dest_partmap && ! fs && !is_ldm && !is_lvm)
>        {
>  	grub_util_warn ("%s", _("Attempting to install GRUB to a partitionless disk or to a partition.  This is a BAD idea."));
>  	goto unable_to_embed;
> @@ -492,7 +493,10 @@
>        maxsec = ((0x78000 - GRUB_KERNEL_I386_PC_LINK_ADDR)
>  		>> GRUB_DISK_SECTOR_BITS);
>  
> -    if (is_ldm)
> +    if (is_lvm)
> +      err = grub_util_lvm_embed (dest_dev->disk, &nsec, maxsec,
> +				 GRUB_EMBED_PCBIOS, &sectors);
> +    else if (is_ldm)
>        err = grub_util_ldm_embed (dest_dev->disk, &nsec, maxsec,
>  				 GRUB_EMBED_PCBIOS, &sectors);
>      else if (ctx.dest_partmap)
> @@ -588,7 +592,7 @@
>  
>    if (dest_dev->disk->dev->id != root_dev->disk->dev->id)
>      grub_util_error ("%s", _("embedding is not possible, but this is required for "
> -			     "RAID and LVM install"));
> +			     "RAID install"));
>  
>    {
>      grub_fs_t fs;
> 
> 
> 
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> https://lists.gnu.org/mailman/listinfo/grub-devel
> 



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 291 bytes --]

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH] Install to LVM PVs
  2013-09-26  8:53 ` Vladimir 'φ-coder/phcoder' Serbinenko
@ 2013-09-27 10:39   ` Gabriel de Perthuis
  2013-09-27 12:48     ` Vladimir 'φ-coder/phcoder' Serbinenko
  0 siblings, 1 reply; 24+ messages in thread
From: Gabriel de Perthuis @ 2013-09-27 10:39 UTC (permalink / raw)
  To: GRUB development, LVM2 development, Peter Rajnoha

Le 26/09/2013 10:53, Vladimir 'φ-coder/phcoder' Serbinenko a écrit:
> On 25.09.2013 14:39, Gabriel de Perthuis wrote:
>> Hello,
>> This patch lets grub install to a reserved area in LVM physical volumes.
>> These bootloader areas can be created with LVM 2.02.99 and the
>> --bootloaderareasize argument to pvcreate and vgconvert.
>> I tested it in QEMU, installing to and booting a disk that contains a PV
>> and no partition table.
>>
> This is not how the use of this area was imagined. There are couple of
> subtleties which your patch didn't take in account.
> Currently there is joint developpement with LVM guys but it wasn't
> published yet.

For anyone else who may be interested, apparently patches exist and are
waiting for Peter Rajnoha to finish them.  They haven't been posted or
discussed publicly and I've never seen them.

According to Vladimir:
> the zone will be subdivided to cover more cases and the agreement was
to use "pvs" to get offsets rather than having own code for this

As shipped in 2.02.99, pvs exposes exactly one ba_start/ba_size area.
Other areas will have to use extra extension fields and extra fields in
the pvs output, to be compatible with released versions of LVM.
Parsing pvs output would be easy, and will behave exactly the same as
this patch.


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH] Install to LVM PVs
  2013-09-27 10:39   ` Gabriel de Perthuis
@ 2013-09-27 12:48     ` Vladimir 'φ-coder/phcoder' Serbinenko
  2013-09-27 13:56       ` Gabriel de Perthuis
                         ` (2 more replies)
  0 siblings, 3 replies; 24+ messages in thread
From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2013-09-27 12:48 UTC (permalink / raw)
  To: grub-devel

[-- Attachment #1: Type: text/plain, Size: 1724 bytes --]

On 27.09.2013 12:39, Gabriel de Perthuis wrote:
> Le 26/09/2013 10:53, Vladimir 'φ-coder/phcoder' Serbinenko a écrit:
>> On 25.09.2013 14:39, Gabriel de Perthuis wrote:
>>> Hello,
>>> This patch lets grub install to a reserved area in LVM physical volumes.
>>> These bootloader areas can be created with LVM 2.02.99 and the
>>> --bootloaderareasize argument to pvcreate and vgconvert.
>>> I tested it in QEMU, installing to and booting a disk that contains a PV
>>> and no partition table.
>>>
>> This is not how the use of this area was imagined. There are couple of
>> subtleties which your patch didn't take in account.
>> Currently there is joint developpement with LVM guys but it wasn't
>> published yet.
> 
> For anyone else who may be interested, apparently patches exist and are
> waiting for Peter Rajnoha to finish them.  They haven't been posted or
> discussed publicly and I've never seen them.
> 
> According to Vladimir:
>> the zone will be subdivided to cover more cases and the agreement was
> to use "pvs" to get offsets rather than having own code for this
> 
> As shipped in 2.02.99, pvs exposes exactly one ba_start/ba_size area.
> Other areas will have to use extra extension fields and extra fields in
> the pvs output, to be compatible with released versions of LVM.
No, you didn't understand: this area will have another header, GRUB one
which will subdivide it. LVM gives us area and we take care of subdivision.
> Parsing pvs output would be easy, and will behave exactly the same as
> this patch.
> 

> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> https://lists.gnu.org/mailman/listinfo/grub-devel
> 



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 291 bytes --]

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH] Install to LVM PVs
  2013-09-27 12:48     ` Vladimir 'φ-coder/phcoder' Serbinenko
@ 2013-09-27 13:56       ` Gabriel de Perthuis
  2013-09-27 14:27       ` Andrey Borzenkov
  2015-02-15 10:47       ` Andrei Borzenkov
  2 siblings, 0 replies; 24+ messages in thread
From: Gabriel de Perthuis @ 2013-09-27 13:56 UTC (permalink / raw)
  To: grub-devel, LVM2 development

Le 27/09/2013 14:48, Vladimir 'φ-coder/phcoder' Serbinenko a écrit :
> On 27.09.2013 12:39, Gabriel de Perthuis wrote:
>> Le 26/09/2013 10:53, Vladimir 'φ-coder/phcoder' Serbinenko a écrit:
>>> On 25.09.2013 14:39, Gabriel de Perthuis wrote:
>>>> Hello,
>>>> This patch lets grub install to a reserved area in LVM physical volumes.
>>>> These bootloader areas can be created with LVM 2.02.99 and the
>>>> --bootloaderareasize argument to pvcreate and vgconvert.
>>>> I tested it in QEMU, installing to and booting a disk that contains a PV
>>>> and no partition table.
>>>>
>>> This is not how the use of this area was imagined. There are couple of
>>> subtleties which your patch didn't take in account.
>>> Currently there is joint developpement with LVM guys but it wasn't
>>> published yet.
>>
>> For anyone else who may be interested, apparently patches exist and are
>> waiting for Peter Rajnoha to finish them.  They haven't been posted or
>> discussed publicly and I've never seen them.
>>
>> According to Vladimir:
>>> the zone will be subdivided to cover more cases and the agreement was
>> to use "pvs" to get offsets rather than having own code for this
>>
>> As shipped in 2.02.99, pvs exposes exactly one ba_start/ba_size area.
>> Other areas will have to use extra extension fields and extra fields in
>> the pvs output, to be compatible with released versions of LVM.

> No, you didn't understand: this area will have another header, GRUB one
> which will subdivide it. LVM gives us area and we take care of subdivision.

Or you could split the task in two: embed Grub on PVs, like it does on
partition tables, ext2-ext4, Btrfs; then add advanced embedding that
does some mini-partitioning of embedding areas.

The first task is really easy and brings an immediate benefit in making
LVM-only disks bootable.

I don't feel qualified to discuss the second task, because I'm not
seeing the use case.  I don't think it's been brought up.



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH] Install to LVM PVs
  2013-09-27 12:48     ` Vladimir 'φ-coder/phcoder' Serbinenko
  2013-09-27 13:56       ` Gabriel de Perthuis
@ 2013-09-27 14:27       ` Andrey Borzenkov
  2015-02-15 10:47       ` Andrei Borzenkov
  2 siblings, 0 replies; 24+ messages in thread
From: Andrey Borzenkov @ 2013-09-27 14:27 UTC (permalink / raw)
  To: grub-devel

[-- Attachment #1: Type: text/plain, Size: 2020 bytes --]

В Fri, 27 Sep 2013 14:48:33 +0200
Vladimir 'φ-coder/phcoder' Serbinenko <phcoder@gmail.com> пишет:

> On 27.09.2013 12:39, Gabriel de Perthuis wrote:
> > Le 26/09/2013 10:53, Vladimir 'φ-coder/phcoder' Serbinenko a écrit:
> >> On 25.09.2013 14:39, Gabriel de Perthuis wrote:
> >>> Hello,
> >>> This patch lets grub install to a reserved area in LVM physical volumes.
> >>> These bootloader areas can be created with LVM 2.02.99 and the
> >>> --bootloaderareasize argument to pvcreate and vgconvert.
> >>> I tested it in QEMU, installing to and booting a disk that contains a PV
> >>> and no partition table.
> >>>
> >> This is not how the use of this area was imagined. There are couple of
> >> subtleties which your patch didn't take in account.
> >> Currently there is joint developpement with LVM guys but it wasn't
> >> published yet.
> > 
> > For anyone else who may be interested, apparently patches exist and are
> > waiting for Peter Rajnoha to finish them.  They haven't been posted or
> > discussed publicly and I've never seen them.
> > 
> > According to Vladimir:
> >> the zone will be subdivided to cover more cases and the agreement was
> > to use "pvs" to get offsets rather than having own code for this
> > 
> > As shipped in 2.02.99, pvs exposes exactly one ba_start/ba_size area.
> > Other areas will have to use extra extension fields and extra fields in
> > the pvs output, to be compatible with released versions of LVM.
> No, you didn't understand: this area will have another header, GRUB one
> which will subdivide it. LVM gives us area and we take care of subdivision.

Is it something specific for LVM? Or useable in all other cases when
grub currently does embedding?

> > Parsing pvs output would be easy, and will behave exactly the same as
> > this patch.
> > 
> 
> > _______________________________________________
> > Grub-devel mailing list
> > Grub-devel@gnu.org
> > https://lists.gnu.org/mailman/listinfo/grub-devel
> > 
> 
> 


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH] Install to LVM PVs
  2013-09-27 12:48     ` Vladimir 'φ-coder/phcoder' Serbinenko
  2013-09-27 13:56       ` Gabriel de Perthuis
  2013-09-27 14:27       ` Andrey Borzenkov
@ 2015-02-15 10:47       ` Andrei Borzenkov
  2 siblings, 0 replies; 24+ messages in thread
From: Andrei Borzenkov @ 2015-02-15 10:47 UTC (permalink / raw)
  To: Vladimir 'φ-coder/phcoder' Serbinenko; +Cc: grub-devel

[-- Attachment #1: Type: text/plain, Size: 1995 bytes --]

В Fri, 27 Sep 2013 14:48:33 +0200
Vladimir 'φ-coder/phcoder' Serbinenko <phcoder@gmail.com> пишет:

> On 27.09.2013 12:39, Gabriel de Perthuis wrote:
> > Le 26/09/2013 10:53, Vladimir 'φ-coder/phcoder' Serbinenko a écrit:
> >> On 25.09.2013 14:39, Gabriel de Perthuis wrote:
> >>> Hello,
> >>> This patch lets grub install to a reserved area in LVM physical volumes.
> >>> These bootloader areas can be created with LVM 2.02.99 and the
> >>> --bootloaderareasize argument to pvcreate and vgconvert.
> >>> I tested it in QEMU, installing to and booting a disk that contains a PV
> >>> and no partition table.
> >>>
> >> This is not how the use of this area was imagined. There are couple of
> >> subtleties which your patch didn't take in account.
> >> Currently there is joint developpement with LVM guys but it wasn't
> >> published yet.
> > 
> > For anyone else who may be interested, apparently patches exist and are
> > waiting for Peter Rajnoha to finish them.  They haven't been posted or
> > discussed publicly and I've never seen them.
> > 
> > According to Vladimir:
> >> the zone will be subdivided to cover more cases and the agreement was
> > to use "pvs" to get offsets rather than having own code for this
> > 
> > As shipped in 2.02.99, pvs exposes exactly one ba_start/ba_size area.
> > Other areas will have to use extra extension fields and extra fields in
> > the pvs output, to be compatible with released versions of LVM.
> No, you didn't understand: this area will have another header, GRUB one
> which will subdivide it. LVM gives us area and we take care of subdivision.

Did anything happen with it? Do you have any pointers to suggested
design?

> > Parsing pvs output would be easy, and will behave exactly the same as
> > this patch.
> > 
> 
> > _______________________________________________
> > Grub-devel mailing list
> > Grub-devel@gnu.org
> > https://lists.gnu.org/mailman/listinfo/grub-devel
> > 
> 
> 


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 181 bytes --]

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH] Install to LVM PVs
@ 2016-05-08  4:53 Dryden Personalis
  2016-05-08  6:05 ` Andrei Borzenkov
  2016-05-08  9:23 ` Andrei Borzenkov
  0 siblings, 2 replies; 24+ messages in thread
From: Dryden Personalis @ 2016-05-08  4:53 UTC (permalink / raw)
  To: grub-devel

[-- Attachment #1: Type: text/plain, Size: 1402 bytes --]

I updated this guy's patch to work with 2.02 beta 2, at least.

I've just worked on the version that gets downloaded and unpacked on 
Kubuntu / Ubuntu 16.04.

One part of the patch didn't apply because apparently some tabs have 
entered a file, namely grub-core/disk/lvm.c.

Another part didn't apply because code had been refactored from 
grub-setup.c to setup.c.

I've only compiled with these extra packages:

- bison
- flex
- libdevmapper-dev

and automake was also required. I've had to symlink the 1.15 executables 
to 1.14.


I'm not sure why the patch never made it into mainline grub, but back 
then (2013) the argument was that it was doing something to an area that 
was not meant for that.

However LVM contains the --bootloaderareasize flag that seems to be 
meant for this, and if you put it to 2048 sectors (or 1M) it ought to 
work cq. just works.

ie. pvcreate --bootloaderareasize 2048s /dev/sda, followed by, 
grub-install /dev/sda, will just work and result in a bootable system 
from that harddisk.

I don't know if I can attach here, and I don't know what will happen 
with tabs if I inline it.

So I will attach first.

Regards.


ps. I did not test booting from the harddisk to a system on the 
harddisk, but it boots a system on another device just fine, so I see no 
reason why it wouldn't work.

reference: 
https://lists.gnu.org/archive/html/grub-devel/2013-09/msg00113.html

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: grub-install-to-partitionless-lvm-pv_2.02~beta2.patch --]
[-- Type: text/x-diff; name=grub-install-to-partitionless-lvm-pv_2.02~beta2.patch, Size: 8957 bytes --]

=== modified file 'grub-core/disk/lvm.c'
--- grub-core/disk/lvm.c        2012-06-25 15:52:20 +0000
+++ grub-core/disk/lvm.c        2013-09-25 11:03:21 +0000
@@ -95,6 +95,38 @@
     }
 }
 
+static struct grub_lvm_pv_header *
+grub_lvm_get_pvh(grub_disk_t disk, char buf[static GRUB_LVM_LABEL_SIZE])
+{
+  struct grub_lvm_label_header *lh = (struct grub_lvm_label_header *) buf;
+  unsigned int i;
+
+  /* Search for label. */
+  for (i = 0; i < GRUB_LVM_LABEL_SCAN_SECTORS; i++)
+    {
+      if (grub_disk_read (disk, i, 0, GRUB_LVM_LABEL_SIZE, buf))
+        return NULL;
+
+      if ((! grub_strncmp ((char *)lh->id, GRUB_LVM_LABEL_ID,
+                          sizeof (lh->id)))
+         && (! grub_strncmp ((char *)lh->type, GRUB_LVM_LVM2_LABEL,
+                             sizeof (lh->type))))
+       break;
+    }
+
+  /* Return if we didn't find a label. */
+  if (i == GRUB_LVM_LABEL_SCAN_SECTORS)
+    {
+#ifdef GRUB_UTIL
+      grub_util_info ("no LVM signature found");
+#endif
+      return NULL;
+    }
+
+  return (struct grub_lvm_pv_header *) (buf + grub_le_to_cpu32(lh->offset_xl));
+}
+
+
 static struct grub_diskfilter_vg * 
 grub_lvm_detect (grub_disk_t disk,
                 struct grub_diskfilter_pv_id *id,
@@ -102,11 +134,10 @@
 {
   grub_err_t err;
   grub_uint64_t mda_offset, mda_size;
-  char buf[GRUB_LVM_LABEL_SIZE];
   char vg_id[GRUB_LVM_ID_STRLEN+1];
   char pv_id[GRUB_LVM_ID_STRLEN+1];
+  char buf[GRUB_LVM_LABEL_SIZE];
   char *metadatabuf, *p, *q, *vgname;
-  struct grub_lvm_label_header *lh = (struct grub_lvm_label_header *) buf;
   struct grub_lvm_pv_header *pvh;
   struct grub_lvm_disk_locn *dlocn;
   struct grub_lvm_mda_header *mdah;
@@ -115,30 +146,9 @@
   struct grub_diskfilter_vg *vg;
   struct grub_diskfilter_pv *pv;
 
-  /* Search for label. */
-  for (i = 0; i < GRUB_LVM_LABEL_SCAN_SECTORS; i++)
-    {
-      err = grub_disk_read (disk, i, 0, sizeof(buf), buf);
-      if (err)
-	goto fail;
-
-      if ((! grub_strncmp ((char *)lh->id, GRUB_LVM_LABEL_ID,
-			   sizeof (lh->id)))
-	  && (! grub_strncmp ((char *)lh->type, GRUB_LVM_LVM2_LABEL,
-			      sizeof (lh->type))))
-	break;
-    }
-
-  /* Return if we didn't find a label. */
-  if (i == GRUB_LVM_LABEL_SCAN_SECTORS)
-    {
-#ifdef GRUB_UTIL
-      grub_util_info ("no LVM signature found");
-#endif
-      goto fail;
-    }
-
-  pvh = (struct grub_lvm_pv_header *) (buf + grub_le_to_cpu32(lh->offset_xl));
+  pvh = grub_lvm_get_pvh(disk, buf);
+  if (! pvh)
+    goto fail;
 
   for (i = 0, j = 0; i < GRUB_LVM_ID_LEN; i++)
     {
@@ -151,7 +161,7 @@
   dlocn = pvh->disk_areas_xl;
 
   dlocn++;
-  /* Is it possible to have multiple data/metadata areas? I haven't
+  /* Is it possible to have multiple data areas? I haven't
      seen devices that have it. */
   if (dlocn->offset)
     {
@@ -746,6 +756,88 @@
   return NULL;
 }
 
+#ifdef GRUB_UTIL
+int
+grub_util_is_lvm(grub_disk_t disk)
+{
+  struct grub_diskfilter_pv_id id;
+  struct grub_diskfilter_vg *vg;
+  grub_disk_addr_t start_sector;
+  vg = grub_lvm_detect(disk, &id, &start_sector);
+  if (! vg)
+    return 0;
+  /* don't free the vg, it's held by grub_diskfilter_vg_register */
+  grub_free(id.uuid);
+  return 1;
+}
+
+grub_err_t
+grub_util_lvm_embed (struct grub_disk *disk, unsigned int *nsectors,
+                    unsigned int max_nsectors,
+                    grub_embed_type_t embed_type,
+                    grub_disk_addr_t **sectors)
+{
+  char buf[GRUB_LVM_LABEL_SIZE];
+  struct grub_lvm_pv_header *pvh;
+  struct grub_lvm_pv_header_ext *pvh_ext;
+  struct grub_diskfilter_pv *pv = NULL;
+  struct grub_diskfilter_vg *vg = NULL;
+  struct grub_lvm_disk_locn *dlocn;
+  grub_uint64_t ba_offset, ba_size, ba_start_sector;
+  unsigned int i;
+
+  if (embed_type != GRUB_EMBED_PCBIOS)
+    return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+                      "LVM curently supports only PC-BIOS embedding");
+  if (disk->partition)
+    return grub_error (GRUB_ERR_BUG, "disk isn't LVM");
+  pv = grub_diskfilter_get_pv_from_disk (disk, &vg);
+  if (! pv)
+    return grub_error (GRUB_ERR_BUG, "disk isn't LVM");
+
+  pvh = grub_lvm_get_pvh(disk, buf);
+  if (! pvh)
+    return grub_error (GRUB_ERR_BUG, "disk isn't LVM");
+
+  dlocn = pvh->disk_areas_xl;
+
+  /* skip past the data area list */
+  while (dlocn->offset)
+    dlocn++;
+  dlocn++;
+  /* and the metadata area list */
+  while (dlocn->offset)
+    dlocn++;
+  dlocn++;
+
+  pvh_ext = (struct grub_lvm_pv_header_ext*)dlocn;
+  if (! pvh_ext->version_xl)
+    return grub_error (GRUB_ERR_BUG, "LVM PV doesn't have a bootloader area");
+
+  dlocn = pvh_ext->disk_areas_xl;
+  ba_offset = grub_le_to_cpu64 (dlocn->offset);
+  ba_size = grub_le_to_cpu64 (dlocn->size);
+  if (! (ba_offset && ba_size))
+    return grub_error (GRUB_ERR_BUG, "LVM PV doesn't have a bootloader area");
+  /* could be worked around with extra arithmetic if this actually happens */
+  if (ba_offset % GRUB_DISK_SECTOR_SIZE)
+    return grub_error (
+      GRUB_ERR_BUG, "LVM bootloader area is improperly aligned");
+  ba_start_sector = ba_offset / GRUB_DISK_SECTOR_SIZE;
+
+  *nsectors = ba_size / GRUB_DISK_SECTOR_SIZE;
+  if (*nsectors > max_nsectors)
+    *nsectors = max_nsectors;
+
+  *sectors = grub_malloc (*nsectors * sizeof (**sectors));
+  if (!*sectors)
+    return grub_errno;
+  for (i = 0; i < *nsectors; i++)
+    (*sectors)[i] = ba_start_sector + i;
+
+  return GRUB_ERR_NONE;
+}
+#endif
 \f
 
 static struct grub_diskfilter grub_lvm_dev = {

=== modified file 'include/grub/diskfilter.h'
--- include/grub/diskfilter.h   2012-06-25 15:36:50 +0000
+++ include/grub/diskfilter.h   2013-09-25 08:59:05 +0000
@@ -75,6 +75,9 @@
 #ifdef GRUB_UTIL
   char **partmaps;
 #endif
+  /* Optional bootloader embedding area */
+  grub_uint64_t ba_offset;
+  grub_uint64_t ba_size;
 };
 
 struct grub_diskfilter_lv {

=== modified file 'include/grub/emu/hostdisk.h'
--- include/grub/emu/hostdisk.h 2013-08-22 14:50:12 +0000
+++ include/grub/emu/hostdisk.h 2013-09-25 07:59:06 +0000
@@ -44,9 +44,16 @@
 char *
 grub_util_get_ldm (grub_disk_t disk, grub_disk_addr_t start);
 int
+grub_util_is_lvm (grub_disk_t disk);
+int
 grub_util_is_ldm (grub_disk_t disk);
 #ifdef GRUB_UTIL
 grub_err_t
+grub_util_lvm_embed (struct grub_disk *disk, unsigned int *nsectors,
+                    unsigned int max_nsectors,
+                    grub_embed_type_t embed_type,
+                    grub_disk_addr_t **sectors);
+grub_err_t
 grub_util_ldm_embed (struct grub_disk *disk, unsigned int *nsectors,
                     unsigned int max_nsectors,
                     grub_embed_type_t embed_type,

=== modified file 'include/grub/lvm.h'
--- include/grub/lvm.h  2012-01-29 13:28:01 +0000
+++ include/grub/lvm.h  2013-09-25 08:32:31 +0000
@@ -62,6 +62,13 @@
   struct grub_lvm_disk_locn disk_areas_xl[0];  /* Two lists */
 } __attribute__ ((packed));
 
+struct grub_lvm_pv_header_ext {
+  grub_uint32_t version_xl;
+  grub_uint32_t flags_xl;
+  /* NULL-terminated list of bootloader embedding areas */
+  struct grub_lvm_disk_locn disk_areas_xl[0];
+} __attribute__ ((packed));
+
 #define GRUB_LVM_FMTT_MAGIC "\040\114\126\115\062\040\170\133\065\101\045\162\060\116\052\076"
 #define GRUB_LVM_FMTT_VERSION 1
 #define GRUB_LVM_MDA_HEADER_SIZE 512

=== modified file 'util/setup.c'
--- util/setup.c	2016-05-08 01:00:00.000000000 +0200
+++ util/setup.c	2016-05-08 02:00:00.000000000 +0200
@@ -390,7 +390,7 @@
       .container = dest_dev->disk->partition,
       .multiple_partmaps = 0
     };
-    int is_ldm;
+    int is_ldm, is_lvm;
     grub_err_t err;
     grub_disk_addr_t *sectors;
     int i;
@@ -423,8 +423,9 @@
       grub_errno = GRUB_ERR_NONE;
 
     is_ldm = grub_util_is_ldm (dest_dev->disk);
+    is_lvm = grub_util_is_lvm (dest_dev->disk);
 
-    if (fs_probe)
+    if (!is_lvm && fs_probe)
       {
 	if (!fs && !ctx.dest_partmap)
 	  grub_util_error (_("unable to identify a filesystem in %s; safety check can't be performed"),
@@ -462,7 +463,7 @@
 
       }
 
-    if (! ctx.dest_partmap && ! fs && !is_ldm)
+    if (! ctx.dest_partmap && ! fs && !is_ldm && !is_lvm)
       {
 	grub_util_warn ("%s", _("Attempting to install GRUB to a partitionless disk or to a partition.  This is a BAD idea."));
 	goto unable_to_embed;
@@ -499,7 +500,10 @@
       maxsec = ((0x78000 - GRUB_KERNEL_I386_PC_LINK_ADDR)
 		>> GRUB_DISK_SECTOR_BITS);
 
-    if (is_ldm)
+    if (is_lvm)
+      err = grub_util_lvm_embed (dest_dev->disk, &nsec, maxsec,
+                                GRUB_EMBED_PCBIOS, &sectors);
+    else if (is_ldm)
       err = grub_util_ldm_embed (dest_dev->disk, &nsec, maxsec,
 				 GRUB_EMBED_PCBIOS, &sectors);
     else if (ctx.dest_partmap)
@@ -602,7 +606,7 @@
 
   if (dest_dev->disk->dev->id != root_dev->disk->dev->id)
     grub_util_error ("%s", _("embedding is not possible, but this is required for "
-			     "RAID and LVM install"));
+			     "RAID install"));
 
   {
     grub_fs_t fs;

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH] Install to LVM PVs
  2016-05-08  4:53 Dryden Personalis
@ 2016-05-08  6:05 ` Andrei Borzenkov
  2016-05-08  8:47   ` Andrei Borzenkov
  2016-05-08 13:01   ` Dryden Personalis
  2016-05-08  9:23 ` Andrei Borzenkov
  1 sibling, 2 replies; 24+ messages in thread
From: Andrei Borzenkov @ 2016-05-08  6:05 UTC (permalink / raw)
  To: The development of GNU GRUB

08.05.2016 07:53, Dryden Personalis пишет:
> I updated this guy's patch to work with 2.02 beta 2, at least.
> 
> I've just worked on the version that gets downloaded and unpacked on
> Kubuntu / Ubuntu 16.04.
> 
> One part of the patch didn't apply because apparently some tabs have
> entered a file, namely grub-core/disk/lvm.c.
> 
> Another part didn't apply because code had been refactored from
> grub-setup.c to setup.c.
> 
> I've only compiled with these extra packages:
> 
> - bison
> - flex
> - libdevmapper-dev
> 
> and automake was also required. I've had to symlink the 1.15 executables
> to 1.14.
> 
> 

Did you actually test it by installing GRUB on PV? Does it boot? Did you
test it both with unpartitioned disk and PV in partition?

> I'm not sure why the patch never made it into mainline grub, but back
> then (2013) the argument was that it was doing something to an area that
> was not meant for that.
> 

Neither am I :) I understand that Vladimir had plans to stuff more
information in this area (personally I'd like to use it for environment
block as example) but just guessing. In any case, we really always can
cut off part of this area by artificially reducing size.

> However LVM contains the --bootloaderareasize flag that seems to be
> meant for this, and if you put it to 2048 sectors (or 1M) it ought to
> work cq. just works.
> 
> ie. pvcreate --bootloaderareasize 2048s /dev/sda, followed by,
> grub-install /dev/sda, will just work and result in a bootable system
> from that harddisk.
> 
> I don't know if I can attach here, and I don't know what will happen
> with tabs if I inline it.
> 
> So I will attach first.
> 

That's fine.

> Regards.
> 
> 
> ps. I did not test booting from the harddisk to a system on the
> harddisk, but it boots a system on another device just fine, so I see no
> reason why it wouldn't work.
> 
> reference:
> https://lists.gnu.org/archive/html/grub-devel/2013-09/msg00113.html
> 

> === modified file 'grub-core/disk/lvm.c'
> --- grub-core/disk/lvm.c        2012-06-25 15:52:20 +0000
> +++ grub-core/disk/lvm.c        2013-09-25 11:03:21 +0000
> @@ -95,6 +95,38 @@
>      }
>  }
>  
> +static struct grub_lvm_pv_header *
> +grub_lvm_get_pvh(grub_disk_t disk, char buf[static GRUB_LVM_LABEL_SIZE])
> +{
> +  struct grub_lvm_label_header *lh = (struct grub_lvm_label_header *) buf;
> +  unsigned int i;
> +
> +  /* Search for label. */
> +  for (i = 0; i < GRUB_LVM_LABEL_SCAN_SECTORS; i++)
> +    {
> +      if (grub_disk_read (disk, i, 0, GRUB_LVM_LABEL_SIZE, buf))
> +        return NULL;
> +
> +      if ((! grub_strncmp ((char *)lh->id, GRUB_LVM_LABEL_ID,
> +                          sizeof (lh->id)))
> +         && (! grub_strncmp ((char *)lh->type, GRUB_LVM_LVM2_LABEL,
> +                             sizeof (lh->type))))
> +       break;
> +    }
> +
> +  /* Return if we didn't find a label. */
> +  if (i == GRUB_LVM_LABEL_SCAN_SECTORS)
> +    {
> +#ifdef GRUB_UTIL
> +      grub_util_info ("no LVM signature found");
> +#endif
> +      return NULL;
> +    }
> +
> +  return (struct grub_lvm_pv_header *) (buf + grub_le_to_cpu32(lh->offset_xl));
> +}
> +
> +
>  static struct grub_diskfilter_vg * 
>  grub_lvm_detect (grub_disk_t disk,
>                  struct grub_diskfilter_pv_id *id,
> @@ -102,11 +134,10 @@
>  {
>    grub_err_t err;
>    grub_uint64_t mda_offset, mda_size;
> -  char buf[GRUB_LVM_LABEL_SIZE];
>    char vg_id[GRUB_LVM_ID_STRLEN+1];
>    char pv_id[GRUB_LVM_ID_STRLEN+1];
> +  char buf[GRUB_LVM_LABEL_SIZE];

Why reordering buf definition?

>    char *metadatabuf, *p, *q, *vgname;
> -  struct grub_lvm_label_header *lh = (struct grub_lvm_label_header *) buf;
>    struct grub_lvm_pv_header *pvh;
>    struct grub_lvm_disk_locn *dlocn;
>    struct grub_lvm_mda_header *mdah;
> @@ -115,30 +146,9 @@
>    struct grub_diskfilter_vg *vg;
>    struct grub_diskfilter_pv *pv;
>  
> -  /* Search for label. */
> -  for (i = 0; i < GRUB_LVM_LABEL_SCAN_SECTORS; i++)
> -    {
> -      err = grub_disk_read (disk, i, 0, sizeof(buf), buf);
> -      if (err)
> -	goto fail;
> -
> -      if ((! grub_strncmp ((char *)lh->id, GRUB_LVM_LABEL_ID,
> -			   sizeof (lh->id)))
> -	  && (! grub_strncmp ((char *)lh->type, GRUB_LVM_LVM2_LABEL,
> -			      sizeof (lh->type))))
> -	break;
> -    }
> -
> -  /* Return if we didn't find a label. */
> -  if (i == GRUB_LVM_LABEL_SCAN_SECTORS)
> -    {
> -#ifdef GRUB_UTIL
> -      grub_util_info ("no LVM signature found");
> -#endif
> -      goto fail;
> -    }
> -
> -  pvh = (struct grub_lvm_pv_header *) (buf + grub_le_to_cpu32(lh->offset_xl));
> +  pvh = grub_lvm_get_pvh(disk, buf);
> +  if (! pvh)
> +    goto fail;
>  
>    for (i = 0, j = 0; i < GRUB_LVM_ID_LEN; i++)
>      {
> @@ -151,7 +161,7 @@
>    dlocn = pvh->disk_areas_xl;
>  
>    dlocn++;
> -  /* Is it possible to have multiple data/metadata areas? I haven't
> +  /* Is it possible to have multiple data areas? I haven't

Could you explain why you deleted "metadata"?

>       seen devices that have it. */
>    if (dlocn->offset)
>      {
> @@ -746,6 +756,88 @@
>    return NULL;
>  }
>  
> +#ifdef GRUB_UTIL
> +int
> +grub_util_is_lvm(grub_disk_t disk)
> +{
> +  struct grub_diskfilter_pv_id id;
> +  struct grub_diskfilter_vg *vg;
> +  grub_disk_addr_t start_sector;
> +  vg = grub_lvm_detect(disk, &id, &start_sector);
> +  if (! vg)
> +    return 0;
> +  /* don't free the vg, it's held by grub_diskfilter_vg_register */
> +  grub_free(id.uuid);
> +  return 1;
> +}
> +

This has side effect of adding duplicate VG definitions; this may later
confuse grub. What about just checking array->driver for LVM? Go through
registered arrays, find disk match and check array driver. See
scan_disk_partition_iter () for example.

> +grub_err_t
> +grub_util_lvm_embed (struct grub_disk *disk, unsigned int *nsectors,
> +                    unsigned int max_nsectors,
> +                    grub_embed_type_t embed_type,
> +                    grub_disk_addr_t **sectors)
> +{
> +  char buf[GRUB_LVM_LABEL_SIZE];
> +  struct grub_lvm_pv_header *pvh;
> +  struct grub_lvm_pv_header_ext *pvh_ext;
> +  struct grub_diskfilter_pv *pv = NULL;
> +  struct grub_diskfilter_vg *vg = NULL;
> +  struct grub_lvm_disk_locn *dlocn;
> +  grub_uint64_t ba_offset, ba_size, ba_start_sector;
> +  unsigned int i;
> +
> +  if (embed_type != GRUB_EMBED_PCBIOS)
> +    return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
> +                      "LVM curently supports only PC-BIOS embedding");
> +  if (disk->partition)
> +    return grub_error (GRUB_ERR_BUG, "disk isn't LVM");

Why? What's wrong with PV on partition?

> +  pv = grub_diskfilter_get_pv_from_disk (disk, &vg);
> +  if (! pv)
> +    return grub_error (GRUB_ERR_BUG, "disk isn't LVM");
> +
> +  pvh = grub_lvm_get_pvh(disk, buf);
> +  if (! pvh)
> +    return grub_error (GRUB_ERR_BUG, "disk isn't LVM");
> +

Please, more specific error message, so they are actually useful to
identify what happened.

None of those is bug; this should probably be GRUB_ERR_BAD_DEVICE.

> +  dlocn = pvh->disk_areas_xl;
> +
> +  /* skip past the data area list */
> +  while (dlocn->offset)
> +    dlocn++;
> +  dlocn++;
> +  /* and the metadata area list */
> +  while (dlocn->offset)
> +    dlocn++;
> +  dlocn++;
> +
> +  pvh_ext = (struct grub_lvm_pv_header_ext*)dlocn;
> +  if (! pvh_ext->version_xl)
> +    return grub_error (GRUB_ERR_BUG, "LVM PV doesn't have a bootloader area");
> +

Again, this is not a bug.

> +  dlocn = pvh_ext->disk_areas_xl;
> +  ba_offset = grub_le_to_cpu64 (dlocn->offset);
> +  ba_size = grub_le_to_cpu64 (dlocn->size);
> +  if (! (ba_offset && ba_size))
> +    return grub_error (GRUB_ERR_BUG, "LVM PV doesn't have a bootloader area");

And this.

> +  /* could be worked around with extra arithmetic if this actually happens */
> +  if (ba_offset % GRUB_DISK_SECTOR_SIZE)
> +    return grub_error (
> +      GRUB_ERR_BUG, "LVM bootloader area is improperly aligned");
> +  ba_start_sector = ba_offset / GRUB_DISK_SECTOR_SIZE;
> +
> +  *nsectors = ba_size / GRUB_DISK_SECTOR_SIZE;
> +  if (*nsectors > max_nsectors)
> +    *nsectors = max_nsectors;
> +
> +  *sectors = grub_malloc (*nsectors * sizeof (**sectors));
> +  if (!*sectors)
> +    return grub_errno;
> +  for (i = 0; i < *nsectors; i++)
> +    (*sectors)[i] = ba_start_sector + i;
> +
> +  return GRUB_ERR_NONE;
> +}
> +#endif
>  
>  
>  static struct grub_diskfilter grub_lvm_dev = {
> 
> === modified file 'include/grub/diskfilter.h'
> --- include/grub/diskfilter.h   2012-06-25 15:36:50 +0000
> +++ include/grub/diskfilter.h   2013-09-25 08:59:05 +0000
> @@ -75,6 +75,9 @@
>  #ifdef GRUB_UTIL
>    char **partmaps;
>  #endif
> +  /* Optional bootloader embedding area */
> +  grub_uint64_t ba_offset;
> +  grub_uint64_t ba_size;
>  };
>  
>  struct grub_diskfilter_lv {
> 
> === modified file 'include/grub/emu/hostdisk.h'
> --- include/grub/emu/hostdisk.h 2013-08-22 14:50:12 +0000
> +++ include/grub/emu/hostdisk.h 2013-09-25 07:59:06 +0000
> @@ -44,9 +44,16 @@
>  char *
>  grub_util_get_ldm (grub_disk_t disk, grub_disk_addr_t start);
>  int
> +grub_util_is_lvm (grub_disk_t disk);
> +int
>  grub_util_is_ldm (grub_disk_t disk);
>  #ifdef GRUB_UTIL
>  grub_err_t
> +grub_util_lvm_embed (struct grub_disk *disk, unsigned int *nsectors,
> +                    unsigned int max_nsectors,
> +                    grub_embed_type_t embed_type,
> +                    grub_disk_addr_t **sectors);
> +grub_err_t
>  grub_util_ldm_embed (struct grub_disk *disk, unsigned int *nsectors,
>                      unsigned int max_nsectors,
>                      grub_embed_type_t embed_type,
> 
> === modified file 'include/grub/lvm.h'
> --- include/grub/lvm.h  2012-01-29 13:28:01 +0000
> +++ include/grub/lvm.h  2013-09-25 08:32:31 +0000
> @@ -62,6 +62,13 @@
>    struct grub_lvm_disk_locn disk_areas_xl[0];  /* Two lists */
>  } __attribute__ ((packed));
>  
> +struct grub_lvm_pv_header_ext {
> +  grub_uint32_t version_xl;
> +  grub_uint32_t flags_xl;
> +  /* NULL-terminated list of bootloader embedding areas */
> +  struct grub_lvm_disk_locn disk_areas_xl[0];
> +} __attribute__ ((packed));
> +
>  #define GRUB_LVM_FMTT_MAGIC "\040\114\126\115\062\040\170\133\065\101\045\162\060\116\052\076"
>  #define GRUB_LVM_FMTT_VERSION 1
>  #define GRUB_LVM_MDA_HEADER_SIZE 512
> 
> === modified file 'util/setup.c'
> --- util/setup.c	2016-05-08 01:00:00.000000000 +0200
> +++ util/setup.c	2016-05-08 02:00:00.000000000 +0200
> @@ -390,7 +390,7 @@
>        .container = dest_dev->disk->partition,
>        .multiple_partmaps = 0
>      };
> -    int is_ldm;
> +    int is_ldm, is_lvm;
>      grub_err_t err;
>      grub_disk_addr_t *sectors;
>      int i;
> @@ -423,8 +423,9 @@
>        grub_errno = GRUB_ERR_NONE;
>  
>      is_ldm = grub_util_is_ldm (dest_dev->disk);
> +    is_lvm = grub_util_is_lvm (dest_dev->disk);
>  
> -    if (fs_probe)
> +    if (!is_lvm && fs_probe)

No, we want to probe for FS here to eliminate corner case of both PV and
FS metadata.

>        {
>  	if (!fs && !ctx.dest_partmap)
>  	  grub_util_error (_("unable to identify a filesystem in %s; safety check can't be performed"),
> @@ -462,7 +463,7 @@
>  
>        }
>  
> -    if (! ctx.dest_partmap && ! fs && !is_ldm)
> +    if (! ctx.dest_partmap && ! fs && !is_ldm && !is_lvm)
>        {
>  	grub_util_warn ("%s", _("Attempting to install GRUB to a partitionless disk or to a partition.  This is a BAD idea."));
>  	goto unable_to_embed;

And you need to add check for LVM here

    if (ctx.multiple_partmaps || (ctx.dest_partmap && fs) || (is_ldm && fs))
      {
        grub_util_warn ("%s", _("Attempting to install GRUB to a disk
with multiple partition labels.  This is not supported yet."));
        goto unable_to_embed;
      }


> @@ -499,7 +500,10 @@
>        maxsec = ((0x78000 - GRUB_KERNEL_I386_PC_LINK_ADDR)
>  		>> GRUB_DISK_SECTOR_BITS);
>  
> -    if (is_ldm)
> +    if (is_lvm)
> +      err = grub_util_lvm_embed (dest_dev->disk, &nsec, maxsec,
> +                                GRUB_EMBED_PCBIOS, &sectors);
> +    else if (is_ldm)
>        err = grub_util_ldm_embed (dest_dev->disk, &nsec, maxsec,
>  				 GRUB_EMBED_PCBIOS, &sectors);
>      else if (ctx.dest_partmap)
> @@ -602,7 +606,7 @@
>  
>    if (dest_dev->disk->dev->id != root_dev->disk->dev->id)
>      grub_util_error ("%s", _("embedding is not possible, but this is required for "
> -			     "RAID and LVM install"));
> +			     "RAID install"));
>  
>    {
>      grub_fs_t fs;



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH] Install to LVM PVs
  2016-05-08  6:05 ` Andrei Borzenkov
@ 2016-05-08  8:47   ` Andrei Borzenkov
  2016-05-08 13:10     ` Dryden Personalis
  2016-05-08 17:16     ` Dryden Personalis
  2016-05-08 13:01   ` Dryden Personalis
  1 sibling, 2 replies; 24+ messages in thread
From: Andrei Borzenkov @ 2016-05-08  8:47 UTC (permalink / raw)
  To: The development of GNU GRUB

08.05.2016 09:05, Andrei Borzenkov пишет:
>>  
>> +#ifdef GRUB_UTIL
>> +int
>> +grub_util_is_lvm(grub_disk_t disk)
>> +{
>> +  struct grub_diskfilter_pv_id id;
>> +  struct grub_diskfilter_vg *vg;
>> +  grub_disk_addr_t start_sector;
>> +  vg = grub_lvm_detect(disk, &id, &start_sector);
>> +  if (! vg)
>> +    return 0;
>> +  /* don't free the vg, it's held by grub_diskfilter_vg_register */
>> +  grub_free(id.uuid);
>> +  return 1;
>> +}
>> +
> 
> This has side effect of adding duplicate VG definitions; this may later
> confuse grub. What about just checking array->driver for LVM? Go through
> registered arrays, find disk match and check array driver. See
> scan_disk_partition_iter () for example.
> 

Which is basically call grub_diskfilter_get_pv_from_disk() and check
vg_out->driver.




^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH] Install to LVM PVs
  2016-05-08  4:53 Dryden Personalis
  2016-05-08  6:05 ` Andrei Borzenkov
@ 2016-05-08  9:23 ` Andrei Borzenkov
  2016-05-08 13:09   ` Dryden Personalis
  2016-05-09  0:10   ` Xen
  1 sibling, 2 replies; 24+ messages in thread
From: Andrei Borzenkov @ 2016-05-08  9:23 UTC (permalink / raw)
  To: The development of GNU GRUB

08.05.2016 07:53, Dryden Personalis пишет:
> +    if (is_lvm)
> +      err = grub_util_lvm_embed (dest_dev->disk, &nsec, maxsec,
> +                                GRUB_EMBED_PCBIOS, &sectors);

PV label may be in the first sector. In this case label will be
overwritten later by boot image. This needs additional check.



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH] Install to LVM PVs
  2016-05-08  6:05 ` Andrei Borzenkov
  2016-05-08  8:47   ` Andrei Borzenkov
@ 2016-05-08 13:01   ` Dryden Personalis
  2016-05-09  6:07     ` Andrei Borzenkov
  1 sibling, 1 reply; 24+ messages in thread
From: Dryden Personalis @ 2016-05-08 13:01 UTC (permalink / raw)
  To: The development of GNU GRUB

Andrei Borzenkov schreef op 08-05-2016 8:05:

> Did you actually test it by installing GRUB on PV? Does it boot? Did 
> you
> test it both with unpartitioned disk and PV in partition?

Hi Andrei,

I must say I have for the most part just copied the patch as it was, and 
just tried to fix it so that the patch would actually apply in full. I 
have no experience yet with Grub code, so I may not be able to answer 
any or all of your questions.

I must say that I did try the former, but not the latter yet. My system 
is not installed though so I can try at any point. What I haven't tried 
yet is booting FROM the PV in the sense of loading a system from it (and 
not just the boot loader) so at this point I have only booted a 
different system from the boot loader on my /dev/sda residing in a 
partitionless PV.

Testing a PV with partitions is trivial, I will do that shortly.

I plan on readily installing a system on that disk after I have my 
scheme sorted out, so then I can test for real the real use case (but 
only in the case of partitionless).


> Neither am I :) I understand that Vladimir had plans to stuff more
> information in this area (personally I'd like to use it for environment
> block as example) but just guessing. In any case, we really always can
> cut off part of this area by artificially reducing size.
>> === modified file 'grub-core/disk/lvm.c'
>> --- grub-core/disk/lvm.c        2012-06-25 15:52:20 +0000
>> +++ grub-core/disk/lvm.c        2013-09-25 11:03:21 +0000
>> @@ -102,11 +134,10 @@
>>  {
>>    grub_err_t err;
>>    grub_uint64_t mda_offset, mda_size;
>> -  char buf[GRUB_LVM_LABEL_SIZE];
>>    char vg_id[GRUB_LVM_ID_STRLEN+1];
>>    char pv_id[GRUB_LVM_ID_STRLEN+1];
>> +  char buf[GRUB_LVM_LABEL_SIZE];
> 
> Why reordering buf definition?

That was just in the original patch. You can see the dates. I put some 
artificial times on the latest hunk, from yesterday. I didn't do 
anything really to the hunks from 2012/2013.

So I don't know the rationale, we'd have to ask the original author, it 
probably makes no sense from my POV, but it does seem nicer lol.

>> -  /* Is it possible to have multiple data/metadata areas? I haven't
>> +  /* Is it possible to have multiple data areas? I haven't
> 
> Could you explain why you deleted "metadata"?

I don't know but I think the guy wanted to simplify by only having one 
block? Or something of the kind?

> 
>>       seen devices that have it. */
>>    if (dlocn->offset)
>>      {
>> @@ -746,6 +756,88 @@
>>    return NULL;
>>  }
>> 
>> +#ifdef GRUB_UTIL
>> +int
>> +grub_util_is_lvm(grub_disk_t disk)
>> +{
>> +  struct grub_diskfilter_pv_id id;
>> +  struct grub_diskfilter_vg *vg;
>> +  grub_disk_addr_t start_sector;
>> +  vg = grub_lvm_detect(disk, &id, &start_sector);
>> +  if (! vg)
>> +    return 0;
>> +  /* don't free the vg, it's held by grub_diskfilter_vg_register */
>> +  grub_free(id.uuid);
>> +  return 1;
>> +}
>> +
> 
> This has side effect of adding duplicate VG definitions; this may later
> confuse grub. What about just checking array->driver for LVM? Go 
> through
> registered arrays, find disk match and check array driver. See
> scan_disk_partition_iter () for example.

Alright this is beyond me at this point, I'd prefer if you gave feedback 
on the other items first.

But do you mean not to use grub_lvm_detect?

Are you saying that "array->driver" would already be loaded before we do 
grub_lvm_detect? (Or rather, before grub_util_is_lvm)? You are meaning 
to imply to just use a different identification measure right, because 
apparently grub_lvm_detect has already been done in that case.


>> +grub_err_t
>> +grub_util_lvm_embed (struct grub_disk *disk, unsigned int *nsectors,
>> +                    unsigned int max_nsectors,
>> +                    grub_embed_type_t embed_type,
>> +                    grub_disk_addr_t **sectors)
>> +{
>> +  char buf[GRUB_LVM_LABEL_SIZE];
>> +  struct grub_lvm_pv_header *pvh;
>> +  struct grub_lvm_pv_header_ext *pvh_ext;
>> +  struct grub_diskfilter_pv *pv = NULL;
>> +  struct grub_diskfilter_vg *vg = NULL;
>> +  struct grub_lvm_disk_locn *dlocn;
>> +  grub_uint64_t ba_offset, ba_size, ba_start_sector;
>> +  unsigned int i;
>> +
>> +  if (embed_type != GRUB_EMBED_PCBIOS)
>> +    return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
>> +                      "LVM curently supports only PC-BIOS 
>> embedding");
>> +  if (disk->partition)
>> +    return grub_error (GRUB_ERR_BUG, "disk isn't LVM");
> 
> Why? What's wrong with PV on partition?

Just for my recollection:

* The function "grub_util_info" now calls "grub_util_is_lvm"
* grub_util_is_lvm only scans the first 4 sectors of a disk, so it will 
not find anything on a partitioned /dev/sda
* The above function grub_util_lvm_embed is only called when it does 
return true.

* If you don't have a VG in the PV, the error never gets triggered.

I don't know, the guy designed the feature for partitionless. Does it 
make sense to use if you don't have partitions? If it is all equivalent 
to Grub, I don't see why it shouldn't be possible.

It means you'd want to embed grub in a partition that has a PV. Don't 
see why it shouldn't be possible.

I can remove it but I will have to find out how to boot from an actual 
partition to test it :p.

Maybe easiest is to clear the MBR and set bootable flag? Don't know if 
that works for grub. If default msdos label has such code....

>> +  pv = grub_diskfilter_get_pv_from_disk (disk, &vg);
>> +  if (! pv)
>> +    return grub_error (GRUB_ERR_BUG, "disk isn't LVM");
>> +
>> +  pvh = grub_lvm_get_pvh(disk, buf);
>> +  if (! pvh)
>> +    return grub_error (GRUB_ERR_BUG, "disk isn't LVM");
>> +
> 
> Please, more specific error message, so they are actually useful to
> identify what happened.

Yes, can do. If I understand get_pvh, but that shouldn't be hard.

> None of those is bug; this should probably be GRUB_ERR_BAD_DEVICE.

Aye, it even reports as a warning while being fatal. Can do.

>> +    return grub_error (GRUB_ERR_BUG, "LVM PV doesn't have a 
>> bootloader area");
>> +
> 
> Again, this is not a bug.

Roger. Will find some other error if I can.

>> -    if (fs_probe)
>> +    if (!is_lvm && fs_probe)
> 
> No, we want to probe for FS here to eliminate corner case of both PV 
> and
> FS metadata.

You mean you want to change it to:

...something that gives a different error as in:

if (fs_probe) {
   if (is_lvm && fs ) {
     grub_util_error (_("a filesystem signature is present on %s, but 
embedding in an LVM PV was requested"), dest_dev->disk->name);
   } else if (!is_lvm && !fs && !ctx.dest_partmap) {
     grub_util_error (_("unable to identify a filesystem in %s; safety 
check can't be performed"), dest_dev->disk->name);
   }
   <therest>
}

That is just my coding style, I understand yours.

>> -    if (! ctx.dest_partmap && ! fs && !is_ldm)
>> +    if (! ctx.dest_partmap && ! fs && !is_ldm && !is_lvm)
>>        {
>>  	grub_util_warn ("%s", _("Attempting to install GRUB to a 
>> partitionless disk or to a partition.  This is a BAD idea."));
>>  	goto unable_to_embed;
> 
> And you need to add check for LVM here
> 
>     if (ctx.multiple_partmaps || (ctx.dest_partmap && fs) || (is_ldm && 
> fs))

I take it you mean:

if (!is_lvm && (ctx.multiple_partmaps || (ctx.dest_partmap && fs) || 
(is_ldm && fs)))

?

Or do you mean:

if (ctx.multiple_partmaps || (ctx.dest_partmap && fs) || (is_ldm && fs) 
|| is_lvm))

?

I take it the former: with is_lvm there should be no warning.

I will work on the changes and post a new patch (not git format, but 
shouldn't matter).


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH] Install to LVM PVs
  2016-05-08  9:23 ` Andrei Borzenkov
@ 2016-05-08 13:09   ` Dryden Personalis
  2016-05-09  0:10   ` Xen
  1 sibling, 0 replies; 24+ messages in thread
From: Dryden Personalis @ 2016-05-08 13:09 UTC (permalink / raw)
  To: The development of GNU GRUB; +Cc: Grub-devel

Andrei Borzenkov schreef op 08-05-2016 11:23:
> 08.05.2016 07:53, Dryden Personalis пишет:
>> +    if (is_lvm)
>> +      err = grub_util_lvm_embed (dest_dev->disk, &nsec, maxsec,
>> +                                GRUB_EMBED_PCBIOS, &sectors);
> 
> PV label may be in the first sector. In this case label will be
> overwritten later by boot image. This needs additional check.

Is that only true for the first sector? I saw it checks the first 4. So 
I don't know what it does by default?

pvcreate will not work on disks that have a partition, but they are okay 
with having a label but no partitions.

the man page suggests wiping the first sector, but it says nothing about 
where it will install itself.

You are suggesting to check whether PV header is in 1-3, and not proceed 
if it is in 0.


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH] Install to LVM PVs
  2016-05-08  8:47   ` Andrei Borzenkov
@ 2016-05-08 13:10     ` Dryden Personalis
  2016-05-08 17:16     ` Dryden Personalis
  1 sibling, 0 replies; 24+ messages in thread
From: Dryden Personalis @ 2016-05-08 13:10 UTC (permalink / raw)
  To: The development of GNU GRUB

Andrei Borzenkov schreef op 08-05-2016 10:47:
> 08.05.2016 09:05, Andrei Borzenkov пишет:
>>> 
>>> +#ifdef GRUB_UTIL
>>> +int
>>> +grub_util_is_lvm(grub_disk_t disk)
>>> +{
>>> +  struct grub_diskfilter_pv_id id;
>>> +  struct grub_diskfilter_vg *vg;
>>> +  grub_disk_addr_t start_sector;
>>> +  vg = grub_lvm_detect(disk, &id, &start_sector);
>>> +  if (! vg)
>>> +    return 0;
>>> +  /* don't free the vg, it's held by grub_diskfilter_vg_register */
>>> +  grub_free(id.uuid);
>>> +  return 1;
>>> +}
>>> +
>> 
>> This has side effect of adding duplicate VG definitions; this may 
>> later
>> confuse grub. What about just checking array->driver for LVM? Go 
>> through
>> registered arrays, find disk match and check array driver. See
>> scan_disk_partition_iter () for example.
>> 
> 
> Which is basically call grub_diskfilter_get_pv_from_disk() and check
> vg_out->driver.

Roger.


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH] Install to LVM PVs
  2016-05-08  8:47   ` Andrei Borzenkov
  2016-05-08 13:10     ` Dryden Personalis
@ 2016-05-08 17:16     ` Dryden Personalis
  2016-05-08 17:40       ` Dryden Personalis
  1 sibling, 1 reply; 24+ messages in thread
From: Dryden Personalis @ 2016-05-08 17:16 UTC (permalink / raw)
  To: The development of GNU GRUB

Andrei Borzenkov schreef op 08-05-2016 10:47:
> 08.05.2016 09:05, Andrei Borzenkov пишет:
>>> 
>>> +#ifdef GRUB_UTIL
>>> +int
>>> +grub_util_is_lvm(grub_disk_t disk)
>>> +{
>>> +  struct grub_diskfilter_pv_id id;
>>> +  struct grub_diskfilter_vg *vg;
>>> +  grub_disk_addr_t start_sector;
>>> +  vg = grub_lvm_detect(disk, &id, &start_sector);
>>> +  if (! vg)
>>> +    return 0;
>>> +  /* don't free the vg, it's held by grub_diskfilter_vg_register */
>>> +  grub_free(id.uuid);
>>> +  return 1;
>>> +}
>>> +
>> 
>> This has side effect of adding duplicate VG definitions; this may 
>> later
>> confuse grub. What about just checking array->driver for LVM? Go 
>> through
>> registered arrays, find disk match and check array driver. See
>> scan_disk_partition_iter () for example.
>> 
> 
> Which is basically call grub_diskfilter_get_pv_from_disk() and check
> vg_out->driver.

This method also has the downside that is_lvm will fail without any 
indication as to why, when no volume group has been created. lvm_detect 
will return null because it can only return a VG. And, you cannot error 
out on that if a non-existing LVM should be okay.

So this call to lvm_detect is pretty annoying.

If it had more info, I could at least give an error in setup.c.

I am not sure whether installation is *possible* without a VG but it 
would be odd if it couldn't?

Anyway I would like a better error message on this because I just wasted 
2 hours trying to get GRUB_UTIL to work and failing. That means as per 
your method I can probably distinguish between PV present and VG present 
(or not present).

Then the only way I know how to report back is to give more values to 
is_lvm, but do we need a VG? Why error out on no VG? I will test.


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH] Install to LVM PVs
  2016-05-08 17:16     ` Dryden Personalis
@ 2016-05-08 17:40       ` Dryden Personalis
  0 siblings, 0 replies; 24+ messages in thread
From: Dryden Personalis @ 2016-05-08 17:40 UTC (permalink / raw)
  To: The development of GNU GRUB

Dryden Personalis schreef op 08-05-2016 19:16:

> I just wasted 2 hours trying to get GRUB_UTIL to work and failing.

I am just not always that brilliant.

Why on earth is that flag in there? If you enable it, stuff won't 
compile anymore. And I merely needed to turn on verbose output for 
grub-install :p. Not that it would have helped much, but at least 
troubleshooting would have been faster.

Omg. I blame the heat. Trying to get a system working that already works 
just fine.

:( :P.


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH] Install to LVM PVs
  2016-05-08  9:23 ` Andrei Borzenkov
  2016-05-08 13:09   ` Dryden Personalis
@ 2016-05-09  0:10   ` Xen
  2016-05-09  0:10     ` Dryden Personalis
  1 sibling, 1 reply; 24+ messages in thread
From: Xen @ 2016-05-09  0:10 UTC (permalink / raw)
  To: The development of GNU GRUB

Andrei Borzenkov schreef op 08-05-2016 11:23:

> PV label may be in the first sector. In this case label will be
> overwritten later by boot image. This needs additional check.

Pardon my last mail.

ON OLD PV SIGNATURES
--------------------

If you have an old PV that had a boatloaderarea, then wiping and or 
recreating the PV doesn't actually clear or reset or reformat that thing 
so as to fail.

It is not necessary to have a VG in order to install grub to a PV.

However, if the VG code is not called (both grub_lvm_detect and 
grub_diskfilter_get_pv_from_disk) then the code will not know how big 
the bootloaderarea is going to be (or whether you have one) -- you still 
don't need a VG, you just need to call that function the way this patch 
is.

Having or not having a VG in the PV makes no difference as to the 
results of any operation.

My code currently pretends that having a PV header is enough, and it 
works out just fine. I have not exhaustively tested what happens if you 
create a VG after (successfully booting) but I doubt it is going to give 
issues.

So the most important thing for this checking code currently is that the 
PV is actually created on a clean disk, ie a simple:

dd if=/dev/zero of=/dev/sda bs=1M count=20

Will ensure correct behaviour.

So it is possible to create a PV without a bootloaderarea on top of an 
older PV that did have one, and the code will see the data structures of 
the old one, but the real PV and its VGs will be based on the new one 
(you can see the difference in that you lose an extent if you create or 
remove an area of 4M).

So the code is not entirely correct in that sense (And I do not 
understand it yet at all) but in most cases it functions correctly.


LOCATION OF SANITY CHECKING
---------------------------

Presently what I am doing is to let the code in setup.c only check the 
basics, if a PV header is present, fine, let's get on with it. The 
embedding code (in lvm.c) then checks whether everything is alright.

The annoying part is that if (and only if) you have placed your PV 
header in the first sector (the way we needed to prevent cq. check) it 
can mean that some info message is going to be output multiple times. 
Each time the checking function is called, it will see the header 
sitting in the first sector, and output some message.

Apart from that the error resolution is pretty outstanding currently.

So I propose to:

- not need any VG
- is_lvm will return true if only a header is present
- sanity checking is not done much in setup.c unless it is a call to 
lvm.c


If you really have zero sector PV header, currently the "info" message 
will be output at least twice, and possibly trice:

- in lvm_detect
- in lvm_embed
- in any checking function called from setup.c

I have put a parameter to get_lvh that supresses the verbosity if zero.

You will see.

At this point the whole VG initialisation system for embedding is only 
apparently needed to check the actual bootloaderarea.


CURRENT RESULTS:
----------------

First off, booting works fine from a non-partition setup. I assume there 
is no difference installing to a disk with a partition table and no LVM.

Personally I cannot get Grub to install on /dev/sda1:

error: cannot find a GRUB drive for /dev/sdal.  Check your device.map.


Presently, this is the output if you try to install on a first-sector PV 
without VG:

info: Scanning for lvm devices on disk hostdisk//dev/sda.
info: couldn't find ID
info: LVM signature in first sector.
warning: installing inside LVM PV, but its header is sitting in the 
first sector; cannot install there.
error: embedding is not possible, but this is required for LVM and RAID 
install.

Upon creating a volume group, LVM will actually restore the PV header to 
the 2nd sector, if you've botched it.

A zero sector (first sector) PV is just not reality.

They are not recognized.


Installing on a PV without bootloaderarea will result in:

info: Scanning for lvm devices on disk hostdisk//dev/sda.
info: Found array linux.
info: Inserting hostdisk//dev/sda (+0,976773168) into linux (lvm)
info: drive = 1.
info: the size of hostdisk//dev/sda is 976773168.
info: Scanning for DISKFILTER devices on disk hostdisk//dev/sda.
warning: you have chosen to install inside an LVM PV, but it doesn't 
have a bootloader area (check pvcreate --bootloaderareasize).
error: embedding is not possible, but this is required for LVM and RAID 
install.

When a VG is present.

I don't think it actually checks for the SIZE of the bootloaderarea but 
that could easily be added I think.

When you do the same without a VG:

info: Scanning for lvm devices on disk hostdisk//dev/sda.
info: couldn't find ID
warning: you have chosen to install inside an LVM PV, but it doesn't 
have a bootloader area (check pvcreate --bootloaderareasize).
error: embedding is not possible, but this is required for LVM and RAID 
install.


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH] Install to LVM PVs
  2016-05-09  0:10   ` Xen
@ 2016-05-09  0:10     ` Dryden Personalis
  0 siblings, 0 replies; 24+ messages in thread
From: Dryden Personalis @ 2016-05-09  0:10 UTC (permalink / raw)
  To: Grub devel

Andrei Borzenkov schreef op 08-05-2016 11:23:

> PV label may be in the first sector. In this case label will be
> overwritten later by boot image. This needs additional check.

Pardon my last mail.

ON OLD PV SIGNATURES
--------------------

If you have an old PV that had a boatloaderarea, then wiping and or 
recreating the PV doesn't actually clear or reset or reformat that thing 
so as to fail.

It is not necessary to have a VG in order to install grub to a PV.

However, if the VG code is not called (both grub_lvm_detect and 
grub_diskfilter_get_pv_from_disk) then the code will not know how big 
the bootloaderarea is going to be (or whether you have one) -- you still 
don't need a VG, you just need to call that function the way this patch 
is.

Having or not having a VG in the PV makes no difference as to the 
results of any operation.

My code currently pretends that having a PV header is enough, and it 
works out just fine. I have not exhaustively tested what happens if you 
create a VG after (successfully booting) but I doubt it is going to give 
issues.

So the most important thing for this checking code currently is that the 
PV is actually created on a clean disk, ie a simple:

dd if=/dev/zero of=/dev/sda bs=1M count=20

Will ensure correct behaviour.

So it is possible to create a PV without a bootloaderarea on top of an 
older PV that did have one, and the code will see the data structures of 
the old one, but the real PV and its VGs will be based on the new one 
(you can see the difference in that you lose an extent if you create or 
remove an area of 4M).

So the code is not entirely correct in that sense (And I do not 
understand it yet at all) but in most cases it functions correctly.


LOCATION OF SANITY CHECKING
---------------------------

Presently what I am doing is to let the code in setup.c only check the 
basics, if a PV header is present, fine, let's get on with it. The 
embedding code (in lvm.c) then checks whether everything is alright.

The annoying part is that if (and only if) you have placed your PV 
header in the first sector (the way we needed to prevent cq. check) it 
can mean that some info message is going to be output multiple times. 
Each time the checking function is called, it will see the header 
sitting in the first sector, and output some message.

Apart from that the error resolution is pretty outstanding currently.

So I propose to:

- not need any VG
- is_lvm will return true if only a header is present
- sanity checking is not done much in setup.c unless it is a call to 
lvm.c


If you really have zero sector PV header, currently the "info" message 
will be output at least twice, and possibly trice:

- in lvm_detect
- in lvm_embed
- in any checking function called from setup.c

I have put a parameter to get_lvh that supresses the verbosity if zero.

You will see.

At this point the whole VG initialisation system for embedding is only 
apparently needed to check the actual bootloaderarea.


CURRENT RESULTS:
----------------

First off, booting works fine from a non-partition setup. I assume there 
is no difference installing to a disk with a partition table and no LVM.

Personally I cannot get Grub to install on /dev/sda1:

error: cannot find a GRUB drive for /dev/sdal.  Check your device.map.


Presently, this is the output if you try to install on a first-sector PV 
without VG:

info: Scanning for lvm devices on disk hostdisk//dev/sda.
info: couldn't find ID
info: LVM signature in first sector.
warning: installing inside LVM PV, but its header is sitting in the 
first sector; cannot install there.
error: embedding is not possible, but this is required for LVM and RAID 
install.

Upon creating a volume group, LVM will actually restore the PV header to 
the 2nd sector, if you've botched it.

A zero sector (first sector) PV is just not reality.

They are not recognized.


Installing on a PV without bootloaderarea will result in:

info: Scanning for lvm devices on disk hostdisk//dev/sda.
info: Found array linux.
info: Inserting hostdisk//dev/sda (+0,976773168) into linux (lvm)
info: drive = 1.
info: the size of hostdisk//dev/sda is 976773168.
info: Scanning for DISKFILTER devices on disk hostdisk//dev/sda.
warning: you have chosen to install inside an LVM PV, but it doesn't 
have a bootloader area (check pvcreate --bootloaderareasize).
error: embedding is not possible, but this is required for LVM and RAID 
install.

When a VG is present.

I don't think it actually checks for the SIZE of the bootloaderarea but 
that could easily be added I think.

When you do the same without a VG:

info: Scanning for lvm devices on disk hostdisk//dev/sda.
info: couldn't find ID
warning: you have chosen to install inside an LVM PV, but it doesn't 
have a bootloader area (check pvcreate --bootloaderareasize).
error: embedding is not possible, but this is required for LVM and RAID 
install.


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH] Install to LVM PVs
  2016-05-08 13:01   ` Dryden Personalis
@ 2016-05-09  6:07     ` Andrei Borzenkov
  2016-05-09  8:41       ` Dryden Personalis
                         ` (2 more replies)
  0 siblings, 3 replies; 24+ messages in thread
From: Andrei Borzenkov @ 2016-05-09  6:07 UTC (permalink / raw)
  To: The development of GNU GRUB

08.05.2016 16:01, Dryden Personalis пишет:
> 
>>> -    if (fs_probe)
>>> +    if (!is_lvm && fs_probe)
>>
>> No, we want to probe for FS here to eliminate corner case of both PV and
>> FS metadata.
> 
> You mean you want to change it to:
> 

No, I do not want to change it at all. It should remain as is and always
probe for FS so that test below actually works
...
>> And you need to add check for LVM here
>>
>>     if (ctx.multiple_partmaps || (ctx.dest_partmap && fs) || (is_ldm
>> && fs))
> 
> I take it you mean:
> 
> if (!is_lvm && (ctx.multiple_partmaps || (ctx.dest_partmap && fs) ||
> (is_ldm && fs)))
>

I mean

if (ctx.multiple_partmaps || (ctx.dest_partmap && fs) || ((is_ldm ||
is_lvm) && fs))




^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH] Install to LVM PVs
  2016-05-09  6:07     ` Andrei Borzenkov
@ 2016-05-09  8:41       ` Dryden Personalis
  2016-05-09 16:10       ` Dryden Personalis
  2016-05-17 18:01       ` Dryden Personalis
  2 siblings, 0 replies; 24+ messages in thread
From: Dryden Personalis @ 2016-05-09  8:41 UTC (permalink / raw)
  To: The development of GNU GRUB

Andrei Borzenkov schreef op 09-05-2016 8:07:

> No, I do not want to change it at all. It should remain as is and 
> always
> probe for FS so that test below actually works

But its output makes no sense, there cannot be a filesystem in a PV. It 
could check for existence of VG AND LV AND filesystem but does it do 
that right now?

Installing Grub is generally a non-destructive operation, apart from 
overwriting the boot sector.

Anyway my foot is hurting and I can't sit behind the computer, I will 
just show the code at some point so to discuss that alright.

>> I take it you mean:
>> 
>> if (!is_lvm && (ctx.multiple_partmaps || (ctx.dest_partmap && fs) ||
>> (is_ldm && fs)))
>> 
> 
> I mean
> 
> if (ctx.multiple_partmaps || (ctx.dest_partmap && fs) || ((is_ldm ||
> is_lvm) && fs))

Yes, I realized. Sorry.


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH] Install to LVM PVs
  2016-05-09  6:07     ` Andrei Borzenkov
  2016-05-09  8:41       ` Dryden Personalis
@ 2016-05-09 16:10       ` Dryden Personalis
  2016-05-09 16:18         ` Dryden Personalis
  2016-05-17 18:01       ` Dryden Personalis
  2 siblings, 1 reply; 24+ messages in thread
From: Dryden Personalis @ 2016-05-09 16:10 UTC (permalink / raw)
  To: The development of GNU GRUB

Currently:

- still searches in first sector for label, and reports error if found 
there
- get_pvh split into regular and one with 2 extra parameters for 
first_sector detection
- some documentation
- VG is not required to install
- does not even check for VG, but function is retained
- is lvm returns true iff header is found
- currently still skips filesystem check for lvm.

- untested installing on partitions
- note: LVM does not support first sector PVs
- we could also skip checking the first sector (my beautiful code)
- in that case split get_pvh is (currently) not needed, but you would 
also not warn people about the bootsector. The header would just not be 
found.

So in principle the solution becomes really simple (not requiring VG).

You can however corrupt the thing by first installing a 
bootloaderareasize PV, then a regular one on top of that, and the code 
will mistakenly believe there is room.

But this is all I can do without diving into the mechanics currently.

This is the function I thought Andrei wanted:

int grub_util_has_lvm_vg (grub_disk_t disk)
{
   struct grub_diskfilter_pv *pv = NULL;
   struct grub_diskfilter_vg *vg = NULL;

   pv = grub_diskfilter_get_pv_from_disk(disk, &vg);
   return pv && vg && vg == vg->driver->detect(disk, &pv->id, 
&pv->start_sector)
     ? 1 : 0;
}

If you are okay, I will attach the patch, but I also did some cleanup in 
lvm.c particularly (removing extraneous \n for instance messing up info 
messages) but I need to separate that with Git.

If you still feel VG should be required, let me know.

But also whether filesystem check (without -s) should be required when 
none can ever be found (at least not in our case here).

I have reverted to that of the patch (or similar):

if (fs_probe)
   {
     if (!is_lvm && !fs && !ctx.dest_partmap)
       grub_util_error (_("unable to identify a filesystem in %s; safety 
check can't be performed"), dest_dev->disk->name);


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH] Install to LVM PVs
  2016-05-09 16:10       ` Dryden Personalis
@ 2016-05-09 16:18         ` Dryden Personalis
  2016-05-09 17:56           ` Dryden Personalis
  0 siblings, 1 reply; 24+ messages in thread
From: Dryden Personalis @ 2016-05-09 16:18 UTC (permalink / raw)
  To: The development of GNU GRUB

Dryden Personalis schreef op 09-05-2016 18:10:

> I have reverted to that of the patch (or similar):
> 
> if (fs_probe)
>   {
>     if (!is_lvm && !fs && !ctx.dest_partmap)
>       grub_util_error (_("unable to identify a filesystem in %s;
> safety check can't be performed"), dest_dev->disk->name);

In particular I feel !is_lvm and !ctx.dest_partmap are equivalent. Why, 
they both indicate partitions, instead of being a partition (with a 
filesystem).


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH] Install to LVM PVs
  2016-05-09 16:18         ` Dryden Personalis
@ 2016-05-09 17:56           ` Dryden Personalis
  0 siblings, 0 replies; 24+ messages in thread
From: Dryden Personalis @ 2016-05-09 17:56 UTC (permalink / raw)
  To: The development of GNU GRUB

[-- Attachment #1: Type: text/plain, Size: 145 bytes --]

Attached my current working patch.

Also attached some housekeeping.

Not sure if it applies to current git version.

Take from it what you like.

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: grub-install-to-partitionless-lvm-pv_2.02~beta2_v3.patch --]
[-- Type: text/x-diff; name=grub-install-to-partitionless-lvm-pv_2.02~beta2_v3.patch, Size: 12369 bytes --]

diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c
index 22c7b64..37e715a 100644
--- a/grub-core/disk/lvm.c
+++ b/grub-core/disk/lvm.c
@@ -95,6 +95,78 @@ grub_lvm_check_flag (char *p, const char *str, const char *flag)
     }
 }
 
+/**
+ * Attribute function obtaining PV header from disk. Currently scans the
+ * first 4 sectors and returns anything found in either of those sectors.
+ *
+ * Sets *first_sector to 1 if header was in first sector, 0 otherwise.
+ * May print first_sector info message if verbose was set.
+ *
+ * Returns header if found, NULL otherwise. Also returns header if first_sector.
+ */
+static struct grub_lvm_pv_header *
+grub_lvm_get_pvh_at(grub_disk_t disk, char buf[static GRUB_LVM_LABEL_SIZE], 
+#ifdef GRUB_UTIL
+    int *first_sector, int verbose
+#else
+    int *first_sector
+#endif
+  )
+
+{
+  struct grub_lvm_label_header *lh = (struct grub_lvm_label_header *) buf;
+  unsigned int i;
+
+  /* Search for label. */
+  for (i = 0; i < GRUB_LVM_LABEL_SCAN_SECTORS; i++)
+    {
+      if (grub_disk_read (disk, i, 0, GRUB_LVM_LABEL_SIZE, buf))
+        return NULL;
+
+      if ((! grub_strncmp ((char *)lh->id, GRUB_LVM_LABEL_ID,
+                          sizeof (lh->id)))
+         && (! grub_strncmp ((char *)lh->type, GRUB_LVM_LVM2_LABEL,
+                             sizeof (lh->type))))
+       break;
+    }
+
+#ifdef GRUB_UTIL
+  if (first_sector) *first_sector = 0;
+#endif
+
+  /* Return if we didn't find a label. */
+  if (i == GRUB_LVM_LABEL_SCAN_SECTORS)
+    {
+#ifdef GRUB_UTIL
+      grub_util_info ("no LVM signature found");
+#endif
+      return NULL;
+    }
+  else if (i == 0)
+    {
+#ifdef GRUB_UTIL
+      if (verbose) grub_util_info ("LVM signature in first sector");
+#endif
+      if (first_sector) *first_sector = 1;
+    }
+
+  return (struct grub_lvm_pv_header *) (buf + grub_le_to_cpu32(lh->offset_xl));
+}
+
+static inline struct grub_lvm_pv_header *grub_lvm_get_pvh(grub_disk_t disk, char buf[static GRUB_LVM_LABEL_SIZE]) 
+{
+#ifdef GRUB_UTIL
+  return grub_lvm_get_pvh_at(disk, buf, NULL, 0);
+#else
+  return grub_lvm_get_pvh_at(disk, buf, NULL);
+#endif
+}
+
+/**
+ * Preexisting function that detects the LVM PV header from disk and proceeds
+ * to fill in VG datastructures. Called from diskfilter as part of the
+ * "driver->detect" functionality.
+ */
 static struct grub_diskfilter_vg * 
 grub_lvm_detect (grub_disk_t disk,
 		 struct grub_diskfilter_pv_id *id,
@@ -106,7 +178,6 @@ grub_lvm_detect (grub_disk_t disk,
   char vg_id[GRUB_LVM_ID_STRLEN+1];
   char pv_id[GRUB_LVM_ID_STRLEN+1];
   char *metadatabuf, *p, *q, *vgname;
-  struct grub_lvm_label_header *lh = (struct grub_lvm_label_header *) buf;
   struct grub_lvm_pv_header *pvh;
   struct grub_lvm_disk_locn *dlocn;
   struct grub_lvm_mda_header *mdah;
@@ -116,30 +187,9 @@ grub_lvm_detect (grub_disk_t disk,
   struct grub_diskfilter_vg *vg;
   struct grub_diskfilter_pv *pv;
 
-  /* Search for label. */
-  for (i = 0; i < GRUB_LVM_LABEL_SCAN_SECTORS; i++)
-    {
-      err = grub_disk_read (disk, i, 0, sizeof(buf), buf);
-      if (err)
-	goto fail;
-
-      if ((! grub_strncmp ((char *)lh->id, GRUB_LVM_LABEL_ID,
-			   sizeof (lh->id)))
-	  && (! grub_strncmp ((char *)lh->type, GRUB_LVM_LVM2_LABEL,
-			      sizeof (lh->type))))
-	break;
-    }
-
-  /* Return if we didn't find a label. */
-  if (i == GRUB_LVM_LABEL_SCAN_SECTORS)
-    {
-#ifdef GRUB_UTIL
-      grub_util_info ("no LVM signature found");
-#endif
-      goto fail;
-    }
-
-  pvh = (struct grub_lvm_pv_header *) (buf + grub_le_to_cpu32(lh->offset_xl));
+  pvh = grub_lvm_get_pvh(disk, buf);
+  if (!pvh)
+    goto fail;
 
   for (i = 0, j = 0; i < GRUB_LVM_ID_LEN; i++)
     {
@@ -770,6 +820,112 @@ grub_lvm_detect (grub_disk_t disk,
   return NULL;
 }
 
+#ifdef GRUB_UTIL
+/**
+ * Requests physical volume from disk and checks whether relations hold up?
+ *
+ * This function only returns true iff a volume group was found
+ */
+int grub_util_has_lvm_vg (grub_disk_t disk)
+{
+  struct grub_diskfilter_pv *pv = NULL;
+  struct grub_diskfilter_vg *vg = NULL;
+
+  pv = grub_diskfilter_get_pv_from_disk(disk, &vg);
+  return pv && vg && vg == vg->driver->detect(disk, &pv->id, &pv->start_sector)
+         ? 1 : 0;
+}
+
+/**
+ * Does nothing other than scanning the first 4 sectors of the device for
+ * a LVM PV header
+ */
+int grub_util_is_lvm (grub_disk_t disk)
+{
+  char buf[GRUB_LVM_LABEL_SIZE];
+  return grub_lvm_get_pvh(disk, buf) ? 1 : 0;
+}
+
+/**
+ * This function embeds the bootloader inside an LVM PV bootloaderarea
+ * specified by --bootloaderareasize on the pvcreate command line.
+ *
+ * It is called from setup.c and returns an error message to the caller,
+ * that gets treated as a warning, if it fails.
+*/
+
+grub_err_t
+grub_util_lvm_embed (struct grub_disk *disk, unsigned int *nsectors,
+                    unsigned int max_nsectors,
+                    grub_embed_type_t embed_type,
+                    grub_disk_addr_t **sectors)
+{
+  char buf[GRUB_LVM_LABEL_SIZE];
+  struct grub_lvm_pv_header *pvh;
+  struct grub_lvm_pv_header_ext *pvh_ext;
+  struct grub_diskfilter_vg *vg = NULL;
+  struct grub_lvm_disk_locn *dlocn;
+  grub_uint64_t ba_offset, ba_size, ba_start_sector;
+  unsigned int i;
+  int first_sector;
+
+  if (embed_type != GRUB_EMBED_PCBIOS)
+    return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+                      "LVM curently supports only PC-BIOS embedding");
+#ifdef GRUB_UTIL
+  pvh = grub_lvm_get_pvh_at(disk, buf, &first_sector, 1);
+#else
+  pvh = grub_lvm_get_pvh_at(disk, buf, &first_sector);
+#endif
+  /* if pvh is NULL, we probably have a bug */
+  if (!pvh)
+    return grub_error (GRUB_ERR_BUG, "trying to install on non-existing PV header, but should already have been prevented by initial screening");
+
+  if (first_sector)
+    return grub_error (GRUB_ERR_BAD_DEVICE, "PV detected inside boot sector, but we need the boot sector to install in");
+
+  /* for some reason the bootloaderarea check will fail if we don't do this here */
+  grub_diskfilter_get_pv_from_disk(disk, &vg);
+
+  dlocn = pvh->disk_areas_xl;
+
+  /* skip past the data area list */
+  while (dlocn->offset)
+    dlocn++;
+  dlocn++;
+  /* and the metadata area list */
+  while (dlocn->offset)
+    dlocn++;
+  dlocn++;
+
+  pvh_ext = (struct grub_lvm_pv_header_ext*)dlocn;
+  if (!pvh_ext->version_xl)
+    return grub_error (GRUB_ERR_BAD_DEVICE, "trying to install on LVM PV but it does not have a bootloader area to embed in. Check pvcreate --bootloaderareasize");
+
+  dlocn = pvh_ext->disk_areas_xl;
+  ba_offset = grub_le_to_cpu64 (dlocn->offset);
+  ba_size = grub_le_to_cpu64 (dlocn->size);
+  if (!(ba_offset && ba_size))
+    return grub_error (GRUB_ERR_BAD_DEVICE, "trying to install on LVM PV but it does not have a bootloader area to embed in. Check pvcreate --bootloaderareasize");
+  /* could be worked around with extra arithmetic if this actually happens */
+  if (ba_offset % GRUB_DISK_SECTOR_SIZE)
+    return grub_error (
+      GRUB_ERR_BAD_DEVICE, "LVM bootloader area is not aligned on sector boundaries (%d)", GRUB_DISK_SECTOR_SIZE);
+  ba_start_sector = ba_offset / GRUB_DISK_SECTOR_SIZE;
+
+  *nsectors = ba_size / GRUB_DISK_SECTOR_SIZE;
+  if (*nsectors > max_nsectors)
+    *nsectors = max_nsectors;
+
+  *sectors = grub_malloc (*nsectors * sizeof (**sectors));
+  if (!*sectors)
+    return grub_errno;
+  for (i = 0; i < *nsectors; i++)
+    (*sectors)[i] = ba_start_sector + i;
+
+  return GRUB_ERR_NONE;
+}
+#endif
 \f
 
 static struct grub_diskfilter grub_lvm_dev = {
diff --git a/include/grub/diskfilter.h b/include/grub/diskfilter.h
index 1aedcd3..ca95dea 100644
--- a/include/grub/diskfilter.h
+++ b/include/grub/diskfilter.h
@@ -75,6 +75,9 @@ struct grub_diskfilter_pv {
 #ifdef GRUB_UTIL
   char **partmaps;
 #endif
+  /* Optional bootloader embedding area */
+  grub_uint64_t ba_offset;
+  grub_uint64_t ba_size;
 };
 
 struct grub_diskfilter_lv {
diff --git a/include/grub/emu/hostdisk.h b/include/grub/emu/hostdisk.h
index e233d37..4e4ddea 100644
--- a/include/grub/emu/hostdisk.h
+++ b/include/grub/emu/hostdisk.h
@@ -44,6 +44,14 @@ char *grub_util_get_ldm (grub_disk_t disk, grub_disk_addr_t start);
 int grub_util_is_ldm (grub_disk_t disk);
 
 #ifdef GRUB_UTIL
+int grub_util_is_lvm (grub_disk_t disk);
+int grub_util_has_lvm_vg (grub_disk_t disk);
+
+grub_err_t
+grub_util_lvm_embed (struct grub_disk *disk, unsigned int *nsectors,
+                    unsigned int max_nsectors,
+                    grub_embed_type_t embed_type,
+                    grub_disk_addr_t **sectors);
 grub_err_t
 grub_util_ldm_embed (struct grub_disk *disk, unsigned int *nsectors,
 		     unsigned int max_nsectors,
diff --git a/include/grub/lvm.h b/include/grub/lvm.h
index 30a609c..dd19552 100644
--- a/include/grub/lvm.h
+++ b/include/grub/lvm.h
@@ -62,6 +62,13 @@ struct grub_lvm_pv_header {
   struct grub_lvm_disk_locn disk_areas_xl[0];	/* Two lists */
 } GRUB_PACKED;
 
+struct grub_lvm_pv_header_ext {
+  grub_uint32_t version_xl;
+  grub_uint32_t flags_xl;
+  /* NULL-terminated list of bootloader embedding areas */
+  struct grub_lvm_disk_locn disk_areas_xl[0];
+} __attribute__ ((packed));
+
 #define GRUB_LVM_FMTT_MAGIC "\040\114\126\115\062\040\170\133\065\101\045\162\060\116\052\076"
 #define GRUB_LVM_FMTT_VERSION 1
 #define GRUB_LVM_MDA_HEADER_SIZE 512
diff --git a/util/setup.c b/util/setup.c
index 7c60083..34c7f80 100644
--- a/util/setup.c
+++ b/util/setup.c
@@ -390,7 +390,7 @@ SETUP (const char *dir,
       .container = dest_dev->disk->partition,
       .multiple_partmaps = 0
     };
-    int is_ldm;
+    int is_ldm, is_lvm;
     grub_err_t err;
     grub_disk_addr_t *sectors;
     int i;
@@ -423,15 +423,17 @@ SETUP (const char *dir,
       grub_errno = GRUB_ERR_NONE;
 
     is_ldm = grub_util_is_ldm (dest_dev->disk);
+    is_lvm = grub_util_is_lvm (dest_dev->disk);
 
     if (fs_probe)
       {
-	if (!fs && !ctx.dest_partmap)
-	  grub_util_error (_("unable to identify a filesystem in %s; safety check can't be performed"),
-			   dest_dev->disk->name);
-	if (fs && !fs->reserved_first_sector)
-	  /* TRANSLATORS: Filesystem may reserve the space just GRUB isn't sure about it.  */
-	  grub_util_error (_("%s appears to contain a %s filesystem which isn't known to "
+        /* Doubt there can be any FS signature on LVM? */
+        if (!is_lvm && !fs && !ctx.dest_partmap)
+          grub_util_error (_("unable to identify a filesystem in %s; safety check can't be performed"), dest_dev->disk->name);
+
+        if (fs && !fs->reserved_first_sector)
+          /* TRANSLATORS: Filesystem may reserve the space just GRUB isn't sure about it. */
+          grub_util_error (_("%s appears to contain a %s filesystem which isn't known to "
 			     "reserve space for DOS-style boot.  Installing GRUB there could "
 			     "result in FILESYSTEM DESTRUCTION if valuable data is overwritten "
 			     "by grub-setup (--skip-fs-probe disables this "
@@ -462,12 +464,12 @@ SETUP (const char *dir,
 
       }
 
-    if (! ctx.dest_partmap && ! fs && !is_ldm)
+    if (! ctx.dest_partmap && ! fs && !is_ldm && !is_lvm)
       {
 	grub_util_warn ("%s", _("Attempting to install GRUB to a partitionless disk or to a partition.  This is a BAD idea."));
 	goto unable_to_embed;
       }
-    if (ctx.multiple_partmaps || (ctx.dest_partmap && fs) || (is_ldm && fs))
+    if (ctx.multiple_partmaps || (ctx.dest_partmap && fs) || ((is_ldm || is_lvm) && fs))
       {
 	grub_util_warn ("%s", _("Attempting to install GRUB to a disk with multiple partition labels.  This is not supported yet."));
 	goto unable_to_embed;
@@ -499,7 +501,10 @@ SETUP (const char *dir,
       maxsec = ((0x78000 - GRUB_KERNEL_I386_PC_LINK_ADDR)
 		>> GRUB_DISK_SECTOR_BITS);
 
-    if (is_ldm)
+    if (is_lvm)
+      err = grub_util_lvm_embed (dest_dev->disk, &nsec, maxsec,
+                                GRUB_EMBED_PCBIOS, &sectors);
+    else if (is_ldm)
       err = grub_util_ldm_embed (dest_dev->disk, &nsec, maxsec,
 				 GRUB_EMBED_PCBIOS, &sectors);
     else if (ctx.dest_partmap)
@@ -602,7 +607,7 @@ unable_to_embed:
 
   if (dest_dev->disk->dev->id != root_dev->disk->dev->id)
     grub_util_error ("%s", _("embedding is not possible, but this is required for "
-			     "RAID and LVM install"));
+			     "LVM and RAID install"));
 
   {
     grub_fs_t fs;

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: housekeeping.patch --]
[-- Type: text/x-diff; name=housekeeping.patch, Size: 6968 bytes --]

diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c
index 483c17e..22c7b64 100644
--- a/grub-core/disk/lvm.c
+++ b/grub-core/disk/lvm.c
@@ -160,7 +160,7 @@ grub_lvm_detect (grub_disk_t disk,
 		  "we don't support multiple LVM data areas");
 
 #ifdef GRUB_UTIL
-      grub_util_info ("we don't support multiple LVM data areas\n");
+      grub_util_info ("we don't support multiple LVM data areas");
 #endif
       goto fail;
     }
@@ -189,7 +189,7 @@ grub_lvm_detect (grub_disk_t disk,
       grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
 		  "unknown LVM metadata header");
 #ifdef GRUB_UTIL
-      grub_util_info ("unknown LVM metadata header\n");
+      grub_util_info ("unknown LVM metadata header");
 #endif
       goto fail2;
     }
@@ -213,7 +213,7 @@ grub_lvm_detect (grub_disk_t disk,
   if (q == metadatabuf + mda_size)
     {
 #ifdef GRUB_UTIL
-      grub_util_info ("error parsing metadata\n");
+      grub_util_info ("error parsing metadata");
 #endif
       goto fail2;
     }
@@ -230,7 +230,7 @@ grub_lvm_detect (grub_disk_t disk,
   if (p == NULL)
     {
 #ifdef GRUB_UTIL
-      grub_util_info ("couldn't find ID\n");
+      grub_util_info ("couldn't find ID");
 #endif
       goto fail3;
     }
@@ -258,7 +258,7 @@ grub_lvm_detect (grub_disk_t disk,
       if (p == NULL)
 	{
 #ifdef GRUB_UTIL
-	  grub_util_info ("unknown extent size\n");
+	  grub_util_info ("unknown extent size");
 #endif
 	  goto fail4;
 	}
@@ -306,7 +306,7 @@ grub_lvm_detect (grub_disk_t disk,
 	      if (p == NULL)
 		{
 #ifdef GRUB_UTIL
-		  grub_util_info ("unknown pe_start\n");
+		  grub_util_info ("unknown pe_start");
 #endif
 		  goto pvs_fail;
 		}
@@ -315,7 +315,7 @@ grub_lvm_detect (grub_disk_t disk,
 	      if (p == NULL)
 		{
 #ifdef GRUB_UTIL
-		  grub_util_info ("error parsing pe_start\n");
+		  grub_util_info ("error parsing pe_start");
 #endif
 		  goto pvs_fail;
 		}
@@ -402,7 +402,7 @@ grub_lvm_detect (grub_disk_t disk,
 		if (p == NULL)
 		  {
 #ifdef GRUB_UTIL
-		    grub_util_info ("couldn't find ID\n");
+		    grub_util_info ("couldn't find ID");
 #endif
 		    goto lvs_fail;
 		  }
@@ -422,7 +422,7 @@ grub_lvm_detect (grub_disk_t disk,
 	      if (p == NULL)
 		{
 #ifdef GRUB_UTIL
-		  grub_util_info ("unknown segment_count\n");
+		  grub_util_info ("unknown segment_count");
 #endif
 		  goto lvs_fail;
 		}
@@ -436,7 +436,7 @@ grub_lvm_detect (grub_disk_t disk,
 		  if (p == NULL)
 		    {
 #ifdef GRUB_UTIL
-		      grub_util_info ("unknown segment\n");
+		      grub_util_info ("unknown segment");
 #endif
 		      goto lvs_segment_fail;
 		    }
@@ -445,7 +445,7 @@ grub_lvm_detect (grub_disk_t disk,
 		  if (p == NULL)
 		    {
 #ifdef GRUB_UTIL
-		      grub_util_info ("unknown start_extent\n");
+		      grub_util_info ("unknown start_extent");
 #endif
 		      goto lvs_segment_fail;
 		    }
@@ -453,7 +453,7 @@ grub_lvm_detect (grub_disk_t disk,
 		  if (p == NULL)
 		    {
 #ifdef GRUB_UTIL
-		      grub_util_info ("unknown extent_count\n");
+		      grub_util_info ("unknown extent_count");
 #endif
 		      goto lvs_segment_fail;
 		    }
@@ -475,7 +475,7 @@ grub_lvm_detect (grub_disk_t disk,
 		      if (p == NULL)
 			{
 #ifdef GRUB_UTIL
-			  grub_util_info ("unknown stripe_count\n");
+			  grub_util_info ("unknown stripe_count");
 #endif
 			  goto lvs_segment_fail;
 			}
@@ -491,7 +491,7 @@ grub_lvm_detect (grub_disk_t disk,
 		      if (p == NULL)
 			{
 #ifdef GRUB_UTIL
-			  grub_util_info ("unknown stripes\n");
+			  grub_util_info ("unknown stripes");
 #endif
 			  goto lvs_segment_fail2;
 			}
@@ -533,7 +533,7 @@ grub_lvm_detect (grub_disk_t disk,
 		      if (p == NULL)
 			{
 #ifdef GRUB_UTIL
-			  grub_util_info ("unknown mirror_count\n");
+			  grub_util_info ("unknown mirror_count");
 #endif
 			  goto lvs_segment_fail;
 			}
@@ -545,7 +545,7 @@ grub_lvm_detect (grub_disk_t disk,
 		      if (p == NULL)
 			{
 #ifdef GRUB_UTIL
-			  grub_util_info ("unknown mirrors\n");
+			  grub_util_info ("unknown mirrors");
 #endif
 			  goto lvs_segment_fail2;
 			}
@@ -603,7 +603,7 @@ grub_lvm_detect (grub_disk_t disk,
 		      if (p == NULL)
 			{
 #ifdef GRUB_UTIL
-			  grub_util_info ("unknown device_count\n");
+			  grub_util_info ("unknown device_count");
 #endif
 			  goto lvs_segment_fail;
 			}
@@ -612,7 +612,7 @@ grub_lvm_detect (grub_disk_t disk,
 		      if (p == NULL)
 			{
 #ifdef GRUB_UTIL
-			  grub_util_info ("unknown stripe_size\n");
+			  grub_util_info ("unknown stripe_size");
 #endif
 			  goto lvs_segment_fail;
 			}
@@ -625,7 +625,7 @@ grub_lvm_detect (grub_disk_t disk,
 		      if (p == NULL)
 			{
 #ifdef GRUB_UTIL
-			  grub_util_info ("unknown mirrors\n");
+			  grub_util_info ("unknown mirrors");
 #endif
 			  goto lvs_segment_fail2;
 			}
@@ -672,7 +672,7 @@ grub_lvm_detect (grub_disk_t disk,
 		      p2 = grub_strchr (p, '"');
 		      if (p2)
 			*p2 = 0;
-		      grub_util_info ("unknown LVM type %s\n", p);
+		      grub_util_info ("unknown LVM type %s", p);
 		      if (p2)
 			*p2 ='"';
 #endif
diff --git a/include/grub/emu/hostdisk.h b/include/grub/emu/hostdisk.h
index e006f0b..e233d37 100644
--- a/include/grub/emu/hostdisk.h
+++ b/include/grub/emu/hostdisk.h
@@ -26,8 +26,8 @@
 #include <grub/emu/hostfile.h>
 
 grub_util_fd_t
-grub_util_fd_open_device (const grub_disk_t disk, grub_disk_addr_t sector, int flags,
-			  grub_disk_addr_t *max);
+grub_util_fd_open_device (const grub_disk_t disk, grub_disk_addr_t sector,
+                         int flags, grub_disk_addr_t *max);
 
 void grub_util_biosdisk_init (const char *dev_map);
 void grub_util_biosdisk_fini (void);
@@ -35,17 +35,14 @@ char *grub_util_biosdisk_get_grub_dev (const char *os_dev);
 const char *grub_util_biosdisk_get_osdev (grub_disk_t disk);
 int grub_util_biosdisk_is_present (const char *name);
 int grub_util_biosdisk_is_floppy (grub_disk_t disk);
-const char *
-grub_util_biosdisk_get_compatibility_hint (grub_disk_t disk);
+const char *grub_util_biosdisk_get_compatibility_hint (grub_disk_t disk);
 grub_err_t grub_util_biosdisk_flush (struct grub_disk *disk);
 grub_err_t
 grub_cryptodisk_cheat_mount (const char *sourcedev, const char *cheat);
-const char *
-grub_util_cryptodisk_get_uuid (grub_disk_t disk);
-char *
-grub_util_get_ldm (grub_disk_t disk, grub_disk_addr_t start);
-int
-grub_util_is_ldm (grub_disk_t disk);
+const char *grub_util_cryptodisk_get_uuid (grub_disk_t disk);
+char *grub_util_get_ldm (grub_disk_t disk, grub_disk_addr_t start);
+int grub_util_is_ldm (grub_disk_t disk);
+
 #ifdef GRUB_UTIL
 grub_err_t
 grub_util_ldm_embed (struct grub_disk *disk, unsigned int *nsectors,
diff --git a/util/setup.c b/util/setup.c
index 3945eff..7c60083 100644
--- a/util/setup.c
+++ b/util/setup.c
@@ -1,4 +1,4 @@
-/* grub-setup.c - make GRUB usable */
+/* setup.c - make GRUB usable */
 /*
  *  GRUB  --  GRand Unified Bootloader
  *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011  Free Software Foundation, Inc.

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* Re: [PATCH] Install to LVM PVs
  2016-05-09  6:07     ` Andrei Borzenkov
  2016-05-09  8:41       ` Dryden Personalis
  2016-05-09 16:10       ` Dryden Personalis
@ 2016-05-17 18:01       ` Dryden Personalis
  2 siblings, 0 replies; 24+ messages in thread
From: Dryden Personalis @ 2016-05-17 18:01 UTC (permalink / raw)
  To: The development of GNU GRUB

Andrei Borzenkov schreef op 09-05-2016 8:07:


I'm sorry, this email had gone missing from my system. I just found it 
back in the trash, after thinking I had already searched for it.

I'm not sure why no one responds anymore, of course Andrei was the only 
one to respond in the first place. I hope nothing is the matter with 
Andrei himself, I mean it could be personal circumstances.

I have basically implemented all suggestions, with just two questions 
that I would like to have answered:

- is it okay to drop the requirement of having a VG configured in the PV
- is it okay to skip the FS-presence test in a LVM that cannot have it 
in any case?

If the group or the ones in charge of this software would be willing to 
shed their light on these issues, I could at least make something that 
you would agree with, if it would be intended for real submission.

So from my perspective the feature works, I tend to think these are the 
only choices to make, and perhaps additional safety checks are required 
to deal with the size of the bootloaderarea, which I can look into if 
needed.

Presently I do not have the knowledge about the PV structure yet.

I did not write the original patch, after all.

I could easily test or demonstrate what would happen if the 
bootloaderareasize were really small; whether grub would overwrite 
essential structures if I did.

I think safety is the biggest requirement here?

As demonstrated, booting itself is not an issue except that I cannot 
test installing on partitions (at all) currently. I do not know why, but 
Grub on my system will not install on any partition whatsoever, not the 
new version, or the standard ubuntu version.

I have still not installed my system again on that harddisk, still 
working off of a USB stick. ;-). So I am actually waiting with 
installing until people have indicated whether additional development or 
testing is required?

I would hope to work with you on this.

(Not just grub, I'm also worried about LVM thin safety, but that is 
another issue).

I'm sorry if I seem not to understand how things work around here, or if 
I actually do not (understand). I have tried to reach Andrei off-list, 
but no response. But I've waited for a week, so I need to go and start 
doing something else if it is not going to happen anyway.

So please.

And regards, and thanks for cooperating (thus far) and of having been of 
help, in any case, regardless. Regards.



> 08.05.2016 16:01, Dryden Personalis пишет:
>> 
>>>> -    if (fs_probe)
>>>> +    if (!is_lvm && fs_probe)
>>> 
>>> No, we want to probe for FS here to eliminate corner case of both PV 
>>> and
>>> FS metadata.
>> 
>> You mean you want to change it to:
>> 
> 
> No, I do not want to change it at all. It should remain as is and 
> always
> probe for FS so that test below actually works
> ...
>>> And you need to add check for LVM here
>>> 
>>>     if (ctx.multiple_partmaps || (ctx.dest_partmap && fs) || (is_ldm
>>> && fs))
>> 
>> I take it you mean:
>> 
>> if (!is_lvm && (ctx.multiple_partmaps || (ctx.dest_partmap && fs) ||
>> (is_ldm && fs)))
>> 
> 
> I mean
> 
> if (ctx.multiple_partmaps || (ctx.dest_partmap && fs) || ((is_ldm ||
> is_lvm) && fs))


^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2016-05-17 18:01 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-09-25 12:39 [PATCH] Install to LVM PVs Gabriel de Perthuis
2013-09-26  8:53 ` Vladimir 'φ-coder/phcoder' Serbinenko
2013-09-27 10:39   ` Gabriel de Perthuis
2013-09-27 12:48     ` Vladimir 'φ-coder/phcoder' Serbinenko
2013-09-27 13:56       ` Gabriel de Perthuis
2013-09-27 14:27       ` Andrey Borzenkov
2015-02-15 10:47       ` Andrei Borzenkov
  -- strict thread matches above, loose matches on Subject: below --
2016-05-08  4:53 Dryden Personalis
2016-05-08  6:05 ` Andrei Borzenkov
2016-05-08  8:47   ` Andrei Borzenkov
2016-05-08 13:10     ` Dryden Personalis
2016-05-08 17:16     ` Dryden Personalis
2016-05-08 17:40       ` Dryden Personalis
2016-05-08 13:01   ` Dryden Personalis
2016-05-09  6:07     ` Andrei Borzenkov
2016-05-09  8:41       ` Dryden Personalis
2016-05-09 16:10       ` Dryden Personalis
2016-05-09 16:18         ` Dryden Personalis
2016-05-09 17:56           ` Dryden Personalis
2016-05-17 18:01       ` Dryden Personalis
2016-05-08  9:23 ` Andrei Borzenkov
2016-05-08 13:09   ` Dryden Personalis
2016-05-09  0:10   ` Xen
2016-05-09  0:10     ` Dryden Personalis

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).