diff options
Diffstat (limited to 'contrib/netbsd-tests/rump/rumpkern')
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(); +} |
