grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [RFC] Dedicated LVM volume as alternative to embedding


From: Vladimir 'φ-coder/phcoder' Serbinenko
Subject: Re: [RFC] Dedicated LVM volume as alternative to embedding
Date: Mon, 03 Jun 2013 03:26:23 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130518 Icedove/17.0.5

This solution wouldn't play well with LVM layers. A better solution is
being jointly developped with lvm guys.
On 03.06.2013 02:58, Piotras wrote:
> Hi,
> 
> Attached patch allows for using alternative disk area when usual embedding
> is not possible. It helps for case where LVM is used on boot disk and user
> can create new volume for exclusive use by GRUB.
> 
> I currently require for the volume to use contiguous sectors on single disk
> (boot disk). Name of the volume is passed with additional parameter for
> grub-setup:
>> grub-bios-setup --dedicated-loader-volume=lvm/myVG-myLoaderLV 
>> --skip-fs-probe ... /dev/sda
> Parameter "--skip-fs-probe" is required for current version of the patch.
> 
> The implementation is inspired by existing function grub_util_ldm_embed in
> grub-core/disk/ldm.c (notice that this function is not working in current
> form).
> 
> It should be possible to generalize my patch to cover both LVM and LDM with
> common function, but I didn't test it. It may also be extend for using with
> traditional partition tables (where use can create new partition for
> exclusing use by GRUB).
> 
> I'd like to check if this feature can be added to official GRUB and what
> changes would be required for the attached patch to be merged.
> 
> 
> Best regards,
> 
> Piotr Krysiuk
> 
> 
> ---
>  grub-core/disk/lvm.c        |   75 
> ++++++++++++++++++++++++++++++++++++++++++-
>  include/grub/emu/hostdisk.h |    7 ++++
>  util/grub-setup.c           |   24 +++++++++++---
>  3 files changed, 100 insertions(+), 6 deletions(-)
> 
> diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c
> index 508e94a..8b7ff44 100644
> --- a/grub-core/disk/lvm.c
> +++ b/grub-core/disk/lvm.c
> @@ -746,7 +746,80 @@ grub_lvm_detect (grub_disk_t disk,
>    return NULL;
>  }
> 
> -
> +#ifdef GRUB_UTIL
> +
> +grub_err_t
> +grub_util_lvm_embed (struct grub_disk *disk,
> +                     const char *loader_lv_name,
> +                     unsigned int *nsectors,
> +                     unsigned int max_nsectors,
> +                     grub_embed_type_t embed_type,
> +                     grub_disk_addr_t **sectors)
> +{
> +  grub_disk_t loader_disk;
> +  struct grub_diskfilter_lv *loader_lv;
> +  unsigned i;
> +
> +  if (embed_type != GRUB_EMBED_PCBIOS)
> +    return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
> +                       "LVM curently supports only PC-BIOS embedding");
> +
> +  loader_disk = grub_disk_open (loader_lv_name);
> +  if (! loader_disk)
> +    grub_util_error ("%s", grub_errmsg);
> +
> +  if (loader_disk->dev->id != GRUB_DISK_DEVICE_DISKFILTER_ID)
> +    goto unable_to_embed;
> +
> +  loader_lv = loader_disk->data;
> +
> +  if (loader_lv->size > (1U << 15))
> +    return grub_error (GRUB_ERR_OUT_OF_RANGE,
> +                       N_("your dedicated loader volume is larger
> then 16MBytes;"
> +                          " grub won't use it to prevent
> unintentional corruption"
> +                          " of user data"));
> +
> +  if (!loader_lv->visible || !loader_lv->fullname)
> +    goto unable_to_embed;
> +
> +  if (loader_lv->segment_count != 1)
> +    goto unable_to_embed;
> +
> +  if (loader_lv->segments->type != GRUB_DISKFILTER_STRIPED
> +      || loader_lv->segments->node_count != 1
> +      || loader_lv->segments->start_extent != 0)
> +    goto unable_to_embed;
> +
> +  if (disk->partition
> +      || grub_strcmp (loader_lv->segments->nodes->pv->disk->name, 
> disk->name))
> +    goto unable_to_embed;
> +
> +  if (loader_lv->size < *nsectors)
> +    return grub_error (GRUB_ERR_OUT_OF_RANGE,
> +                       N_("your dedicated loader volume is too small;"
> +                          " grub can't use it"));
> +  *nsectors = loader_lv->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] = (loader_lv->segments->nodes->start
> +                     + loader_lv->segments->nodes->pv->start_sector
> +                     + i);
> +
> +  grub_disk_close (loader_disk);
> +  return GRUB_ERR_NONE;
> +
> + unable_to_embed:
> +
> +  return grub_error (GRUB_ERR_FILE_NOT_FOUND,
> +                     N_("your dedicated loader volume is invalid;"
> +                        " grub can't use it"));
> +}
> +
> +#endif
> 
>  static struct grub_diskfilter grub_lvm_dev = {
>    .name = "lvm",
> diff --git a/include/grub/emu/hostdisk.h b/include/grub/emu/hostdisk.h
> index 058973b..af59b9e 100644
> --- a/include/grub/emu/hostdisk.h
> +++ b/include/grub/emu/hostdisk.h
> @@ -51,6 +51,13 @@ grub_util_ldm_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_lvm_embed (struct grub_disk *disk,
> +                     const char *loader_lv_name,
> +                     unsigned int *nsectors,
> +                     unsigned int max_nsectors,
> +                     grub_embed_type_t embed_type,
> +                     grub_disk_addr_t **sectors);
>  #endif
>  grub_disk_addr_t
>  grub_hostdisk_find_partition_start (const char *dev);
> diff --git a/util/grub-setup.c b/util/grub-setup.c
> index 27a815f..b95d05b 100644
> --- a/util/grub-setup.c
> +++ b/util/grub-setup.c
> @@ -85,6 +85,7 @@
> 
>  #define DEFAULT_BOOT_FILE "boot.img"
>  #define DEFAULT_CORE_FILE "core.img"
> +#define OPT_LOADER_VOLUME       -3
> 
>  #ifdef GRUB_SETUP_SPARC64
>  #define grub_target_to_host16(x) grub_be_to_cpu16(x)
> @@ -243,7 +244,7 @@ identify_partmap (grub_disk_t disk __attribute__ 
> ((unused)),
>  static void
>  setup (const char *dir,
>         const char *boot_file, const char *core_file,
> -       const char *dest, int force,
> +       const char *dest, const char *loader_volume, int force,
>         int fs_probe, int allow_floppy)
>  {
>    char *boot_path, *core_path, *core_path_dev, *core_path_dev_full;
> @@ -459,12 +460,12 @@ setup (const char *dir,
> 
>      free (tmp_img);
> 
> -    if (! ctx.dest_partmap && ! fs && !is_ldm)
> +    if (! ctx.dest_partmap && ! fs && !is_ldm && !loader_volume)
>        {
>   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
> && fs) || (loader_volume && 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;
> @@ -492,7 +493,10 @@ setup (const char *dir,
>        maxsec = ((0x78000 - GRUB_KERNEL_I386_PC_LINK_ADDR)
>   >> GRUB_DISK_SECTOR_BITS);
> 
> -    if (is_ldm)
> +    if (loader_volume)
> +      err = grub_util_lvm_embed (dest_dev->disk, loader_volume, &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)
> @@ -983,6 +987,8 @@ static struct argp_option options[] = {
>     N_("use GRUB files in the directory DIR [default=%s]"), 0},
>    {"device-map",  'm', N_("FILE"), 0,
>     N_("use FILE as the device map [default=%s]"), 0},
> +  {"dedicated-loader-volume", OPT_LOADER_VOLUME, N_("VOLUME"), 0,
> +   N_("allocate VOLUME for exclusive use by GRUB. Existing data on
> VOLUME will be overwritten!"), 0},
>    {"force",       'f', 0,      0,
>     N_("install even if problems are detected"), 0},
>    {"skip-fs-probe",'s',0,      0,
> @@ -1024,6 +1030,7 @@ struct arguments
>    char *core_file;
>    char *dir;
>    char *dev_map;
> +  char *loader_volume;
>    int  force;
>    int  fs_probe;
>    int allow_floppy;
> @@ -1071,6 +1078,13 @@ argp_parser (int key, char *arg, struct
> argp_state *state)
>          arguments->dev_map = xstrdup (arg);
>          break;
> 
> +      case OPT_LOADER_VOLUME:
> +        if (arguments->loader_volume)
> +          free (arguments->loader_volume);
> +
> +        arguments->loader_volume = xstrdup (arg);
> +        break;
> +
>        case 'f':
>          arguments->force = 1;
>          break;
> @@ -1203,7 +1217,7 @@ main (int argc, char *argv[])
>    setup (arguments.dir ? : DEFAULT_DIRECTORY,
>   arguments.boot_file ? : DEFAULT_BOOT_FILE,
>   arguments.core_file ? : DEFAULT_CORE_FILE,
> - dest_dev, arguments.force,
> + dest_dev, arguments.loader_volume, arguments.force,
>   arguments.fs_probe, arguments.allow_floppy);
> 
>    /* Free resources.  */
> --
> 1.7.9.5
> 
> _______________________________________________
> Grub-devel mailing list
> address@hidden
> https://lists.gnu.org/mailman/listinfo/grub-devel
> 


Attachment: signature.asc
Description: OpenPGP digital signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]