From 3079e4f3c977098762651c98409925096669b86a Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Boric Date: Thu, 29 Dec 2016 08:19:48 +0000 Subject: [PATCH] rump: import rump server This includes the worst POSIX semaphore emulation ever created by mankind. It's that bad. --- distrib/sets/lists/minix-base/mi | 4 + distrib/sets/lists/minix-man/mi | 4 + usr.bin/Makefile | 4 +- usr.bin/rump_allserver/Makefile | 21 + usr.bin/rump_allserver/rump_allserver.1 | 230 +++++++ usr.bin/rump_allserver/rump_allserver.c | 801 ++++++++++++++++++++++++ usr.bin/rump_halt/Makefile | 13 + usr.bin/rump_halt/rump.halt.1 | 79 +++ usr.bin/rump_halt/rump.halt.c | 96 +++ usr.bin/rump_server/Makefile | 18 + usr.bin/rump_wmd/Makefile | 7 + usr.bin/rump_wmd/rump_wmd.1 | 98 +++ usr.bin/rump_wmd/rump_wmd.sh | 161 +++++ 13 files changed, 1534 insertions(+), 2 deletions(-) mode change 100644 => 100755 usr.bin/Makefile create mode 100755 usr.bin/rump_allserver/Makefile create mode 100644 usr.bin/rump_allserver/rump_allserver.1 create mode 100755 usr.bin/rump_allserver/rump_allserver.c create mode 100755 usr.bin/rump_halt/Makefile create mode 100644 usr.bin/rump_halt/rump.halt.1 create mode 100644 usr.bin/rump_halt/rump.halt.c create mode 100755 usr.bin/rump_server/Makefile create mode 100644 usr.bin/rump_wmd/Makefile create mode 100644 usr.bin/rump_wmd/rump_wmd.1 create mode 100755 usr.bin/rump_wmd/rump_wmd.sh diff --git a/distrib/sets/lists/minix-base/mi b/distrib/sets/lists/minix-base/mi index 4e6306852..12494819e 100644 --- a/distrib/sets/lists/minix-base/mi +++ b/distrib/sets/lists/minix-base/mi @@ -472,6 +472,10 @@ ./usr/bin/rotate minix-base ./usr/bin/rput minix-base ./usr/bin/rsh minix-base +./usr/bin/rump.halt minix-base rump +./usr/bin/rump_allserver minix-base rump +./usr/bin/rump_server minix-base rump +./usr/bin/rump_wmd minix-base rump ./usr/bin/rz minix-base ./usr/bin/screendump minix-base ./usr/bin/sdiff minix-base diff --git a/distrib/sets/lists/minix-man/mi b/distrib/sets/lists/minix-man/mi index 7316f8bbb..8659ba19f 100644 --- a/distrib/sets/lists/minix-man/mi +++ b/distrib/sets/lists/minix-man/mi @@ -327,6 +327,10 @@ ./usr/man/man1/rmd160.1 minix-man ./usr/man/man1/rmdir.1 minix-man ./usr/man/man1/rsh.1 minix-man +./usr/man/man1/rump.halt.1 minix-man rump +./usr/man/man1/rump_allserver.1 minix-man rump +./usr/man/man1/rump_server.1 minix-man rump +./usr/man/man1/rump_wmd.1 minix-man rump ./usr/man/man1/rz.1 minix-man ./usr/man/man1/sdiff.1 minix-man ./usr/man/man1/sed.1 minix-man diff --git a/usr.bin/Makefile b/usr.bin/Makefile old mode 100644 new mode 100755 index 01e633bd2..12a2ae9d3 --- a/usr.bin/Makefile +++ b/usr.bin/Makefile @@ -48,8 +48,8 @@ SUBDIR+= apropos whatis .endif .if (${MKRUMP} != "no") -#SUBDIR+= rump_allserver rump_dhcpclient rump_halt rump_server shmif_dumpbus \ -# rump_wmd +SUBDIR+= rump_allserver rump_halt rump_server \ + rump_wmd .endif .if (${MKBSDGREP} != "no") diff --git a/usr.bin/rump_allserver/Makefile b/usr.bin/rump_allserver/Makefile new file mode 100755 index 000000000..d777cf491 --- /dev/null +++ b/usr.bin/rump_allserver/Makefile @@ -0,0 +1,21 @@ +# $NetBSD: Makefile,v 1.7 2013/11/13 17:47:27 pooka Exp $ +# + +PROG= rump_allserver +MLINKS+=rump_allserver.1 rump_server.1 + +RUMPTOP=${.CURDIR}/../../sys/rump + +.include "${RUMPTOP}/dev/Makefile.rumpdevcomp" +.include "${RUMPTOP}/fs/Makefile.rumpfscomp" +.include "${RUMPTOP}/kern/Makefile.rumpkerncomp" +.include "${RUMPTOP}/net/Makefile.rumpnetcomp" + +LDADD+= ${RUMPDEVLDADD} ${RUMPFSLDADD} ${RUMPKERNLDADD} ${RUMPNETLDADD} +.if defined(__MINIX) +LDADD+= -lrumpdev -lrumpvfs -lrumpnet -lrump -lrumpuser +.else +LDADD+= -lrumpdev -lrumpvfs -lrumpnet -lrump -lrumpuser -lpthread +.endif + +.include diff --git a/usr.bin/rump_allserver/rump_allserver.1 b/usr.bin/rump_allserver/rump_allserver.1 new file mode 100644 index 000000000..dc8c0b675 --- /dev/null +++ b/usr.bin/rump_allserver/rump_allserver.1 @@ -0,0 +1,230 @@ +.\" $NetBSD: rump_allserver.1,v 1.21 2014/01/16 00:32:48 pooka Exp $ +.\" +.\" Copyright (c) 2010 Antti Kantee. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.Dd January 15, 2014 +.Dt RUMP_SERVER 1 +.Os +.Sh NAME +.Nm rump_server , +.Nm rump_allserver +.Nd rump kernel server +.Sh SYNOPSIS +.Nm +.Op Fl s +.Op Fl c Ar ncpu +.Op Fl d Ar drivespec +.Op Fl l Ar library +.Op Fl m Ar module +.Ar url +.Sh DESCRIPTION +The +.Nm +utility is used to provide a rump kernel service. +Clients can use the system calls provided by +.Nm +via +.Ar url . +.Pp +The difference between +.Nm +and +.Nm rump_allserver +is that +.Nm +offers only a minimalistic set of features, +while +.Nm rump_allserver +provides all rump kernel components which were available when the +system was built. +At execution time it is possible to load components from the command +line as described in the options section. +.Bl -tag -width indent +.It Fl c Ar ncpu +Configure +.Ar ncpu +virtual CPUs on SMP-capable archs. +By default, the number of CPUs equals the number of CPUs on the +host. +.It Fl d Ar drivespec +The argument +.Ar drivespec +maps a host file in the rump kernel fs namespace. +The string +.Ar drivespec +must be of comma-separated +.Dq name=value +format and must contain the following tokens: +.Bl -tag -width hostpath1234 +.It Ar key +Block device path in rump kernel namespace. +This must be specified according to the rules for a key in +.Xr rump_etfs 3 . +.It Ar hostpath +Host file used for storage. +If the file does not exist, it will be created. +.It Ar size +Size of the mapping. +Similar to +.Xr dd 1 , +this argument accepts a suffix as the multiplier for the number. +The special value +.Dq host +indicates that the current size of +.Ar hostpath +will be used. +In this case it is assumed that +.Ar hostpath +exists and is a regular file. +.It OR +.It Ar disklabel +Use a disklabel partition identifier to specify the offset and size +of the mapping. +.Ar hostpath +must contain an existing and valid disklabel within the first 64k. +.El +.Pp +The following are optional: +.Bl -tag -width hostpath1234 +.It Ar offset +Offset of the mapping. +The window into +.Ar hostpath +therefore is +.Fa [ offset , offset+size ] . +In case this parameter is not given, the default value 0 is used. +.It Ar type +The type of file that +.Ar key +is exposed as within the rump kernel. +The possibilities are +.Dq blk , +.Dq chr , +and +.Dq reg +for block device, character device and regular file, respectively. +The default is a block device. +.Pp +Note: the contents of block devices are cached in the rump kernel's +buffer cache. +To avoid cache incoherency, it is advisable not to access a file +through the host namespace while it is mapped as a block device in +a rump kernel. +.El +.Pp +In case +.Ar hostpath +does not exist, it will be created as a regular file with mode +0644 (plus any restrictions placed by umask). +In case +.Ar hostpath +is a regular file and is not large enough to accommodate the +specified size, it will be extended to the specified size. +.It Fl l Ar library +Call +.Fn dlopen +on library before initializing the rump kernel. +In case +.Ar library +provides a kernel module, it will appear as a builtin module in the +rump kernel. +Any rump kernel component present in +.Ar library +will also be initialized. +.Pp +The argument +.Ar library +can contain a full path or a filename, in which case the standard +dynamic library search path will be used. +By default, lazy resolution is used, and may result in a runtime +error due to missing components. +To test a configuration, run +.Nm +with +.Ev LD_BIND_NOW=1 +(see examples). +.It Fl m Ar module +Load and link a kernel module after the rump kernel is initialized. +For this to work, the rump kernel must include the vfs faction, +since the module is loaded using kernel vfs code (see +.Sx EXAMPLES ) . +.It Fl r Ar total_ram +Sets the limit of kernel memory allocatable by the server to +.Ar total_ram +as opposed to the default which allows the server to allocate as much +memory as the host will give it. +This parameter is especially useful for VFS servers, since by +default the virtual file system will attempt to consume as much +memory as it can, and accessing large files can cause an excessive +amount of memory to be used as file system cache. +.It Fl s +Do not detach from the terminal. +By default, +.Nm +detaches from the terminal once the service is running on +.Ar url . +.It Fl v +Set bootverbose. +.El +.Pp +After use, +.Nm +can be made to exit using +.Xr rump.halt 1 . +.Sh EXAMPLES +Start a server and load the tmpfs file system module, and halt the +server immediately afterwards: +.Bd -literal -offset indent +$ rump_server -lrumpvfs -m /modules/tmpfs.kmod unix://sock +$ env RUMP_SERVER=unix://sock rump.halt +.Ed +.Pp +Start a server with the one gigabyte host file +.Pa dk.img +mapped as the block device +.Pa /dev/dk +in the rump kernel. +.Bd -literal -offset indent +$ rump_allserver -d key=/dev/dk,hostpath=dk.img,size=1g unix://sock +.Ed +.Pp +Start a server which listens on INADDR_ANY port 3755 +.Bd -literal -offset indent +$ rump_server tcp://0:3755/ +.Ed +.Pp +Test that a configuration contains all of the necessary components: +.Bd -literal -offset indent +$ env LD_BIND_NOW=1 rump_server -lrumpvfs -lrumpfs_ffs unix://tsock +.Ed +.Pp +Start a FFS server with a 16MB kernel memory limit. +.Bd -literal -offset indent +$ rump_server -lrumpfs_ffs [...] -r 16m unix://ffs +.Ed +.Sh SEE ALSO +.Xr rump.halt 1 , +.Xr dlopen 3 , +.Xr rump 3 , +.Xr rump_sp 7 diff --git a/usr.bin/rump_allserver/rump_allserver.c b/usr.bin/rump_allserver/rump_allserver.c new file mode 100755 index 000000000..b603e97a1 --- /dev/null +++ b/usr.bin/rump_allserver/rump_allserver.c @@ -0,0 +1,801 @@ +/* $NetBSD: rump_allserver.c,v 1.39 2015/04/16 10:05:43 pooka Exp $ */ + +/*- + * Copyright (c) 2010, 2011 Antti Kantee. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +#ifndef lint +__RCSID("$NetBSD: rump_allserver.c,v 1.39 2015/04/16 10:05:43 pooka Exp $"); +#endif /* !lint */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#if defined(__minix) + +/* + * XXX: This is the worst POSIX semaphore emulation ever created by mankind. + */ + +#define sem_t volatile int +#define sem_init(a,b,c) *a = 1 +#define sem_post(a) *a = 0 +#define sem_wait(a) do { sleep(1); } while (*a); +#endif + +__dead static void +usage(void) +{ + +#ifndef HAVE_GETPROGNAME +#define getprogname() "rump_server" +#endif + fprintf(stderr, "usage: %s [-s] [-c ncpu] [-d drivespec] [-l libs] " + "[-m modules] bindurl\n", getprogname()); + exit(1); +} + +__dead static void +diedie(int sflag, const char *reason, int error, const char *errstr) +{ + + if (reason != NULL) + fputs(reason, stderr); + if (errstr) { + fprintf(stderr, ": %s", errstr); + } + fputc('\n', stderr); + if (!sflag) + rump_daemonize_done(error); + exit(1); +} + +__dead static void +die(int sflag, int error, const char *reason) +{ + + diedie(sflag, reason, error, error == 0 ? NULL : strerror(error)); +} + +__dead static void +die_rumperr(int sflag, int error, const char *reason) +{ + + diedie(sflag, reason, error, error == 0 ? NULL : rump_strerror(error)); +} + +static sem_t sigsem; +static void +sigreboot(int sig) +{ + + sem_post(&sigsem); +} + +static const char *const disktokens[] = { +#define DKEY 0 + "key", +#define DFILE 1 + "hostpath", +#define DSIZE 2 +#define DSIZE_E -1 + "size", +#define DOFFSET 3 + "offset", +#define DLABEL 4 + "disklabel", +#define DTYPE 5 + "type", + NULL +}; + +struct etfsreg { + const char *key; + const char *hostpath; + off_t flen; + off_t foffset; + char partition; + enum rump_etfs_type type; +}; + +struct etfstype { + const char *name; + enum rump_etfs_type type; +} etfstypes[] = { + { "blk", RUMP_ETFS_BLK }, + { "chr", RUMP_ETFS_CHR }, + { "reg", RUMP_ETFS_REG }, +}; + +static void processlabel(int, int, int, off_t *, off_t *); + +#define ALLOCCHUNK 32 + +int +main(int argc, char *argv[]) +{ + const char *serverurl; + struct etfsreg *etfs = NULL; + unsigned netfs = 0, curetfs = 0; + int error; + int ch, sflag, onthepath; + unsigned i; + char **modarray = NULL, **libarray = NULL; + unsigned nmods = 0, curmod = 0, nlibs = 0, curlib = 0, libidx; + unsigned liblast = -1; /* XXXgcc */ + + setprogname(argv[0]); + sflag = 0; + while ((ch = getopt(argc, argv, "c:d:l:m:r:sv")) != -1) { + switch (ch) { + case 'c': + setenv("RUMP_NCPU", optarg, 1); + break; + case 'd': { + char *options, *value; + char *key, *hostpath; + long long flen, foffset; + char partition; + int ftype; + + flen = foffset = 0; + partition = 0; + key = hostpath = NULL; + ftype = -1; + options = optarg; + while (*options) { + switch (getsubopt(&options, + __UNCONST(disktokens), &value)) { + case DKEY: + if (key != NULL) { + fprintf(stderr, + "key already given\n"); + usage(); + } + key = value; + break; + + case DFILE: + if (hostpath != NULL) { + fprintf(stderr, + "hostpath already given\n"); + usage(); + } + hostpath = value; + break; + + case DSIZE: + if (flen != 0) { + fprintf(stderr, + "size already given\n"); + usage(); + } + if (strcmp(value, "host") == 0) { + if (foffset != 0) { + fprintf(stderr, + "cannot specify " + "offset with " + "size=host\n"); + usage(); + } + flen = DSIZE_E; + } else { +#ifdef HAVE_STRSUFTOLL + /* XXX: off_t max? */ + flen = strsuftoll("-d size", + value, 0, LLONG_MAX); +#else + flen = strtoull(value, + NULL, 10); +#endif + } + break; + case DOFFSET: + if (foffset != 0) { + fprintf(stderr, + "offset already given\n"); + usage(); + } + if (flen == DSIZE_E) { + fprintf(stderr, "cannot " + "specify offset with " + "size=host\n"); + usage(); + } +#ifdef HAVE_STRSUFTOLL + /* XXX: off_t max? */ + foffset = strsuftoll("-d offset", value, + 0, LLONG_MAX); +#else + foffset = strtoull(value, NULL, 10); +#endif + break; + + case DLABEL: + if (foffset != 0 || flen != 0) { + fprintf(stderr, + "disklabel needs to be " + "used alone\n"); + usage(); + } + if (strlen(value) != 1 || + *value < 'a' || *value > 'z') { + fprintf(stderr, + "invalid label part\n"); + usage(); + } + partition = *value; + break; + + case DTYPE: + if (ftype != -1) { + fprintf(stderr, + "type already specified\n"); + usage(); + } + + for (i = 0; + i < __arraycount(etfstypes); + i++) { + if (strcmp(etfstypes[i].name, + value) == 0) + break; + } + if (i == __arraycount(etfstypes)) { + fprintf(stderr, + "invalid type %s\n", value); + usage(); + } + ftype = etfstypes[i].type; + break; + + default: + fprintf(stderr, "invalid dtoken\n"); + usage(); + break; + } + } + + if (key == NULL || hostpath == NULL || + (flen == 0 + && partition == 0 && ftype != RUMP_ETFS_REG)) { + fprintf(stderr, "incomplete drivespec\n"); + usage(); + } + if (ftype == -1) + ftype = RUMP_ETFS_BLK; + + if (netfs - curetfs == 0) { + etfs = realloc(etfs, + (netfs+ALLOCCHUNK)*sizeof(*etfs)); + if (etfs == NULL) + die(1, errno, "realloc etfs"); + netfs += ALLOCCHUNK; + } + + etfs[curetfs].key = key; + etfs[curetfs].hostpath = hostpath; + etfs[curetfs].flen = flen; + etfs[curetfs].foffset = foffset; + etfs[curetfs].partition = partition; + etfs[curetfs].type = ftype; + curetfs++; + + break; + } + case 'l': + if (nlibs - curlib == 0) { + libarray = realloc(libarray, + (nlibs+ALLOCCHUNK) * sizeof(char *)); + if (libarray == NULL) + die(1, errno, "realloc"); + nlibs += ALLOCCHUNK; + } + libarray[curlib++] = optarg; + break; + case 'm': + if (nmods - curmod == 0) { + modarray = realloc(modarray, + (nmods+ALLOCCHUNK) * sizeof(char *)); + if (modarray == NULL) + die(1, errno, "realloc"); + nmods += ALLOCCHUNK; + } + modarray[curmod++] = optarg; + break; + case 'r': + setenv("RUMP_MEMLIMIT", optarg, 1); + break; + case 's': + sflag = 1; + break; + case 'v': + setenv("RUMP_VERBOSE", "1", 1); + break; + default: + usage(); + /*NOTREACHED*/ + } + } + + argc -= optind; + argv += optind; + + if (argc != 1) + usage(); + + /* + * Automatically "resolve" component dependencies, i.e. + * try to load libs in a loop until all are loaded or a + * full loop completes with no loads (latter case is an error). + */ + for (onthepath = 1, nlibs = curlib; onthepath && nlibs > 0;) { + onthepath = 0; + for (libidx = 0; libidx < curlib; libidx++) { + /* loaded already? */ + if (libarray[libidx] == NULL) + continue; + + /* try to load */ + liblast = libidx; + if (dlopen(libarray[libidx], + RTLD_LAZY|RTLD_GLOBAL) == NULL) { + char pb[MAXPATHLEN]; + /* try to mimic linker -l syntax */ + snprintf(pb, sizeof(pb), + "lib%s.so", libarray[libidx]); + if (dlopen(pb, RTLD_LAZY|RTLD_GLOBAL) == NULL) + continue; + } + + /* managed to load that one */ + libarray[libidx] = NULL; + nlibs--; + onthepath = 1; + } + } + if (nlibs > 0) { + fprintf(stderr, + "failed to load -libraries, last error from \"%s\":\n", + libarray[liblast]); + fprintf(stderr, " %s", dlerror()); + die(1, 0, NULL); + } + free(libarray); + + serverurl = argv[0]; + + if (!sflag) { + error = rump_daemonize_begin(); + if (error) + die_rumperr(1, error, "rump daemonize"); + } + + error = rump_init(); + if (error) + die_rumperr(sflag, error, "rump init failed"); + + /* load modules */ + for (i = 0; i < curmod; i++) { + struct rump_modctl_load ml; + +#define ETFSKEY "/module.mod" + if ((error = rump_pub_etfs_register(ETFSKEY, + modarray[0], RUMP_ETFS_REG)) != 0) + die_rumperr(sflag, + error, "module etfs register failed"); + memset(&ml, 0, sizeof(ml)); + ml.ml_filename = ETFSKEY; + /* + * XXX: since this is a syscall, error namespace depends + * on loaded emulations. revisit and fix. + */ + if (rump_sys_modctl(RUMP_MODCTL_LOAD, &ml) == -1) + die(sflag, errno, "module load failed"); + rump_pub_etfs_remove(ETFSKEY); +#undef ETFSKEY + } + free(modarray); + + /* register host drives */ + for (i = 0; i < curetfs; i++) { + struct stat sb; + off_t foffset, flen, fendoff; + int fd, oflags; + + oflags = etfs[i].flen == DSIZE_E ? 0 : O_CREAT; + fd = open(etfs[i].hostpath, O_RDWR | oflags, 0644); + if (fd == -1) + die(sflag, errno, "etfs hostpath open"); + + if (etfs[i].partition) { + processlabel(sflag, fd, etfs[i].partition - 'a', + &foffset, &flen); + } else { + foffset = etfs[i].foffset; + flen = etfs[i].flen; + } + + if (fstat(fd, &sb) == -1) + die(sflag, errno, "fstat etfs hostpath"); + if (flen == DSIZE_E) { + if (sb.st_size == 0) + die(sflag, EINVAL, "size=host, but cannot " + "query non-zero size"); + flen = sb.st_size; + } + fendoff = foffset + flen; + if (S_ISREG(sb.st_mode) && sb.st_size < fendoff) { + if (ftruncate(fd, fendoff) == -1) + die(sflag, errno, "truncate"); + } + close(fd); + + if ((error = rump_pub_etfs_register_withsize(etfs[i].key, + etfs[i].hostpath, etfs[i].type, foffset, flen)) != 0) + die_rumperr(sflag, error, "etfs register"); + } + + error = rump_init_server(serverurl); + if (error) + die_rumperr(sflag, error, "rump server init failed"); + + if (!sflag) + rump_daemonize_done(RUMP_DAEMONIZE_SUCCESS); + + sem_init(&sigsem, 0, 0); + signal(SIGTERM, sigreboot); + signal(SIGINT, sigreboot); + sem_wait(&sigsem); + + rump_sys_reboot(0, NULL); + /*NOTREACHED*/ + + return 0; +} + +/* + * Copyright (c) 1987, 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)disklabel.h 8.2 (Berkeley) 7/10/94 + */ + +#define RUMPSERVER_MAXPARTITIONS 22 +#define RUMPSERVER_DISKMAGIC ((uint32_t)0x82564557) /* magic */ +#define RUMPSERVER_DEVSHIFT 9 + +struct rumpserver_disklabel { + uint32_t d_magic; /* the magic number */ + uint16_t d_type; /* drive type */ + uint16_t d_subtype; /* controller/d_type specific */ + char d_typename[16]; /* type name, e.g. "eagle" */ + + /* + * d_packname contains the pack identifier and is returned when + * the disklabel is read off the disk or in-core copy. + * d_boot0 and d_boot1 are the (optional) names of the + * primary (block 0) and secondary (block 1-15) bootstraps + * as found in /usr/mdec. These are returned when using + * getdiskbyname(3) to retrieve the values from /etc/disktab. + */ + union { + char un_d_packname[16]; /* pack identifier */ + struct { + char *un_d_boot0; /* primary bootstrap name */ + char *un_d_boot1; /* secondary bootstrap name */ + } un_b; + } d_un; +#define d_packname d_un.un_d_packname +#define d_boot0 d_un.un_b.un_d_boot0 +#define d_boot1 d_un.un_b.un_d_boot1 + + /* disk geometry: */ + uint32_t d_secsize; /* # of bytes per sector */ + uint32_t d_nsectors; /* # of data sectors per track */ + uint32_t d_ntracks; /* # of tracks per cylinder */ + uint32_t d_ncylinders; /* # of data cylinders per unit */ + uint32_t d_secpercyl; /* # of data sectors per cylinder */ + uint32_t d_secperunit; /* # of data sectors per unit */ + + /* + * Spares (bad sector replacements) below are not counted in + * d_nsectors or d_secpercyl. Spare sectors are assumed to + * be physical sectors which occupy space at the end of each + * track and/or cylinder. + */ + uint16_t d_sparespertrack; /* # of spare sectors per track */ + uint16_t d_sparespercyl; /* # of spare sectors per cylinder */ + /* + * Alternative cylinders include maintenance, replacement, + * configuration description areas, etc. + */ + uint32_t d_acylinders; /* # of alt. cylinders per unit */ + + /* hardware characteristics: */ + /* + * d_interleave, d_trackskew and d_cylskew describe perturbations + * in the media format used to compensate for a slow controller. + * Interleave is physical sector interleave, set up by the + * formatter or controller when formatting. When interleaving is + * in use, logically adjacent sectors are not physically + * contiguous, but instead are separated by some number of + * sectors. It is specified as the ratio of physical sectors + * traversed per logical sector. Thus an interleave of 1:1 + * implies contiguous layout, while 2:1 implies that logical + * sector 0 is separated by one sector from logical sector 1. + * d_trackskew is the offset of sector 0 on track N relative to + * sector 0 on track N-1 on the same cylinder. Finally, d_cylskew + * is the offset of sector 0 on cylinder N relative to sector 0 + * on cylinder N-1. + */ + uint16_t d_rpm; /* rotational speed */ + uint16_t d_interleave; /* hardware sector interleave */ + uint16_t d_trackskew; /* sector 0 skew, per track */ + uint16_t d_cylskew; /* sector 0 skew, per cylinder */ + uint32_t d_headswitch; /* head switch time, usec */ + uint32_t d_trkseek; /* track-to-track seek, usec */ + uint32_t d_flags; /* generic flags */ +#define NDDATA 5 + uint32_t d_drivedata[NDDATA]; /* drive-type specific information */ +#define NSPARE 5 + uint32_t d_spare[NSPARE]; /* reserved for future use */ + uint32_t d_magic2; /* the magic number (again) */ + uint16_t d_checksum; /* xor of data incl. partitions */ + + /* filesystem and partition information: */ + uint16_t d_npartitions; /* number of partitions in following */ + uint32_t d_bbsize; /* size of boot area at sn0, bytes */ + uint32_t d_sbsize; /* max size of fs superblock, bytes */ + struct rumpserver_partition { /* the partition table */ + uint32_t p_size; /* number of sectors in partition */ + uint32_t p_offset; /* starting sector */ + union { + uint32_t fsize; /* FFS, ADOS: + filesystem basic fragment size */ + uint32_t cdsession; /* ISO9660: session offset */ + } __partition_u2; +#define p_fsize __partition_u2.fsize +#define p_cdsession __partition_u2.cdsession + uint8_t p_fstype; /* filesystem type, see below */ + uint8_t p_frag; /* filesystem fragments per block */ + union { + uint16_t cpg; /* UFS: FS cylinders per group */ + uint16_t sgs; /* LFS: FS segment shift */ + } __partition_u1; +#define p_cpg __partition_u1.cpg +#define p_sgs __partition_u1.sgs + } d_partitions[RUMPSERVER_MAXPARTITIONS]; /* actually may be more */ +}; + + +/* for swapping disklabel, so don't care about perf, just portability */ +#define bs32(x) \ + ((((x) & 0xff000000) >> 24)| \ + (((x) & 0x00ff0000) >> 8) | \ + (((x) & 0x0000ff00) << 8) | \ + (((x) & 0x000000ff) << 24)) +#define bs16(x) ((((x) & 0xff00) >> 8) | (((x) & 0x00ff) << 8)) + +/* + * From: + * $NetBSD: disklabel_dkcksum.c,v 1.4 2005/05/15 21:01:34 thorpej Exp + */ + +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +static uint16_t +rs_dl_dkcksum(struct rumpserver_disklabel *lp, int imswapped) +{ + uint16_t *start, *end; + uint16_t sum; + uint16_t npart; + + if (imswapped) + npart = bs16(lp->d_npartitions); + else + npart = lp->d_npartitions; + + sum = 0; + start = (uint16_t *)(void *)lp; + end = (uint16_t *)(void *)&lp->d_partitions[npart]; + while (start < end) { + if (imswapped) + sum ^= bs16(*start); + else + sum ^= *start; + start++; + } + return (sum); +} + +/* + * From: + * NetBSD: disklabel_scan.c,v 1.3 2009/01/18 12:13:03 lukem Exp + */ + +/*- + * Copyright (c) 2002 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Roland C. Dowdeswell. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +static int +rs_dl_scan(struct rumpserver_disklabel *lp, int *isswapped, + char *buf, size_t buflen) +{ + size_t i; + int imswapped; + uint16_t npart; + + /* scan for the correct magic numbers. */ + + for (i=0; i <= buflen - sizeof(*lp); i += 4) { + memcpy(lp, buf + i, sizeof(*lp)); + if (lp->d_magic == RUMPSERVER_DISKMAGIC && + lp->d_magic2 == RUMPSERVER_DISKMAGIC) { + imswapped = 0; + goto sanity; + } + if (lp->d_magic == bs32(RUMPSERVER_DISKMAGIC) && + lp->d_magic2 == bs32(RUMPSERVER_DISKMAGIC)) { + imswapped = 1; + goto sanity; + } + } + + return 1; + +sanity: + if (imswapped) + npart = bs16(lp->d_npartitions); + else + npart = lp->d_npartitions; + /* we've found something, let's sanity check it */ + if (npart > RUMPSERVER_MAXPARTITIONS + || rs_dl_dkcksum(lp, imswapped)) + return 1; + + *isswapped = imswapped; + return 0; +} + +static void +processlabel(int sflag, int fd, int partition, off_t *foffp, off_t *flenp) +{ + struct rumpserver_disklabel dl; + char buf[1<<16]; + uint32_t foffset, flen; + int imswapped; + + if (pread(fd, buf, sizeof(buf), 0) == -1) + die(sflag, errno, "could not read disk device"); + if (rs_dl_scan(&dl, &imswapped, buf, sizeof(buf))) + die(sflag, ENOENT, "disklabel not found"); + + if (partition >= dl.d_npartitions) + die(sflag, ENOENT, "partition not available"); + + foffset = dl.d_partitions[partition].p_offset << RUMPSERVER_DEVSHIFT; + flen = dl.d_partitions[partition].p_size << RUMPSERVER_DEVSHIFT; + if (imswapped) { + foffset = bs32(foffset); + flen = bs32(flen); + } + + *foffp = (off_t)foffset; + *flenp = (off_t)flen; +} diff --git a/usr.bin/rump_halt/Makefile b/usr.bin/rump_halt/Makefile new file mode 100755 index 000000000..360a76878 --- /dev/null +++ b/usr.bin/rump_halt/Makefile @@ -0,0 +1,13 @@ +# $NetBSD: Makefile,v 1.1 2010/12/12 12:48:31 pooka Exp $ +# + +PROG= rump.halt + +.if defined(__MINIX) +LDADD+= -lrumpclient -lmthread +.else +LDADD+= -lrumpclient +.endif +DPADD+= ${RUMPCLIENT} + +.include diff --git a/usr.bin/rump_halt/rump.halt.1 b/usr.bin/rump_halt/rump.halt.1 new file mode 100644 index 000000000..292be003c --- /dev/null +++ b/usr.bin/rump_halt/rump.halt.1 @@ -0,0 +1,79 @@ +.\" $NetBSD: rump.halt.1,v 1.2 2010/12/12 17:15:16 pooka Exp $ +.\" +.\" Copyright (c) 1990, 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)reboot.8 8.1 (Berkeley) 6/9/93 +.\" +.Dd December 12, 2010 +.Dt RUMP.HALT 1 +.Os +.Sh NAME +.Nm rump.halt +.Nd halt a rump kernel +.Sh SYNOPSIS +.Nm +.Op Fl dhn +.Sh DESCRIPTION +The +.Nm +utility exits a rump kernel. +The file system cache, if present, is flushed. +Since a rump kernel does not control its clients, they are not +directly affected by +.Nm . +However, they will be unable to request further services from the +halted rump kernel. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl d +Create a core dump. +The core file is saved according to standard userland program +coredump rules, and can be later examined with a debugger. +.It Fl h +By default the process hosting the rump kernel exits. +Using this option shuts down rump kernel activity, but does not +cause the hosting process to exit. +.It Fl n +Do not flush the file system cache. +This option should be used with extreme caution. +It can be used if a virtual disk or a virtual processor is virtually on fire. +.El +.Sh SEE ALSO +.Xr rump 3 +.Sh HISTORY +The +.Nm +command appeared in +.Nx 6.0 . +.Sh CAVEATS +While using +.Fl h +makes it impossible to issue further system calls, it does not necessarily +stop all activity in a rump kernel. +It is recommended this option is used only for debugging purposes. diff --git a/usr.bin/rump_halt/rump.halt.c b/usr.bin/rump_halt/rump.halt.c new file mode 100644 index 000000000..496e6f131 --- /dev/null +++ b/usr.bin/rump_halt/rump.halt.c @@ -0,0 +1,96 @@ +/* $NetBSD: rump.halt.c,v 1.5 2014/11/04 19:05:17 pooka Exp $ */ + +/*- + * Copyright (c) 2010 Antti Kantee. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +#include +#ifndef lint +__RCSID("$NetBSD: rump.halt.c,v 1.5 2014/11/04 19:05:17 pooka Exp $"); +#endif /* !lint */ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#define ARGFLAGS "dhn" + +#ifndef HAVE_GETPROGNAME +#define getprogname() "rump_halt" +#endif + +__dead static void +usage(void) +{ + + fprintf(stderr, "usage: %s [-" ARGFLAGS "]\n", getprogname()); + exit(1); +} + +int +main(int argc, char *argv[]) +{ + int ch, flags; + + setprogname(argv[0]); + flags = 0; + while ((ch = getopt(argc, argv, ARGFLAGS)) != -1) { + switch (ch) { + case 'd': + flags |= RUMP_RB_DUMP; + break; + case 'h': + flags |= RUMP_RB_HALT; + break; + case 'n': + flags |= RUMP_RB_NOSYNC; + break; + default: + usage(); + break; + } + } + + if (optind != argc) + usage(); + + if (rumpclient_init() == -1) + err(1, "init failed"); + + if (rump_sys_reboot(flags, NULL) == -1) + err(1, "reboot"); + + return 0; +} diff --git a/usr.bin/rump_server/Makefile b/usr.bin/rump_server/Makefile new file mode 100755 index 000000000..ebb1e105c --- /dev/null +++ b/usr.bin/rump_server/Makefile @@ -0,0 +1,18 @@ +# $NetBSD: Makefile,v 1.8 2015/01/07 22:24:03 pooka Exp $ +# + +.PATH: ${.CURDIR}/../rump_allserver + +PROG= rump_server +SRCS= rump_allserver.c +NOMAN= installed by ../rump_allserver + +.if defined(__MINIX) +LDADD+= -Wl,--whole-archive -lrumpkern_sysproxy -lrump \ + -lrumpuser -Wl,--no-whole-archive -lmthread +.else +LDADD+= -Wl,--whole-archive -lrumpkern_sysproxy -lrump \ + -lrumpuser -Wl,--no-whole-archive -lpthread +.endif + +.include diff --git a/usr.bin/rump_wmd/Makefile b/usr.bin/rump_wmd/Makefile new file mode 100644 index 000000000..1208c068f --- /dev/null +++ b/usr.bin/rump_wmd/Makefile @@ -0,0 +1,7 @@ +# $NetBSD: Makefile,v 1.1 2014/01/16 01:54:47 pooka Exp $ +# + +MAN= rump_wmd.1 +SCRIPTS=rump_wmd.sh + +.include diff --git a/usr.bin/rump_wmd/rump_wmd.1 b/usr.bin/rump_wmd/rump_wmd.1 new file mode 100644 index 000000000..278b5dcd9 --- /dev/null +++ b/usr.bin/rump_wmd/rump_wmd.1 @@ -0,0 +1,98 @@ +.\" $NetBSD: rump_wmd.1,v 1.3 2014/01/28 14:02:54 pooka Exp $ +.\" +.\" Copyright (c) 2014 Antti Kantee. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.Dd January 28, 2014 +.Dt RUMP_WMD 1 +.Os +.Sh NAME +.Nm rump_wmd +.Nd Resolve rump kernel component dependencies +.Sh SYNOPSIS +.Nm +.Op Fl hv +.Op Fl L Ar dir +.Fl l Ar component +.Sh DESCRIPTION +The +.Nm +utility can be used to resolve the link dependencies of rump kernel +components. +This functionality is useful when desiring to run a rump kernel with +a given set of drivers, but not being sure what the dependencies of +those drivers are. +The output of +.Nm +is accepted as command line input by +.Xr rump_server 1 . +.Pp +The command line options are: +.Bl -tag -width indent +.It Fl h +Print the usage. +.It Fl L Ar dir +By default, rump kernel components in +.Pa /usr/lib +are examined. +If this option is supplied, components in +.Ar dir +are examined instead. +.It Fl v +Increase debug output from the utility. +This option may be given multiple times. +.El +.Pp +The desired components are given using +.Fl l Ar component . +This parameter may be specified multiple time and must be the last +set of parameters. +.Sh EXAMPLES +Resolve dependencies for FFS: +.Bd -literal -offset indent +$ rump_wmd -lrumpfs_ffs +DEBUG0: Searching component combinations. This may take a while ... +DEBUG0: Found a set +-lrumpdev -lrumpdev_disk -lrumpvfs -lrumpfs_ffs +.Ed +.Pp +Resolve dependencies for NFS, use IPv6 networking and the virtif +network interface: +.Bd -literal -offset indent +$ rump_wmd -lrumpfs_nfs -lrumpnet_netinet6 -lrumpnet_virtif +DEBUG0: Searching component combinations. This may take a while ... +DEBUG0: Found a set +-lrumpnet -lrumpnet_net -lrumpvfs -lrumpfs_nfs -lrumpnet_netinet6 -lrumpnet_virtif +.Ed +.Sh SEE ALSO +.Xr rump_server 1 +.Sh CAVEATS +Since +.Nm +uses trial-and-error brute force resolution, it runs somewhat slow. +If several seconds are spent for dependency resolution, the benefit of +a rump kernel booting in 10ms is somewhat lost. +Caching the output is highly recommended. +.Sh FUN FACTS +.Nm +is short for "rump, where's my dependency". diff --git a/usr.bin/rump_wmd/rump_wmd.sh b/usr.bin/rump_wmd/rump_wmd.sh new file mode 100755 index 000000000..26a495be6 --- /dev/null +++ b/usr.bin/rump_wmd/rump_wmd.sh @@ -0,0 +1,161 @@ +#!/bin/sh +# +# $NetBSD: rump_wmd.sh,v 1.4 2014/01/28 13:58:25 pooka Exp $ +# +# Copyright (c) 2014 Antti Kantee +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +: ${CC:=cc} +DEBUGLEVEL=0 +LIBDIR=/usr/lib + +die () +{ + + echo $* >&2 + exit 1 +} + +usage () +{ + + die "Usage: $0 [-hv] [-L libdir] -lrump_component [...]" +} + +unset FIRSTLIB +while getopts 'hl:L:v' opt; do + case "${opt}" in + l) + : ${FIRSTLIB:=${OPTIND}} + ;; + L) + [ -z "${FIRSTLIB}" ] || usage + LIBDIR=${OPTARG} + ;; + v) + [ -z "${FIRSTLIB}" ] || usage + DEBUGLEVEL=$((DEBUGLEVEL + 1)) + ;; + -h|*) + usage + ;; + esac +done +[ -z "${FIRSTLIB}" ] && usage +shift $((${FIRSTLIB} - 2)) +[ $# -eq 0 ] && usage + +debug () +{ + + [ ${DEBUGLEVEL} -ge ${1} ] && \ + { lvl=$1; shift; echo DEBUG${lvl}: $* >&2; } +} + +# filters from list +filter () +{ + + filtee=$1 + vname=$2 + tmplist='' + found=false + for x in $(eval echo \${${vname}}); do + if [ "${filtee}" = "${x}" ]; then + found=true + else + tmplist="${tmplist} ${x}" + fi + done + ${found} || die \"${1}\" not found in \$${2} + + eval ${vname}="\${tmplist}" +} + +SEEDPROG='int rump_init(void); int main() { rump_init(); }' +CCPARAMS='-Wl,--no-as-needed -o /dev/null -x c -' + +# sanity-check +for lib in $* ; do + [ "${lib#-l}" = "${lib}" -o -z "${lib#-l}" ] \ + && die Param \"${lib}\" is not of format -llib +done + +# starting set and available components +WANTEDCOMP="$*" +RUMPBASE='-lrump -lrumpuser' +CURCOMP="${WANTEDCOMP}" +NEEDEDCOMP='' +ALLCOMP=$(ls ${LIBDIR} 2>/dev/null \ + | sed -n '/^librump.*.so$/{s/lib/-l/;s/\.so//p;}') +[ -z "${ALLCOMP}" ] && die No rump kernel components in \"${LIBDIR}\" + +# filter out ones we'll definitely not use +for f in ${CURCOMP} -lrumphijack -lrumpclient; do + filter ${f} ALLCOMP +done + +# put the factions first so that they'll be tried first. +# this is an optimization to minimize link attempts. +FACTIONS='-lrumpvfs -lrumpnet -lrumpdev' +for f in ${FACTIONS}; do + filter ${f} ALLCOMP +done +ALLCOMP="${FACTIONS} ${ALLCOMP}" + +debug 0 Searching component combinations. This may take a while ... +while :; do + debug 1 Current components: ${CURCOMP} + + IFS=' ' + out=$(echo ${SEEDPROG} \ + | ${CC} -L${LIBDIR} ${CCPARAMS} ${CURCOMP} ${RUMPBASE} 2>&1) + [ -z "${out}" ] && break + undef=$(echo ${out} \ + | sed -n '/undefined reference to/{s/.*`//;s/.$//p;q;}') + [ -z "${undef}" ] && break + + debug 1 Trying to find ${undef} + for attempt in ${ALLCOMP}; do + debug 2 Component attempt: ${attempt} + unset IFS + nowundef=$(echo ${SEEDPROG} \ + | ${CC} -L${LIBDIR} ${CCPARAMS} \ + ${attempt} ${CURCOMP} ${RUMPBASE} 2>&1 \ + | sed -n '/undefined reference to/{s/.*`//;s/.$//p;}') + for one in ${nowundef}; do + [ "${one}" = "${undef}" ] && continue 2 + done + CURCOMP="${attempt} ${CURCOMP}" + filter ${attempt} ALLCOMP + debug 1 Found ${undef} from ${attempt} + continue 2 + done + die Internal error: unreachable statement +done + +[ ! -z "${out}" ] && { echo 'ERROR:' >&2 ; echo ${out} >&2 ; exit 1 ; } +debug 0 Found a set +echo ${CURCOMP} +exit 0