rump: import rump server

This includes the worst POSIX semaphore emulation ever created by
mankind. It's that bad.
This commit is contained in:
Jean-Baptiste Boric 2016-12-29 08:19:48 +00:00
parent bdc9fdfc65
commit 3079e4f3c9
13 changed files with 1534 additions and 2 deletions

View File

@ -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

View File

@ -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

4
usr.bin/Makefile Normal file → Executable file
View File

@ -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")

21
usr.bin/rump_allserver/Makefile Executable file
View File

@ -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 <bsd.prog.mk>

View File

@ -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

View File

@ -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 <rump/rumpuser_port.h>
#ifndef lint
__RCSID("$NetBSD: rump_allserver.c,v 1.39 2015/04/16 10:05:43 pooka Exp $");
#endif /* !lint */
#include <sys/types.h>
#include <sys/stat.h>
#include <dlfcn.h>
#include <errno.h>
#include <fcntl.h>
#include <semaphore.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <rump/rump.h>
#include <rump/rump_syscalls.h>
#include <rump/rumpdefs.h>
#include <rump/rumperr.h>
#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;
}

13
usr.bin/rump_halt/Makefile Executable file
View File

@ -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 <bsd.prog.mk>

View File

@ -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.

View File

@ -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 <rump/rumpuser_port.h>
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: rump.halt.c,v 1.5 2014/11/04 19:05:17 pooka Exp $");
#endif /* !lint */
#include <sys/types.h>
#include <rump/rump.h>
#include <rump/rumpclient.h>
#include <rump/rump_syscalls.h>
#include <err.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#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;
}

18
usr.bin/rump_server/Makefile Executable file
View File

@ -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 <bsd.prog.mk>

View File

@ -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 <bsd.prog.mk>

View File

@ -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".

161
usr.bin/rump_wmd/rump_wmd.sh Executable file
View File

@ -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 <pooka@iki.fi>
#
# 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