diff options
author | Damien Zammit <damien@zamaudio.com> | 2020-08-01 14:40:02 +1000 |
---|---|---|
committer | Damien Zammit <damien@zamaudio.com> | 2020-11-07 17:42:31 +1100 |
commit | 2225054243dc391e9bf13eebd95d099730fd5319 (patch) | |
tree | 52fd5d897eaeae0dbf54d2ccd6d2a4cccab19ca3 | |
parent | cf99ce09b4b2487d557860b794dbd1b57a9f035b (diff) |
libmachdev: Install as translator when bootstrapping
-rw-r--r-- | libmachdev/trivfs_server.c | 103 |
1 files changed, 88 insertions, 15 deletions
diff --git a/libmachdev/trivfs_server.c b/libmachdev/trivfs_server.c index c5407145..cff464e0 100644 --- a/libmachdev/trivfs_server.c +++ b/libmachdev/trivfs_server.c @@ -40,10 +40,13 @@ #include "notify_S.h" #include "fsys_S.h" #include "mach_i386_S.h" +#include "io_S.h" #include "trivfs_server.h" #include "libmachdev/machdev.h" +#define DEV_RUMPDISK "/dev/rumpdisk" + struct port_bucket *port_bucket; /* Trivfs hooks. */ @@ -54,18 +57,51 @@ int trivfs_support_write = 0; int trivfs_support_exec = 0; int trivfs_allow_open = O_READ | O_WRITE; -/* Our port classes. */ -struct port_class *trivfs_protid_class; +/* Our port classes */ struct port_class *trivfs_cntl_class; +struct port_class *trivfs_protid_class; + +/* Our control struct */ +struct trivfs_control *control; + +/* Are we providing bootstrap translator? */ +static boolean_t bootstrapped; + +/* Our underlying node for bootstrap */ +static mach_port_t underlying; /* Our control port */ -static mach_port_t machdev_ctl; +static mach_port_t control_port; /* Startup and shutdown notifications management */ struct port_class *machdev_shutdown_notify_class; static void arrange_shutdown_notification (void); +static void +install_as_translator (mach_port_t bootport) +{ + error_t err; + + underlying = file_name_lookup (DEV_RUMPDISK, O_NOTRANS, 0); + if (! MACH_PORT_VALID (underlying)) + { + if (errno == ENOENT) + mach_print("Missing DEV\n"); + mach_print("Error with DEV\n"); + return; + } + + /* Install translator */ + err = file_set_translator (underlying, + 0, FS_TRANS_SET, 0, + NULL, 0, + bootport, MACH_MSG_TYPE_COPY_SEND); + assert_perror_backtrace (err); + + mach_print("Set translator on DEV\n"); +} + /* Implementation of notify interface */ kern_return_t do_mach_notify_port_deleted (struct port_info *pi, @@ -209,15 +245,16 @@ trivfs_S_fsys_startup (mach_port_t bootport, mach_port_t *realnode, mach_msg_type_name_t *realnodetype) { - machdev_ctl = cntl; + mach_print("XXX FSYS_STARTUP XXX\n"); + control_port = cntl; *realnode = MACH_PORT_NULL; *realnodetype = MACH_MSG_TYPE_MOVE_SEND; return 0; } kern_return_t -trivfs_S_fsys_init (struct trivfs_control *tc, +trivfs_S_fsys_init (struct trivfs_control *fsys, mach_port_t reply, mach_msg_type_name_t replytype, mach_port_t procserver, mach_port_t authhandle) @@ -229,10 +266,13 @@ trivfs_S_fsys_init (struct trivfs_control *tc, mach_port_t root; retry_type retry; string_t retry_name; + mach_port_t right = MACH_PORT_NULL; - err = fsys_getroot (machdev_ctl, MACH_PORT_NULL, MACH_MSG_TYPE_COPY_SEND, - idlist, 3, idlist, 3, 0, - &retry, retry_name, &root); + mach_print("XXX FSYS_INIT XXX\n"); + + err = fsys_getroot (control_port, MACH_PORT_NULL, MACH_MSG_TYPE_COPY_SEND, + idlist, 3, idlist, 3, 0, + &retry, retry_name, &root); assert_perror_backtrace (err); assert_backtrace (retry == FS_RETRY_NORMAL); assert_backtrace (retry_name[0] == '\0'); @@ -249,6 +289,17 @@ trivfs_S_fsys_init (struct trivfs_control *tc, _hurd_init (0, NULL, portarray, INIT_PORT_MAX, NULL, 0); arrange_shutdown_notification (); + + /* Install the bootstrap port on /dev/something so users + * can still access the bootstrapped device */ + if (bootstrapped) + { + mach_print("Installing translator\n"); + right = ports_get_send_right (&control->pi); + install_as_translator (right); + mach_port_deallocate (mach_task_self (), right); + control->underlying = underlying; + } return 0; } @@ -326,20 +377,14 @@ resume_bootstrap_server(mach_port_t server_task, const char *server_name) error_t err; mach_port_t right; mach_port_t dev, cons; - struct port_info *server_info; assert_backtrace (server_task != MACH_PORT_NULL); - err = ports_create_port (trivfs_cntl_class, port_bucket, - sizeof (struct port_info), &server_info); - assert_perror_backtrace (err); - right = ports_get_send_right (server_info); - ports_port_deref (server_info); + right = ports_get_send_right (&control->pi); err = task_set_special_port (server_task, TASK_BOOTSTRAP_PORT, right); assert_perror_backtrace (err); err = mach_port_deallocate (mach_task_self (), right); assert_perror_backtrace (err); - err = task_resume (server_task); assert_perror_backtrace (err); @@ -363,17 +408,24 @@ machdev_trivfs_init(mach_port_t bootstrap_resume_task, const char *name, mach_po port_bucket = ports_create_bucket (); trivfs_cntl_class = ports_create_class (trivfs_clean_cntl, 0); trivfs_protid_class = ports_create_class (trivfs_clean_protid, 0); + trivfs_create_control (MACH_PORT_NULL, trivfs_cntl_class, port_bucket, + trivfs_protid_class, 0, &control); if (bootstrap_resume_task != MACH_PORT_NULL) { resume_bootstrap_server(bootstrap_resume_task, name); *bootstrap = MACH_PORT_NULL; + /* We need to install as a translator later */ + bootstrapped = TRUE; } else { task_get_bootstrap_port (mach_task_self (), bootstrap); if (*bootstrap == MACH_PORT_NULL) error (1, 0, "must be started as a translator"); + + /* We do not need to install as a translator later */ + bootstrapped = FALSE; } return 0; @@ -438,6 +490,22 @@ demuxer (mach_msg_header_t *inp, mach_msg_header_t *outp) return FALSE; } +kern_return_t +trivfs_S_io_stat (struct trivfs_protid *cred, + mach_port_t reply, + mach_msg_type_name_t replytype, + struct stat *st) +{ + if (! trivfs_fsid) + trivfs_fsid = getpid(); + + st->st_fstype = trivfs_fstype; + st->st_fsid = trivfs_fsid; + st->st_mode = (st->st_mode & ~S_IFMT & ~S_ITRANS) | S_IFBLK | S_IROOT; + + return 0; +} + void trivfs_modify_stat (struct trivfs_protid *cred, io_statbuf_t *stat) { @@ -451,6 +519,7 @@ machdev_trivfs_server(mach_port_t bootstrap) if (bootstrap != MACH_PORT_NULL) { + /* This path is executed when a parent exists */ err = trivfs_startup (bootstrap, 0, trivfs_cntl_class, port_bucket, trivfs_protid_class, port_bucket, &fsys); @@ -458,6 +527,10 @@ machdev_trivfs_server(mach_port_t bootstrap) if (err) error (1, err, "Contacting parent"); } + else + { + fsys = control; + } /* Launch. */ do |