summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Zammit <damien@zamaudio.com>2021-03-09 00:04:56 +1100
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2021-03-08 22:17:03 +0100
commitb261eb886e4ee068515484727955e416517a03b4 (patch)
treeedf55004020d488a008e1cd8ab70a94724e89094
parenta5fc9f2e767f034830ee5b179123b093180bf259 (diff)
pci-arbiter: Introduce machdev into this server
* pci-arbiter/Makefile Add machdev lib and simplify * pci-arbiter/main.c (pci_device_{open,close,shutdown}): New methods (netfs_server_func): Thread the demuxer loop (pcifs_startup): Custom startup method (main): Use machdev for server and detach worker threads * pci-arbiter/options.{c,h} Add disk-server-task and priv ports * pci-arbiter/startup-ops.c Delete file Message-Id: <20210308130457.693821-4-damien@zamaudio.com>
-rw-r--r--pci-arbiter/Makefile7
-rw-r--r--pci-arbiter/main.c187
-rw-r--r--pci-arbiter/options.c19
-rw-r--r--pci-arbiter/options.h8
-rw-r--r--pci-arbiter/pcifs.c29
-rw-r--r--pci-arbiter/pcifs.h6
-rw-r--r--pci-arbiter/startup-ops.c44
7 files changed, 229 insertions, 71 deletions
diff --git a/pci-arbiter/Makefile b/pci-arbiter/Makefile
index 1d0309dc..b32bc579 100644
--- a/pci-arbiter/Makefile
+++ b/pci-arbiter/Makefile
@@ -22,11 +22,10 @@ PORTDIR = $(srcdir)/port
SRCS = main.c pci-ops.c netfs_impl.c \
pcifs.c ncache.c options.c func_files.c startup.c \
- startup-ops.c
-MIGSRCS = pciServer.c startup_notifyServer.c
-OBJS = $(patsubst %.S,%.o,$(patsubst %.c,%.o, $(SRCS) $(MIGSRCS)))
+ pciServer.c startup_notifyServer.c
+OBJS = $(SRCS:.c=.o) $(MIGSTUBS)
-HURDLIBS= fshelp ports shouldbeinlibc netfs iohelp ihash
+HURDLIBS= fshelp ports shouldbeinlibc netfs iohelp ihash trivfs machdev
LDLIBS = -lpthread $(libpciaccess_LIBS)
target = pci-arbiter
diff --git a/pci-arbiter/main.c b/pci-arbiter/main.c
index 181bdee2..efb9f65c 100644
--- a/pci-arbiter/main.c
+++ b/pci-arbiter/main.c
@@ -24,7 +24,12 @@
#include <fcntl.h>
#include <version.h>
#include <argp.h>
+#include <unistd.h>
#include <hurd/netfs.h>
+#include <hurd/ports.h>
+#include <hurd/fsys.h>
+#include <device/device.h>
+#include <sys/mman.h>
#include <pci_S.h>
#include <startup_notify_S.h>
@@ -34,7 +39,9 @@
#include "libnetfs/fsys_S.h"
#include "libports/interrupt_S.h"
#include "libnetfs/ifsock_S.h"
+#include "libmachdev/machdev.h"
#include <pciaccess.h>
+#include <pthread.h>
#include "pcifs.h"
#include "startup.h"
@@ -46,6 +53,96 @@ int netfs_maxsymlinks = 0;
char *netfs_server_name = "pci-arbiter";
char *netfs_server_version = HURD_VERSION;
+static mach_port_t pci_control_port;
+
+
+static io_return_t
+pci_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;
+ mach_port_t dev_master, root;
+ string_t retry_name;
+ retry_type retry;
+ uid_t idlist[] = {0, 0, 0};
+
+ if (strncmp(name, "pci", 3))
+ err = D_NO_SUCH_DEVICE;
+
+ /* Fall back to opening kernel device master */
+ if (err)
+ {
+ err = get_privileged_ports(NULL, &dev_master);
+ if (err)
+ return err;
+ if (dev_master == MACH_PORT_NULL)
+ return D_NO_SUCH_DEVICE;
+ err = device_open (dev_master, mode, name, devp);
+ if (err)
+ return err;
+ *devicePoly = MACH_MSG_TYPE_MOVE_SEND;
+ return D_SUCCESS;
+ }
+
+ err = fsys_getroot(pci_control_port, MACH_PORT_NULL, MACH_MSG_TYPE_COPY_SEND,
+ idlist, 3, idlist, 3, 0,
+ &retry, retry_name, &root);
+ if (err)
+ return err;
+
+ *devp = root;
+ *devicePoly = MACH_MSG_TYPE_COPY_SEND;
+ return D_SUCCESS;
+}
+
+static io_return_t
+pci_device_close (void *d)
+{
+ ports_port_deref (&pci_control_port);
+ return 0;
+}
+
+static void
+pci_device_shutdown (mach_port_t dosync_handle)
+{
+ struct port_info *inpi = ports_lookup_port (netfs_port_bucket, dosync_handle,
+ pci_shutdown_notify_class);
+
+ if (!inpi)
+ return;
+
+ // Free all libpciaccess resources
+ pci_system_cleanup ();
+
+ ports_port_deref (inpi);
+
+ ports_destroy_right (&pci_control_port);
+
+ netfs_shutdown (FSYS_GOAWAY_FORCE);
+}
+
+static struct machdev_device_emulation_ops pci_arbiter_emulation_ops = {
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ pci_device_open,
+ pci_device_close,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ pci_device_shutdown,
+};
+
int
netfs_demuxer (mach_msg_header_t * inp, mach_msg_header_t * outp)
{
@@ -67,25 +164,83 @@ netfs_demuxer (mach_msg_header_t * inp, mach_msg_header_t * outp)
return FALSE;
}
+static void *
+netfs_server_func (void *arg)
+{
+ error_t err;
+
+ do
+ {
+ ports_manage_port_operations_multithread (netfs_port_bucket,
+ netfs_demuxer,
+ 1000 * 60 * 2, /* two minutes thread */
+ 1000 * 60 * 10,/* ten minutes server */
+ 0);
+ err = netfs_shutdown (0);
+ }
+ while (err);
+ return NULL;
+}
+
+
+static mach_port_t
+pcifs_startup(mach_port_t bootstrap, int flags)
+{
+ error_t err;
+ mach_port_t realnode;
+ struct port_info *newpi;
+
+ err = ports_create_port (netfs_control_class, netfs_port_bucket,
+ sizeof (struct port_info), &newpi);
+ if (!err)
+ {
+ pci_control_port = ports_get_send_right (newpi);
+ err = fsys_startup (bootstrap, flags, pci_control_port, MACH_MSG_TYPE_COPY_SEND,
+ &realnode);
+ assert_perror_backtrace (err);
+ }
+ if (err)
+ error (11, err, "Translator startup failure: fsys_startup");
+
+ return realnode;
+}
+
int
main (int argc, char **argv)
{
error_t err;
mach_port_t bootstrap;
+ mach_port_t disk_server_task;
+ pthread_t t, nt;
/* Parse options */
alloc_file_system (&fs);
argp_parse (netfs_runtime_argp, argc, argv, 0, 0, 0);
+ disk_server_task = fs->params.disk_server_task;
- task_get_bootstrap_port (mach_task_self (), &bootstrap);
- if (bootstrap == MACH_PORT_NULL)
- error (1, 0, "must be started as a translator");
-
+ if (disk_server_task != MACH_PORT_NULL)
+ {
+ machdev_register (&pci_arbiter_emulation_ops);
+ machdev_device_init ();
+ machdev_trivfs_init (disk_server_task, "pci", "/servers/bus/pci", &bootstrap);
+ err = pthread_create (&t, NULL, machdev_server, NULL);
+ if (err)
+ error (1, err, "Creating machdev thread");
+ pthread_detach (t);
+ }
+ else
+ {
+ task_get_bootstrap_port (mach_task_self (), &bootstrap);
+ if (bootstrap == MACH_PORT_NULL)
+ error (1, 0, "must be started as a translator");
+ }
/* Initialize netfs and start the translator. */
netfs_init ();
err = maptime_map (0, 0, &pcifs_maptime);
if (err)
+ err = maptime_map (1, 0, &pcifs_maptime);
+ if (err)
error (1, err, "mapping time");
/* Start the PCI system: NB: pciaccess will choose x86 first and take lock */
@@ -93,8 +248,18 @@ main (int argc, char **argv)
if (err)
error (1, err, "Starting the PCI system");
- /* Create the PCI filesystem */
- err = init_file_system (netfs_startup (bootstrap, O_READ), fs);
+ if (disk_server_task != MACH_PORT_NULL)
+ machdev_trivfs_server(bootstrap);
+ /* Timer started, quickly do all these next, before we call rump_init */
+
+ /* Create the root node first */
+ err = init_root_node ();
+ if (err)
+ error (1, err, "Creating the root node");
+
+ pcifs_startup (bootstrap, O_READ);
+
+ err = init_file_system (fs);
if (err)
error (1, err, "Creating the PCI filesystem");
@@ -108,13 +273,19 @@ main (int argc, char **argv)
if (err)
error (1, err, "Setting permissions");
+ err = pthread_create (&nt, NULL, netfs_server_func, NULL);
+ if (err)
+ error (1, err, "Creating netfs loop thread");
+ pthread_detach (nt);
+
/*
* Ask init to tell us when the system is going down,
* so we can try to be friendly to our correspondents on the network.
*/
arrange_shutdown_notification ();
- netfs_server_loop (); /* Never returns. */
-
+ /* Let the other threads do their job */
+ pthread_exit(NULL);
+ /* Never reached */
return 0;
}
diff --git a/pci-arbiter/options.c b/pci-arbiter/options.c
index 5767ad27..141c69e3 100644
--- a/pci-arbiter/options.c
+++ b/pci-arbiter/options.c
@@ -241,6 +241,15 @@ parse_opt (int opt, char *arg, struct argp_state *state)
case 'n':
h->ncache_len = atoi (arg);
break;
+ case 'T':
+ h->disk_server_task = atoi (arg);
+ break;
+ case 'H':
+ h->host_priv_port = atoi (arg);
+ break;
+ case 'P':
+ h->dev_master_port = atoi (arg);
+ break;
case ARGP_KEY_INIT:
/* Initialize our parsing state. */
h = malloc (sizeof (struct parse_hook));
@@ -250,6 +259,9 @@ parse_opt (int opt, char *arg, struct argp_state *state)
h->permsets = 0;
h->num_permsets = 0;
h->ncache_len = NODE_CACHE_MAX;
+ h->disk_server_task = MACH_PORT_NULL;
+ h->host_priv_port = MACH_PORT_NULL;
+ h->dev_master_port = MACH_PORT_NULL;
err = parse_hook_add_set (h);
if (err)
FAIL (err, 1, err, "option parsing");
@@ -286,6 +298,11 @@ parse_opt (int opt, char *arg, struct argp_state *state)
/* Set cache len */
fs->params.node_cache_max = h->ncache_len;
+ /* Set bootstrap ports */
+ fs->params.disk_server_task = h->disk_server_task;
+ _hurd_host_priv = h->host_priv_port;
+ _hurd_device_master = h->dev_master_port;
+
if (fs->root)
{
/*
@@ -364,6 +381,8 @@ netfs_append_args (char **argz, size_t * argz_len)
if (fs->params.node_cache_max != NODE_CACHE_MAX)
ADD_OPT ("--ncache=%u", fs->params.node_cache_max);
+ if (fs->params.disk_server_task != MACH_PORT_NULL)
+ ADD_OPT ("--disk-server-task=%lu", fs->params.disk_server_task);
#undef ADD_OPT
return err;
}
diff --git a/pci-arbiter/options.h b/pci-arbiter/options.h
index 8e5a9da4..292d2963 100644
--- a/pci-arbiter/options.h
+++ b/pci-arbiter/options.h
@@ -45,6 +45,11 @@ struct parse_hook
/* Node cache length */
size_t ncache_len;
+
+ /* Mach ports */
+ mach_port_t disk_server_task;
+ mach_port_t host_priv_port;
+ mach_port_t dev_master_port;
};
/* Lwip translator options. Used for both startup and runtime. */
@@ -65,6 +70,9 @@ static const struct argp_option options[] = {
{0, 0, 0, 0, "Global configuration options:", 3},
{"ncache", 'n', "LENGTH", 0,
"Node cache length. " STR (NODE_CACHE_MAX) " by default"},
+ {"disk-server-task", 'T', "TASK", 0, "Task for bootstrapping disk server"},
+ {"host-priv-port", 'H', "PORT", 0, "Port for bootstrapping host"},
+ {"dev-master-port", 'P', "PORT", 0, "Port for bootstrapping device master"},
{0}
};
diff --git a/pci-arbiter/pcifs.c b/pci-arbiter/pcifs.c
index e09bdd13..699d5942 100644
--- a/pci-arbiter/pcifs.c
+++ b/pci-arbiter/pcifs.c
@@ -92,20 +92,11 @@ alloc_file_system (struct pcifs ** fs)
}
error_t
-init_file_system (file_t underlying_node, struct pcifs * fs)
+init_root_node (void)
{
- error_t err;
struct node *np;
io_statbuf_t *underlying_node_stat = &underlying_stat;
- if (underlying_node)
- {
- /* Initialize status from underlying node. */
- err = io_stat (underlying_node, underlying_node_stat);
- if (err)
- return err;
- }
-
np = netfs_make_node_alloc (sizeof (struct netnode));
if (!np)
return ENOMEM;
@@ -120,19 +111,29 @@ init_file_system (file_t underlying_node, struct pcifs * fs)
fshelp_touch (&np->nn_stat, TOUCH_ATIME | TOUCH_MTIME | TOUCH_CTIME,
pcifs_maptime);
+ netfs_root_node = np;
+ return 0;
+}
+
+error_t
+init_file_system (struct pcifs * fs)
+{
+ error_t err;
+ struct node *np = netfs_root_node;
+
fs->entries = calloc (1, sizeof (struct pcifs_dirent));
if (!fs->entries)
- {
- return ENOMEM;
- }
+ return ENOMEM;
/* Create the root entry */
err =
create_dir_entry (-1, -1, -1, -1, -1, "", 0, np->nn_stat, np, 0,
fs->entries);
+ if (err)
+ return err;
fs->num_entries = 1;
- fs->root = netfs_root_node = np;
+ fs->root = np;
fs->root->nn->ln = fs->entries;
pthread_mutex_init (&fs->node_cache_lock, 0);
pthread_mutex_init (&fs->pci_conf_lock, 0);
diff --git a/pci-arbiter/pcifs.h b/pci-arbiter/pcifs.h
index 72cf2910..33a2b8c1 100644
--- a/pci-arbiter/pcifs.h
+++ b/pci-arbiter/pcifs.h
@@ -141,6 +141,9 @@ struct pcifs_params
/* The size of the node cache. */
size_t node_cache_max;
+ /* Bootstrap disk server task */
+ mach_port_t disk_server_task;
+
/* FS permissions. */
struct pcifs_perm *perms;
size_t num_perms;
@@ -202,7 +205,8 @@ extern volatile struct mapped_time_value *pcifs_maptime;
/* FS manipulation functions */
error_t alloc_file_system (struct pcifs **fs);
-error_t init_file_system (file_t underlying_node, struct pcifs *fs);
+error_t init_root_node (void);
+error_t init_file_system (struct pcifs *fs);
error_t create_fs_tree (struct pcifs *fs);
error_t fs_set_permissions (struct pcifs *fs);
error_t entry_check_perms (struct iouser *user, struct pcifs_dirent *e,
diff --git a/pci-arbiter/startup-ops.c b/pci-arbiter/startup-ops.c
deleted file mode 100644
index eb387fd9..00000000
--- a/pci-arbiter/startup-ops.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- Copyright (C) 2017 Free Software Foundation, Inc.
- Written by Michael I. Bushnell, p/BSG.
-
- This file is part of the GNU Hurd.
-
- The GNU Hurd is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2, or (at
- your option) any later version.
-
- The GNU Hurd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with the GNU Hurd. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <startup_notify_S.h>
-
-#include <pciaccess.h>
-#include <hurd/netfs.h>
-
-#include "startup.h"
-
-/* The system is going down. Call netfs_shutdown() */
-error_t
-S_startup_dosync (mach_port_t handle)
-{
- struct port_info *inpi = ports_lookup_port (netfs_port_bucket, handle,
- pci_shutdown_notify_class);
-
- if (!inpi)
- return EOPNOTSUPP;
-
- // Free all libpciaccess resources
- pci_system_cleanup ();
-
- ports_port_deref (inpi);
-
- return netfs_shutdown (FSYS_GOAWAY_FORCE);
-}