From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1aUIfS-0003wr-By for mharc-grub-devel@gnu.org; Fri, 12 Feb 2016 13:42:10 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51982) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aUIfP-0003wb-Ex for grub-devel@gnu.org; Fri, 12 Feb 2016 13:42:09 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aUIfN-000521-Du for grub-devel@gnu.org; Fri, 12 Feb 2016 13:42:07 -0500 Received: from mail-wm0-x231.google.com ([2a00:1450:400c:c09::231]:37253) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aUIfM-00051J-Ud for grub-devel@gnu.org; Fri, 12 Feb 2016 13:42:05 -0500 Received: by mail-wm0-x231.google.com with SMTP id g62so31157340wme.0 for ; Fri, 12 Feb 2016 10:42:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=subject:to:references:from:message-id:date:user-agent:mime-version :in-reply-to:content-type; bh=mz2RysIsfvvNaRcxn34SZ2VBTDM0fo7OkY/GLgPc9m8=; b=a16hR55W3nysVxCTd/GtKhXxw53VwWY4dDZvNHF7+LIxBYaNRHcqpUCC3uQpfKgVBg c74y5/6zTsVLsG+rm9scaprzZPIUTV0ff30CgVhAdz33wt8mG92lJYq7GyslasuzYUX6 3K4+HXhIacCeadSIecfEJmIlFlc3Ze26cMUFCVGfG03273nQVzY4a4+EgW97GyTN6kuv XbhKqeTd+QRHFgMO1vr634Xo8UpSb4SofKKt6gh7q+zMOYQKt9uyMAqx0foV08U5CIZW drpdZd3wVHEfb+bHJR66w/snN8MOqUCkOUDpgEfYtLmGqR5rdoyB5+KLCmzQvoPlIKs5 Xr/A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:subject:to:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-type; bh=mz2RysIsfvvNaRcxn34SZ2VBTDM0fo7OkY/GLgPc9m8=; b=ZgLNTTcq4WyjNo3MamKF2LXg0INKjDiNur2U+lX5gSaZAUZtDU3V5H350+UxKlCufo MZcU2jGHofNUaAb94zvwhS+xZyTygU142sz7i1a6FJDNfwJCkHCneAjbffOS8fwnX7sA 0Ss6QKzbvuSM/NoLWu3wgWrh8U/fU4FXvChgPVXvhnkRO/WfyM67kMFiQ97yAtsSyCsd 7KDqTTOoaQO7Ur+QZmG2dc3sBnbObDAfKK9i+7pHt+xpPkaV7KcD95wDWXjadtA1bI7r S4rypuNZwuHyHGTv/ezaik1HqcqsOsPHaXc7IhNSp0SmDkLzvM5U9T9pBz927XqqmdYl 6ZyQ== X-Gm-Message-State: AG10YOQdn4XAFJFdBljKx+fNNrwznld/3ZHq//jP1nPKyA832GARYsWpwuJqCcoyWQvC9w== X-Received: by 10.194.216.2 with SMTP id om2mr3210974wjc.164.1455302524194; Fri, 12 Feb 2016 10:42:04 -0800 (PST) Received: from ?IPv6:2620:0:105f:fd00:a2a8:cdff:fe64:b3b5? ([2620:0:105f:fd00:a2a8:cdff:fe64:b3b5]) by smtp.gmail.com with ESMTPSA id gg7sm13226372wjd.10.2016.02.12.10.42.02 for (version=TLSv1/SSLv3 cipher=OTHER); Fri, 12 Feb 2016 10:42:03 -0800 (PST) Subject: Re: [RFC] grub-install: allow none or multiple install devices on PC BIOS To: The development of GNU GRUB References: <1431111221-32399-1-git-send-email-arvidjaar@gmail.com> From: =?UTF-8?Q?Vladimir_'=cf=86-coder/phcoder'_Serbinenko?= Message-ID: <56BE2774.60806@gmail.com> Date: Fri, 12 Feb 2016 19:41:56 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Icedove/38.5.0 MIME-Version: 1.0 In-Reply-To: <1431111221-32399-1-git-send-email-arvidjaar@gmail.com> Content-Type: multipart/signed; micalg=pgp-sha512; protocol="application/pgp-signature"; boundary="D7mJob4hdOhwfwlto8Lcod32nKIWhupGv" X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2a00:1450:400c:c09::231 X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list Reply-To: The development of GNU GRUB List-Id: The development of GNU GRUB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 12 Feb 2016 18:42:09 -0000 This is an OpenPGP/MIME signed message (RFC 4880 and 3156) --D7mJob4hdOhwfwlto8Lcod32nKIWhupGv Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable On 08.05.2015 20:53, Andrei Borzenkov wrote: > There are two main applications. >=20 > 1. Omit install device to create generic image intended for chainloadin= g > from other master loader. Such image can be put on any device (or file > system) and will still be able to find its $root. Currently even with > --no-bootsector grub-install optimizes image by skipping UUID search if= > possible. >=20 > 2. Redundant installation on multi-device filesystem, RAID or similar. > This allows both optimizing image w.r.t. to using --prefix vs. load.cfg= > as well as creating image just once. >=20 > Patch allows transparently use none or multiple installation devices, > similar to >=20 > grub_devices=3D"/dev/sda /dev/sda1 /dev/sdb" > grub-install $grub_devices >=20 > where grub_devices can be empty and still do the right thing. >=20 > This is work in progress, although it is functionally complete and just= > needs some cleanups. >=20 > Comments? I like the idea and it was on my "nice to have" list for some time. Do you want to clean it up first or should I review this version? >=20 > --- > grub-core/kern/disk.c | 5 +- > include/grub/disk.h | 2 + > util/grub-install.c | 217 +++++++++++++++++++++++++++++++-----------= -------- > 3 files changed, 143 insertions(+), 81 deletions(-) >=20 > diff --git a/grub-core/kern/disk.c b/grub-core/kern/disk.c > index 789f8c0..56f16b4 100644 > --- a/grub-core/kern/disk.c > +++ b/grub-core/kern/disk.c > @@ -168,7 +168,10 @@ grub_disk_dev_unregister (grub_disk_dev_t dev) > =20 > /* Return the location of the first ',', if any, which is not > escaped by a '\'. */ > -static const char * > +#if !defined (GRUB_UTIL) > +static > +#endif > +const char * > find_part_sep (const char *name) > { > const char *p =3D name; > diff --git a/include/grub/disk.h b/include/grub/disk.h > index b385af8..b2081eb 100644 > --- a/include/grub/disk.h > +++ b/include/grub/disk.h > @@ -256,6 +256,8 @@ void grub_ldm_fini (void); > void grub_mdraid09_fini (void); > void grub_mdraid1x_fini (void); > void grub_diskfilter_fini (void); > +extern const char *find_part_sep (const char *); > + > #endif > =20 > #endif /* ! GRUB_DISK_HEADER */ > diff --git a/util/grub-install.c b/util/grub-install.c > index 7b394c9..bb6532c 100644 > --- a/util/grub-install.c > +++ b/util/grub-install.c > @@ -57,7 +57,10 @@ static char *target; > static int removable =3D 0; > static int recheck =3D 0; > static int update_nvram =3D 1; > -static char *install_device =3D NULL; > +static char **install_devices =3D NULL; > +static char **install_drives =3D NULL; > +static int n_install_devices; > +static int n_allocated_devices; > static char *debug_image =3D NULL; > static char *rootdir =3D NULL; > static char *bootdir =3D NULL; > @@ -234,9 +237,12 @@ argp_parser (int key, char *arg, struct argp_state= *state) > return 0; > =20 > case ARGP_KEY_ARG: > - if (install_device) > - grub_util_error ("%s", _("More than one install device?")); > - install_device =3D xstrdup (arg); > + if (n_install_devices >=3D n_allocated_devices) > + { > + n_allocated_devices +=3D 16; > + install_devices =3D xrealloc (install_devices, n_allocated_devices)= ; > + } > + install_devices[n_install_devices++] =3D xstrdup (arg); > return 0; > =20 > default: > @@ -534,25 +540,55 @@ probe_cryptodisk_uuid (grub_disk_t disk) > } > =20 > static int > -is_same_disk (const char *a, const char *b) > +same_disks (char **root_devs) > { > - while (1) > + int i; > + > + for (i =3D 0; i < n_install_devices; i++) > { > - if ((*a =3D=3D ',' || *a =3D=3D '\0') && (*b =3D=3D ',' || *b =3D= =3D '\0')) > - return 1; > - if (*a !=3D *b) > - return 0; > - if (*a =3D=3D '\\') > + char **d; > + const char *p1 =3D find_part_sep (install_drives[i]); > + size_t len1 =3D p1 ? p1 - install_drives[i] : strlen (install_dr= ives[i]); > + > + for (d =3D root_devs; *d; d++) > { > - if (a[1] !=3D b[1]) > - return 0; > - a +=3D 2; > - b +=3D 2; > - continue; > + const char *p2 =3D find_part_sep (*d); > + size_t len2 =3D p2 ? p2 - *d : strlen (*d); > + > + if (len1 =3D=3D len2 && > + strncmp (install_drives[i], *d, len1) =3D=3D 0) > + break; > } > - a++; > - b++; > + if (!*d) > + return 0; > + } > + > + return 1; > +} > + > +static int > +same_partitions (char **root_devs) > +{ > + const char *first_part; > + char **p; > + > + if (!root_devs[1]) > + return 1; > + > + first_part =3D find_part_sep (root_devs[0]); > + for (p =3D root_devs + 1; *p; p++) > + { > + const char *part =3D find_part_sep (*p); > + > + if ((first_part =3D=3D NULL) ^ (part =3D=3D NULL)) > + return 0; > + if (!first_part && !part) > + continue; > + if (strcmp (first_part, part)) > + return 0; > } > + > + return 1; > } > =20 > static char * > @@ -835,6 +871,8 @@ main (int argc, char *argv[]) > int efidir_is_mac =3D 0; > int is_prep =3D 0; > const char *pkgdatadir; > + size_t i; > + > =20 > grub_util_host_init (&argc, &argv); > product_version =3D xstrdup (PACKAGE_VERSION); > @@ -926,12 +964,26 @@ main (int argc, char *argv[]) > switch (platform) > { > case GRUB_INSTALL_PLATFORM_I386_PC: > + break; > + > + default: > + if (n_install_devices > 1) > + grub_util_error ("%s", _("More than one install device?")); > + break; > + } > + > + switch (platform) > + { > + case GRUB_INSTALL_PLATFORM_I386_PC: > + if (!install_devices) > + install_bootsector =3D 0; > + break; > case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275: > - if (!install_device) > + if (!install_devices) > grub_util_error ("%s", _("install device isn't specified")); > break; > case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275: > - if (install_device) > + if (install_devices) > is_prep =3D 1; > break; > case GRUB_INSTALL_PLATFORM_MIPS_ARC: > @@ -952,8 +1004,11 @@ main (int argc, char *argv[]) > case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS: > case GRUB_INSTALL_PLATFORM_I386_XEN: > case GRUB_INSTALL_PLATFORM_X86_64_XEN: > - free (install_device); > - install_device =3D NULL; > + for (i =3D 0; i < n_install_devices; i++) > + free (install_devices[i]); > + free (install_devices); > + install_devices =3D NULL; > + n_install_devices =3D n_allocated_devices =3D 0; > break; > =20 > /* pacify warning. */ > @@ -996,11 +1051,6 @@ main (int argc, char *argv[]) > is_efi =3D 1; > break; > default: > - is_efi =3D 0; > - break; > - > - /* pacify warning. */ > - case GRUB_INSTALL_PLATFORM_MAX: > break; > } > =20 > @@ -1009,8 +1059,6 @@ main (int argc, char *argv[]) > if (is_efi) > { > grub_fs_t fs; > - free (install_device); > - install_device =3D NULL; > if (!efidir) > { > char *d =3D grub_util_path_concat (2, bootdir, "efi"); > @@ -1045,7 +1093,9 @@ main (int argc, char *argv[]) > if (!efidir_device_names || !efidir_device_names[0]) > grub_util_error (_("cannot find a device for %s (is /dev mounted?)"),= > efidir); > - install_device =3D efidir_device_names[0]; > + /* FIXME free install_devices */ > + /* We will use just the first device */ > + install_devices =3D efidir_device_names; > =20 > for (curdev =3D efidir_device_names; *curdev; curdev++) > grub_util_pull_device (*curdev); > @@ -1207,7 +1257,9 @@ main (int argc, char *argv[]) > if (grub_strcmp (fs->name, "hfs") =3D=3D 0 > || grub_strcmp (fs->name, "hfsplus") =3D=3D 0) > { > - install_device =3D macppcdir_device_names[0]; > + /* FIXME free install_devices */ > + /* We just use the first one */ > + install_devices =3D macppcdir_device_names; > is_prep =3D 0; > } > } > @@ -1318,35 +1370,37 @@ main (int argc, char *argv[]) > debug_image); > } > char *prefix_drive =3D NULL; > - char *install_drive =3D NULL; > =20 > - if (install_device) > + if (install_devices) > { > - if (install_device[0] =3D=3D '(' > - && install_device[grub_strlen (install_device) - 1] =3D=3D ')') > - { > - size_t len =3D grub_strlen (install_device) - 2; > - install_drive =3D xmalloc (len + 1); > - memcpy (install_drive, install_device + 1, len); > - install_drive[len] =3D '\0'; > - } > - else > - { > - grub_util_pull_device (install_device); > - install_drive =3D grub_util_get_grub_dev (install_device); > - if (!install_drive) > - grub_util_error (_("cannot find a GRUB drive for %s. Check your = device.map"), > - install_device); > - } > + install_drives =3D xmalloc (n_install_devices * sizeof (*install= _drives)); > + > + for (i =3D 0; i < n_install_devices; i++) > + if (install_devices[i][0] =3D=3D '(' > + && install_devices[i][grub_strlen (install_devices[i]) - 1] =3D=3D= ')') > + { > + size_t len =3D grub_strlen (install_devices[i]) - 2; > + install_drives[i] =3D xmalloc (len + 1); > + memcpy (install_drives[i], install_devices[i] + 1, len); > + install_drives[i][len] =3D '\0'; > + } > + else > + { > + grub_util_pull_device (install_devices[i]); > + install_drives[i] =3D grub_util_get_grub_dev (install_devices[i])= ; > + if (!install_drives[i]) > + grub_util_error (_("cannot find a GRUB drive for %s. Check you= r device.map"), > + install_devices[i]); > + } > } > =20 > if (!have_abstractions) > { > if ((disk_module && grub_strcmp (disk_module, "biosdisk") !=3D 0= ) > - || grub_drives[1] > - || (!install_drive > + || (grub_drives[1] && !same_partitions (grub_drives)) > + || (!install_drives > && platform !=3D GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275) > - || (install_drive && !is_same_disk (grub_drives[0], install_drive))= > + || (install_drives && !same_disks (grub_drives)) > || !have_bootdev (platform)) > { > char *uuid =3D NULL; > @@ -1656,24 +1710,27 @@ main (int argc, char *argv[]) > "boot.img"); > grub_install_copy_file (boot_img_src, boot_img, 1); > =20 > - grub_util_info ("%sgrub-bios-setup %s %s %s %s %s --directory=3D'%s' = --device-map=3D'%s' '%s'", > - /* TRANSLATORS: This is a prefix in the log to indicate that usuall= y > - a command would be executed but due to an option was skipped. *= / > - install_bootsector ? "" : _("NOT RUNNING: "), > - allow_floppy ? "--allow-floppy " : "", > - verbosity ? "--verbose " : "", > - force ? "--force " : "", > - !fs_probe ? "--skip-fs-probe" : "", > - !add_rs_codes ? "--no-rs-codes" : "", > - platdir, > - device_map, > - install_device); > - =09 > - /* Now perform the installation. */ > - if (install_bootsector) > - grub_util_bios_setup (platdir, "boot.img", "core.img", > - install_drive, force, > - fs_probe, allow_floppy, add_rs_codes); > + for (i =3D 0; i < n_install_devices; i++) > + { > + grub_util_info ("%sgrub-bios-setup %s %s %s %s %s --directory=3D'= %s' --device-map=3D'%s' '%s'", > + /* TRANSLATORS: This is a prefix in the log to indicate that us= ually > + a command would be executed but due to an option was skipped= =2E */ > + install_bootsector ? "" : _("NOT RUNNING: "), > + allow_floppy ? "--allow-floppy " : "", > + verbosity ? "--verbose " : "", > + force ? "--force " : "", > + !fs_probe ? "--skip-fs-probe" : "", > + !add_rs_codes ? "--no-rs-codes" : "", > + platdir, > + device_map, > + install_devices[i]); > + > + /* Now perform the installation. */ > + if (install_bootsector) > + grub_util_bios_setup (platdir, "boot.img", "core.img", > + install_drives[i], force, > + fs_probe, allow_floppy, add_rs_codes); > + } > break; > } > case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275: > @@ -1693,12 +1750,12 @@ main (int argc, char *argv[]) > !fs_probe ? "--skip-fs-probe" : "", > platdir, > device_map, > - install_drive); > + install_drives[0]); > =09 > /* Now perform the installation. */ > if (install_bootsector) > grub_util_sparc_setup (platdir, "boot.img", "core.img", > - install_device, force, > + install_devices[0], force, > fs_probe, allow_floppy, > 0 /* unused */ ); > break; > @@ -1734,7 +1791,7 @@ main (int argc, char *argv[]) > =20 > fill_core_services (core_services); > =20 > - ins_dev =3D grub_device_open (install_drive); > + ins_dev =3D grub_device_open (install_drives[0]); > =20 > bless (ins_dev, core_services, 0); > =20 > @@ -1745,7 +1802,7 @@ main (int argc, char *argv[]) > =20 > partno =3D ins_dev->disk->partition > ? ins_dev->disk->partition->number + 1 : 0; > - dev =3D grub_util_get_os_disk (install_device); > + dev =3D grub_util_get_os_disk (install_devices[0]); > grub_install_register_ieee1275 (0, dev, partno, > "\\\\BootX"); > } > @@ -1757,10 +1814,10 @@ main (int argc, char *argv[]) > break; > } > /* If a install device is defined, copy the core.elf to PReP par= tition. */ > - if (is_prep && install_device && install_device[0]) > + if (is_prep) > { > grub_device_t ins_dev; > - ins_dev =3D grub_device_open (install_drive); > + ins_dev =3D grub_device_open (install_drives[0]); > if (!ins_dev || !is_prep_partition (ins_dev)) > { > grub_util_error ("%s", _("the chosen partition is not a PReP pa= rtition")); > @@ -1772,13 +1829,13 @@ main (int argc, char *argv[]) > } > else > { > - char *s =3D xasprintf ("dd if=3D/dev/zero of=3D%s", install_dev= ice); > + char *s =3D xasprintf ("dd if=3D/dev/zero of=3D%s", install_dev= ices[0]); > grub_util_error (_("the PReP partition is not empty. If you are= sure you want to use it, run dd to clear it: `%s'"), > s); > } > grub_device_close (ins_dev); > if (update_nvram) > - grub_install_register_ieee1275 (1, grub_util_get_os_disk (install= _device), > + grub_install_register_ieee1275 (1, grub_util_get_os_disk (install= _devices[0]), > 0, NULL); > break; > } > @@ -1798,7 +1855,7 @@ main (int argc, char *argv[]) > } > break; > case GRUB_INSTALL_PLATFORM_MIPS_ARC: > - grub_install_sgi_setup (install_device, imgfile, "grub"); > + grub_install_sgi_setup (install_devices[0], imgfile, "grub"); > break; > =20 > case GRUB_INSTALL_PLATFORM_I386_EFI: > @@ -1834,7 +1891,7 @@ main (int argc, char *argv[]) > =20 > fill_core_services(core_services); > =20 > - ins_dev =3D grub_device_open (install_drive); > + ins_dev =3D grub_device_open (install_drives[0]); > =20 > bless (ins_dev, boot_efi, 1); > if (!removable && update_nvram) >=20 --D7mJob4hdOhwfwlto8Lcod32nKIWhupGv Content-Type: application/pgp-signature; name="signature.asc" Content-Description: OpenPGP digital signature Content-Disposition: attachment; filename="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iF4EAREKAAYFAla+J3QACgkQmBXlbbo5nOtj2QD/R2i15cvIdNajIU/mF99aoBVS L6FcuR3Lh7ZZopbFgE4BAIPyG49EYgpD3jgSqQIIr4lmAxosCkIwUsqUKp7JDlG9 =EQ6y -----END PGP SIGNATURE----- --D7mJob4hdOhwfwlto8Lcod32nKIWhupGv--