]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
2009-11-21 Samuel Thibault <samuel.thibault@ens-lyon.org>
authorSamuel Thibault <samuel.thibault@ens-lyon.org>
Sat, 21 Nov 2009 17:00:23 +0000 (18:00 +0100)
committerSamuel Thibault <samuel.thibault@ens-lyon.org>
Sat, 21 Nov 2009 17:00:23 +0000 (18:00 +0100)
* util/getroot.c [__GNU__]: Include <hurd.h>, <hurd/lookup.h>, and
<hurd/fs.h>
[__GNU__] (grub_guess_root_device): Call file_name_lookup and
file_get_storage_info to implement grub_guess_root_device.

ChangeLog
util/getroot.c

index 2e6ab2bdc16499935153355781436a6a5313f604..243a92c4d35fa8fcefd4f3a7a6cecd8dff9be2a2 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2009-11-21  Samuel Thibault  <samuel.thibault@ens-lyon.org>
+
+       * util/getroot.c [__GNU__]: Include <hurd.h>, <hurd/lookup.h>, and
+       <hurd/fs.h>
+       [__GNU__] (grub_guess_root_device): Call file_name_lookup and
+       file_get_storage_info to implement grub_guess_root_device.
+
 2009-11-21  Felix Zielcke  <fzielcke@z-51.de>
 
        * util/grub-mkrescue.in: Print an error and usage if output option
index 120ab13b145aa5eaa7605f3c042c0bf4ac413374..2915ab4f2f17e6efe9aaac3bea41511d3c5e392e 100644 (file)
 # define DEV_CYGDRIVE_MAJOR 98
 #endif
 
+#ifdef __GNU__
+#include <hurd.h>
+#include <hurd/lookup.h>
+#include <hurd/fs.h>
+#endif
+
 #include <grub/util/misc.h>
 #include <grub/util/hostdisk.h>
 #include <grub/util/getroot.h>
@@ -378,8 +384,65 @@ find_cygwin_root_device (const char *path, dev_t dev)
 char *
 grub_guess_root_device (const char *dir)
 {
-  struct stat st;
   char *os_dev;
+#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);
+#else /* !__GNU__ */
+  struct stat st;
 
   if (stat (dir, &st) < 0)
     grub_util_error ("Cannot stat `%s'", dir);
@@ -393,6 +456,7 @@ grub_guess_root_device (const char *dir)
   /* This might be truly slow, but is there any better way?  */
   os_dev = find_root_device ("/dev", st.st_dev);
 #endif
+#endif /* !__GNU__ */
 
   return os_dev;
 }