grub-devel.gnu.org archive mirror
 help / color / mirror / Atom feed
From: "Vladimir 'φ-coder/phcoder' Serbinenko" <phcoder@gmail.com>
To: grub-devel@gnu.org
Subject: Re: [RFC] Dedicated LVM volume as alternative to embedding
Date: Mon, 03 Jun 2013 03:26:23 +0200	[thread overview]
Message-ID: <51ABF0BF.6050508@gmail.com> (raw)
In-Reply-To: <CAFzhf4pWu1Pbz7hYT7vXcCKZemjC8p-rMFgkiBRygm8VSQ0G1A@mail.gmail.com>

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

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
> Grub-devel@gnu.org
> https://lists.gnu.org/mailman/listinfo/grub-devel
> 



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

  reply	other threads:[~2013-06-03  1:26 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-06-03  0:58 [RFC] Dedicated LVM volume as alternative to embedding Piotras
2013-06-03  1:26 ` Vladimir 'φ-coder/phcoder' Serbinenko [this message]
2013-06-03  4:42   ` Andrey Borzenkov
2013-06-03 10:09     ` Vladimir 'φ-coder/phcoder' Serbinenko
2013-06-18 19:00       ` Phillip Susi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=51ABF0BF.6050508@gmail.com \
    --to=phcoder@gmail.com \
    --cc=grub-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).