diff options
-rw-r--r-- | libtrivfs/startup.c | 69 | ||||
-rw-r--r-- | libtrivfs/trivfs.h | 11 | ||||
-rw-r--r-- | storeio/storeio.c | 46 |
3 files changed, 117 insertions, 9 deletions
diff --git a/libtrivfs/startup.c b/libtrivfs/startup.c index 56ef02c4..d5767df2 100644 --- a/libtrivfs/startup.c +++ b/libtrivfs/startup.c @@ -86,3 +86,72 @@ trivfs_startup(mach_port_t bootstrap, int flags, return err; } + +/* Start in debug mode, no need to be called by settrans. Common options are + the same as in trivfs_startup. FILE_NAME is the path of the node where the + translator is set*/ +error_t +trivfs_startup_debug(const char *file_name, + struct port_class *control_class, + struct port_bucket *control_bucket, + struct port_class *protid_class, + struct port_bucket *protid_bucket, + struct trivfs_control **control) +{ + mach_port_t underlying, right, goaway; + struct trivfs_control *fsys; + error_t err = + trivfs_create_control (MACH_PORT_NULL, + control_class, control_bucket, + protid_class, protid_bucket, + &fsys); + + if (err) + return err; + + right = ports_get_send_right (fsys); + goaway = ports_get_send_right (fsys); + + /* Start ourselves as transpator instead of replying to settrans */ + underlying = file_name_lookup(file_name, 0, 0); + if (underlying == MACH_PORT_NULL) + err = errno; + else + err = file_set_translator(underlying, 0, FS_TRANS_SET, 0, "", 0, + right, MACH_MSG_TYPE_COPY_SEND); + mach_port_deallocate (mach_task_self (), right); + + if (! err) + fsys->underlying = underlying; + + ports_port_deref (fsys); + + /* Pass back what we got, unless the caller doesn't want it. */ + if (!err && control) + *control = fsys; + + /* don't mark us as important and install a SIGTERM handler, so we can be + * easily killed by Ctrl-C */ + void handler_sigterm(int signum) + { + error_t ee; + ee = fsys_goaway(goaway, 0); + if (ee == ESUCCESS) + { + mach_port_deallocate (mach_task_self (), goaway); + } + else if (ee != EBUSY) + { + /* Not nice */ + error(99, err, "fsys_goaway"); + } + /* else the translator is busy, please retry */ + } + + struct sigaction sa; + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = handler_sigterm; + if (sigaction(SIGTERM, &sa, NULL) < 0) + err = errno; + return err; +} diff --git a/libtrivfs/trivfs.h b/libtrivfs/trivfs.h index c9e5defa..4802f5fc 100644 --- a/libtrivfs/trivfs.h +++ b/libtrivfs/trivfs.h @@ -174,6 +174,17 @@ error_t trivfs_startup (mach_port_t bootstrap, int flags, struct port_bucket *protid_bucket, struct trivfs_control **control); +/* Start in debug mode, no need to be called by settrans. Common options are + the same as in trivfs_startup. FILE_NAME is the path of the node where the + translator is set*/ +error_t +trivfs_startup_debug(const char *file_name, + struct port_class *control_class, + struct port_bucket *control_bucket, + struct port_class *protid_class, + struct port_bucket *protid_bucket, + struct trivfs_control **control); + /* Create a new trivfs control port, with underlying node UNDERLYING, and return it in CONTROL. CONTROL_CLASS & CONTROL_BUCKET are passed to the ports library to create the control port, and PROTID_CLASS & diff --git a/storeio/storeio.c b/storeio/storeio.c index 872b388f..5b8db0d3 100644 --- a/storeio/storeio.c +++ b/storeio/storeio.c @@ -24,6 +24,7 @@ #include <argp.h> #include <argz.h> #include <sys/sysmacros.h> +#include <stdbool.h> #include <hurd.h> #include <hurd/ports.h> @@ -42,6 +43,8 @@ static struct argp_option options[] = {"no-file-io", 'F', 0, 0,"Never perform io via plain file io RPCs"}, {"no-fileio", 0, 0, OPTION_ALIAS | OPTION_HIDDEN}, {"enforced", 'e', 0, 0,"Never reveal underlying devices, even to root"}, + {"debug", 'd', "PATH", 0, + "Launch a standalone translator, for debug purposes"}, {"rdev", 'n', "ID", 0, "The stat rdev number for this node; may be either a" " single integer, or of the form MAJOR,MINOR"}, @@ -50,7 +53,10 @@ static struct argp_option options[] = static const char doc[] = "Translator for devices and other stores"; const char *argp_program_version = STANDARD_HURD_VERSION (storeio); - + +static bool debug=false; +static char *debug_fname=NULL; + /* Desired store parameters specified by the user. */ struct storeio_argp_params { @@ -97,6 +103,16 @@ parse_opt (int key, char *arg, struct argp_state *state) } break; + case 'd': + { + debug=true; + char *new = strdup (arg); + if (new == NULL) + return ENOMEM; + debug_fname = new; + } + break; + case ARGP_KEY_INIT: /* Now store_argp's parser will get to initialize its state. The default_type member is our input parameter to it. */ @@ -135,14 +151,26 @@ main (int argc, char *argv[]) params.dev = &device; argp_parse (&argp, argc, argv, 0, 0, ¶ms); - task_get_bootstrap_port (mach_task_self (), &bootstrap); - if (bootstrap == MACH_PORT_NULL) - error (2, 0, "Must be started as a translator"); - - /* Reply to our parent */ - err = trivfs_startup (bootstrap, 0, 0, 0, 0, 0, &storeio_fsys); - if (err) - error (3, err, "trivfs_startup"); + if (debug) + { + if (debug_fname) + err = trivfs_startup_debug (debug_fname, 0, 0, 0, 0, &storeio_fsys); + else + error (3, err, "missing translated node"); + if (err) + error (3, err, "trivfs_startup_debug failed"); + } + else + { + task_get_bootstrap_port (mach_task_self (), &bootstrap); + if (bootstrap == MACH_PORT_NULL) + error (2, 0, "Must be started as a translator"); + + /* Reply to our parent */ + err = trivfs_startup (bootstrap, 0, 0, 0, 0, 0, &storeio_fsys); + if (err) + error (3, err, "trivfs_startup"); + } storeio_fsys->hook = &device; |