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