From 94779df38295bcd1b07795970685e0e5e2ce2a81 Mon Sep 17 00:00:00 2001 From: Damien Zammit Date: Sat, 25 Jul 2020 11:18:47 +1000 Subject: rumpdisk: Use bootstrap resume of fs task in machdev Message-Id: <20200725011847.186969-4-damien@zamaudio.com> --- rumpdisk/block-rump.c | 39 ++++++++++++++++----- rumpdisk/main.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 123 insertions(+), 11 deletions(-) diff --git a/rumpdisk/block-rump.c b/rumpdisk/block-rump.c index 42ace30d..474852cd 100644 --- a/rumpdisk/block-rump.c +++ b/rumpdisk/block-rump.c @@ -25,8 +25,6 @@ #include #include -#include "mach_U.h" - #include #include #include @@ -34,8 +32,6 @@ #define MACH_INCLUDE #include "libmachdev/machdev.h" -#include "device_reply_U.h" - #include #include #include @@ -45,6 +41,7 @@ #define DIOCGSECTORSIZE _IOR('d', 133, unsigned int) #define DISK_NAME_LEN 32 +#define MAX_DISK_DEV 2 /* One of these is associated with each open instance of a device. */ struct block_data @@ -89,7 +86,30 @@ search_bd (char *name) static void translate_name (char *output, int len, char *name) { - snprintf (output, len, "%sd", name); + snprintf (output, len - 1, "%sd", name); +} + +static boolean_t +is_disk_device (char *name, int len) +{ + char *dev; + const char *allowed_devs[MAX_DISK_DEV] = { + "/dev/wd", + "/dev/cd" + }; + uint8_t i; + + if (len < 8) + return FALSE; + + for (i = 0; i < MAX_DISK_DEV; i++) + { + dev = (char *)allowed_devs[i]; + /* /dev/XXN but we only care about /dev/XX prefix */ + if (! strncmp (dev, name, 7)) + return TRUE; + } + return FALSE; } static int @@ -136,12 +156,15 @@ device_open (mach_port_t reply_port, mach_msg_type_name_t reply_port_type, dev_mode_t mode, char *name, device_t * devp, mach_msg_type_name_t * devicePoly) { - io_return_t err = D_SUCCESS; + io_return_t err = D_ALREADY_OPEN; struct block_data *bd = NULL; char dev_name[DISK_NAME_LEN]; off_t media_size; uint32_t block_size; + if (! is_disk_device (name, 8)) + return D_NO_SUCH_DEVICE; + translate_name (dev_name, DISK_NAME_LEN, name); /* Find previous device or open if new */ @@ -167,7 +190,7 @@ device_open (mach_port_t reply_port, mach_msg_type_name_t reply_port_type, if (err < 0) { mach_print ("DIOCGMEDIASIZE ioctl fails\n"); - err = D_NO_SUCH_DEVICE; + err = rump_errno2host (errno); goto out; } @@ -175,7 +198,7 @@ device_open (mach_port_t reply_port, mach_msg_type_name_t reply_port_type, if (err < 0) { mach_print ("DIOCGSECTORSIZE ioctl fails\n"); - err = D_NO_SUCH_DEVICE; + err = rump_errno2host (errno); goto out; } bd->media_size = media_size; diff --git a/rumpdisk/main.c b/rumpdisk/main.c index 0181f685..27a8ea38 100644 --- a/rumpdisk/main.c +++ b/rumpdisk/main.c @@ -16,24 +16,113 @@ * Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + #include "libmachdev/machdev.h" #include "block-rump.h" #include #include +/* TODO: Add api to pciaccess to allow selecting backend. + * For now we pretend to be the arbiter and claim x86 method. + */ +char *netfs_server_name = "pci-arbiter"; + +mach_port_t bootstrap_resume_task = MACH_PORT_NULL; + +static const struct argp_option options[] = { + {"host-priv-port", 'h', "PORT", 0, "Host private port PORT"}, + {"device-master-port",'d', "PORT", 0, "Device master port PORT"}, + {"filesystem-task", 'f', "TASK", 0, "Filesystem task TASK"}, + {0} +}; + + +/* Parse a command line option. */ +static error_t +parse_opt (int key, char *arg, struct argp_state *state) +{ + /* We save our parsed values in this structure, hung off STATE->hook. + Only after parsing all options successfully will we use these values. */ + struct + { + int host_priv; + int dev_master; + int fs_task; + } *values = state->hook; + + switch (key) + { + case 'h': + values->host_priv = atoi(arg); + break; + case 'd': + values->dev_master = atoi(arg); + break; + case 'f': + values->fs_task = atoi(arg); + break; + + case ARGP_KEY_INIT: + state->child_inputs[0] = state->input; + values = malloc (sizeof *values); + if (values == 0) + return ENOMEM; + state->hook = values; + memset (values, 0, sizeof *values); + break; + + case ARGP_KEY_SUCCESS: + /* All options parsed successfully */ + _hurd_host_priv = values->host_priv; + _hurd_device_master = values->dev_master; + bootstrap_resume_task = values->fs_task; + break; + + default: + return ARGP_ERR_UNKNOWN; + } + return 0; +} + +static struct argp_child empty_argp_children[] = {{0}}; +static struct argp rumpdisk_argp = {options, parse_opt, 0, 0, empty_argp_children}; +static const struct argp *rumpdisk_argp_bootup = &rumpdisk_argp; + int -main () +main (int argc, char **argv) { + mach_port_t bootstrap = MACH_PORT_NULL; int err; pthread_t t; + setenv ("RUMP_NCPU", "1", 1); + setenv ("RUMP_VERBOSE", "1", 1); + setenv ("RUMP_HOSTNAME", "HURD0", 1); + setenv ("HOSTNAME", "HURD0", 1); + setenv ("RUMP_PANIC", "1", 1); + + err = argp_parse (rumpdisk_argp_bootup, argc, argv, 0, 0, NULL); + if (err) + { + error(1, err, "Missing parameters for bootstrap"); + } + rump_register_block (); machdev_device_init (); - machdev_trivfs_init (); + machdev_trivfs_init (bootstrap_resume_task, "fs", &bootstrap); err = pthread_create (&t, NULL, machdev_server, NULL); if (err) return err; pthread_detach (t); - machdev_trivfs_server (); + machdev_trivfs_server (bootstrap); return 0; } -- cgit v1.2.3