summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustus Winter <justus@gnupg.org>2016-11-05 18:47:34 +0100
committerJustus Winter <justus@gnupg.org>2016-11-05 18:47:34 +0100
commit8cf212d402b0a392ed6c89f9e1035cbbf9988478 (patch)
tree426438d04368f6bd964c00df1f2e09d2fd101828
parent54c6736341bda9564a028ad3d61d46488e53b8a6 (diff)
boot: Improve device pass-through.
Previously, the device file was opened once at startup time. This is fragile, as the remote server might die. Open it at device open time instead. * boot/boot.c (options): Improve documentation. (struct dev_map): Rename fields, document, store the name of the device file instead of a port. (add_dev_map): Update accordingly. (lookup_dev): Likewise. (ds_device_open): Open the device file here instead.
-rw-r--r--boot/boot.c50
1 files changed, 36 insertions, 14 deletions
diff --git a/boot/boot.c b/boot/boot.c
index f7c7d77f..d0e02075 100644
--- a/boot/boot.c
+++ b/boot/boot.c
@@ -234,32 +234,45 @@ static struct argp_option options[] =
"Pause for user confirmation at various times during booting" },
{ "isig", 'I', 0, 0,
"Do not disable terminal signals, so you can suspend and interrupt boot"},
- { "device", 'f', "device_name=device_file", 0,
- "Specify a device file used by subhurd and its virtual name"},
+ { "device", 'f', "SUBHURD_NAME=DEVICE_FILE", 0,
+ "Pass the given DEVICE_FILE to the Subhurd as device SUBHURD_NAME"},
{ "privileged", OPT_PRIVILEGED, NULL, 0,
"Allow the subhurd to access privileged kernel ports"},
{ 0 }
};
static char doc[] = "Boot a second hurd";
-struct dev_map
+
+
+/* Device pass through. */
+
+struct dev_map
{
- char *name;
- mach_port_t port;
+ char *device_name; /* The name of the device in the Subhurd. */
+ char *file_name; /* The filename outside the Subhurd. */
struct dev_map *next;
};
static struct dev_map *dev_map_head;
-static struct dev_map *add_dev_map (char *dev_name, char *dev_file)
+static struct dev_map *
+add_dev_map (const char *dev_name, const char *dev_file)
{
- struct dev_map *map = malloc (sizeof (*map));
+ file_t node;
+ struct dev_map *map;
+
+ /* See if we can open the file. */
+ node = file_name_lookup (dev_file, 0, 0);
+ if (! MACH_PORT_VALID (node))
+ error (1, errno, "%s", dev_file);
+ mach_port_deallocate (mach_task_self (), node);
- assert (map);
- map->name = dev_name;
- map->port = file_name_lookup (dev_file, 0, 0);
- if (map->port == MACH_PORT_NULL)
- error (1, errno, "file_name_lookup: %s", dev_file);
+ map = malloc (sizeof *map);
+ if (map == NULL)
+ return NULL;
+
+ map->device_name = strdup (dev_name);
+ map->file_name = strdup (dev_file);
map->next = dev_map_head;
dev_map_head = map;
return map;
@@ -271,7 +284,7 @@ static struct dev_map *lookup_dev (char *dev_name)
for (map = dev_map_head; map; map = map->next)
{
- if (strcmp (map->name, dev_name) == 0)
+ if (strcmp (map->device_name, dev_name) == 0)
return map;
}
return NULL;
@@ -899,8 +912,17 @@ ds_device_open (mach_port_t master_port,
map = lookup_dev (name);
if (map)
{
+ error_t err;
+ file_t node;
+
+ node = file_name_lookup (map->file_name, 0, 0);
+ if (! MACH_PORT_VALID (node))
+ return D_NO_SUCH_DEVICE;
+
*devicetype = MACH_MSG_TYPE_MOVE_SEND;
- return device_open (map->port, mode, "", device);
+ err = device_open (node, mode, "", device);
+ mach_port_deallocate (mach_task_self (), node);
+ return err;
}
*devicetype = MACH_MSG_TYPE_MOVE_SEND;