summaryrefslogtreecommitdiffstats
path: root/master/debian/userland-part.patch
blob: 16d2156a1145df108804fd88a6355fa78b1ef275 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
Description: Handle hurd userspace partitions.
Author: Samuel Thibault <samuel.thibault@ens-lyon.org>
Origin: upstream, http://bazaar.launchpad.net/~vcs-imports/grub/grub2-bzr/revision/4290
Forwarded: not-needed
Applied-Upstream: http://bazaar.launchpad.net/~vcs-imports/grub/grub2-bzr/revision/4290
Last-Update: 2012-06-08

--- 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
@@ -337,6 +337,75 @@
 
 #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 *
@@ -565,61 +634,8 @@
 {
   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;