From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1SMSm9-0008Nr-It for mharc-grub-devel@gnu.org; Mon, 23 Apr 2012 19:34:33 -0400 Received: from eggs.gnu.org ([208.118.235.92]:52187) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SMSm6-0008Ni-BQ for grub-devel@gnu.org; Mon, 23 Apr 2012 19:34:32 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SMSm3-0002MI-Np for grub-devel@gnu.org; Mon, 23 Apr 2012 19:34:29 -0400 Received: from toccata.ens-lyon.org ([140.77.166.68]:37002) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SMSm3-0002HX-DD for grub-devel@gnu.org; Mon, 23 Apr 2012 19:34:27 -0400 Received: from localhost (localhost [127.0.0.1]) by toccata.ens-lyon.org (Postfix) with ESMTP id 6F74C84082 for ; Tue, 24 Apr 2012 01:34:25 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at toccata.ens-lyon.org Received: from toccata.ens-lyon.org ([127.0.0.1]) by localhost (toccata.ens-lyon.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id QbCC6mNviU6c for ; Tue, 24 Apr 2012 01:34:25 +0200 (CEST) Received: from type.ipv6 (youpi.is-a-geek.org [80.67.176.89]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by toccata.ens-lyon.org (Postfix) with ESMTPSA id CDCBA8407A for ; Tue, 24 Apr 2012 01:34:24 +0200 (CEST) Received: from samy by type.ipv6 with local (Exim 4.77) (envelope-from ) id 1SMSlz-00057e-Tb for grub-devel@gnu.org; Tue, 24 Apr 2012 01:34:23 +0200 Date: Tue, 24 Apr 2012 01:34:23 +0200 From: Samuel Thibault To: The development of GNU GRUB Subject: Re: [PATCH,HURD] Fix grub-probe with userland partition support Message-ID: <20120423233423.GC4755@type.famille.thibault.fr> References: <20120422182439.GE4755@type.famille.thibault.fr> <4F951839.4070309@gmail.com> <20120423094030.GB4755@type.famille.thibault.fr> <4F9532B5.9050701@gmail.com> <20120423110627.GL4755@type.famille.thibault.fr> <4F953A3B.3000708@gmail.com> <20120423212606.GV4755@type.famille.thibault.fr> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="hQiwHBbRI9kgIhsi" Content-Disposition: inline In-Reply-To: <20120423212606.GV4755@type.famille.thibault.fr> User-Agent: Mutt/1.5.21+34 (58baf7c9f32f) (2010-12-30) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 1) X-Received-From: 140.77.166.68 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: Mon, 23 Apr 2012 23:34:32 -0000 --hQiwHBbRI9kgIhsi Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Here is a revamped patch. Samuel --hQiwHBbRI9kgIhsi Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=patch-grub === modified file 'Makefile.util.def' --- Makefile.util.def 2012-04-01 19:35:18 +0000 +++ Makefile.util.def 2012-04-22 18:26:01 +0000 @@ -170,7 +170,7 @@ ldadd = libgrubgcry.a; ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM) $(LIBSTORE)'; }; program = { @@ -300,7 +300,7 @@ ldadd = libgrubgcry.a; ldadd = libgrubkern.a; ldadd = grub-core/gnulib/libgnu.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM) $(LIBSTORE)'; }; program = { @@ -316,7 +316,7 @@ ldadd = libgrubkern.a; ldadd = libgrubgcry.a; ldadd = grub-core/gnulib/libgnu.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM) $(LIBSTORE)'; cppflags = '-DGRUB_SETUP_BIOS=1'; }; @@ -334,7 +334,7 @@ ldadd = libgrubkern.a; ldadd = libgrubgcry.a; ldadd = grub-core/gnulib/libgnu.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM) $(LIBSTORE)'; cppflags = '-DGRUB_SETUP_SPARC64=1'; }; === modified file 'configure.ac' --- configure.ac 2012-04-19 09:34:43 +0000 +++ configure.ac 2012-04-22 17:50:59 +0000 @@ -341,6 +341,18 @@ ]) AC_SUBST([LIBUTIL]) +# On Hurd we need libstore for kern/emu/getroot.c +case "$host_kernel" in + hurd) + AC_CHECK_HEADER([hurd/store.h], [], [AC_MSG_ERROR([hurd/store.h is needed])]) + AC_CHECK_LIB([store], [store_create], [], [AC_MSG_ERROR([libstore is needed])]) + LIBSTORE="-lstore" + ;; + *) + ;; +esac +AC_SUBST([LIBSTORE]) + # # Check for host and build compilers. # === modified file 'util/getroot.c' --- util/getroot.c 2012-04-22 19:02:55 +0000 +++ util/getroot.c 2012-04-24 01:27:50 +0000 @@ -45,8 +45,11 @@ #endif #ifdef __GNU__ +#include #include #include +#include +#include #include #include #endif @@ -700,6 +703,115 @@ #elif defined (__GNU__) +/* Open a store for storage information only. */ +static struct store * +storeinfo_store (const char *path) +{ + file_t file; + struct store *store; + int err; + + file = file_name_lookup (path, 0, 0); + if (file == MACH_PORT_NULL) + return NULL; + + err = store_create (file, STORE_INACTIVE | STORE_NO_FILEIO, NULL, &store); + if (err) + { + errno = err; + return NULL; + } + + return store; +} + +/* Retrieve the storage information for PATH, and search which partitions + * contains its start. */ +static char * +find_hurd_root_device (const char *path) +{ + struct store *path_store, *part_store; + char *devpath = NULL; + const char *prefix; + size_t len, prefix_len; + store_offset_t path_start; + int part; + + path_store = storeinfo_store (path); + if (! path_store) + grub_util_error ("Could not retrieve storage information for `%s'", path); + if (! path_store->name) + grub_util_error ("No storage name associated with `%s'", path); + + grub_util_info ("Storage is %s, type %d", + path_store->name, path_store->class->id); + + if (path_store->class->id == STORAGE_DEVICE) + prefix = "/dev/"; + else + prefix = ""; + + prefix_len = strlen (prefix); + len = strlen (path_store->name); + devpath = xmalloc (prefix_len + len + 4 + 1); + + path_start = path_store->runs[0].start * path_store->block_size; + + grub_util_info ("Path runs from %llu", path_start); + + for (part = 1; part < 1000; part++) + { + struct store_run *first_run, *last_run; + + snprintf (devpath, prefix_len + len + 4 + 1, "%s%ss%u", + prefix, path_store->name, part); + + grub_util_info ("Trying partition %s", devpath); + part_store = storeinfo_store (devpath); + if (! part_store) + { + if (errno == ENOENT && part >= 5) + { + free (devpath); + devpath = NULL; + break; + } + continue; + } + + first_run = &part_store->runs[0]; + last_run = &part_store->runs[part_store->num_runs - 1]; + + grub_util_info ("Partition %u runs from %llu to %llu", part, + first_run->start * part_store->block_size, + (last_run->start + last_run->length) * part_store->block_size); + + if (first_run->start * part_store->block_size <= path_start && + (last_run->start + last_run->length) * part_store->block_size > path_start) { + store_free (part_store); + break; + } + store_free (part_store); + } + + if (part >= 1000) + { + free (devpath); + devpath = NULL; + } + + if (!devpath) + { + devpath = xmalloc (prefix_len + len + 1); + snprintf (devpath, prefix_len + len + 1, "%s%s", prefix, path_store->name); + grub_util_info ("End of partitions, assuming %s", devpath); + } + + store_free (path_store); + + return devpath; +} + #elif ! defined(__CYGWIN__) char * @@ -930,65 +1042,7 @@ grub_guess_root_devices (const char *dir) { char **os_dev = NULL; -#ifdef __GNU__ - file_t file; - mach_port_t *ports; - int *ints; - loff_t *offsets; - char *data; - error_t err; - mach_msg_type_number_t num_ports = 0, num_ints = 0, num_offsets = 0, data_len = 0; - size_t name_len; - - file = file_name_lookup (dir, 0, 0); - if (file == MACH_PORT_NULL) - return 0; - - err = file_get_storage_info (file, - &ports, &num_ports, - &ints, &num_ints, - &offsets, &num_offsets, - &data, &data_len); - - if (num_ints < 1) - grub_util_error (_("Storage info for `%s' does not include type"), dir); - if (ints[0] != STORAGE_DEVICE) - grub_util_error (_("Filesystem of `%s' is not stored on local disk"), dir); - - if (num_ints < 5) - grub_util_error (_("Storage info for `%s' does not include name"), dir); - name_len = ints[4]; - if (name_len < data_len) - grub_util_error (_("Bogus name length for storage info for `%s'"), dir); - if (data[name_len - 1] != '\0') - grub_util_error (_("Storage name for `%s' not NUL-terminated"), dir); - - os_dev = xmalloc (2 * sizeof (os_dev[0])); - os_dev[0] = xmalloc (sizeof ("/dev/") - 1 + data_len); - memcpy (os_dev[0], "/dev/", sizeof ("/dev/") - 1); - memcpy (os_dev[0] + sizeof ("/dev/") - 1, data, data_len); - os_dev[1] = 0; - - if (ports && num_ports > 0) - { - mach_msg_type_number_t i; - for (i = 0; i < num_ports; i++) - { - mach_port_t port = ports[i]; - if (port != MACH_PORT_NULL) - mach_port_deallocate (mach_task_self(), port); - } - munmap ((caddr_t) ports, num_ports * sizeof (*ports)); - } - - if (ints && num_ints > 0) - munmap ((caddr_t) ints, num_ints * sizeof (*ints)); - if (offsets && num_offsets > 0) - munmap ((caddr_t) offsets, num_offsets * sizeof (*offsets)); - if (data && data_len > 0) - munmap (data, data_len); - mach_port_deallocate (mach_task_self (), file); -#else /* !__GNU__ */ +#ifndef __GNU__ struct stat st; dev_t dev; @@ -1035,6 +1089,7 @@ grub_util_error (_("cannot stat `%s': %s"), dir, strerror (errno)); dev = st.st_dev; +#endif /* !__GNU__ */ os_dev = xmalloc (2 * sizeof (os_dev[0])); @@ -1042,6 +1097,10 @@ /* Cygwin specific function. */ os_dev[0] = grub_find_device (dir, dev); +#elif defined __GNU__ + /* GNU/Hurd specific function. */ + os_dev[0] = find_hurd_root_device (dir); + #else /* This might be truly slow, but is there any better way? */ @@ -1054,7 +1113,6 @@ } os_dev[1] = 0; -#endif /* !__GNU__ */ return os_dev; } --hQiwHBbRI9kgIhsi--