Bug#670186: hurd-i386: add userland partition support
Samuel Thibault
sthibault at debian.org
Fri May 11 22:45:45 UTC 2012
Hello,
Samuel Thibault, le Mon 23 Apr 2012 22:42:52 +0200, a écrit :
> I have begun submitting it upstream, but disk detection has changed
> considerably, so it will have to be rethought. The attached patch can
> be used in Debian in the meanwhile.
A revised patch was commited upstream, here is a backport, please apply
it with next grub2 upload.
Samuel
-------------- next part --------------
--- a/grub-core/kern/emu/getroot.c 2012-05-03 20:59:16 +0000
+++ b/grub-core/kern/emu/getroot.c 2012-05-03 21:41:46 +0000
@@ -710,6 +710,75 @@ grub_find_device (const char *dir __attr
#elif defined (__GNU__)
+static char *
+find_hurd_root_device (const char *path)
+{
+ file_t file;
+ error_t err;
+ char *argz = NULL, *name = NULL, *ret;
+ size_t argz_len = 0;
+ int i;
+
+ file = file_name_lookup (path, 0, 0);
+ if (file == MACH_PORT_NULL)
+ grub_util_error ("cannot open `%s': %s", path, strerror (errno));
+
+ /* This returns catenated 0-terminated strings. */
+ err = file_get_fs_options (file, &argz, &argz_len);
+ if (err)
+ grub_util_error ("cannot get filesystem options "
+ "for path `%s': %s", path, strerror(err));
+ if (argz_len == 0)
+ /* TRANSLATORS: a "translator" is similar to a filesystem, but handled by a
+ * userland daemon. */
+ grub_util_error ("translator is empty for path `%s'", path);
+
+ /* Make sure the string is terminated. */
+ argz[argz_len-1] = 0;
+
+ /* Skip first word (translator path) and options. */
+ for (i = strlen (argz) + 1; i < argz_len; i += strlen (argz + i) + 1)
+ {
+ if (argz[i] != '-')
+ {
+ /* Non-option. Only accept one, assumed to be the FS path. */
+ /* XXX: this should be replaced by an RPC to the translator. */
+ if (name)
+ /* TRANSLATORS: we expect to get something like
+ /hurd/foobar --option1 --option2=baz /dev/something
+ */
+ grub_util_error ("translator `%s' for path `%s' has several "
+ "non-option words, at least `%s' and `%s'",
+ argz, path, name, argz + i);
+ name = argz + i;
+ }
+ }
+
+ if (!name)
+ /* TRANSLATORS: we expect to get something like
+ /hurd/foobar --option1 --option2=baz /dev/something
+ */
+ grub_util_error ("translator `%s' for path `%s' is given only options, "
+ "cannot find device part", argz, path);
+
+ if (strncmp (name, "device:", sizeof ("device:") - 1) == 0)
+ {
+ char *dev_name = name + sizeof ("device:") - 1;
+ size_t size = sizeof ("/dev/") - 1 + strlen (dev_name) + 1;
+ char *next;
+ ret = malloc (size);
+ next = stpncpy (ret, "/dev/", size);
+ stpncpy (next, dev_name, size - (next - ret));
+ }
+ else if (!strncmp (name, "file:", sizeof ("file:") - 1))
+ ret = strdup (name + sizeof ("file:") - 1);
+ else
+ ret = strdup (name);
+
+ munmap (argz, argz_len);
+ return ret;
+}
+
#elif ! defined(__CYGWIN__)
char *
@@ -940,62 +1009,9 @@ char **
grub_guess_root_device (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 (strlen ("/dev/") + data_len);
- memcpy (os_dev, "/dev/", strlen ("/dev/"));
- memcpy (os_dev + strlen ("/dev/"), data, data_len);
-
- 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);
+ /* GNU/Hurd specific function. */
+ os_dev = find_hurd_root_device (dir);
#else /* !__GNU__ */
struct stat st;
dev_t dev;
More information about the Pkg-grub-devel
mailing list