aboutsummaryrefslogtreecommitdiff
path: root/contrib/netbsd-tests/rump/rumpkern
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/netbsd-tests/rump/rumpkern')
-rw-r--r--contrib/netbsd-tests/rump/rumpkern/h_client/h_forkcli.c169
-rw-r--r--contrib/netbsd-tests/rump/rumpkern/h_client/h_reconcli.c121
-rw-r--r--contrib/netbsd-tests/rump/rumpkern/h_client/h_sigcli.c84
-rw-r--r--contrib/netbsd-tests/rump/rumpkern/h_client/h_simplecli.c30
-rw-r--r--contrib/netbsd-tests/rump/rumpkern/h_client/h_stresscli.c219
-rw-r--r--contrib/netbsd-tests/rump/rumpkern/h_server/h_simpleserver.c64
-rw-r--r--contrib/netbsd-tests/rump/rumpkern/t_copy.c139
-rw-r--r--contrib/netbsd-tests/rump/rumpkern/t_kern.c119
-rw-r--r--contrib/netbsd-tests/rump/rumpkern/t_lwproc.c318
-rw-r--r--contrib/netbsd-tests/rump/rumpkern/t_modcmd.c182
-rw-r--r--contrib/netbsd-tests/rump/rumpkern/t_modlinkset.c73
-rw-r--r--contrib/netbsd-tests/rump/rumpkern/t_signals.c127
-rwxr-xr-xcontrib/netbsd-tests/rump/rumpkern/t_sp.sh129
-rw-r--r--contrib/netbsd-tests/rump/rumpkern/t_threads.c81
-rw-r--r--contrib/netbsd-tests/rump/rumpkern/t_tsleep.c63
-rw-r--r--contrib/netbsd-tests/rump/rumpkern/t_vm.c91
16 files changed, 2009 insertions, 0 deletions
diff --git a/contrib/netbsd-tests/rump/rumpkern/h_client/h_forkcli.c b/contrib/netbsd-tests/rump/rumpkern/h_client/h_forkcli.c
new file mode 100644
index 000000000000..3b89727bedd6
--- /dev/null
+++ b/contrib/netbsd-tests/rump/rumpkern/h_client/h_forkcli.c
@@ -0,0 +1,169 @@
+/* $NetBSD: h_forkcli.c,v 1.1 2011/01/05 17:19:09 pooka Exp $ */
+
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <rump/rump_syscalls.h>
+#include <rump/rumpclient.h>
+
+static void
+simple(void)
+{
+ struct rumpclient_fork *rf;
+ pid_t pid1, pid2;
+ int fd, status;
+
+ if ((pid1 = rump_sys_getpid()) < 2)
+ errx(1, "unexpected pid %d", pid1);
+
+ fd = rump_sys_open("/dev/null", O_CREAT | O_RDWR);
+ if (rump_sys_write(fd, &fd, sizeof(fd)) != sizeof(fd))
+ errx(1, "write newlyopened /dev/null");
+
+ if ((rf = rumpclient_prefork()) == NULL)
+ err(1, "prefork");
+
+ switch (fork()) {
+ case -1:
+ err(1, "fork");
+ break;
+ case 0:
+ if (rumpclient_fork_init(rf) == -1)
+ err(1, "postfork init failed");
+
+ if ((pid2 = rump_sys_getpid()) < 2)
+ errx(1, "unexpected pid %d", pid2);
+ if (pid1 == pid2)
+ errx(1, "child and parent pids are equal");
+
+ /* check that we can access the fd, the close it and exit */
+ if (rump_sys_write(fd, &fd, sizeof(fd)) != sizeof(fd))
+ errx(1, "write child /dev/null");
+ rump_sys_close(fd);
+ break;
+ default:
+ /*
+ * check that we can access the fd, wait for the child, and
+ * check we can still access the fd
+ */
+ if (rump_sys_write(fd, &fd, sizeof(fd)) != sizeof(fd))
+ errx(1, "write parent /dev/null");
+ if (wait(&status) == -1)
+ err(1, "wait failed");
+ if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
+ errx(1, "child exited with status %d", status);
+ if (rump_sys_write(fd, &fd, sizeof(fd)) != sizeof(fd))
+ errx(1, "write parent /dev/null");
+ break;
+ }
+}
+
+static void
+cancel(void)
+{
+
+ /* XXX: not implemented in client / server !!! */
+}
+
+#define TESTSTR "i am your fatherrrrrrr"
+#define TESTSLEN (sizeof(TESTSTR)-1)
+static void
+pipecomm(void)
+{
+ struct rumpclient_fork *rf;
+ char buf[TESTSLEN+1];
+ int pipetti[2];
+ int status;
+
+ if (rump_sys_pipe(pipetti) == -1)
+ errx(1, "pipe");
+
+ if ((rf = rumpclient_prefork()) == NULL)
+ err(1, "prefork");
+
+ switch (fork()) {
+ case -1:
+ err(1, "fork");
+ break;
+ case 0:
+ if (rumpclient_fork_init(rf) == -1)
+ err(1, "postfork init failed");
+
+ memset(buf, 0, sizeof(buf));
+ if (rump_sys_read(pipetti[0], buf, TESTSLEN) != TESTSLEN)
+ err(1, "pipe read");
+ if (strcmp(TESTSTR, buf) != 0)
+ errx(1, "teststring doesn't match, got %s", buf);
+ break;
+ default:
+ if (rump_sys_write(pipetti[1], TESTSTR, TESTSLEN) != TESTSLEN)
+ err(1, "pipe write");
+ if (wait(&status) == -1)
+ err(1, "wait failed");
+ if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
+ errx(1, "child exited with status %d", status);
+ break;
+ }
+}
+
+static void
+fakeauth(void)
+{
+ struct rumpclient_fork *rf;
+ uint32_t *auth;
+ int rv;
+
+ if ((rf = rumpclient_prefork()) == NULL)
+ err(1, "prefork");
+
+ /* XXX: we know the internal structure of rf */
+ auth = (void *)rf;
+ *(auth+3) = *(auth+3) ^ 0x1;
+
+ rv = rumpclient_fork_init(rf);
+ if (!(rv == -1 && errno == ESRCH))
+ exit(1);
+}
+
+struct parsa {
+ const char *arg; /* sp arg, el */
+ void (*spring)(void); /* spring into action */
+} paragus[] = {
+ { "simple", simple },
+ { "cancel", cancel },
+ { "pipecomm", pipecomm },
+ { "fakeauth", fakeauth },
+};
+
+int
+main(int argc, char *argv[])
+{
+ unsigned i;
+
+ if (argc != 2)
+ errx(1, "invalid usage");
+
+ if (rumpclient_init() == -1)
+ err(1, "rumpclient init");
+
+ for (i = 0; i < __arraycount(paragus); i++) {
+ if (strcmp(argv[1], paragus[i].arg) == 0) {
+ paragus[i].spring();
+ break;
+ }
+ }
+ if (i == __arraycount(paragus)) {
+ printf("invalid test %s\n", argv[1]);
+ exit(1);
+ }
+
+ exit(0);
+}
diff --git a/contrib/netbsd-tests/rump/rumpkern/h_client/h_reconcli.c b/contrib/netbsd-tests/rump/rumpkern/h_client/h_reconcli.c
new file mode 100644
index 000000000000..c594bbf8b834
--- /dev/null
+++ b/contrib/netbsd-tests/rump/rumpkern/h_client/h_reconcli.c
@@ -0,0 +1,121 @@
+/* $NetBSD: h_reconcli.c,v 1.2 2011/02/19 09:56:45 pooka Exp $ */
+
+#include <sys/types.h>
+#include <sys/sysctl.h>
+
+#include <rump/rumpclient.h>
+#include <rump/rump_syscalls.h>
+
+#include <err.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static volatile int quit, riseandwhine;
+
+static pthread_mutex_t closermtx;
+static pthread_cond_t closercv;
+
+static void *
+closer(void *arg)
+{
+
+ pthread_mutex_lock(&closermtx);
+ while (!quit) {
+ while (!riseandwhine)
+ pthread_cond_wait(&closercv, &closermtx);
+ riseandwhine = 0;
+ pthread_mutex_unlock(&closermtx);
+
+ /* try to catch a random slot */
+ usleep(random() % 100000);
+
+ /*
+ * wide-angle disintegration beam, but takes care
+ * of the client rumpkernel communication socket.
+ */
+ closefrom(3);
+
+ pthread_mutex_lock(&closermtx);
+ }
+ pthread_mutex_unlock(&closermtx);
+
+ return NULL;
+}
+
+static const int hostnamemib[] = { CTL_KERN, KERN_HOSTNAME };
+static char goodhostname[128];
+
+static void *
+worker(void *arg)
+{
+ char hostnamebuf[128];
+ size_t blen;
+
+ pthread_mutex_lock(&closermtx);
+ while (!quit) {
+ pthread_mutex_unlock(&closermtx);
+ if (rump_sys_getpid() == -1)
+ err(1, "getpid");
+
+ blen = sizeof(hostnamebuf);
+ memset(hostnamebuf, 0, sizeof(hostnamebuf));
+ if (rump_sys___sysctl(hostnamemib, __arraycount(hostnamemib),
+ hostnamebuf, &blen, NULL, 0) == -1)
+ err(1, "sysctl");
+ if (strcmp(hostnamebuf, goodhostname) != 0)
+ exit(1);
+ pthread_mutex_lock(&closermtx);
+ riseandwhine = 1;
+ pthread_cond_signal(&closercv);
+ }
+ riseandwhine = 1;
+ pthread_cond_signal(&closercv);
+ pthread_mutex_unlock(&closermtx);
+
+ return NULL;
+}
+
+int
+main(int argc, char *argv[])
+{
+ pthread_t pt, w1, w2, w3, w4;
+ size_t blen;
+ int timecount;
+
+ if (argc != 2)
+ errx(1, "need timecount");
+ timecount = atoi(argv[1]);
+ if (timecount <= 0)
+ errx(1, "invalid timecount %d\n", timecount);
+
+ srandom(time(NULL));
+
+ rumpclient_setconnretry(RUMPCLIENT_RETRYCONN_INFTIME);
+ if (rumpclient_init() == -1)
+ err(1, "init");
+
+ blen = sizeof(goodhostname);
+ if (rump_sys___sysctl(hostnamemib, __arraycount(hostnamemib),
+ goodhostname, &blen, NULL, 0) == -1)
+ err(1, "sysctl");
+
+ pthread_create(&pt, NULL, closer, NULL);
+ pthread_create(&w1, NULL, worker, NULL);
+ pthread_create(&w2, NULL, worker, NULL);
+ pthread_create(&w3, NULL, worker, NULL);
+ pthread_create(&w4, NULL, worker, NULL);
+
+ sleep(timecount);
+ quit = 1;
+
+ pthread_join(pt, NULL);
+ pthread_join(w1, NULL);
+ pthread_join(w2, NULL);
+ pthread_join(w3, NULL);
+ pthread_join(w4, NULL);
+
+ exit(0);
+}
diff --git a/contrib/netbsd-tests/rump/rumpkern/h_client/h_sigcli.c b/contrib/netbsd-tests/rump/rumpkern/h_client/h_sigcli.c
new file mode 100644
index 000000000000..9134f98b5741
--- /dev/null
+++ b/contrib/netbsd-tests/rump/rumpkern/h_client/h_sigcli.c
@@ -0,0 +1,84 @@
+/* $NetBSD: h_sigcli.c,v 1.3 2011/02/07 20:05:09 pooka Exp $ */
+
+#include <sys/types.h>
+#include <sys/sysctl.h>
+
+#include <err.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <rump/rump_syscalls.h>
+#include <rump/rumpclient.h>
+
+static const int hostnamemib[] = { CTL_KERN, KERN_HOSTNAME };
+static char hostnamebuf[128];
+
+static volatile sig_atomic_t sigexecs;
+
+static void
+sighand(int sig)
+{
+ char buf[128];
+ size_t blen = sizeof(buf);
+
+ if (rump_sys___sysctl(hostnamemib, __arraycount(hostnamemib),
+ buf, &blen, NULL, 0) == -1)
+ err(1, "sighand sysctl");
+ if (strcmp(buf, hostnamebuf) != 0)
+ errx(1, "sighandler hostname");
+ sigexecs++;
+}
+
+int
+main(void)
+{
+ char buf[128];
+ time_t tstart;
+ struct itimerval itv;
+ size_t hnbsize;
+ int i;
+ size_t blen;
+
+ if (rumpclient_init() == -1)
+ err(1, "rumpclient init");
+
+ hnbsize = sizeof(hostnamebuf);
+ if (rump_sys___sysctl(hostnamemib, __arraycount(hostnamemib),
+ hostnamebuf, &hnbsize, NULL, 0) == -1)
+ err(1, "sysctl");
+
+ if (signal(SIGALRM, sighand) == SIG_ERR)
+ err(1, "signal");
+
+ itv.it_interval.tv_sec = itv.it_value.tv_sec = 0;
+ itv.it_interval.tv_usec = itv.it_value.tv_usec = 10000; /* 10ms */
+
+ if (setitimer(ITIMER_REAL, &itv, NULL) == -1)
+ err(1, "itimer");
+
+ tstart = time(NULL);
+ for (i = 0;; i++) {
+ blen = sizeof(buf);
+ if (rump_sys___sysctl(hostnamemib, __arraycount(hostnamemib),
+ buf, &blen, NULL, 0) == -1)
+ err(1, "sysctl");
+ if (strcmp(buf, hostnamebuf) != 0)
+ errx(1, "main hostname");
+
+ /*
+ * check every 100 cycles to avoid doing
+ * nothing but gettimeofday()
+ */
+ if (i == 100) {
+ if (time(NULL) - tstart > 5)
+ break;
+ i = 0;
+ }
+ }
+
+ if (!sigexecs) {
+ printf("no signal handlers run. test busted?\n");
+ }
+}
diff --git a/contrib/netbsd-tests/rump/rumpkern/h_client/h_simplecli.c b/contrib/netbsd-tests/rump/rumpkern/h_client/h_simplecli.c
new file mode 100644
index 000000000000..11f432c38aad
--- /dev/null
+++ b/contrib/netbsd-tests/rump/rumpkern/h_client/h_simplecli.c
@@ -0,0 +1,30 @@
+/* $NetBSD: h_simplecli.c,v 1.2 2011/01/14 13:23:15 pooka Exp $ */
+
+#include <sys/types.h>
+
+#include <err.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include <rump/rump_syscalls.h>
+#include <rump/rumpclient.h>
+
+int
+main(int argc, char *argv[])
+{
+
+ if (rumpclient_init() == -1)
+ err(1, "rumpclient init");
+
+ if (argc > 1) {
+ for (;;) {
+ rump_sys_getpid();
+ usleep(10000);
+ }
+ } else {
+ if (rump_sys_getpid() > 0)
+ exit(0);
+ err(1, "getpid");
+ }
+}
diff --git a/contrib/netbsd-tests/rump/rumpkern/h_client/h_stresscli.c b/contrib/netbsd-tests/rump/rumpkern/h_client/h_stresscli.c
new file mode 100644
index 000000000000..d49edeb9a6f2
--- /dev/null
+++ b/contrib/netbsd-tests/rump/rumpkern/h_client/h_stresscli.c
@@ -0,0 +1,219 @@
+/* $NetBSD: h_stresscli.c,v 1.9 2011/06/26 13:17:36 christos Exp $ */
+
+#include <sys/types.h>
+#include <sys/atomic.h>
+#include <sys/sysctl.h>
+#include <sys/wait.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+
+#include <err.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <signal.h>
+
+#include <rump/rump_syscalls.h>
+#include <rump/rumpclient.h>
+
+static unsigned int syscalls, bindcalls;
+static pid_t mypid;
+static volatile sig_atomic_t doquit;
+
+static void
+signaali(int sig)
+{
+
+ doquit = 1;
+}
+
+static const int hostnamemib[] = { CTL_KERN, KERN_HOSTNAME };
+static char hostnamebuf[128];
+#define HOSTNAMEBASE "rumpclient"
+
+static int iskiller;
+
+static void *
+client(void *arg)
+{
+ char buf[256];
+ struct sockaddr_in sin;
+ size_t blen;
+ int port = (int)(uintptr_t)arg;
+ int s, fd, x;
+
+ memset(&sin, 0, sizeof(sin));
+ sin.sin_family = AF_INET;
+ sin.sin_len = sizeof(sin);
+ sin.sin_port = htons(port);
+
+ while (!doquit) {
+ pid_t pidi;
+ blen = sizeof(buf);
+ s = rump_sys_socket(PF_INET, SOCK_STREAM, 0);
+ if (s == -1)
+ err(1, "socket");
+ atomic_inc_uint(&syscalls);
+
+ fd = rump_sys_open("/dev/null", O_RDWR);
+ atomic_inc_uint(&syscalls);
+
+ if (doquit)
+ goto out;
+
+ x = 1;
+ if (rump_sys_setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
+ &x, sizeof(x)) == -1)
+ err(1, "reuseaddr");
+
+ /*
+ * we don't really know when the kernel handles our disconnect,
+ * so be soft about about the failure in case of a killer client
+ */
+ if (rump_sys_bind(s, (struct sockaddr*)&sin, sizeof(sin))==-1) {
+ if (!iskiller)
+ err(1, "bind to port %d failed",
+ ntohs(sin.sin_port));
+ } else {
+ atomic_inc_uint(&bindcalls);
+ }
+ atomic_inc_uint(&syscalls);
+
+ if (doquit)
+ goto out;
+
+ if (rump_sys___sysctl(hostnamemib, __arraycount(hostnamemib),
+ buf, &blen, NULL, 0) == -1)
+ err(1, "sysctl");
+ if (strncmp(buf, hostnamebuf, sizeof(HOSTNAMEBASE)-1) != 0)
+ errx(1, "hostname (%s/%s) mismatch", buf, hostnamebuf);
+ atomic_inc_uint(&syscalls);
+
+ if (doquit)
+ goto out;
+
+ pidi = rump_sys_getpid();
+ if (pidi == -1)
+ err(1, "getpid");
+ if (pidi != mypid)
+ errx(1, "mypid mismatch");
+ atomic_inc_uint(&syscalls);
+
+ if (doquit)
+ goto out;
+
+ if (rump_sys_write(fd, buf, 16) != 16)
+ err(1, "write /dev/null");
+ atomic_inc_uint(&syscalls);
+
+ out:
+ rump_sys_close(fd);
+ atomic_inc_uint(&syscalls);
+ rump_sys_close(s);
+ atomic_inc_uint(&syscalls);
+ }
+
+ return NULL;
+}
+
+/* Stress with max 32 clients, 8 threads each (256 concurrent threads) */
+#define NCLI 32
+#define NTHR 8
+
+int
+main(int argc, char *argv[])
+{
+ pthread_t pt[NTHR-1];
+ pid_t clis[NCLI];
+ pid_t apid;
+ int ncli = 0;
+ int i = 0, j;
+ int status, thesig;
+ int rounds, myport;
+
+ if (argc != 2 && argc != 3)
+ errx(1, "need roundcount");
+
+ if (argc == 3) {
+ if (strcmp(argv[2], "kill") != 0)
+ errx(1, "optional 3rd param must be kill");
+ thesig = SIGKILL;
+ iskiller = 1;
+ } else {
+ thesig = SIGUSR1;
+ }
+
+ signal(SIGUSR1, signaali);
+
+ memset(clis, 0, sizeof(clis));
+ for (rounds = 1; rounds < atoi(argv[1])*10; rounds++) {
+ while (ncli < NCLI) {
+ switch ((apid = fork())) {
+ case -1:
+ err(1, "fork failed");
+ case 0:
+ if (rumpclient_init() == -1)
+ err(1, "rumpclient init");
+
+ mypid = rump_sys_getpid();
+ sprintf(hostnamebuf, HOSTNAMEBASE "%d", mypid);
+ if (rump_sys___sysctl(hostnamemib,
+ __arraycount(hostnamemib), NULL, NULL,
+ hostnamebuf, strlen(hostnamebuf)+1) == -1)
+ err(1, "sethostname");
+
+ for (j = 0; j < NTHR-1; j++) {
+ myport = i*NCLI + j+2;
+ if (pthread_create(&pt[j], NULL,
+ client,
+ (void*)(uintptr_t)myport) !=0 )
+ err(1, "pthread create");
+ }
+ myport = i*NCLI+1;
+ client((void *)(uintptr_t)myport);
+ for (j = 0; j < NTHR-1; j++)
+ pthread_join(pt[j], NULL);
+ membar_consumer();
+ fprintf(stderr, "done %d\n", syscalls);
+ exit(0);
+ /* NOTREACHED */
+ default:
+ ncli++;
+ clis[i] = apid;
+ break;
+ }
+
+ i = (i + 1) % NCLI;
+ }
+
+ usleep(100000);
+ kill(clis[i], thesig);
+
+ apid = wait(&status);
+ if (apid != clis[i])
+ errx(1, "wanted pid %d, got %d\n", clis[i], apid);
+ clis[i] = 0;
+ ncli--;
+ if (thesig == SIGUSR1) {
+ if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
+ fprintf(stderr, "child died with 0x%x\n",
+ status);
+ exit(1);
+ }
+ } else {
+ if (!WIFSIGNALED(status) || WTERMSIG(status) != thesig){
+ fprintf(stderr, "child died with 0x%x\n",
+ status);
+ exit(1);
+ }
+ }
+ }
+
+ for (i = 0; i < NCLI; i++)
+ if (clis[i])
+ kill(clis[i], SIGKILL);
+}
diff --git a/contrib/netbsd-tests/rump/rumpkern/h_server/h_simpleserver.c b/contrib/netbsd-tests/rump/rumpkern/h_server/h_simpleserver.c
new file mode 100644
index 000000000000..0ab39589e125
--- /dev/null
+++ b/contrib/netbsd-tests/rump/rumpkern/h_server/h_simpleserver.c
@@ -0,0 +1,64 @@
+/* $NetBSD: h_simpleserver.c,v 1.4 2016/01/25 12:21:42 pooka Exp $ */
+
+#include <sys/types.h>
+
+#include <rump/rump.h>
+
+#include <err.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "../../kernspace/kernspace.h"
+
+#define NOFAIL(e) do { int rv = e; if (rv) err(1, #e); } while (/*CONSTCOND*/0)
+
+struct {
+ const char *str;
+ void (*dofun)(char *);
+} actions[] = {
+ { "sendsig", rumptest_sendsig },
+};
+
+int
+main(int argc, char *argv[])
+{
+ unsigned i;
+ bool match;
+
+ if (argc < 2)
+ exit(1);
+
+ NOFAIL(rump_daemonize_begin());
+ NOFAIL(rump_init());
+ NOFAIL(rump_init_server(argv[1]));
+ NOFAIL(rump_daemonize_done(RUMP_DAEMONIZE_SUCCESS));
+
+ if (argc > 2) {
+ char *arg = NULL;
+
+ if (argc == 4)
+ arg = argv[3];
+
+ for (i = 0; i < __arraycount(actions); i++) {
+ if (strcmp(actions[i].str, argv[2]) == 0) {
+ rump_schedule();
+ actions[i].dofun(arg);
+ rump_unschedule();
+ match = true;
+ }
+ }
+
+ if (!match) {
+ exit(1);
+ }
+ pause();
+ } else {
+ for (;;)
+ pause();
+ }
+
+ return 0;
+}
diff --git a/contrib/netbsd-tests/rump/rumpkern/t_copy.c b/contrib/netbsd-tests/rump/rumpkern/t_copy.c
new file mode 100644
index 000000000000..a31e58ca7a37
--- /dev/null
+++ b/contrib/netbsd-tests/rump/rumpkern/t_copy.c
@@ -0,0 +1,139 @@
+/* $NetBSD: t_copy.c,v 1.2 2013/07/26 16:09:48 njoly Exp $ */
+
+/*-
+ * Copyright (c) 2010 The NetBSD Foundation, Inc.
+ * 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 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.
+ */
+
+#include <sys/types.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <string.h>
+
+#include <rump/rump.h>
+
+ATF_TC(copystr);
+ATF_TC_HEAD(copystr, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Tests copystr()");
+}
+
+ATF_TC(copyinstr);
+ATF_TC_HEAD(copyinstr, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Tests copyinstr()");
+}
+
+ATF_TC(copyoutstr);
+ATF_TC_HEAD(copyoutstr, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Tests copyoutstr()");
+}
+
+typedef int (copystr_fn)(const void *, void *, size_t, size_t *);
+typedef int (copy_fn)(const void *, void *, size_t);
+
+extern copystr_fn rumpns_copystr, rumpns_copyinstr, rumpns_copyoutstr;
+extern copy_fn rumpns_copyin, rumpns_copyout;
+
+#define TESTSTR "jippii, lisaa puuroa"
+
+static void
+dotest(copystr_fn *thefun)
+{
+ char buf[sizeof(TESTSTR)+1];
+ size_t len;
+
+ rump_init();
+ rump_schedule();
+
+ /* larger buffer */
+ memset(buf, 0xaa, sizeof(buf));
+ ATF_REQUIRE_EQ(thefun(TESTSTR, buf, sizeof(buf), &len), 0);
+ ATF_REQUIRE_EQ(len, sizeof(TESTSTR));
+ ATF_REQUIRE_STREQ(TESTSTR, buf);
+
+ /* just large enough */
+ memset(buf, 0xaa, sizeof(buf));
+ ATF_REQUIRE_EQ(thefun(TESTSTR, buf, sizeof(buf)-1, &len), 0);
+ ATF_REQUIRE_EQ(len, sizeof(TESTSTR));
+ ATF_REQUIRE_STREQ(TESTSTR, buf);
+
+ /* one too small */
+ memset(buf, 0xaa, sizeof(buf));
+ ATF_REQUIRE_EQ(thefun(TESTSTR, buf, sizeof(buf)-2, NULL), ENAMETOOLONG);
+
+ rump_unschedule();
+}
+
+ATF_TC_BODY(copystr, tc)
+{
+
+ dotest(rumpns_copystr);
+}
+
+ATF_TC_BODY(copyinstr, tc)
+{
+
+ dotest(rumpns_copyinstr);
+}
+
+ATF_TC_BODY(copyoutstr, tc)
+{
+
+ dotest(rumpns_copyoutstr);
+}
+
+ATF_TC(copy_efault);
+ATF_TC_HEAD(copy_efault, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Tests that copy(9) functions can return EFAULT");
+}
+ATF_TC_BODY(copy_efault, tc)
+{
+ char buf[1024];
+
+ ATF_REQUIRE_EQ(rumpns_copyin(NULL, buf, sizeof(buf)), EFAULT);
+ ATF_REQUIRE_EQ(rumpns_copyout(buf, NULL, sizeof(buf)), EFAULT);
+
+ ATF_REQUIRE_EQ(rumpns_copyinstr(NULL, buf, sizeof(buf), NULL), EFAULT);
+ ATF_REQUIRE_EQ(rumpns_copyoutstr(buf, NULL, sizeof(buf), NULL), EFAULT);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, copystr);
+ ATF_TP_ADD_TC(tp, copyinstr);
+ ATF_TP_ADD_TC(tp, copyoutstr);
+ ATF_TP_ADD_TC(tp, copy_efault);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/rump/rumpkern/t_kern.c b/contrib/netbsd-tests/rump/rumpkern/t_kern.c
new file mode 100644
index 000000000000..15b258605ba9
--- /dev/null
+++ b/contrib/netbsd-tests/rump/rumpkern/t_kern.c
@@ -0,0 +1,119 @@
+/* $NetBSD: t_kern.c,v 1.4 2017/01/13 21:30:43 christos Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * 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 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.
+ */
+
+#include <sys/types.h>
+#include <sys/signal.h>
+#include <sys/wait.h>
+
+#include <rump/rump.h>
+
+#include <atf-c.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "h_macros.h"
+#include "../kernspace/kernspace.h"
+
+#define LOCKFUN(_name_, _descr_,_needld_, _expect_) \
+ ATF_TC(lockme_##_name_); \
+ ATF_TC_HEAD(lockme_##_name_, tc) { \
+ atf_tc_set_md_var(tc, "descr", _descr_); \
+ } \
+ ATF_TC_BODY(lockme_##_name_, tc) { \
+ locktest(tc, LOCKME_##_name_, _needld_, _expect_); \
+ }
+
+static void
+locktest(const atf_tc_t *tc, enum locktest lt, int needld, const char *expect)
+{
+ extern const int rump_lockdebug;
+ int pipetti[2];
+ int status;
+
+ if (needld && !rump_lockdebug)
+ atf_tc_skip("test requires LOCKDEBUG kernel");
+ RL(pipe(pipetti));
+
+ switch (fork()) {
+ case 0:
+ RL(dup2(pipetti[1], STDOUT_FILENO));
+ RL(dup2(pipetti[1], STDOUT_FILENO));
+ rump_init();
+ rump_schedule();
+ rumptest_lockme(lt);
+ rump_unschedule();
+ break;
+ default:
+ RL(wait(&status));
+ ATF_REQUIRE(WIFSIGNALED(status) && WTERMSIG(status) == SIGABRT);
+ if (rump_lockdebug) {
+ char buf[8192];
+
+ ATF_REQUIRE(read(pipetti[0], buf, sizeof(buf)) > 0);
+ if (strncmp(buf, expect, strlen(expect)) != 0)
+ atf_tc_fail("unexpected output");
+ }
+ break;
+ case -1:
+ atf_tc_fail("fork");
+ }
+}
+
+LOCKFUN(DESTROYHELD, "destroy lock while held", 0,
+ "mutex error: lockdebug_free: is locked or in use");
+LOCKFUN(DOUBLEFREE, "free lock twice", 0,
+ "panic: lockdebug_lookup: uninitialized lock");
+LOCKFUN(DOUBLEINIT, "init lock twice", 1,
+ "mutex error: lockdebug_alloc: already initialized");
+LOCKFUN(MEMFREE, "free memory active lock is in", 1,
+ "mutex error: kmem_intr_free: allocation contains active lock");
+LOCKFUN(MTX, "locking-against-self mutex", 0,
+ "mutex error: lockdebug_wantlock: locking against myself");
+LOCKFUN(RWDOUBLEX, "locking-against-self exclusive rwlock", 0,
+ "rwlock error: lockdebug_wantlock: locking against myself");
+LOCKFUN(RWRX, "rw: first shared, then exclusive", 1,
+ "rwlock error: lockdebug_wantlock: locking against myself");
+LOCKFUN(RWXR, "rw: first execusive, then shared", 0,
+ "rwlock error: lockdebug_wantlock: locking against myself");
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, lockme_MTX);
+ ATF_TP_ADD_TC(tp, lockme_RWDOUBLEX);
+ ATF_TP_ADD_TC(tp, lockme_RWRX);
+ ATF_TP_ADD_TC(tp, lockme_RWXR);
+ ATF_TP_ADD_TC(tp, lockme_DOUBLEINIT);
+ ATF_TP_ADD_TC(tp, lockme_DOUBLEFREE);
+ ATF_TP_ADD_TC(tp, lockme_DESTROYHELD);
+ ATF_TP_ADD_TC(tp, lockme_MEMFREE);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/rump/rumpkern/t_lwproc.c b/contrib/netbsd-tests/rump/rumpkern/t_lwproc.c
new file mode 100644
index 000000000000..f31997982c79
--- /dev/null
+++ b/contrib/netbsd-tests/rump/rumpkern/t_lwproc.c
@@ -0,0 +1,318 @@
+/* $NetBSD: t_lwproc.c,v 1.9 2017/01/13 21:30:43 christos Exp $ */
+
+/*
+ * Copyright (c) 2010 The NetBSD Foundation, Inc.
+ * 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 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.
+ */
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+
+#include <rump/rump.h>
+#include <rump/rump_syscalls.h>
+
+#include <atf-c.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <util.h>
+
+#include "h_macros.h"
+
+ATF_TC(makelwp);
+ATF_TC_HEAD(makelwp, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "tests that lwps can be attached to "
+ "processes");
+}
+
+ATF_TC_BODY(makelwp, tc)
+{
+ struct lwp *l;
+ pid_t pid;
+
+ rump_init();
+ RZ(rump_pub_lwproc_newlwp(0));
+ ATF_REQUIRE_EQ(rump_pub_lwproc_newlwp(37), ESRCH);
+ l = rump_pub_lwproc_curlwp();
+
+ RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG));
+ ATF_REQUIRE(rump_pub_lwproc_curlwp() != l);
+ l = rump_pub_lwproc_curlwp();
+
+ RZ(rump_pub_lwproc_newlwp(rump_sys_getpid()));
+ ATF_REQUIRE(rump_pub_lwproc_curlwp() != l);
+
+ pid = rump_sys_getpid();
+ ATF_REQUIRE(pid != -1 && pid != 0);
+}
+
+ATF_TC(proccreds);
+ATF_TC_HEAD(proccreds, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "check that procs have different creds");
+}
+
+ATF_TC_BODY(proccreds, tc)
+{
+ struct lwp *l1, *l2;
+
+ rump_init();
+ RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG));
+ l1 = rump_pub_lwproc_curlwp();
+ RZ(rump_pub_lwproc_newlwp(rump_sys_getpid()));
+
+ RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG));
+ l2 = rump_pub_lwproc_curlwp();
+
+ RL(rump_sys_setuid(22));
+ ATF_REQUIRE_EQ(rump_sys_getuid(), 22);
+
+ rump_pub_lwproc_switch(l1);
+ ATF_REQUIRE_EQ(rump_sys_getuid(), 0); /* from parent, proc0 */
+ RL(rump_sys_setuid(11));
+ ATF_REQUIRE_EQ(rump_sys_getuid(), 11);
+
+ rump_pub_lwproc_switch(l2);
+ ATF_REQUIRE_EQ(rump_sys_getuid(), 22);
+ rump_pub_lwproc_newlwp(rump_sys_getpid());
+ ATF_REQUIRE_EQ(rump_sys_getuid(), 22);
+}
+
+
+ATF_TC(inherit);
+ATF_TC_HEAD(inherit, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "new processes inherit creds from "
+ "parents");
+}
+
+ATF_TC_BODY(inherit, tc)
+{
+
+ rump_init();
+
+ RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG));
+ RL(rump_sys_setuid(66));
+ ATF_REQUIRE_EQ(rump_sys_getuid(), 66);
+
+ RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG));
+ ATF_REQUIRE_EQ(rump_sys_getuid(), 66);
+
+ /* release lwp and proc */
+ rump_pub_lwproc_releaselwp();
+ ATF_REQUIRE_EQ(rump_sys_getuid(), 0);
+}
+
+ATF_TC(lwps);
+ATF_TC_HEAD(lwps, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "proc can hold many lwps and is "
+ "automatically g/c'd when the last one exits");
+}
+
+#define LOOPS 128
+ATF_TC_BODY(lwps, tc)
+{
+ struct lwp *l[LOOPS];
+ pid_t mypid;
+ struct lwp *l_orig;
+ int i;
+
+ rump_init();
+
+ RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG));
+ mypid = rump_sys_getpid();
+ RL(rump_sys_setuid(375));
+
+ l_orig = rump_pub_lwproc_curlwp();
+ for (i = 0; i < LOOPS; i++) {
+ mypid = rump_sys_getpid();
+ ATF_REQUIRE(mypid != -1 && mypid != 0);
+ RZ(rump_pub_lwproc_newlwp(mypid));
+ l[i] = rump_pub_lwproc_curlwp();
+ ATF_REQUIRE_EQ(rump_sys_getuid(), 375);
+ }
+
+ rump_pub_lwproc_switch(l_orig);
+ rump_pub_lwproc_releaselwp();
+ for (i = 0; i < LOOPS; i++) {
+ rump_pub_lwproc_switch(l[i]);
+ ATF_REQUIRE_EQ(rump_sys_getpid(), mypid);
+ ATF_REQUIRE_EQ(rump_sys_getuid(), 375);
+ rump_pub_lwproc_releaselwp();
+ ATF_REQUIRE_EQ(rump_sys_getpid(), 1);
+ ATF_REQUIRE_EQ(rump_sys_getuid(), 0);
+ }
+
+ ATF_REQUIRE_EQ(rump_pub_lwproc_newlwp(mypid), ESRCH);
+}
+
+ATF_TC(nolwprelease);
+ATF_TC_HEAD(nolwprelease, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "check that lwp context is required "
+ "for lwproc_releaselwp()");
+}
+
+ATF_TC_BODY(nolwprelease, tc)
+{
+ int status;
+
+ switch (fork()) {
+ case 0:
+ rump_init();
+ rump_pub_lwproc_releaselwp();
+ atf_tc_fail("survived");
+ break;
+ case -1:
+ atf_tc_fail_errno("fork");
+ break;
+ default:
+ wait(&status);
+ ATF_REQUIRE(WIFSIGNALED(status));
+ ATF_REQUIRE_EQ(WTERMSIG(status), SIGABRT);
+
+ }
+}
+
+ATF_TC(nolwp);
+ATF_TC_HEAD(nolwp, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "check that curlwp for an implicit "
+ "context is NULL");
+}
+
+ATF_TC_BODY(nolwp, tc)
+{
+
+ rump_init();
+ ATF_REQUIRE_EQ(rump_pub_lwproc_curlwp(), NULL);
+}
+
+ATF_TC(nullswitch);
+ATF_TC_HEAD(nullswitch, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "check that switching to NULL marks "
+ "current lwp as not running");
+}
+
+ATF_TC_BODY(nullswitch, tc)
+{
+ struct lwp *l;
+
+ rump_init();
+ RZ(rump_pub_lwproc_newlwp(0));
+ l = rump_pub_lwproc_curlwp();
+ rump_pub_lwproc_switch(NULL);
+ /* if remains LP_RUNNING, next call will panic */
+ rump_pub_lwproc_switch(l);
+}
+
+ATF_TC(rfork);
+ATF_TC_HEAD(rfork, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "check that fork shares fd's");
+}
+
+ATF_TC_BODY(rfork, tc)
+{
+ struct stat sb;
+ struct lwp *l, *l2;
+ int fd;
+
+ RZ(rump_init());
+
+ ATF_REQUIRE_EQ(rump_pub_lwproc_rfork(RUMP_RFFDG|RUMP_RFCFDG), EINVAL);
+
+ RZ(rump_pub_lwproc_rfork(0));
+ l = rump_pub_lwproc_curlwp();
+
+ RL(fd = rump_sys_open("/file", O_RDWR | O_CREAT, 0777));
+
+ /* ok, first check rfork(RUMP_RFCFDG) does *not* preserve fd's */
+ RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG));
+ ATF_REQUIRE_ERRNO(EBADF, rump_sys_write(fd, &fd, sizeof(fd)) == -1);
+
+ /* then check that rfork(0) does */
+ rump_pub_lwproc_switch(l);
+ RZ(rump_pub_lwproc_rfork(0));
+ ATF_REQUIRE_EQ(rump_sys_write(fd, &fd, sizeof(fd)), sizeof(fd));
+ RL(rump_sys_fstat(fd, &sb));
+ l2 = rump_pub_lwproc_curlwp();
+
+ /*
+ * check that the shared fd table is really shared by
+ * closing fd in parent
+ */
+ rump_pub_lwproc_switch(l);
+ RL(rump_sys_close(fd));
+ rump_pub_lwproc_switch(l2);
+ ATF_REQUIRE_ERRNO(EBADF, rump_sys_fstat(fd, &sb) == -1);
+
+ /* redo, this time copying the fd table instead of sharing it */
+ rump_pub_lwproc_releaselwp();
+ rump_pub_lwproc_switch(l);
+ RL(fd = rump_sys_open("/file", O_RDWR, 0777));
+ RZ(rump_pub_lwproc_rfork(RUMP_RFFDG));
+ ATF_REQUIRE_EQ(rump_sys_write(fd, &fd, sizeof(fd)), sizeof(fd));
+ RL(rump_sys_fstat(fd, &sb));
+ l2 = rump_pub_lwproc_curlwp();
+
+ /* check that the fd table is copied */
+ rump_pub_lwproc_switch(l);
+ RL(rump_sys_close(fd));
+ rump_pub_lwproc_switch(l2);
+ RL(rump_sys_fstat(fd, &sb));
+ ATF_REQUIRE_EQ(sb.st_size, sizeof(fd));
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, makelwp);
+ ATF_TP_ADD_TC(tp, proccreds);
+ ATF_TP_ADD_TC(tp, inherit);
+ ATF_TP_ADD_TC(tp, lwps);
+ ATF_TP_ADD_TC(tp, nolwprelease);
+ ATF_TP_ADD_TC(tp, nolwp);
+ ATF_TP_ADD_TC(tp, nullswitch);
+ ATF_TP_ADD_TC(tp, rfork);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/rump/rumpkern/t_modcmd.c b/contrib/netbsd-tests/rump/rumpkern/t_modcmd.c
new file mode 100644
index 000000000000..e48bcb53dbf7
--- /dev/null
+++ b/contrib/netbsd-tests/rump/rumpkern/t_modcmd.c
@@ -0,0 +1,182 @@
+/* $NetBSD: t_modcmd.c,v 1.10 2017/01/13 21:30:43 christos Exp $ */
+
+/*
+ * Copyright (c) 2009 The NetBSD Foundation, Inc.
+ * 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 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.
+ */
+
+#include <sys/types.h>
+#include <sys/mount.h>
+#include <sys/sysctl.h>
+
+#include <rump/rump.h>
+#include <rump/rump_syscalls.h>
+
+#include <fs/tmpfs/tmpfs_args.h>
+
+#include <atf-c.h>
+#include <dlfcn.h>
+#include <err.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <util.h>
+
+#include "h_macros.h"
+/*
+ * We verify that modules can be loaded and unloaded.
+ * tmpfs was chosen because it does not depend on an image.
+ */
+
+ATF_TC(cmsg_modcmd);
+ATF_TC_HEAD(cmsg_modcmd, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks that loading and unloading "
+ "a module (vfs/tmpfs) is possible");
+}
+
+static int
+disable_autoload(void)
+{
+ struct sysctlnode q, ans[256];
+ int mib[3];
+ size_t alen;
+ unsigned i;
+ bool no;
+
+ mib[0] = CTL_KERN;
+ mib[1] = CTL_QUERY;
+ alen = sizeof(ans);
+
+ memset(&q, 0, sizeof(q));
+ q.sysctl_flags = SYSCTL_VERSION;
+
+ if (rump_sys___sysctl(mib, 2, ans, &alen, &q, sizeof(q)) == -1)
+ return -1;
+
+ for (i = 0; i < __arraycount(ans); i++)
+ if (strcmp("module", ans[i].sysctl_name) == 0)
+ break;
+ if (i == __arraycount(ans)) {
+ errno = ENOENT;
+ return -1;
+ }
+
+ mib[1] = ans[i].sysctl_num;
+ mib[2] = CTL_QUERY;
+
+ if (rump_sys___sysctl(mib, 3, ans, &alen, &q, sizeof(q)) == -1)
+ return errno;
+
+ for (i = 0; i < __arraycount(ans); i++)
+ if (strcmp("autoload", ans[i].sysctl_name) == 0)
+ break;
+ if (i == __arraycount(ans)) {
+ errno = ENOENT;
+ return -1;
+ }
+
+ mib[2] = ans[i].sysctl_num;
+
+ no = false;
+ alen = 0;
+ if (rump_sys___sysctl(mib, 3, NULL, &alen, &no, sizeof(no)) == -1)
+ return errno;
+
+ return 0;
+
+}
+
+#define TMPFSMODULE "librumpfs_tmpfs.so"
+ATF_TC_BODY(cmsg_modcmd, tc)
+{
+ struct tmpfs_args args;
+ const struct modinfo *const *mi_start, *const *mi_end;
+ void *handle;
+ int i, rv, loop = 0;
+
+ rump_init();
+
+ if (disable_autoload() == -1)
+ atf_tc_fail_errno("count not disable module autoload");
+
+ memset(&args, 0, sizeof(args));
+ args.ta_version = TMPFS_ARGS_VERSION;
+ args.ta_root_mode = 0777;
+
+ if (rump_sys_mkdir("/mp", 0777) == -1)
+ atf_tc_fail_errno("mkdir mountpoint");
+ if (rump_sys_mount(MOUNT_TMPFS, "/mp", 0, &args, sizeof(args)) != -1)
+ atf_tc_fail("mount unexpectedly succeeded");
+
+ handle = dlopen(TMPFSMODULE, RTLD_GLOBAL);
+ if (handle == NULL) {
+ const char *dlmsg = dlerror();
+ atf_tc_fail("cannot open %s: %s", TMPFSMODULE, dlmsg);
+ }
+
+ again:
+ mi_start = dlsym(handle, "__start_link_set_modules");
+ mi_end = dlsym(handle, "__stop_link_set_modules");
+ if (mi_start == NULL || mi_end == NULL)
+ atf_tc_fail("cannot find module info");
+ if ((rv = rump_pub_module_init(mi_start, (size_t)(mi_end-mi_start)))!=0)
+ atf_tc_fail("module init failed: %d (%s)", rv, strerror(rv));
+ if ((rv = rump_pub_module_init(mi_start, (size_t)(mi_end-mi_start)))==0)
+ atf_tc_fail("module double init succeeded");
+
+ if (rump_sys_mount(MOUNT_TMPFS, "/mp", 0, &args, sizeof(args)) == -1)
+ atf_tc_fail_errno("still cannot mount");
+ if (rump_sys_unmount("/mp", 0) == -1)
+ atf_tc_fail("cannot unmount");
+ for (i = 0; i < (int)(mi_end-mi_start); i++) {
+ if ((rv = rump_pub_module_fini(mi_start[i])) != 0)
+ atf_tc_fail("module fini failed: %d (%s)",
+ rv, strerror(rv));
+ }
+ for (i = 0; i < (int)(mi_end-mi_start); i++) {
+ if ((rv = rump_pub_module_fini(mi_start[i])) == 0)
+ atf_tc_fail("module double fini succeeded");
+ }
+ if (loop++ == 0)
+ goto again;
+
+ if (dlclose(handle)) {
+ const char *dlmsg = dlerror();
+ atf_tc_fail("cannot close %s: %s", TMPFSMODULE, dlmsg);
+ }
+
+ if (rump_sys_mount(MOUNT_TMPFS, "/mp", 0, &args, sizeof(args)) != -1)
+ atf_tc_fail("mount unexpectedly succeeded");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, cmsg_modcmd);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/rump/rumpkern/t_modlinkset.c b/contrib/netbsd-tests/rump/rumpkern/t_modlinkset.c
new file mode 100644
index 000000000000..7d725dc7cc07
--- /dev/null
+++ b/contrib/netbsd-tests/rump/rumpkern/t_modlinkset.c
@@ -0,0 +1,73 @@
+/* $NetBSD: t_modlinkset.c,v 1.3 2017/01/13 21:30:43 christos Exp $ */
+
+/*
+ * Copyright (c) 2009 The NetBSD Foundation, Inc.
+ * 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 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.
+ */
+
+#include <sys/types.h>
+#include <sys/mount.h>
+
+#include <rump/rump.h>
+#include <rump/ukfs.h>
+
+#include <atf-c.h>
+#include <dlfcn.h>
+#include <err.h>
+#include <errno.h>
+#include <string.h>
+
+#include "h_macros.h"
+
+ATF_TC(modlinkset);
+ATF_TC_HEAD(modlinkset, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Check that module linkset bootstrap "
+ "works");
+}
+
+/*
+ * We link against cd9660 and msdosfs (both chosed because the names
+ * are unlikely to ever be a substring of a another file system).
+ * Without proper linkset handling at most one will be reported.
+ */
+ATF_TC_BODY(modlinkset, tc)
+{
+ char buf[1024];
+
+ rump_init();
+ if (ukfs_vfstypes(buf, sizeof(buf)) == -1)
+ atf_tc_fail_errno("ukfs_vfstypes");
+
+ ATF_CHECK((strstr(buf, "msdos") != NULL));
+ ATF_CHECK((strstr(buf, "cd9660") != NULL));
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, modlinkset);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/rump/rumpkern/t_signals.c b/contrib/netbsd-tests/rump/rumpkern/t_signals.c
new file mode 100644
index 000000000000..ba0c0ea36fb2
--- /dev/null
+++ b/contrib/netbsd-tests/rump/rumpkern/t_signals.c
@@ -0,0 +1,127 @@
+/* $NetBSD: t_signals.c,v 1.3 2017/01/13 21:30:43 christos Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * 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 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.
+ */
+
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <string.h>
+#include <signal.h>
+#include <unistd.h>
+
+#include <rump/rump.h>
+
+#include "../kernspace/kernspace.h"
+#include "h_macros.h"
+
+ATF_TC(sigraise);
+ATF_TC_HEAD(sigraise, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "RUMP_SIGMODEL_RAISE");
+}
+
+ATF_TC(sigignore);
+ATF_TC_HEAD(sigignore, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "RUMP_SIGMODEL_IGNORE");
+}
+
+ATF_TC(sigpanic);
+ATF_TC_HEAD(sigpanic, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "RUMP_SIGMODEL_PANIC");
+}
+
+static volatile sig_atomic_t sigcnt;
+static void
+thehand(int sig)
+{
+
+ sigcnt++;
+}
+
+ATF_TC_BODY(sigraise, tc)
+{
+
+ signal(SIGUSR2, thehand);
+ rump_boot_setsigmodel(RUMP_SIGMODEL_RAISE);
+
+ rump_init();
+ rump_schedule();
+ rumptest_localsig(SIGUSR2);
+ rump_unschedule();
+ ATF_REQUIRE_EQ(sigcnt, 1);
+}
+
+ATF_TC_BODY(sigignore, tc)
+{
+
+ rump_boot_setsigmodel(RUMP_SIGMODEL_IGNORE);
+
+ rump_init();
+ rump_schedule();
+ rumptest_localsig(SIGKILL);
+ rump_unschedule();
+}
+
+ATF_TC_BODY(sigpanic, tc)
+{
+ int status;
+
+ rump_boot_setsigmodel(RUMP_SIGMODEL_PANIC);
+
+ switch (fork()) {
+ case 0:
+ rump_init();
+ rump_schedule();
+ rumptest_localsig(SIGCONT);
+ /* NOTREACHED */
+ exit(1);
+ default:
+ wait(&status);
+ ATF_REQUIRE(WIFSIGNALED(status) && WTERMSIG(status) == SIGABRT);
+ break;
+ case -1:
+ atf_tc_fail_errno("fork");
+ }
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, sigraise);
+ ATF_TP_ADD_TC(tp, sigignore);
+ ATF_TP_ADD_TC(tp, sigpanic);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/rump/rumpkern/t_sp.sh b/contrib/netbsd-tests/rump/rumpkern/t_sp.sh
new file mode 100755
index 000000000000..2c4404afb584
--- /dev/null
+++ b/contrib/netbsd-tests/rump/rumpkern/t_sp.sh
@@ -0,0 +1,129 @@
+# $NetBSD: t_sp.sh,v 1.13 2016/08/10 23:47:14 kre Exp $
+#
+# Copyright (c) 2010 The NetBSD Foundation, Inc.
+# 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 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.
+#
+
+test_case()
+{
+ local name="${1}"; shift
+ local check_function="${1}"; shift
+
+ atf_test_case "${name}" cleanup
+ eval "${name}_head() { }"
+ eval "${name}_body() { \
+ ${check_function} " "${@}" "; \
+ }"
+ eval "${name}_cleanup() { \
+ RUMP_SERVER=unix://commsock rump.halt
+ }"
+}
+
+test_case basic basic
+test_case stress_short stress 1
+test_case stress_long stress 2
+test_case stress_killer stress 5 kill
+test_case fork_simple fork simple
+test_case fork_pipecomm fork pipecomm
+test_case fork_fakeauth fork fakeauth
+test_case sigsafe sigsafe sigsafe
+test_case signal signal
+test_case reconnect reconnect
+
+basic()
+{
+ export RUMP_SERVER=unix://commsock
+ atf_check -s exit:0 rump_server ${RUMP_SERVER}
+ atf_check -s exit:0 $(atf_get_srcdir)/h_client/h_simplecli
+}
+
+stress_short_head()
+{
+ atf_set "require.memory" "64M"
+}
+
+stress_long_head()
+{
+ atf_set "require.memory" "64M"
+}
+
+stress()
+{
+
+ export RUMP_SERVER=unix://commsock
+ atf_check -s exit:0 rump_server \
+ -lrumpvfs -lrumpnet -lrumpnet_net -lrumpnet_netinet -lrumpdev \
+ ${RUMP_SERVER}
+ atf_check -s exit:0 -e ignore $(atf_get_srcdir)/h_client/h_stresscli $@
+}
+
+fork()
+{
+
+ export RUMP_SERVER=unix://commsock
+ atf_check -s exit:0 rump_server -lrumpvfs -lrumpdev ${RUMP_SERVER}
+ atf_check -s exit:0 $(atf_get_srcdir)/h_client/h_forkcli ${1}
+}
+
+sigsafe()
+{
+
+ export RUMP_SERVER=unix://commsock
+ atf_check -s exit:0 rump_server ${RUMP_SERVER}
+ atf_check -s exit:0 $(atf_get_srcdir)/h_client/h_sigcli
+
+}
+
+signal()
+{
+
+ export RUMP_SERVER=unix://commsock
+ atf_check -s exit:0 $(atf_get_srcdir)/h_server/h_simpleserver \
+ ${RUMP_SERVER} sendsig 27
+ atf_check -s signal:27 $(atf_get_srcdir)/h_client/h_simplecli block
+}
+
+reconnect()
+{
+
+
+ export RUMP_SERVER=unix://commsock
+ atf_check -s exit:0 rump_server ${RUMP_SERVER}
+ atf_check -s exit:0 -e ignore $(atf_get_srcdir)/h_client/h_reconcli 2
+}
+
+atf_init_test_cases()
+{
+
+ atf_add_test_case basic
+ atf_add_test_case stress_short
+ atf_add_test_case stress_long
+ atf_add_test_case stress_killer
+ atf_add_test_case fork_simple
+ atf_add_test_case fork_pipecomm
+ atf_add_test_case fork_fakeauth
+ atf_add_test_case sigsafe
+ atf_add_test_case signal
+ atf_add_test_case reconnect
+}
diff --git a/contrib/netbsd-tests/rump/rumpkern/t_threads.c b/contrib/netbsd-tests/rump/rumpkern/t_threads.c
new file mode 100644
index 000000000000..2931fa60d148
--- /dev/null
+++ b/contrib/netbsd-tests/rump/rumpkern/t_threads.c
@@ -0,0 +1,81 @@
+/* $NetBSD: t_threads.c,v 1.2 2017/01/13 21:30:43 christos Exp $ */
+
+/*-
+ * Copyright (c) 2010 The NetBSD Foundation, Inc.
+ * 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 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.
+ */
+
+#include <sys/types.h>
+#include <sys/mount.h>
+#include <sys/sysctl.h>
+
+#include <rump/rump.h>
+
+#include <atf-c.h>
+
+#include "h_macros.h"
+#include "../kernspace/kernspace.h"
+
+ATF_TC(threadjoin);
+ATF_TC_HEAD(threadjoin, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Checks joinable threads work");
+}
+
+ATF_TC_BODY(threadjoin, tc)
+{
+
+ rump_init();
+
+ rump_schedule();
+ rumptest_threadjoin(); /* panics if fails */
+ rump_unschedule();
+}
+
+ATF_TC(kthread);
+ATF_TC_HEAD(kthread, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Checks kthread_create/exit works");
+}
+
+ATF_TC_BODY(kthread, tc)
+{
+
+ rump_init();
+
+ rump_schedule();
+ rumptest_threadjoin(); /* panics if fails */
+ rump_unschedule();
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, threadjoin);
+ ATF_TP_ADD_TC(tp, kthread);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/rump/rumpkern/t_tsleep.c b/contrib/netbsd-tests/rump/rumpkern/t_tsleep.c
new file mode 100644
index 000000000000..126a89de5280
--- /dev/null
+++ b/contrib/netbsd-tests/rump/rumpkern/t_tsleep.c
@@ -0,0 +1,63 @@
+/* $NetBSD: t_tsleep.c,v 1.2 2017/01/13 21:30:43 christos Exp $ */
+
+/*-
+ * Copyright (c) 2010 The NetBSD Foundation, Inc.
+ * 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 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.
+ */
+
+#include <sys/types.h>
+#include <sys/mount.h>
+#include <sys/sysctl.h>
+
+#include <rump/rump.h>
+
+#include <atf-c.h>
+
+#include "h_macros.h"
+#include "../kernspace/kernspace.h"
+
+ATF_TC(tsleep);
+ATF_TC_HEAD(tsleep, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Check tsleep variants");
+}
+
+ATF_TC_BODY(tsleep, tc)
+{
+
+ rump_init();
+
+ rump_schedule();
+ rumptest_tsleep(); /* panics if fails */
+ rump_unschedule();
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, tsleep);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/rump/rumpkern/t_vm.c b/contrib/netbsd-tests/rump/rumpkern/t_vm.c
new file mode 100644
index 000000000000..ddb005c8eeae
--- /dev/null
+++ b/contrib/netbsd-tests/rump/rumpkern/t_vm.c
@@ -0,0 +1,91 @@
+/* $NetBSD: t_vm.c,v 1.4 2017/01/13 21:30:43 christos Exp $ */
+
+/*-
+ * Copyright (c) 2010 The NetBSD Foundation, Inc.
+ * 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 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.
+ */
+
+#include <sys/types.h>
+#include <sys/mount.h>
+#include <sys/sysctl.h>
+
+#include <rump/rump.h>
+
+#include <atf-c.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "h_macros.h"
+#include "../kernspace/kernspace.h"
+
+ATF_TC(busypage);
+ATF_TC_HEAD(busypage, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Checks VM pagewaits work");
+}
+
+ATF_TC_BODY(busypage, tc)
+{
+
+ rump_init();
+
+ rump_schedule();
+ rumptest_busypage();
+ rump_unschedule();
+}
+
+ATF_TC(uvmwait);
+ATF_TC_HEAD(uvmwait, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Tests that uvm_wait works");
+ atf_tc_set_md_var(tc, "timeout", "30");
+}
+
+#define UVMWAIT_LIMIT 1024*1024
+ATF_TC_BODY(uvmwait, tc)
+{
+ char buf[64];
+
+ /* limit rump kernel memory */
+ snprintf(buf, sizeof(buf), "%d", UVMWAIT_LIMIT);
+ setenv("RUMP_MEMLIMIT", buf, 1);
+
+ rump_init();
+
+ rump_schedule();
+ rumptest_alloc(UVMWAIT_LIMIT);
+ rump_unschedule();
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, busypage);
+ ATF_TP_ADD_TC(tp, uvmwait);
+
+ return atf_no_error();
+}