diff options
author | ngie <ngie@FreeBSD.org> | 2014-10-02 23:26:49 +0000 |
---|---|---|
committer | ngie <ngie@FreeBSD.org> | 2014-10-02 23:26:49 +0000 |
commit | 3f09b8d0af642c2aeb96a4d667cefb7fe3bce443 (patch) | |
tree | 544932e2a2c5a5a202b752beefba0b3e327b3858 /contrib/netbsd-tests/kernel | |
parent | b941fec92da62b0eab650295f4e8a381dbbc04b4 (diff) | |
parent | e1f2d32c0e0678782c353c48364cddedfae58b0a (diff) | |
download | FreeBSD-src-3f09b8d0af642c2aeb96a4d667cefb7fe3bce443.zip FreeBSD-src-3f09b8d0af642c2aeb96a4d667cefb7fe3bce443.tar.gz |
Import the NetBSD test suite from ^/vendor/NetBSD/tests/09.30.2014_20.45 ,
minus the vendor Makefiles
Provide directions for how to bootstrap the vendor sources in
FREEBSD-upgrade
MFC after 2 weeks
Discussed with: rpaulo
Sponsored by: EMC / Isilon Storage Division
Diffstat (limited to 'contrib/netbsd-tests/kernel')
31 files changed, 4964 insertions, 0 deletions
diff --git a/contrib/netbsd-tests/kernel/gen_t_subr_prf b/contrib/netbsd-tests/kernel/gen_t_subr_prf new file mode 100755 index 0000000..b58a6ba --- /dev/null +++ b/contrib/netbsd-tests/kernel/gen_t_subr_prf @@ -0,0 +1,134 @@ +#!/bin/sh + +cat << _EOF > $2 +#include <sys/types.h> +#include <sys/time.h> +#include <stdio.h> +#include <stdarg.h> +#include <stdint.h> +#include <string.h> +#include <sha2.h> + +#include <atf-c.h> + +/* Avoid SSP re-definitions */ +#undef snprintf +#undef vsnprintf +#undef sprintf +#undef vsprintf + +#define KPRINTF_BUFSIZE 1024 +#undef putchar +#define putchar xputchar + +static int putchar(char c, int foo, void *b) +{ + return fputc(c, stderr); +} + +#define TOBUFONLY 1 +static const char HEXDIGITS[] = "0123456789ABCDEF"; +static const char hexdigits[] = "0123456789abcdef"; + +typedef int device_t; + +#if 0 +static SHA512_CTX kprnd_sha; +#endif + +#define timespec timeval +#define nanotime(ts) gettimeofday(ts, NULL) + +#define device_xname(a) "" +int kprintf(const char *, int, void *, char *, va_list) __printflike(1, 0); +void device_printf(device_t, const char *, ...) __printflike(2, 3); + +static void +empty(void) +{ +} + +static void (*v_flush)(void) = empty; + +ATF_TC(snprintf_print); +ATF_TC_HEAD(snprintf_print, tc) +{ + atf_tc_set_md_var(tc, "descr", "checks snprintf print"); +} + +ATF_TC_BODY(snprintf_print, tc) +{ + char buf[10]; + int i; + + memset(buf, 'x', sizeof(buf)); + i = snprintf(buf, sizeof(buf), "number %d", 10); + ATF_CHECK_EQ(i, 9); + ATF_CHECK_STREQ(buf, "number 10"); +} + +ATF_TC(snprintf_print_overflow); +ATF_TC_HEAD(snprintf_print_overflow, tc) +{ + atf_tc_set_md_var(tc, "descr", "checks snprintf print with overflow"); +} + +ATF_TC_BODY(snprintf_print_overflow, tc) +{ + char buf[10]; + int i; + + memset(buf, 'x', sizeof(buf)); + i = snprintf(buf, sizeof(buf), "fjsdfsdjfsdf %d\n", 10); + ATF_CHECK_EQ(i, 16); + ATF_CHECK_STREQ(buf, "fjsdfsdjf"); +} + +ATF_TC(snprintf_count); +ATF_TC_HEAD(snprintf_count, tc) +{ + atf_tc_set_md_var(tc, "descr", "checks snprintf count"); +} + +ATF_TC_BODY(snprintf_count, tc) +{ + int i; + + i = snprintf(NULL, 20, "number %d", 10); + ATF_CHECK_EQ(i, 9); +} + +ATF_TC(snprintf_count_overflow); +ATF_TC_HEAD(snprintf_count_overflow, tc) +{ + atf_tc_set_md_var(tc, "descr", "checks snprintf count with overflow"); +} + +ATF_TC_BODY(snprintf_count_overflow, tc) +{ + int i; + + i = snprintf(NULL, 10, "fjsdfsdjfsdf %d\n", 10); + ATF_CHECK_EQ(i, 16); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, snprintf_print); + ATF_TP_ADD_TC(tp, snprintf_print_overflow); + ATF_TP_ADD_TC(tp, snprintf_count); + ATF_TP_ADD_TC(tp, snprintf_count_overflow); + + return atf_no_error(); +} +_EOF + +awk ' +/^snprintf\(/ { + print prevline + out = 1 +} +{ + if (out) print + else prevline = $0 +}' $1 >>$2 diff --git a/contrib/netbsd-tests/kernel/h_ps_strings1.c b/contrib/netbsd-tests/kernel/h_ps_strings1.c new file mode 100644 index 0000000..64d8c71 --- /dev/null +++ b/contrib/netbsd-tests/kernel/h_ps_strings1.c @@ -0,0 +1,74 @@ +/* $NetBSD: h_ps_strings1.c,v 1.1 2011/03/05 18:14:33 pgoyette Exp $ */ +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDERS 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/exec.h> +#include <stdlib.h> +#include <unistd.h> + +extern struct ps_strings *__ps_strings; + +int +main(int argc, char **argv, char **environ) +{ + int ret = 0; + int nenv; + + if (__ps_strings->ps_nargvstr != argc) { + static const char nargv_err[] = "Wrong argc in ps_strings"; + write(STDOUT_FILENO, nargv_err, sizeof(nargv_err)); + ret = 1; + } + + if (__ps_strings->ps_argvstr != argv) { + static const char argv_err[] = "Wrong argv in ps_strings"; + write(STDOUT_FILENO, argv_err, sizeof(argv_err)); + ret = 1; + } + + if (__ps_strings->ps_envstr != environ) { + static const char env_err[] = "Wrong env in ps_strings"; + write(STDOUT_FILENO, env_err, sizeof(env_err)); + ret = 1; + } + nenv = 0; + while (environ[nenv]) + ++nenv; + if (__ps_strings->ps_nenvstr != nenv) { + static const char nenv_err[] = "Wrong nenv in ps_strings"; + write(STDOUT_FILENO, nenv_err, sizeof(nenv_err)); + ret = 1; + } + + return ret; +} diff --git a/contrib/netbsd-tests/kernel/h_ps_strings2.c b/contrib/netbsd-tests/kernel/h_ps_strings2.c new file mode 100644 index 0000000..d9c1c24 --- /dev/null +++ b/contrib/netbsd-tests/kernel/h_ps_strings2.c @@ -0,0 +1,69 @@ +/* $NetBSD: h_ps_strings2.c,v 1.1 2011/03/05 18:14:33 pgoyette Exp $ */ +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDERS 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/exec.h> +#include <err.h> +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#define LEN 16384 + +extern struct ps_strings *__ps_strings; + +int +main(void) +{ + size_t i; + char buf[16]; + char **argv; + + if ((argv = calloc(LEN, sizeof(*argv))) == NULL) + errx(1, "calloc failed"); + for (i = 0; i < LEN; ++i) { + snprintf(buf, sizeof(buf), "arg%04zx", i); + if ((argv[i] = strdup(buf)) == NULL) + errx(1, "strdup failed"); + } + __ps_strings->ps_argvstr = argv; + __ps_strings->ps_nargvstr = LEN; + + printf("Sleeping forever...\n"); + do { + sleep(UINT_MAX); + } while /* CONSTCOND */ (1); + return 0; +} diff --git a/contrib/netbsd-tests/kernel/kqueue/read/t_fifo.c b/contrib/netbsd-tests/kernel/kqueue/read/t_fifo.c new file mode 100644 index 0000000..5908547 --- /dev/null +++ b/contrib/netbsd-tests/kernel/kqueue/read/t_fifo.c @@ -0,0 +1,98 @@ +/* $NetBSD: t_fifo.c,v 1.3 2010/11/07 17:51:20 jmmv Exp $ */ + +/*- + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Luke Mewburn and Jaromir Dolecek. + * + * 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/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_fifo.c,v 1.3 2010/11/07 17:51:20 jmmv Exp $"); + +#include <sys/event.h> +#include <sys/stat.h> + +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <inttypes.h> + +#include <atf-c.h> + +#include "../../../h_macros.h" + +#define FIFONAME "fifo" + +ATF_TC(fifo); +ATF_TC_HEAD(fifo, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks EVFILT_READ on fifo"); +} +ATF_TC_BODY(fifo, tc) +{ + int kq, n, fd; + struct kevent event[1]; + char buffer[128]; + + RL(mkfifo(FIFONAME, 0644)); + RL(fd = open(FIFONAME, O_RDWR, 0644)); + + RL(kq = kqueue()); + + EV_SET(&event[0], fd, EVFILT_READ, EV_ADD|EV_ENABLE, 0, 0, 0); + RL(kevent(kq, event, 1, NULL, 0, NULL)); + + /* make sure there is something in the fifo */ + RL(write(fd, "foo", 3)); + (void)printf("fifo: wrote 'foo'\n"); + + (void)memset(event, 0, sizeof(event)); + + RL(n = kevent(kq, NULL, 0, event, 1, NULL)); + + (void)printf("kevent num %d filt %d flags: %#x, fflags: %#x, " + "data: %" PRId64 "\n", n, event[0].filter, event[0].flags, + event[0].fflags, event[0].data); + + ATF_REQUIRE_EQ(event[0].filter, EVFILT_READ); + + RL(n = read(fd, buffer, event[0].data)); + buffer[n] = '\0'; + (void)printf("fifo: read '%s'\n", buffer); + + RL(close(fd)); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, fifo); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/kernel/kqueue/read/t_file.c b/contrib/netbsd-tests/kernel/kqueue/read/t_file.c new file mode 100644 index 0000000..2335172 --- /dev/null +++ b/contrib/netbsd-tests/kernel/kqueue/read/t_file.c @@ -0,0 +1,139 @@ +/* $NetBSD: t_file.c,v 1.3 2010/11/07 17:51:20 jmmv Exp $ */ + +/*- + * Copyright (c) 2002, 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Luke Mewburn. + * + * 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/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_file.c,v 1.3 2010/11/07 17:51:20 jmmv Exp $"); + +#include <sys/param.h> +#include <sys/event.h> +#include <sys/mount.h> +#include <sys/wait.h> + +#include <err.h> +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <inttypes.h> + +#include <atf-c.h> + +#include "../../../h_macros.h" + +#define FILENAME "file" +#define NLINES 5 + +static void +child(void) +{ + int i, n, fd; + + (void)sleep(1); + + for (i = 0; i < NLINES; ++i) { + fd = open(FILENAME, O_WRONLY|O_APPEND, 0644); + if (fd < 0) + err(EXIT_FAILURE, "open()"); + + n = write(fd, "foo\n", 4); + if (n < 0) + err(EXIT_FAILURE, "write()"); + + (void)close(fd); + (void)sleep(1); + } + _exit(0); +} + +ATF_TC(file); +ATF_TC_HEAD(file, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks EVFILT_READ on regular file"); +} +ATF_TC_BODY(file, tc) +{ + char buffer[128]; + struct kevent event[1]; + pid_t pid; + int fd, kq, n, num, status; + + RL(pid = fork()); + if (pid == 0) { + child(); + /* NOTREACHED */ + } + + RL(fd = open(FILENAME, O_RDONLY|O_CREAT, 0644)); + +#if 1 /* XXX: why was this disabled? */ + RL(lseek(fd, 0, SEEK_END)); +#endif + + RL(kq = kqueue()); + + EV_SET(&event[0], fd, EVFILT_READ, EV_ADD|EV_ENABLE, 0, 0, 0); + RL(kevent(kq, event, 1, NULL, 0, NULL)); + + for (num = 0; num < NLINES;) { + RL(n = kevent(kq, NULL, 0, event, 1, NULL)); + num += n; + + (void)printf("kevent num %d flags: %#x, fflags: %#x, data: " + "%" PRId64 "\n", n, event[0].flags, event[0].fflags, + event[0].data); + + if (event[0].data < 0) +#if 1 /* XXXLUKEM */ + RL(lseek(fd, 0, SEEK_END)); +#else + RL(lseek(fd, event[0].data, SEEK_END)); +#endif + + RL(n = read(fd, buffer, 128)); + buffer[n] = '\0'; + (void)printf("file(%d): %s", num, buffer); + } + + (void)waitpid(pid, &status, 0); + + (void)printf("read: successful end\n"); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, file); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/kernel/kqueue/read/t_file2.c b/contrib/netbsd-tests/kernel/kqueue/read/t_file2.c new file mode 100644 index 0000000..c77d283 --- /dev/null +++ b/contrib/netbsd-tests/kernel/kqueue/read/t_file2.c @@ -0,0 +1,79 @@ +/* $NetBSD: t_file2.c,v 1.3 2010/11/07 17:51:20 jmmv Exp $ */ + +/*- + * Copyright (c) 2002, 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jaromir Dolecek. + * + * 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/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_file2.c,v 1.3 2010/11/07 17:51:20 jmmv Exp $"); + +#include <sys/event.h> + +#include <fcntl.h> +#include <unistd.h> + +#include <atf-c.h> + +#include "../../../h_macros.h" + +ATF_TC(file2); +ATF_TC_HEAD(file2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks EVFILT_READ for regular files. This test used to " + "trigger deadlock caused by problem fixed in revision 1.79.2.10 " + "of sys/kern/kern_descrip.c"); +} +ATF_TC_BODY(file2, tc) +{ + int fd1, fd2, kq; + struct kevent event[1]; + + RL(fd1 = open("afile", O_RDONLY|O_CREAT, 0644)); + RL(fd2 = open("bfile", O_RDONLY|O_CREAT, 0644)); + +#if 1 /* XXX: why was this disabled? */ + RL(lseek(fd1, 0, SEEK_END)); +#endif + + RL(kq = kqueue()); + + EV_SET(&event[0], fd1, EVFILT_READ, EV_ADD|EV_ENABLE, 0, 0, 0); + RL(kevent(kq, event, 1, NULL, 0, NULL)); + + RL(dup2(fd2, fd1)); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, file2); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/kernel/kqueue/read/t_pipe.c b/contrib/netbsd-tests/kernel/kqueue/read/t_pipe.c new file mode 100644 index 0000000..d8e05f2 --- /dev/null +++ b/contrib/netbsd-tests/kernel/kqueue/read/t_pipe.c @@ -0,0 +1,84 @@ +/* $NetBSD: t_pipe.c,v 1.1 2009/02/20 21:39:57 jmmv Exp $ */ + +/*- + * Copyright (c) 2002, 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Luke Mewburn and Jaromir Dolecek. + * + * 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/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_pipe.c,v 1.1 2009/02/20 21:39:57 jmmv Exp $"); + +#include <sys/event.h> + +#include <stdio.h> +#include <unistd.h> + +#include <atf-c.h> + +#include "../../../h_macros.h" + +ATF_TC(pipe); +ATF_TC_HEAD(pipe, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks EVFILT_READ for pipes"); +} +ATF_TC_BODY(pipe, tc) +{ + struct kevent event[1]; + char buffer[128]; + int fds[2]; + int kq, n; + + RL(pipe(fds)); + RL(kq = kqueue()); + + EV_SET(&event[0], fds[0], EVFILT_READ, EV_ADD|EV_ENABLE, 0, 0, 0); + RL(kevent(kq, event, 1, NULL, 0, NULL)); + + /* make sure there is something in the pipe */ + RL(write(fds[1], "foo", 3)); + (void)printf("pipe: wrote 'foo' to pipe\n"); + + RL(n = kevent(kq, NULL, 0, event, 1, NULL)); + (void)printf("kevent num %d flags: %#x, fflags: %#x, data: " + "%" PRId64 "\n", n, event[0].flags, event[0].fflags, event[0].data); + + RL(n = read(fds[0], buffer, event[0].data)); + buffer[n] = '\0'; + + (void)printf("pipe: read '%s'\n", buffer); + (void)printf("pipe: successful end\n"); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, pipe); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/kernel/kqueue/read/t_ttypty.c b/contrib/netbsd-tests/kernel/kqueue/read/t_ttypty.c new file mode 100644 index 0000000..3a42fd3 --- /dev/null +++ b/contrib/netbsd-tests/kernel/kqueue/read/t_ttypty.c @@ -0,0 +1,144 @@ +/* $NetBSD: t_ttypty.c,v 1.1 2009/02/20 21:39:57 jmmv Exp $ */ + +/*- + * Copyright (c) 2002, 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Luke Mewburn and Jaromir Dolecek. + * + * 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/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_ttypty.c,v 1.1 2009/02/20 21:39:57 jmmv Exp $"); + +#include <sys/event.h> +#include <sys/wait.h> + +#include <poll.h> +#include <stdio.h> +#include <termios.h> +#include <unistd.h> +#include <util.h> + +#include <atf-c.h> + +#include "../../../h_macros.h" + +static void +h_check(bool check_master) +{ + char slavetty[1024]; + char buffer[128]; + struct kevent event[1]; + pid_t child; + int amaster, aslave, acurrent; + int kq, n, status; +#if 0 + int fl; +#endif + struct pollfd pfd; + struct termios tio; + + RL(openpty(&amaster, &aslave, slavetty, NULL, NULL)); + + (void)printf("tty: openpty master %d slave %d tty '%s'\n", + amaster, aslave, slavetty); + acurrent = check_master ? amaster : aslave; + + RL(child = fork()); + if (child == 0) { + sleep(1); + + (void)printf("tty: child writing 'f00\\n'\n"); + (void)write(check_master ? aslave : amaster, "f00\n", 4); + + _exit(0); + } + + /* switch ONLCR off, to not get confused by newline translation */ + RL(tcgetattr(acurrent, &tio)); + tio.c_oflag &= ~ONLCR; + RL(tcsetattr(acurrent, TCSADRAIN, &tio)); + + pfd.fd = acurrent; + pfd.events = POLLIN; + (void)printf("tty: polling ...\n"); + RL(poll(&pfd, 1, INFTIM)); + (void)printf("tty: returned from poll - %d\n", pfd.revents); + +#if 0 + fl = 1; + if (ioctl(acurrent, TIOCPKT, &fl) < 0) + err(1, "ioctl"); +#endif + + RL(kq = kqueue()); + + EV_SET(&event[0], acurrent, EVFILT_READ, EV_ADD|EV_ENABLE, 0, 0, 0); + RL(kevent(kq, event, 1, NULL, 0, NULL)); + + RL(n = kevent(kq, NULL, 0, event, 1, NULL)); + + (void)printf("kevent num %d filt %d flags: %#x, fflags: %#x, " + "data: %" PRId64 "\n", n, event[0].filter, event[0].flags, + event[0].fflags, event[0].data); + + ATF_REQUIRE_EQ(event[0].filter, EVFILT_READ); + + RL(n = read(acurrent, buffer, 128)); + (void)printf("tty: read '%.*s' (n=%d)\n", n, buffer, n); + + (void)waitpid(child, &status, 0); + (void)printf("tty: successful end\n"); +} + +ATF_TC(master); +ATF_TC_HEAD(master, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks EVFILT_READ for master tty"); +} +ATF_TC_BODY(master, tc) +{ + h_check(true); +} + +ATF_TC(slave); +ATF_TC_HEAD(slave, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks EVFILT_READ for slave tty"); +} +ATF_TC_BODY(slave, tc) +{ + h_check(false); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, master); + ATF_TP_ADD_TC(tp, slave); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/kernel/kqueue/t_ioctl.c b/contrib/netbsd-tests/kernel/kqueue/t_ioctl.c new file mode 100644 index 0000000..8ed5a79 --- /dev/null +++ b/contrib/netbsd-tests/kernel/kqueue/t_ioctl.c @@ -0,0 +1,115 @@ +/* $NetBSD: t_ioctl.c,v 1.1 2009/02/20 21:39:57 jmmv Exp $ */ + +/*- + * Copyright (c) 2002, 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Luke Mewburn. + * + * 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/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_ioctl.c,v 1.1 2009/02/20 21:39:57 jmmv Exp $"); + +#include <sys/event.h> +#include <sys/ioctl.h> + +#include <stdio.h> +#include <string.h> + +#include <atf-c.h> + +#include "../../h_macros.h" + +ATF_TC(kfilter_byfilter); +ATF_TC_HEAD(kfilter_byfilter, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks KFILTER_BYFILTER ioctl"); +} +ATF_TC_BODY(kfilter_byfilter, tc) +{ + char buf[32]; + struct kfilter_mapping km; + int i, kq; + + RL(kq = kqueue()); + + km.name = buf; + km.len = sizeof(buf) - 1; + + for (i = 0; i < 7; ++i) { + km.filter = i; + RL(ioctl(kq, KFILTER_BYFILTER, &km)); + (void)printf(" map %d -> %s\n", km.filter, km.name); + } + + km.filter = 7; + ATF_REQUIRE_EQ(ioctl(kq, KFILTER_BYFILTER, &km), -1); +} + +ATF_TC(kfilter_byname); +ATF_TC_HEAD(kfilter_byname, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks KFILTER_BYNAME ioctl"); +} +ATF_TC_BODY(kfilter_byname, tc) +{ + const char *tests[] = { + "EVFILT_READ", + "EVFILT_WRITE", + "EVFILT_AIO", + "EVFILT_VNODE", + "EVFILT_PROC", + "EVFILT_SIGNAL", + "EVFILT_TIMER", + NULL + }; + char buf[32]; + struct kfilter_mapping km; + const char **test; + int kq; + + RL(kq = kqueue()); + + km.name = buf; + + for (test = &tests[0]; *test != NULL; ++test) { + (void)strlcpy(buf, *test, sizeof(buf)); + RL(ioctl(kq, KFILTER_BYNAME, &km)); + (void)printf(" map %s -> %d\n", km.name, km.filter); + } + + (void)strlcpy(buf, "NOTREG_FILTER", sizeof(buf)); + ATF_REQUIRE_EQ(ioctl(kq, KFILTER_BYNAME, &km), -1); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, kfilter_byfilter); + ATF_TP_ADD_TC(tp, kfilter_byname); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/kernel/kqueue/t_proc1.c b/contrib/netbsd-tests/kernel/kqueue/t_proc1.c new file mode 100644 index 0000000..e755309 --- /dev/null +++ b/contrib/netbsd-tests/kernel/kqueue/t_proc1.c @@ -0,0 +1,154 @@ +/* $NetBSD: t_proc1.c,v 1.1 2009/02/20 21:39:57 jmmv Exp $ */ + +/*- + * Copyright (c) 2002, 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Luke Mewburn and Jaromir Dolecek. + * + * 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/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_proc1.c,v 1.1 2009/02/20 21:39:57 jmmv Exp $"); + +/* + * this also used to trigger problem fixed in + * rev. 1.1.1.1.2.13 of sys/kern/kern_event.c + */ + +#include <sys/param.h> +#include <sys/event.h> +#include <sys/wait.h> + +#include <err.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <inttypes.h> + +#include <atf-c.h> + +#include "../../h_macros.h" + +static int +child(void) +{ + pid_t ch; + int status; + char *argv[] = { NULL, NULL }; + char *envp[] = { NULL, NULL }; + + if ((argv[0] = strdup("true")) == NULL) + err(EXIT_FAILURE, "strdup(\"true\")"); + + if ((envp[0] = strdup("FOO=BAZ")) == NULL) + err(EXIT_FAILURE, "strdup(\"FOO=BAZ\")"); + + /* Ensure parent is ready */ + (void)sleep(2); + + /* Do fork */ + switch (ch = fork()) { + case -1: + return EXIT_FAILURE; + /* NOTREACHED */ + case 0: + return EXIT_SUCCESS; + /* NOTREACHED */ + default: + wait(&status); + break; + } + + /* Exec */ + execve("/usr/bin/true", argv, envp); + + /* NOTREACHED */ + return EXIT_FAILURE; +} + +ATF_TC(proc1); +ATF_TC_HEAD(proc1, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks EVFILT_PROC"); +} +ATF_TC_BODY(proc1, tc) +{ + struct kevent event[1]; + pid_t pid; + int kq, want, status; + + RL(kq = kqueue()); + + /* fork a child for doing the events */ + RL(pid = fork()); + if (pid == 0) { + _exit(child()); + /* NOTREACHED */ + } + + (void)sleep(1); /* give child some time to come up */ + + event[0].ident = pid; + event[0].filter = EVFILT_PROC; + event[0].flags = EV_ADD | EV_ENABLE; + event[0].fflags = NOTE_EXIT | NOTE_FORK | NOTE_EXEC; /* | NOTE_TRACK;*/ + want = NOTE_EXIT | NOTE_FORK | NOTE_EXEC; + + RL(kevent(kq, event, 1, NULL, 0, NULL)); + + /* wait until we get all events we want */ + while (want) { + RL(kevent(kq, NULL, 0, event, 1, NULL)); + printf("%ld:", (long)event[0].ident); + + if (event[0].fflags & NOTE_EXIT) { + want &= ~NOTE_EXIT; + printf(" NOTE_EXIT"); + } + if (event[0].fflags & NOTE_EXEC) { + want &= ~NOTE_EXEC; + printf(" NOTE_EXEC"); + } + if (event[0].fflags & NOTE_FORK) { + want &= ~NOTE_FORK; + printf(" NOTE_FORK"); + } + if (event[0].fflags & NOTE_CHILD) + printf(" NOTE_CHILD, parent = %" PRId64, event[0].data); + + printf("\n"); + } + + (void)waitpid(pid, &status, 0); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, proc1); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/kernel/kqueue/t_proc2.c b/contrib/netbsd-tests/kernel/kqueue/t_proc2.c new file mode 100644 index 0000000..54769d6 --- /dev/null +++ b/contrib/netbsd-tests/kernel/kqueue/t_proc2.c @@ -0,0 +1,138 @@ +/* $NetBSD: t_proc2.c,v 1.1 2009/02/20 21:39:57 jmmv Exp $ */ + +/*- + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Peter Werner <Peter.Werner@wgsn.com>. + * + * 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/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_proc2.c,v 1.1 2009/02/20 21:39:57 jmmv Exp $"); + +#include <sys/event.h> +#include <sys/time.h> +#include <sys/types.h> +#include <sys/wait.h> + +#include <err.h> +#include <pwd.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#include <atf-c.h> + +#include "../../h_macros.h" + +static void +child_two(void) +{ + _exit(EXIT_SUCCESS); +} + +static void +child_one(void) +{ + pid_t pid; + struct passwd *pwd; + const char *nam = "nobody"; + + pwd = getpwnam(nam); + if (pwd == NULL) + err(EXIT_FAILURE, "getpwnam(\"%s\")", nam); + + if ((setuid(pwd->pw_uid)) == -1) + err(EXIT_FAILURE, "setuid(%d)", pwd->pw_uid); + + pid = fork(); + if (pid == -1) + err(EXIT_FAILURE, "fork()"); + + if (pid == 0) + child_two(); + + _exit(EXIT_SUCCESS); +} + +ATF_TC(proc2); +ATF_TC_HEAD(proc2, tc) +{ + atf_tc_set_md_var(tc, "require.user", "root"); + atf_tc_set_md_var(tc, "descr", + "Checks EVFILT_PROC for NOTE_FORK|NOTE_TRACK error path problem " + "fixed in rev. 1.1.1.1.2.17 of sys/kern/kern_event.c"); +} +ATF_TC_BODY(proc2, tc) +{ + pid_t pid = 0; + int kq, status; + struct kevent ke; + struct timespec timeout; + + RL(kq = kqueue()); + + timeout.tv_sec = 0; + timeout.tv_nsec = 0; + + RL(pid = fork()); + if (pid == 0) { + (void)sleep(1); /* let parent set kevent */ + child_one(); + /* NOTREACHED */ + } + + EV_SET(&ke, pid, EVFILT_PROC, EV_ADD, NOTE_FORK|NOTE_TRACK, 0, 0); + + RL(kevent(kq, &ke, 1, NULL, 0, &timeout)); + + (void)sleep(2); + + ke.ident = 0; + ke.fflags = 0; + ke.flags = EV_ENABLE; + + RL(kevent(kq, NULL, 0, &ke, 1, &timeout)); + RL(close(kq)); + + RL(waitpid(pid, &status, 0)); + ATF_REQUIRE(WIFEXITED(status)); + ATF_REQUIRE_EQ(WEXITSTATUS(status), EXIT_SUCCESS); + + /* + * we are expecting an error here as we should not have + * been able to add a knote to child 2. + */ + ATF_REQUIRE(ke.fflags & NOTE_TRACKERR); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, proc2); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/kernel/kqueue/t_proc3.c b/contrib/netbsd-tests/kernel/kqueue/t_proc3.c new file mode 100644 index 0000000..3cb9ae5 --- /dev/null +++ b/contrib/netbsd-tests/kernel/kqueue/t_proc3.c @@ -0,0 +1,99 @@ +/* $NetBSD: t_proc3.c,v 1.1 2012/11/17 21:55:24 joerg Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * 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/cdefs.h> +__RCSID("$NetBSD: t_proc3.c,v 1.1 2012/11/17 21:55:24 joerg Exp $"); + +#include <sys/event.h> +#include <sys/time.h> +#include <sys/types.h> +#include <sys/wait.h> + +#include <err.h> +#include <pwd.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#include <atf-c.h> + +#include "../../h_macros.h" + +ATF_TC(proc3); +ATF_TC_HEAD(proc3, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks EVFILT_PROC for NOTE_TRACK on self bug "); +} + +ATF_TC_BODY(proc3, tc) +{ + pid_t pid = 0; + int kq, status; + struct kevent ke; + struct timespec timeout; + + RL(kq = kqueue()); + + EV_SET(&ke, getpid(), EVFILT_PROC, EV_ADD, NOTE_TRACK, 0, 0); + + RL(kevent(kq, &ke, 1, NULL, 0, NULL)); + + RL(pid = fork()); + if (pid == 0) { + _exit(EXIT_SUCCESS); + /* NOTREACHED */ + } + + RL(waitpid(pid, &status, 0)); + ATF_REQUIRE(WIFEXITED(status)); + ATF_REQUIRE_EQ(WEXITSTATUS(status), EXIT_SUCCESS); + + timeout.tv_sec = 0; + timeout.tv_nsec = 0; + ke.ident = 0; + ke.fflags = 0; + ke.flags = EV_ENABLE; + + RL(kevent(kq, NULL, 0, &ke, 1, &timeout)); + RL(close(kq)); + + ATF_REQUIRE(ke.fflags & NOTE_CHILD); + ATF_REQUIRE((ke.fflags & NOTE_TRACKERR) == 0); + ATF_REQUIRE_EQ((pid_t)ke.ident, pid); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, proc3); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/kernel/kqueue/t_sig.c b/contrib/netbsd-tests/kernel/kqueue/t_sig.c new file mode 100644 index 0000000..4fc0758 --- /dev/null +++ b/contrib/netbsd-tests/kernel/kqueue/t_sig.c @@ -0,0 +1,133 @@ +/* $NetBSD: t_sig.c,v 1.2 2010/11/03 16:10:20 christos Exp $ */ + +/*- + * Copyright (c) 2002, 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Luke Mewburn and Jaromir Dolecek. + * + * 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/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_sig.c,v 1.2 2010/11/03 16:10:20 christos Exp $"); + +#include <sys/event.h> +#include <sys/ioctl.h> +#include <sys/param.h> +#include <sys/time.h> +#include <sys/wait.h> + +#include <inttypes.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#include <atf-c.h> + +#include "../../h_macros.h" + +#define NSIGNALS 5 + +ATF_TC(sig); +ATF_TC_HEAD(sig, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks EVFILT_SIGNAL"); +} +ATF_TC_BODY(sig, tc) +{ + struct timespec timeout; + struct kfilter_mapping km; + struct kevent event[1]; + char namebuf[32]; + pid_t pid, child; + int kq, n, num, status; + + pid = getpid(); + (void)printf("my pid: %d\n", pid); + + /* fork a child to send signals */ + RL(child = fork()); + if (child == 0) { + int i; + (void)sleep(2); + for(i = 0; i < NSIGNALS; ++i) { + (void)kill(pid, SIGUSR1); + (void)sleep(2); + } + _exit(0); + /* NOTREACHED */ + } + + RL(kq = kqueue()); + + (void)strlcpy(namebuf, "EVFILT_SIGNAL", sizeof(namebuf)); + km.name = namebuf; + RL(ioctl(kq, KFILTER_BYNAME, &km)); + (void)printf("got %d as filter number for `%s'.\n", km.filter, km.name); + + /* ignore the signal to avoid taking it for real */ + REQUIRE_LIBC(signal(SIGUSR1, SIG_IGN), SIG_ERR); + + event[0].ident = SIGUSR1; + event[0].filter = km.filter; + event[0].flags = EV_ADD | EV_ENABLE; + + RL(kevent(kq, event, 1, NULL, 0, NULL)); + + (void)sleep(1); + + timeout.tv_sec = 1; + timeout.tv_nsec = 0; + + for (num = 0; num < NSIGNALS; num += n) { + struct timeval then, now, diff; + + RL(gettimeofday(&then, NULL)); + RL(n = kevent(kq, NULL, 0, event, 1, &timeout)); + RL(gettimeofday(&now, NULL)); + timersub(&now, &then, &diff); + + (void)printf("sig: kevent returned %d in %lld.%06ld\n", + n, (long long)diff.tv_sec, (long)diff.tv_usec); + + if (n == 0) + continue; + + (void)printf("sig: kevent flags: 0x%x, data: %" PRId64 " (# " + "times signal posted)\n", event[0].flags, event[0].data); + } + + (void)waitpid(child, &status, 0); + (void)printf("sig: finished successfully\n"); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, sig); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/kernel/kqueue/write/t_fifo.c b/contrib/netbsd-tests/kernel/kqueue/write/t_fifo.c new file mode 100644 index 0000000..82b256c --- /dev/null +++ b/contrib/netbsd-tests/kernel/kqueue/write/t_fifo.c @@ -0,0 +1,102 @@ +/* $NetBSD: t_fifo.c,v 1.3 2010/11/07 17:51:20 jmmv Exp $ */ + +/*- + * Copyright (c) 2002, 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Luke Mewburn and Jaromir Dolecek. + * + * 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/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_fifo.c,v 1.3 2010/11/07 17:51:20 jmmv Exp $"); + +#include <sys/event.h> +#include <sys/stat.h> +#include <sys/wait.h> + +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <atf-c.h> + +#include "../../../h_macros.h" + +#define FIFONAME "fifo" + +ATF_TC(fifo); +ATF_TC_HEAD(fifo, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks EVFILT_WRITE for fifo"); +} +ATF_TC_BODY(fifo, tc) +{ + char buffer[128]; + struct kevent event[1]; + pid_t child; + int kq, n, fd, status; + + RL(mkfifo(FIFONAME, 0644)); + RL(fd = open(FIFONAME, O_RDWR, 0644)); + RL(kq = kqueue()); + + /* spawn child reader */ + RL(child = fork()); + if (child == 0) { + int sz = read(fd, buffer, 128); + if (sz > 0) + (void)printf("fifo: child read '%.*s'\n", sz, buffer); + _exit(sz <= 0); + } + + EV_SET(&event[0], fd, EVFILT_WRITE, EV_ADD|EV_ENABLE, 0, 0, 0); + RL(kevent(kq, event, 1, NULL, 0, NULL)); + + (void)memset(event, 0, sizeof(event)); + RL(n = kevent(kq, NULL, 0, event, 1, NULL)); + + (void)printf("kevent num %d filt %d flags: %#x, fflags: %#x, " + "data: %" PRId64 "\n", n, event[0].filter, event[0].flags, + event[0].fflags, event[0].data); + + ATF_REQUIRE_EQ(event[0].filter, EVFILT_WRITE); + + RL(write(fd, "foo", 3)); + (void)printf("fifo: wrote 'foo'\n"); + RL(close(fd)); + + (void)waitpid(child, &status, 0); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, fifo); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/kernel/kqueue/write/t_pipe.c b/contrib/netbsd-tests/kernel/kqueue/write/t_pipe.c new file mode 100644 index 0000000..459a1f7 --- /dev/null +++ b/contrib/netbsd-tests/kernel/kqueue/write/t_pipe.c @@ -0,0 +1,147 @@ +/* $NetBSD: t_pipe.c,v 1.1 2009/02/20 21:39:57 jmmv Exp $ */ + +/*- + * Copyright (c) 2002 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Luke Mewburn and Jaromir Dolecek. + * + * 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/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_pipe.c,v 1.1 2009/02/20 21:39:57 jmmv Exp $"); + +#include <sys/event.h> +#include <sys/wait.h> + +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#include <atf-c.h> + +#include "../../../h_macros.h" + +ATF_TC(pipe1); +ATF_TC_HEAD(pipe1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks EVFILT_WRITE for pipes. This test used to trigger " + "problem fixed in rev. 1.5.2.7 of sys/kern/sys_pipe.c"); +} +ATF_TC_BODY(pipe1, tc) +{ + struct kevent event[1]; + int fds[2]; + int kq, n; + + RL(pipe(fds)); + RL(kq = kqueue()); + RL(close(fds[0])); + + EV_SET(&event[0], fds[1], EVFILT_WRITE, EV_ADD|EV_ENABLE, 0, 0, 0); + ATF_REQUIRE_EQ_MSG((n = kevent(kq, event, 1, NULL, 0, NULL)), + -1, "got: %d", n); + ATF_REQUIRE_EQ_MSG(errno, EBADF, "got: %s", strerror(errno)); +} + +ATF_TC(pipe2); +ATF_TC_HEAD(pipe2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks EVFILT_WRITE for pipes. This test used to trigger problem " + "fixed in rev. 1.5.2.9 of sys/kern/sys_pipe.c"); +} +ATF_TC_BODY(pipe2, tc) +{ + struct kevent event[1]; + char buffer[128]; + int fds[2]; + int kq, n; + int status; + pid_t child; + + RL(pipe(fds)); + RL(kq = kqueue()); + + EV_SET(&event[0], fds[1], EVFILT_WRITE, EV_ADD|EV_ENABLE, 0, 0, 0); + RL(kevent(kq, event, 1, NULL, 0, NULL)); + + /* spawn child reader */ + RL(child = fork()); + if (child == 0) { + int sz = read(fds[0], buffer, 128); + if (sz > 0) + (void)printf("pipe: child read '%.*s'\n", sz, buffer); + exit(sz <= 0); + } + + RL(n = kevent(kq, NULL, 0, event, 1, NULL)); + + (void)printf("kevent num %d flags: %#x, fflags: %#x, data: " + "%" PRId64 "\n", n, event[0].flags, event[0].fflags, event[0].data); + + RL(n = write(fds[1], "foo", 3)); + RL(close(fds[1])); + + (void)waitpid(child, &status, 0); +} + +ATF_TC(pipe3); +ATF_TC_HEAD(pipe3, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks EVFILT_WRITE for pipes. This test used to trigger problem " + "fixed in rev. 1.5.2.10 of sys/kern/sys_pipe.c"); +} +ATF_TC_BODY(pipe3, tc) +{ + struct kevent event[1]; + int fds[2]; + int kq; + + RL(pipe(fds)); + RL(kq = kqueue()); + + EV_SET(&event[0], fds[1], EVFILT_WRITE, EV_ADD|EV_ENABLE, 0, 0, 0); + RL(kevent(kq, event, 1, NULL, 0, NULL)); + + /* close 'read' end first, then 'write' */ + + RL(close(fds[0])); + RL(close(fds[1])); +} + + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, pipe1); + ATF_TP_ADD_TC(tp, pipe2); + ATF_TP_ADD_TC(tp, pipe3); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/kernel/kqueue/write/t_ttypty.c b/contrib/netbsd-tests/kernel/kqueue/write/t_ttypty.c new file mode 100644 index 0000000..6983910 --- /dev/null +++ b/contrib/netbsd-tests/kernel/kqueue/write/t_ttypty.c @@ -0,0 +1,130 @@ +/* $NetBSD: t_ttypty.c,v 1.1 2009/02/20 21:39:58 jmmv Exp $ */ + +/*- + * Copyright (c) 2002, 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Luke Mewburn and Jaromir Dolecek. + * + * 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/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_ttypty.c,v 1.1 2009/02/20 21:39:58 jmmv Exp $"); + +#include <sys/event.h> +#include <sys/wait.h> + +#include <fcntl.h> +#include <poll.h> +#include <stdio.h> +#include <stdlib.h> +#include <termios.h> +#include <unistd.h> +#include <util.h> + +#include <atf-c.h> + +#include "../../../h_macros.h" + +static void +h_check(bool check_master) +{ + char slavetty[1024]; + char buffer[128]; + struct kevent event[1]; + struct pollfd pfd; + pid_t child; + int status, kq, n; + int amaster, aslave, acurrent; + + RL(openpty(&amaster, &aslave, slavetty, NULL, NULL)); + (void)printf("tty: openpty master %d slave %d tty '%s'\n", + amaster, aslave, slavetty); + acurrent = check_master ? amaster : aslave; + + RL(child = fork()); + if (child == 0) { + (void)sleep(1); + + n = read(check_master ? aslave : amaster, buffer, 128); + (void)printf("tty: child read '%.*s'\n", n, buffer); + + _exit(0); + } + + pfd.fd = acurrent; + pfd.events = POLLOUT; + (void)printf("tty: polling ...\n"); + RL(poll(&pfd, 1, INFTIM)); + (void)printf("tty: returned from poll - %d\n", pfd.revents); + + RL(kq = kqueue()); + + EV_SET(&event[0], acurrent, EVFILT_WRITE, EV_ADD|EV_ENABLE, 0, 0, 0); + RL(kevent(kq, event, 1, NULL, 0, NULL)); + + RL(n = kevent(kq, NULL, 0, event, 1, NULL)); + + (void)printf("kevent num %d filt %d flags: %#x, fflags: %#x, data: " + "%" PRId64 "\n", n, event[0].filter, event[0].flags, event[0].fflags, + event[0].data); + + ATF_REQUIRE_EQ(event[0].filter, EVFILT_WRITE); + + RL(n = write(acurrent, "f00\n", 4)); + (void)printf("tty: wrote 'f00\\n' (wrote %d characters)\n", n); + + (void)waitpid(child, &status, 0); + (void)printf("tty: successful end\n"); +} + +ATF_TC(master); +ATF_TC_HEAD(master, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks EVFILT_WRITE for master tty"); +} +ATF_TC_BODY(master, tc) +{ + h_check(true); +} + +ATF_TC(slave); +ATF_TC_HEAD(slave, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks EVFILT_WRITE for slave tty"); +} +ATF_TC_BODY(slave, tc) +{ + h_check(false); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, master); + ATF_TP_ADD_TC(tp, slave); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/kernel/t_extattrctl.c b/contrib/netbsd-tests/kernel/t_extattrctl.c new file mode 100644 index 0000000..2f8932e --- /dev/null +++ b/contrib/netbsd-tests/kernel/t_extattrctl.c @@ -0,0 +1,28 @@ +#include <sys/types.h> + +#include <rump/rump.h> +#include <rump/rump_syscalls.h> + +#include <atf-c.h> + +ATF_TC(extattrctl_namei); +ATF_TC_HEAD(extattrctl_namei, tc) +{ + + atf_tc_set_md_var(tc, "descr", "extattrctl namei safety (kern/43328)"); +} + +ATF_TC_BODY(extattrctl_namei, tc) +{ + + rump_init(); + + rump_sys_extattrctl("/anyfile", 0, "/", 0, 0); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, extattrctl_namei); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/kernel/t_extent.c b/contrib/netbsd-tests/kernel/t_extent.c new file mode 100644 index 0000000..faefafa --- /dev/null +++ b/contrib/netbsd-tests/kernel/t_extent.c @@ -0,0 +1,385 @@ +/* $NetBSD: t_extent.c,v 1.4 2012/01/27 18:53:10 para Exp $ */ + +/*- + * Copyright (c) 2008 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/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_extent.c,v 1.4 2012/01/27 18:53:10 para Exp $"); + +#include <sys/types.h> +#include <sys/queue.h> +#include <sys/extent.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <atf-c.h> + +#include "../h_macros.h" + +static int ret; +static struct extent *ex; + +#define h_create(name, start, end, flags) \ + ATF_REQUIRE((ex = extent_create(name, \ + start, end, 0, 0, flags)) != NULL); + +#define h_alloc_region(start, size) \ + ATF_REQUIRE_EQ_MSG(ret = extent_alloc_region(ex, \ + start, size, 0), 0, "%s", strerror(ret)); + +#define h_free(start, size) \ + ATF_REQUIRE_EQ_MSG(ret = extent_free(ex, \ + start, size, 0), 0, "%s", strerror(ret)); + +static void +h_alloc_subregion(u_long substart, u_long subend, u_long size, + u_long alignment, u_long boundary, int expret, u_long expres) +{ + u_long result; + +#define FAIL(fmt, ...) \ + atf_tc_fail("extent_alloc_subregion1(ex, %#lx, %#lx, %#lx, %#lx, 0, " \ + "%#lx, 0, &result): " fmt, substart, subend, size, alignment, \ + boundary, ##__VA_ARGS__) + + ret = extent_alloc_subregion1(ex, substart, subend, size, + alignment, 0, boundary, 0, &result); + + if (ret != expret) + FAIL("%s", strerror(errno)); + + if (expret == 0 && result != expres) + FAIL("result should be: %#lx, got: %#lx", expres, result); +#undef FAIL +} + +static void +h_require(const char *name, u_long start, + u_long end, int flags, const char *exp) +{ + char buf[4096]; + struct extent_region *rp; + int n = 0; + + ATF_REQUIRE_STREQ_MSG(ex->ex_name, name, + "expected: \"%s\", got: \"%s\"", name, ex->ex_name); + ATF_REQUIRE_EQ_MSG(ex->ex_start, start, + "expected: %#lx, got: %#lx", start, ex->ex_start); + ATF_REQUIRE_EQ_MSG(ex->ex_end, end, + "expected: %#lx, got: %#lx", end, ex->ex_end); + ATF_REQUIRE_EQ_MSG(ex->ex_flags, flags, + "expected: %#x, got: %#x", flags, ex->ex_flags); + + (void)memset(buf, 0, sizeof(buf)); + LIST_FOREACH(rp, &ex->ex_regions, er_link) + n += snprintf(buf + n, sizeof(buf) - n, + "0x%lx - 0x%lx\n", rp->er_start, rp->er_end); + + if (strcmp(buf, exp) == 0) + return; + + printf("Incorrect extent map\n"); + printf("Expected:\n%s\n", exp); + printf("Got:\n%s\n", buf); + atf_tc_fail("incorrect extent map"); +} + +ATF_TC(coalesce); +ATF_TC_HEAD(coalesce, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks coalescing of regions"); +} +ATF_TC_BODY(coalesce, tc) +{ + h_create("test1", 0, 0x4f, 0); + + h_alloc_region(0x00, 0x10); + h_alloc_region(0x20, 0x10); + h_alloc_region(0x40, 0x10); + h_alloc_region(0x10, 0x10); + h_alloc_subregion(0, 0x4f, 0x10, EX_NOALIGN, EX_NOBOUNDARY, 0, 0x30); + + h_require("test1", 0x00, 0x4f, 0x00, + "0x0 - 0x4f\n"); + + extent_destroy(ex); +} + +ATF_TC(subregion1); +ATF_TC_HEAD(subregion1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks that subregions work (PR kern/7539)"); +} +ATF_TC_BODY(subregion1, tc) +{ + h_create("test2", 0, 0x2f, EX_NOCOALESCE); + + h_alloc_region(0x00, 0x10); + h_alloc_subregion(0x20, 0x30, 0x10, EX_NOALIGN, EX_NOBOUNDARY, 0, 0x20); + + h_require("test2", 0x00, 0x2f, 0x2, + "0x0 - 0xf\n" + "0x20 - 0x2f\n"); + + extent_destroy(ex); +} + +ATF_TC(subregion2); +ATF_TC_HEAD(subregion2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks that subregion allocations don't overlap with existing " + "ones (fixed in 1.25)"); +} +ATF_TC_BODY(subregion2, tc) +{ + h_create("test3", 0, 0x3f, EX_NOCOALESCE); + + h_alloc_region(0x00, 0x20); + h_alloc_region(0x30, 0x10); + h_alloc_subregion(0x10, 0x3f, 0x10, + EX_NOALIGN, EX_NOBOUNDARY, 0, 0x20); + + h_require("test3", 0x00, 0x3f, 0x2, + "0x0 - 0x1f\n" + "0x20 - 0x2f\n" + "0x30 - 0x3f\n"); + + extent_destroy(ex); +} + +ATF_TC(bound1); +ATF_TC_HEAD(bound1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks for overflow in boundary check, before an allocated region " + "(fixed in 1.32)"); +} +ATF_TC_BODY(bound1, tc) +{ + h_create("test4", 0xf0000000, 0xffffffff, 0); + + h_alloc_region(0xf1000000, 0x1); + h_alloc_subregion(0xf0000000, 0xffffffff, 0x1, + EX_NOALIGN, 0x20000000, 0, 0xf0000000); + + h_require("test4", 0xf0000000, 0xffffffff, 0x0, + "0xf0000000 - 0xf0000000\n" + "0xf1000000 - 0xf1000000\n"); + + extent_destroy(ex); +} + +ATF_TC(bound2); +ATF_TC_HEAD(bound2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks for overflow in boundary checks, before the subregion end " + "(fixed in 1.32)"); +} +ATF_TC_BODY(bound2, tc) +{ + h_create("test5", 0xf0000000, 0xffffffff, 0); + + h_alloc_subregion(0xf0000000, 0xffffffff, 0x1, + EX_NOALIGN, 0x20000000, 0, 0xf0000000); + + h_require("test5", 0xf0000000, 0xffffffff, 0x0, + "0xf0000000 - 0xf0000000\n"); + + extent_destroy(ex); +} + +ATF_TC(bound3); +ATF_TC_HEAD(bound3, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks allocation beyond last boundary line: last two " + "allocations should succeed without boundary \"fixups\""); +} +ATF_TC_BODY(bound3, tc) +{ + h_create("test6", 0, 11, 0); + + h_alloc_subregion(0, 11, 8, EX_NOALIGN, 8, 0, 0); + h_alloc_subregion(0, 11, 2, EX_NOALIGN, 8, 0, 0x8); + h_alloc_subregion(0, 11, 2, EX_NOALIGN, 8, 0, 0xa); + + h_require("test6", 0x0, 0xb, 0x0, "0x0 - 0xb\n"); + + extent_destroy(ex); +} + +ATF_TC(bound4); +ATF_TC_HEAD(bound4, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks allocation beyond last boundary line: last allocation " + "should be bumped to the next boundary and exactly fit the " + "remaining space"); +} +ATF_TC_BODY(bound4, tc) +{ + h_create("test7", 0, 11, 0); + + h_alloc_subregion(0, 11, 7, EX_NOALIGN, 8, 0, 0); + h_alloc_subregion(0, 11, 4, EX_NOALIGN, 8, 0, 8); + + h_require("test7", 0x0, 0xb, 0x0, + "0x0 - 0x6\n" + "0x8 - 0xb\n"); + + extent_destroy(ex); +} + +ATF_TC(subregion3); +ATF_TC_HEAD(subregion3, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks that we don't allocate a region pasts the end of " + "subregion (i.e., the second alloc_subregion should fail). " + "subr_extent.c prior to rev. 1.43 allocated region starting " + "from 0x10"); +} +ATF_TC_BODY(subregion3, tc) +{ + h_create("test8", 0, 0x4f, EX_NOCOALESCE); + + h_alloc_region(0x30, 0x10); + h_alloc_subregion(0, 0xf, 0x10, EX_NOALIGN, EX_NOBOUNDARY, 0, 0); + h_alloc_subregion(0, 0xf, 0x10, EX_NOALIGN, EX_NOBOUNDARY, EAGAIN, 0); + + h_require("test8", 0x0, 0x4f, 0x2, + "0x0 - 0xf\n" + "0x30 - 0x3f\n"); + + extent_destroy(ex); +} + +ATF_TC(bound5); +ATF_TC_HEAD(bound5, tc) +{ + atf_tc_set_md_var(tc, "descr", + "When allocating a region with a boundary constraint, checks " + "proper detection of overflaps once the candidate region has " + "been aligned. subr_extent.c prior 1.45 could corrupt the extent " + "map in this situation"); +} +ATF_TC_BODY(bound5, tc) +{ + h_create("test9", 0, 0x4f, 0); + + h_alloc_subregion(0, 0x10, 4, EX_NOALIGN, 0, 0, 0); + h_alloc_subregion(0xd, 0x20, 2, EX_NOALIGN, 0, 0, 0xd); + h_alloc_subregion(0, 0x4f, 8, EX_NOALIGN, 8, 0, 0x10); + + h_require("test9", 0x0, 0x4f, 0x0, + "0x0 - 0x3\n" + "0xd - 0xe\n" + "0x10 - 0x17\n"); + + extent_destroy(ex); +} + +ATF_TC(free); +ATF_TC_HEAD(free, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks extent_free()"); +} +ATF_TC_BODY(free, tc) +{ + h_create("test10", 0xc0002000, 0xffffe000, EX_BOUNDZERO); + + h_alloc_subregion(0xc0002000, 0xffffe000, 0x2000, + 0x10000, 0x10000, 0, 0xc0010000); + h_alloc_subregion(0xc0002000, 0xffffe000, 0x2000, + 0x10000, 0x10000, 0, 0xc0020000); + + h_require("test10", 0xc0002000, 0xffffe000, 0x0, + "0xc0010000 - 0xc0011fff\n" + "0xc0020000 - 0xc0021fff\n"); + + h_free(0xc0020000, 0x2000); + h_require("test10", 0xc0002000, 0xffffe000, 0x0, + "0xc0010000 - 0xc0011fff\n"); + + h_alloc_subregion(0xc0002000, 0xffffe000, 0x10000, + 0x10000, 0x10000, 0, 0xc0022000); + + h_require("test10", 0xc0002000, 0xffffe000, 0x0, + "0xc0010000 - 0xc0011fff\n" + "0xc0022000 - 0xc0031fff\n"); + + extent_destroy(ex); +} + +ATF_TC(subregion4); +ATF_TC_HEAD(subregion4, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks for off-by-one bug which would cause a region at the end " + "of the extent to be allocated multiple times (fixed in 1.51)"); +} +ATF_TC_BODY(subregion4, tc) +{ + h_create("test11", 0x10, 0x20, EX_NOCOALESCE); + + h_alloc_subregion(0x10, 0x13, 0x4, EX_NOALIGN, EX_NOBOUNDARY, 0, 0x10); + h_alloc_subregion(0x1e, 0x1f, 0x2, EX_NOALIGN, EX_NOBOUNDARY, 0, 0x1e); + h_alloc_subregion(0x20, 0x20, 0x1, EX_NOALIGN, EX_NOBOUNDARY, 0, 0x20); + h_alloc_subregion(0x20, 0x20, 0x1, EX_NOALIGN, EX_NOBOUNDARY, EAGAIN, 0); + h_alloc_subregion(0x10, 0x20, 0x1, EX_NOALIGN, EX_NOBOUNDARY, 0, 0x14); + + h_require("test11", 0x10, 0x20, 0x2, + "0x10 - 0x13\n" + "0x14 - 0x14\n" + "0x1e - 0x1f\n" + "0x20 - 0x20\n"); + + extent_destroy(ex); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, coalesce); + ATF_TP_ADD_TC(tp, subregion1); + ATF_TP_ADD_TC(tp, subregion2); + ATF_TP_ADD_TC(tp, bound1); + ATF_TP_ADD_TC(tp, bound2); + ATF_TP_ADD_TC(tp, bound3); + ATF_TP_ADD_TC(tp, bound4); + ATF_TP_ADD_TC(tp, subregion3); + ATF_TP_ADD_TC(tp, bound5); + ATF_TP_ADD_TC(tp, free); + ATF_TP_ADD_TC(tp, subregion4); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/kernel/t_filedesc.c b/contrib/netbsd-tests/kernel/t_filedesc.c new file mode 100644 index 0000000..6b367ee --- /dev/null +++ b/contrib/netbsd-tests/kernel/t_filedesc.c @@ -0,0 +1,108 @@ +/* $NetBSD: t_filedesc.c,v 1.5 2012/03/18 09:46:50 jruoho 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/cdefs.h> +__RCSID("$NetBSD: t_filedesc.c,v 1.5 2012/03/18 09:46:50 jruoho Exp $"); + +#include <sys/types.h> + +#include <assert.h> +#include <atf-c.h> +#include <fcntl.h> +#include <stdlib.h> +#include <pthread.h> + +#include <rump/rump.h> +#include <rump/rump_syscalls.h> + +#include "../h_macros.h" + +ATF_TC(getfilerace); +ATF_TC_HEAD(getfilerace, tc) +{ + + atf_tc_set_md_var(tc, "descr", "race between multithreaded proc. " + "fd_getfile() and fd_close() (PR kern/43694)"); +} + +static int fd; +static volatile bool quit; + +static void * +wrkwrk(void *arg) +{ + + /* just something to cause fd_getfile() to be called */ + while (!quit) + rump_sys_write(fd, &fd, sizeof(fd)); + + return NULL; +} + +/* for me, 1000 triggers extremely seldom, 10k sometimes, 100k almost always */ +#define DEFAULT_ITERATIONS 10000 + +ATF_TC_BODY(getfilerace, tc) +{ + pthread_t pt; + int fd_wrk; + int i, iters; + + /* + * Want a multiprocessor virtual kernel. A multiprocessor host + * probably helps too, but that's harder to do in software... + */ + setenv("RUMP_NCPU", "2", 1); + rump_init(); + + fd = fd_wrk = rump_sys_open("/dev/null", O_RDWR, 0); + if (fd == -1) + atf_tc_fail_errno("cannot open /dev/null"); + + if (atf_tc_has_config_var(tc, "iters")) + iters = atoi(atf_tc_get_config_var(tc, "iters")); + else + iters = DEFAULT_ITERATIONS; + + pthread_create(&pt, NULL, wrkwrk, NULL); + for (i = 0; i < iters; i++) { + rump_sys_close(fd_wrk); + fd_wrk = rump_sys_open("/dev/null", O_RDWR, 0); + assert(fd == fd_wrk); + } + + quit = true; + pthread_join(pt, NULL); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, getfilerace); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/kernel/t_kauth_pr_47598.c b/contrib/netbsd-tests/kernel/t_kauth_pr_47598.c new file mode 100644 index 0000000..f54b289 --- /dev/null +++ b/contrib/netbsd-tests/kernel/t_kauth_pr_47598.c @@ -0,0 +1,169 @@ +/*- + * Copyright (c) 2013 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/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2013\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_kauth_pr_47598.c,v 1.3 2014/04/28 08:34:16 martin Exp $"); + +#include <errno.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/sysctl.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <atf-c.h> + +/* + * helper function + */ +static const char curtain_name[] = "security.models.bsd44.curtain"; +static const char securelevel_name[] = "security.models.bsd44.securelevel"; + +static bool may_lower_curtain(void); +static int get_curtain(void); +static void set_curtain(int newval); + +static bool +may_lower_curtain(void) +{ + int seclevel; + size_t len = sizeof(seclevel); + + if (sysctlbyname(securelevel_name, &seclevel, &len, NULL, 0) != 0) + atf_tc_fail("failed to read %s", securelevel_name); + + return seclevel <= 0; +} + +static int +get_curtain(void) +{ + int curtain; + size_t len = sizeof(curtain); + + if (sysctlbyname(curtain_name, &curtain, &len, NULL, 0) != 0) + atf_tc_fail("failed to read %s", curtain_name); + + return curtain; +} + +static void +set_curtain(int newval) +{ + + if (sysctlbyname(curtain_name, NULL, 0, &newval, sizeof(newval)) != 0) + atf_tc_fail("failed to set %s to %d", curtain_name, newval); +} + +/* + * PR kern/47598: if security.models.extensions.curtain = 1 we crash when + * doing a netstat while an embryonic (not yet fully accepted) connection + * exists. + * This has been fixed with rev. 1.5 of + * src/sys/secmodel/extensions/secmodel_extensions.c. + */ + + +ATF_TC(kauth_curtain); +ATF_TC_HEAD(kauth_curtain, tc) +{ + atf_tc_set_md_var(tc, "require.user", "root"); + atf_tc_set_md_var(tc, "require.progs", "netstat"); + atf_tc_set_md_var(tc, "descr", + "Checks for kernel crash with curtain active (PR kern/47598)"); +} + +ATF_TC_BODY(kauth_curtain, tc) +{ + + int old_curtain, s, s2, err; + socklen_t slen; + struct sockaddr_in sa; + + /* + * save old value of "curtain" and enable it + */ + old_curtain = get_curtain(); + if (old_curtain < 1 && !may_lower_curtain()) + atf_tc_skip("curtain is not enabled and we would not be able" + " to drop it later due to securelevel settings"); + + set_curtain(1); + + /* + * create a socket and bind it to some arbitray free port + */ + s = socket(PF_INET, SOCK_STREAM|SOCK_NONBLOCK, 0); + ATF_REQUIRE(s != -1); + memset(&sa, 0, sizeof(sa)); + sa.sin_family = AF_INET; + sa.sin_len = sizeof(sa); + sa.sin_addr.s_addr = inet_addr("127.0.0.1"); + ATF_REQUIRE(bind(s, (struct sockaddr *)&sa, sizeof(sa))==0); + ATF_REQUIRE(listen(s, 16)==0); + + /* + * extract address and open a connection to the port + */ + slen = sizeof(sa); + ATF_REQUIRE(getsockname(s, (struct sockaddr *)&sa, &slen)==0); + s2 = socket(PF_INET, SOCK_STREAM|SOCK_NONBLOCK, 0); + ATF_REQUIRE(s2 != -1); + printf("port is %d\n", ntohs(sa.sin_port)); + err = connect(s2, (struct sockaddr *)&sa, sizeof(sa)); + ATF_REQUIRE_MSG(err == -1 && errno == EINPROGRESS, + "conect returned %d with errno %d", err, errno); + fflush(stdout); + fflush(stderr); + + /* + * we now have a pending, not yet accepted connection - run netstat + */ + system("netstat -aA"); + + /* + * cleanup + */ + close(s2); + close(s); + + /* + * restore old value of curtain + */ + set_curtain(old_curtain); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, kauth_curtain); + + return atf_no_error(); +} + + diff --git a/contrib/netbsd-tests/kernel/t_lock.c b/contrib/netbsd-tests/kernel/t_lock.c new file mode 100644 index 0000000..3704afb --- /dev/null +++ b/contrib/netbsd-tests/kernel/t_lock.c @@ -0,0 +1,87 @@ +/* $NetBSD: t_lock.c,v 1.1 2009/02/20 21:39:57 jmmv Exp $ */ + +/*- + * Copyright (c) 2002, 2008 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/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_lock.c,v 1.1 2009/02/20 21:39:57 jmmv Exp $"); + +#include <sys/time.h> + +#include <machine/lock.h> +#include <signal.h> + +#include <atf-c.h> + +#include "../h_macros.h" + +__cpu_simple_lock_t lk; +volatile int handled = 0; + +static void +handler(int sig) +{ + handled = 1; + __cpu_simple_unlock(&lk); +} + +ATF_TC(lock); +ATF_TC_HEAD(lock, tc) +{ + atf_tc_set_md_var(tc, "timeout", "3"); + atf_tc_set_md_var(tc, "descr", + "Checks __cpu_simple_lock()/__cpu_simple_unlock()"); +} +ATF_TC_BODY(lock, tc) +{ + struct itimerval itv; + + __cpu_simple_lock_init(&lk); + + REQUIRE_LIBC(signal(SIGVTALRM, handler), SIG_ERR); + + itv.it_interval.tv_sec = 0; + itv.it_interval.tv_usec = 0; + itv.it_value.tv_sec = 1; + itv.it_value.tv_usec = 0; + RL(setitimer(ITIMER_VIRTUAL, &itv, NULL)); + + __cpu_simple_lock(&lk); + __cpu_simple_lock(&lk); + + ATF_REQUIRE(handled); + + __cpu_simple_unlock(&lk); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, lock); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/kernel/t_lockf.c b/contrib/netbsd-tests/kernel/t_lockf.c new file mode 100644 index 0000000..d937301 --- /dev/null +++ b/contrib/netbsd-tests/kernel/t_lockf.c @@ -0,0 +1,262 @@ +/* $NetBSD: t_lockf.c,v 1.9 2013/10/19 17:45:00 christos Exp $ */ + +/*- + * Copyright (c) 2000 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 <atf-c.h> +#include <err.h> +#include <errno.h> +#include <fcntl.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <sys/types.h> +#include <sys/wait.h> +#include <sys/ptrace.h> + +/* + * lockf1 regression test: + * + * Tests: + * Fork N child processes, each of which gets M random byte range locks + * on a common file. We ignore all lock errors (practically speaking, + * this means EDEADLK or ENOLOCK), but we make numerous passes over all + * the children to make sure that they are still awake. (We do this by + * verifying that we can ptrace(ATTACH/DETACH) to the children and get + * their status via waitpid().) + * When finished, reap all the children. + */ + +#define nlocks 500 /* number of locks per thread */ +#define nprocs 10 /* number of processes to spawn */ +#define npasses 50 /* number of passes to make over the children */ +#define sleeptime 150000 /* sleep time between locks, usec */ +#define filesize 8192 /* size of file to lock */ + +const char *lockfile = "lockf_test"; + +static u_int32_t +random_uint32(void) +{ + return lrand48(); +} + +static void +trylocks(int id) +{ + int i, fd; + + srand48(getpid()); + + fd = open (lockfile, O_RDWR, 0); + + if (fd < 0) + err(1, "%s", lockfile); + + printf("%d: start\n", id); + + for (i = 0; i < nlocks; i++) { + struct flock fl; + + fl.l_start = random_uint32() % filesize; + fl.l_len = random_uint32() % filesize; + switch (random_uint32() % 3) { + case 0: + fl.l_type = F_RDLCK; + break; + case 1: + fl.l_type = F_WRLCK; + break; + case 2: + fl.l_type = F_UNLCK; + break; + } + fl.l_whence = SEEK_SET; + + (void)fcntl(fd, F_SETLKW, &fl); + + if (usleep(sleeptime) < 0) + err(1, "usleep"); + } + printf("%d: done\n", id); + close (fd); +} + +ATF_TC(randlock); +ATF_TC_HEAD(randlock, tc) +{ + + atf_tc_set_md_var(tc, "timeout", "300"); + atf_tc_set_md_var(tc, "descr", "Checks fcntl(2) locking"); +} + +ATF_TC_BODY(randlock, tc) +{ + int i, j, fd; + int pipe_fd[2]; + pid_t *pid; + int status; + char pipe_in, pipe_out; + const char pipe_errmsg[] = "child: pipe write failed\n"; + + (void)unlink(lockfile); + + fd = open (lockfile, O_RDWR|O_CREAT|O_EXCL|O_TRUNC, 0666); + ATF_REQUIRE_MSG(fd >= 0, "open(%s): %s", lockfile, strerror(errno)); + + ATF_REQUIRE_MSG(ftruncate(fd, filesize) >= 0, + "ftruncate(%s): %s", lockfile, strerror(errno)); + + ATF_REQUIRE_MSG(pipe(pipe_fd) == 0, "pipe: %s", strerror(errno)); + + fsync(fd); + close(fd); + + pid = malloc(nprocs * sizeof(pid_t)); + + for (i = 0; i < nprocs; i++) { + pipe_out = (char)('A' + i); + pid[i] = fork(); + switch (pid[i]) { + case 0: + if (write(pipe_fd[1], &pipe_out, 1) != 1) + write(STDERR_FILENO, pipe_errmsg, + __arraycount(pipe_errmsg) - 1); + else + trylocks(i); + _exit(0); + break; + case -1: + atf_tc_fail("fork %d failed", i); + break; + default: + ATF_REQUIRE_MSG(read(pipe_fd[0], &pipe_in, 1) == 1, + "parent: read_pipe(%i): %s", i, strerror(errno)); + ATF_REQUIRE_MSG(pipe_in == pipe_out, + "parent: pipe does not match"); + break; + } + } + for (j = 0; j < npasses; j++) { + printf("parent: run %i\n", j+1); + for (i = 0; i < nprocs; i++) { + ATF_REQUIRE_MSG(ptrace(PT_ATTACH, pid[i], 0, 0) >= 0, + "ptrace attach %d", pid[i]); + ATF_REQUIRE_MSG(waitpid(pid[i], &status, WUNTRACED) >= 0, + "waitpid(ptrace)"); + usleep(sleeptime / 3); + ATF_REQUIRE_MSG(ptrace(PT_DETACH, pid[i], (caddr_t)1, + 0) >= 0, + "ptrace detach %d", pid[i]); + usleep(sleeptime / 3); + } + } + for (i = 0; i < nprocs; i++) { + printf("reap %d: ", i); + fflush(stdout); + kill(pid[i], SIGINT); + waitpid(pid[i], &status, 0); + printf(" status %d\n", status); + } + atf_tc_pass(); +} + +static int +dolock(int fd, int op, off_t lk_off, off_t lk_size) +{ + off_t result; + int ret; + + result = lseek(fd, lk_off, SEEK_SET); + if (result == -1) { + return errno; + } + ATF_REQUIRE_MSG(result == lk_off, "lseek to wrong offset"); + ret = lockf(fd, op, lk_size); + if (ret == -1) { + return errno; + } + return 0; +} + +ATF_TC(deadlock); +ATF_TC_HEAD(deadlock, tc) +{ + + atf_tc_set_md_var(tc, "timeout", "30"); + atf_tc_set_md_var(tc, "descr", "Checks fcntl(2) deadlock detection"); +} + +ATF_TC_BODY(deadlock, tc) +{ + int fd; + int error; + int ret; + pid_t pid; + + (void)unlink(lockfile); + + fd = open (lockfile, O_RDWR|O_CREAT|O_EXCL|O_TRUNC, 0666); + ATF_REQUIRE_MSG(fd >= 0, "open(%s): %s", lockfile, strerror(errno)); + + ATF_REQUIRE_MSG(ftruncate(fd, filesize) >= 0, + "ftruncate(%s): %s", lockfile, strerror(errno)); + + fsync(fd); + + error = dolock(fd, F_LOCK, 0, 1); + ATF_REQUIRE_MSG(error == 0, "initial dolock: %s", strerror(errno)); + + pid = fork(); + ATF_REQUIRE_MSG(pid != -1, "fork failed: %s", strerror(errno)); + if (pid == 0) { + error = dolock(fd, F_LOCK, 1, 1); + ATF_REQUIRE_MSG(error == 0, "child dolock: %s", + strerror(errno)); + dolock(fd, F_LOCK, 0, 1); /* will block */ + atf_tc_fail("child did not block"); + } + sleep(1); /* give child time to grab its lock then block */ + + error = dolock(fd, F_LOCK, 1, 1); + ATF_REQUIRE_MSG(error == EDEADLK, "parent did not detect deadlock: %s", + strerror(errno)); + ret = kill(pid, SIGKILL); + ATF_REQUIRE_MSG(ret != -1, "failed to kill child: %s", strerror(errno)); + + atf_tc_pass(); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, randlock); + ATF_TP_ADD_TC(tp, deadlock); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/kernel/t_mqueue.c b/contrib/netbsd-tests/kernel/t_mqueue.c new file mode 100644 index 0000000..2a03101 --- /dev/null +++ b/contrib/netbsd-tests/kernel/t_mqueue.c @@ -0,0 +1,137 @@ +/* $NetBSD: t_mqueue.c,v 1.4 2014/03/02 19:56:48 jmmv Exp $ */ + +/* + * Test for POSIX message queue priority handling. + * + * This file is in the Public Domain. + */ + +#include <atf-c.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <unistd.h> + +#include <mqueue.h> + +#define MQ_PRIO_BASE 24 + +static void +send_msgs(mqd_t mqfd) +{ + char msg[2]; + + msg[1] = '\0'; + + msg[0] = 'a'; + ATF_REQUIRE_MSG(mq_send(mqfd, msg, sizeof(msg), MQ_PRIO_BASE) != -1, + "mq_send 1 failed: %d", errno); + + msg[0] = 'b'; + ATF_REQUIRE_MSG(mq_send(mqfd, msg, sizeof(msg), MQ_PRIO_BASE + 1) != -1, + "mq_send 2 failed: %d", errno); + + msg[0] = 'c'; + ATF_REQUIRE_MSG(mq_send(mqfd, msg, sizeof(msg), MQ_PRIO_BASE) != -1, + "mq_send 3 failed: %d", errno); + + msg[0] = 'd'; + ATF_REQUIRE_MSG(mq_send(mqfd, msg, sizeof(msg), MQ_PRIO_BASE - 1) != -1, + "mq_send 4 failed: %d", errno); + + msg[0] = 'e'; + ATF_REQUIRE_MSG(mq_send(mqfd, msg, sizeof(msg), 0) != -1, + "mq_send 5 failed: %d", errno); + + msg[0] = 'f'; + ATF_REQUIRE_MSG(mq_send(mqfd, msg, sizeof(msg), MQ_PRIO_BASE + 1) != -1, + "mq_send 6 failed: %d", errno); +} + +static void +receive_msgs(mqd_t mqfd) +{ + struct mq_attr mqa; + char *m; + unsigned p; + int len; + + ATF_REQUIRE_MSG(mq_getattr(mqfd, &mqa) != -1, "mq_getattr failed %d", + errno); + + len = mqa.mq_msgsize; + m = calloc(1, len); + ATF_REQUIRE_MSG(m != NULL, "calloc failed"); + + ATF_REQUIRE_MSG(mq_receive(mqfd, m, len, &p) != -1, + "mq_receive 1 failed: %d", errno); + ATF_REQUIRE_MSG(p == (MQ_PRIO_BASE + 1) && m[0] == 'b', + "mq_receive 1 prio/data mismatch"); + + ATF_REQUIRE_MSG(mq_receive(mqfd, m, len, &p) != -1, + "mq_receive 2 failed: %d", errno); + ATF_REQUIRE_MSG(p == (MQ_PRIO_BASE + 1) && m[0] == 'f', + "mq_receive 2 prio/data mismatch"); + + ATF_REQUIRE_MSG(mq_receive(mqfd, m, len, &p) != -1, + "mq_receive 3 failed: %d", errno); + ATF_REQUIRE_MSG(p == MQ_PRIO_BASE && m[0] == 'a', + "mq_receive 3 prio/data mismatch"); + + ATF_REQUIRE_MSG(mq_receive(mqfd, m, len, &p) != -1, + "mq_receive 4 failed: %d", errno); + ATF_REQUIRE_MSG(p == MQ_PRIO_BASE && m[0] == 'c', + "mq_receive 4 prio/data mismatch"); + + ATF_REQUIRE_MSG(mq_receive(mqfd, m, len, &p) != -1, + "mq_receive 5 failed: %d", errno); + ATF_REQUIRE_MSG(p == (MQ_PRIO_BASE - 1) && m[0] == 'd', + "mq_receive 5 prio/data mismatch"); + + ATF_REQUIRE_MSG(mq_receive(mqfd, m, len, &p) != -1, + "mq_receive 6 failed: %d", errno); + ATF_REQUIRE_MSG(p == 0 && m[0] == 'e', + "mq_receive 6 prio/data mismatch"); +} + +ATF_TC(mqueue); +ATF_TC_HEAD(mqueue, tc) +{ + + atf_tc_set_md_var(tc, "timeout", "3"); + atf_tc_set_md_var(tc, "descr", "Checks mqueue send/receive"); +} + +ATF_TC_BODY(mqueue, tc) +{ + int status; + char *tmpdir; + char template[32]; + char mq_name[64]; + + strlcpy(template, "./t_mqueue.XXXXXX", sizeof(template)); + tmpdir = mkdtemp(template); + ATF_REQUIRE_MSG(tmpdir != NULL, "mkdtemp failed: %d", errno); + snprintf(mq_name, sizeof(mq_name), "%s/mq", tmpdir); + + mqd_t mqfd; + + mqfd = mq_open(mq_name, O_RDWR | O_CREAT, + S_IRUSR | S_IRWXG | S_IROTH, NULL); + ATF_REQUIRE_MSG(mqfd != -1, "mq_open failed: %d", errno); + + send_msgs(mqfd); + receive_msgs(mqfd); + + status = mq_close(mqfd); + ATF_REQUIRE_MSG(status == 0, "mq_close failed: %d", errno); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, mqueue); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/kernel/t_ps_strings.sh b/contrib/netbsd-tests/kernel/t_ps_strings.sh new file mode 100755 index 0000000..8adba54 --- /dev/null +++ b/contrib/netbsd-tests/kernel/t_ps_strings.sh @@ -0,0 +1,85 @@ +# $NetBSD: t_ps_strings.sh,v 1.1 2011/03/05 18:14:33 pgoyette Exp $ +# +# Copyright (c) 2008 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. +# + +atf_test_case validate +validate_head() +{ + atf_set "descr" "Validates ps_strings passed to program" +} +validate_body() +{ + atf_check -s exit:0 -o ignore -e ignore \ + $(atf_get_srcdir)/h_ps_strings1 +} + +# Function to parse and validate the output from ps + +parse_ps() { + local pid seq arg + + pid="$1" ; shift + + while [ "$1" != "$pid" ] ; do + echo $1 + shift + done + if [ $# -eq 0 ] ; then + echo "NO_PID" + return + fi + shift + + seq=0 + while [ $# -gt 1 ] ; do + arg=$(printf "arg%04x" $seq) + if [ "$arg" != "$1" ] ; then + echo BAD_$seq + return + fi + shift + done + echo "OK" +} + +atf_test_case update +update_head() +{ + atf_set "descr" "Check updating of ps_strings" +} +update_body() +{ + $(atf_get_srcdir)/h_ps_strings2 > /dev/null 2>&1 & + h_pid=$! + parse=$(parse_ps $h_pid $(ps -wwo pid,args -p $h_pid) ) + kill $h_pid +} + +atf_init_test_cases() +{ + atf_add_test_case validate + atf_add_test_case update +} diff --git a/contrib/netbsd-tests/kernel/t_pty.c b/contrib/netbsd-tests/kernel/t_pty.c new file mode 100644 index 0000000..fccfc17b --- /dev/null +++ b/contrib/netbsd-tests/kernel/t_pty.c @@ -0,0 +1,351 @@ +/* $Id: t_pty.c,v 1.1 2011/09/24 15:53:01 christos Exp $ */ + +/* + * Allocates a pty(4) device, and sends the specified number of packets of the + * specified length though it, while a child reader process reads and reports + * results. + * + * Written by Matthew Mondor + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_pty.c,v 1.1 2011/09/24 15:53:01 christos Exp $"); + +#include <errno.h> +#include <err.h> +#include <fcntl.h> +#include <poll.h> +#include <stdio.h> +#ifdef __linux__ +#define _XOPEN_SOURCE +#define __USE_XOPEN +#endif +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <termios.h> +#include <unistd.h> + +#include <sys/ioctl.h> +#include <sys/types.h> +#include <sys/wait.h> + +#ifdef STANDALONE +static __dead void usage(const char *); +static void parse_args(int, char **); +#else +#include <atf-c.h> +#include "../h_macros.h" +#endif + +static int pty_open(void); +static int tty_open(const char *); +static void fd_nonblock(int); +static pid_t child_spawn(const char *); +static void run(void); + +static size_t buffer_size = 4096; +static size_t packets = 2; +static uint8_t *dbuf; +static int verbose; +static int qsize; + + +static +void run(void) +{ + size_t i; + int pty; + int status; + pid_t child; + if ((dbuf = calloc(1, buffer_size)) == NULL) + err(EXIT_FAILURE, "malloc(%zu)", buffer_size); + + if (verbose) + (void)printf( + "parent: started; opening PTY and spawning child\n"); + pty = pty_open(); + child = child_spawn(ptsname(pty)); + if (verbose) + (void)printf("parent: sleeping to make sure child is ready\n"); + (void)sleep(1); + + for (i = 0; i < buffer_size; i++) + dbuf[i] = i & 0xff; + + if (verbose) + (void)printf("parent: writing\n"); + + for (i = 0; i < packets; i++) { + ssize_t size; + + if (verbose) + (void)printf( + "parent: attempting to write %zu bytes to PTY\n", + buffer_size); + if ((size = write(pty, dbuf, buffer_size)) == -1) { + err(EXIT_FAILURE, "parent: write()"); + break; + } + if (verbose) + (void)printf("parent: wrote %zd bytes to PTY\n", size); + } + + if (verbose) + (void)printf("parent: waiting for child to exit\n"); + if (waitpid(child, &status, 0) == -1) + err(EXIT_FAILURE, "waitpid"); + if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) + errx(EXIT_FAILURE, "child failed"); + + if (verbose) + (void)printf("parent: closing PTY\n"); + (void)close(pty); + if (verbose) + (void)printf("parent: exiting\n"); +} + +static void +condition(int fd) +{ + struct termios tios; + + if (qsize) { + int opt = qsize; + if (ioctl(fd, TIOCSQSIZE, &opt) == -1) + err(EXIT_FAILURE, "Couldn't set tty(4) buffer size"); + if (ioctl(fd, TIOCGQSIZE, &opt) == -1) + err(EXIT_FAILURE, "Couldn't get tty(4) buffer size"); + if (opt != qsize) + errx(EXIT_FAILURE, "Wrong qsize %d != %d\n", + qsize, opt); + } + if (tcgetattr(fd, &tios) == -1) + err(EXIT_FAILURE, "tcgetattr()"); + cfmakeraw(&tios); + cfsetspeed(&tios, B921600); + if (tcsetattr(fd, TCSANOW, &tios) == -1) + err(EXIT_FAILURE, "tcsetattr()"); +} + +static int +pty_open(void) +{ + int fd; + + if ((fd = posix_openpt(O_RDWR)) == -1) + err(EXIT_FAILURE, "Couldn't pty(4) device"); + condition(fd); + if (grantpt(fd) == -1) + err(EXIT_FAILURE, + "Couldn't grant permissions on tty(4) device"); + + + condition(fd); + + if (unlockpt(fd) == -1) + err(EXIT_FAILURE, "unlockpt()"); + + return fd; +} + +static int +tty_open(const char *ttydev) +{ + int fd; + + if ((fd = open(ttydev, O_RDWR, 0)) == -1) + err(EXIT_FAILURE, "Couldn't open tty(4) device"); + +#ifdef USE_PPP_DISCIPLINE + { + int opt = PPPDISC; + if (ioctl(fd, TIOCSETD, &opt) == -1) + err(EXIT_FAILURE, + "Couldn't set tty(4) discipline to PPP"); + } +#endif + + condition(fd); + + return fd; +} + +static void +fd_nonblock(int fd) +{ + int opt; + + if ((opt = fcntl(fd, F_GETFL, NULL)) == -1) + err(EXIT_FAILURE, "fcntl()"); + if (fcntl(fd, F_SETFL, opt | O_NONBLOCK) == -1) + err(EXIT_FAILURE, "fcntl()"); +} + +static pid_t +child_spawn(const char *ttydev) +{ + pid_t pid; + int tty; + struct pollfd pfd; + size_t total = 0; + + if ((pid = fork()) == -1) + err(EXIT_FAILURE, "fork()"); + (void)setsid(); + if (pid != 0) + return pid; + + if (verbose) + (void)printf("child: started; open \"%s\"\n", ttydev); + tty = tty_open(ttydev); + fd_nonblock(tty); + + if (verbose) + (void)printf("child: TTY open, starting read loop\n"); + pfd.fd = tty; + pfd.events = POLLIN; + pfd.revents = 0; + for (;;) { + int ret; + ssize_t size; + + if (verbose) + (void)printf("child: polling\n"); + if ((ret = poll(&pfd, 1, 2000)) == -1) + err(EXIT_FAILURE, "child: poll()"); + if (ret == 0) + break; + if ((pfd.revents & POLLERR) != 0) + break; + if ((pfd.revents & POLLIN) != 0) { + for (;;) { + if (verbose) + (void)printf( + "child: attempting to read %zu" + " bytes\n", buffer_size); + if ((size = read(tty, dbuf, buffer_size)) + == -1) { + if (errno == EAGAIN) + break; + err(EXIT_FAILURE, "child: read()"); + } + if (qsize && size < qsize && + (size_t)size < buffer_size) + errx(EXIT_FAILURE, "read returned %zd " + "less than the queue size %d", + size, qsize); + if (verbose) + (void)printf( + "child: read %zd bytes from TTY\n", + size); + if (size == 0) + goto end; + total += size; + } + } + } +end: + if (verbose) + (void)printf("child: closing TTY %zu\n", total); + (void)close(tty); + if (verbose) + (void)printf("child: exiting\n"); + if (total != buffer_size * packets) + errx(EXIT_FAILURE, + "Lost data %zu != %zu\n", total, buffer_size * packets); + + exit(EXIT_SUCCESS); +} + +#ifdef STANDALONE +static void +usage(const char *msg) +{ + + if (msg != NULL) + (void) fprintf(stderr, "\n%s\n\n", msg); + + (void)fprintf(stderr, + "Usage: %s [-v] [-q <qsize>] [-s <packetsize>] [-n <packets>]\n", + getprogname()); + + exit(EXIT_FAILURE); +} + +static void +parse_args(int argc, char **argv) +{ + int ch; + + while ((ch = getopt(argc, argv, "n:q:s:v")) != -1) { + switch (ch) { + case 'n': + packets = (size_t)atoi(optarg); + break; + case 'q': + qsize = atoi(optarg); + break; + case 's': + buffer_size = (size_t)atoi(optarg); + break; + case 'v': + verbose++; + break; + default: + usage(NULL); + break; + } + } + if (buffer_size < 0 || buffer_size > 65536) + usage("-s must be between 0 and 65536"); + if (packets < 1 || packets > 100) + usage("-p must be between 1 and 100"); +} + +int +main(int argc, char **argv) +{ + + parse_args(argc, argv); + run(); + exit(EXIT_SUCCESS); +} + +#else +ATF_TC(pty_no_queue); + +ATF_TC_HEAD(pty_no_queue, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks that writing to pty " + "does not lose data with the default queue size of 1024"); +} + +ATF_TC_BODY(pty_no_queue, tc) +{ + qsize = 0; + run(); +} + +ATF_TC(pty_queue); + +ATF_TC_HEAD(pty_queue, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks that writing to pty " + "does not lose data with the a queue size of 4096"); +} + +ATF_TC_BODY(pty_queue, tc) +{ + qsize = 4096; + run(); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, pty_no_queue); + ATF_TP_ADD_TC(tp, pty_queue); + + return atf_no_error(); +} +#endif diff --git a/contrib/netbsd-tests/kernel/t_rnd.c b/contrib/netbsd-tests/kernel/t_rnd.c new file mode 100644 index 0000000..7f1f288 --- /dev/null +++ b/contrib/netbsd-tests/kernel/t_rnd.c @@ -0,0 +1,95 @@ +/* $NetBSD: t_rnd.c,v 1.5 2012/03/18 09:46:50 jruoho 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/cdefs.h> +__RCSID("$NetBSD: t_rnd.c,v 1.5 2012/03/18 09:46:50 jruoho Exp $"); + +#include <sys/types.h> +#include <sys/fcntl.h> +#include <sys/ioctl.h> +#include <sys/rnd.h> + +#include <atf-c.h> + +#include <rump/rump.h> +#include <rump/rump_syscalls.h> + +#include "../h_macros.h" + +ATF_TC(RNDADDDATA); +ATF_TC_HEAD(RNDADDDATA, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks ioctl(RNDADDDATA) (PR kern/42020)"); +} + +/* Adapted from example provided by Juho Salminen in the noted PR. */ +ATF_TC_BODY(RNDADDDATA, tc) +{ + rnddata_t rd; + int fd; + + rump_init(); + fd = rump_sys_open("/dev/random", O_RDWR, 0); + if (fd == -1) + atf_tc_fail_errno("cannot open /dev/random"); + + rd.entropy = 1; + rd.len = 1; + if (rump_sys_ioctl(fd, RNDADDDATA, &rd) == -1) + atf_tc_fail_errno("RNDADDDATA"); +} + +ATF_TC(RNDADDDATA2); +ATF_TC_HEAD(RNDADDDATA2, tc) +{ + atf_tc_set_md_var(tc, "descr", "checks ioctl(RNDADDDATA) deals with " + "garbage len field"); +} +ATF_TC_BODY(RNDADDDATA2, tc) +{ + rnddata_t rd; + int fd; + + rump_init(); + fd = rump_sys_open("/dev/random", O_RDWR, 0); + if (fd == -1) + atf_tc_fail_errno("cannot open /dev/random"); + + rd.entropy = 1; + rd.len = -1; + ATF_REQUIRE_ERRNO(EINVAL, rump_sys_ioctl(fd, RNDADDDATA, &rd) == -1); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, RNDADDDATA); + ATF_TP_ADD_TC(tp, RNDADDDATA2); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/kernel/t_sysctl.c b/contrib/netbsd-tests/kernel/t_sysctl.c new file mode 100644 index 0000000..8b7c97e --- /dev/null +++ b/contrib/netbsd-tests/kernel/t_sysctl.c @@ -0,0 +1,74 @@ +/* $NetBSD: t_sysctl.c,v 1.1 2014/08/09 07:04:03 gson Exp $ */ + +/*- + * Copyright (c) 2014 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/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2014\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_sysctl.c,v 1.1 2014/08/09 07:04:03 gson Exp $"); + +#include <sys/sysctl.h> +#include <errno.h> +#include <memory.h> + +#include <atf-c.h> + +ATF_TC(bufsize); +ATF_TC_HEAD(bufsize, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test sysctl integer reads with different buffer sizes"); +} +ATF_TC_BODY(bufsize, tc) +{ + union { + int int_val; + unsigned char space[256]; + } buf; + size_t len; + for (len = 0; len < sizeof(buf); len++) { + size_t oldlen = len; + int r; + memset(&buf, 0xFF, sizeof(buf)); + r = sysctlbyname("kern.job_control", &buf, &oldlen, 0, (size_t) 0); + if (len < sizeof(int)) { + ATF_REQUIRE_EQ(r, -1); + ATF_REQUIRE_EQ(errno, ENOMEM); + } else { + ATF_REQUIRE_EQ(r, 0); + ATF_REQUIRE_EQ(buf.int_val, 1); + ATF_REQUIRE_EQ(oldlen, sizeof(int)); + } + } +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, bufsize); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/kernel/t_sysv.c b/contrib/netbsd-tests/kernel/t_sysv.c new file mode 100644 index 0000000..0860d4b --- /dev/null +++ b/contrib/netbsd-tests/kernel/t_sysv.c @@ -0,0 +1,854 @@ +/* $NetBSD: t_sysv.c,v 1.4 2014/03/02 20:13:12 jmmv Exp $ */ + +/*- + * Copyright (c) 1999, 2007 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, + * NASA Ames Research Center, and by Andrew Doran. + * + * 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 the SVID-compatible Message Queue facility. + */ + +#include <atf-c.h> + +#include <err.h> +#include <errno.h> +#include <fcntl.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <unistd.h> + +#include <sys/ipc.h> +#include <sys/msg.h> +#include <sys/param.h> +#include <sys/sem.h> +#include <sys/shm.h> +#include <sys/wait.h> + +volatile int did_sigsys, did_sigchild; +volatile int child_status, child_count; + +void sigsys_handler(int); +void sigchld_handler(int); + +key_t get_ftok(int); + +void print_msqid_ds(struct msqid_ds *, mode_t); +void receiver(void); + +void print_semid_ds(struct semid_ds *, mode_t); +void waiter(void); + +void print_shmid_ds(struct shmid_ds *, mode_t); +void sharer(void); + +#define MESSAGE_TEXT_LEN 256 + +struct mymsg { + long mtype; + char mtext[MESSAGE_TEXT_LEN]; +}; + +const char *m1_str = "California is overrated."; +const char *m2_str = "The quick brown fox jumped over the lazy dog."; + +size_t pgsize; + +#define MTYPE_1 1 +#define MTYPE_1_ACK 2 + +#define MTYPE_2 3 +#define MTYPE_2_ACK 4 + +pid_t child_pid; + +key_t msgkey, semkey, shmkey; + +int maxloop = 1; + +union semun { + int val; /* value for SETVAL */ + struct semid_ds *buf; /* buffer for IPC_{STAT,SET} */ + u_short *array; /* array for GETALL & SETALL */ +}; + + +/* Writes an integer to a file. To be used from the body of the test + * cases below to pass any global identifiers to the cleanup routine. */ +static void +write_int(const char *path, const int value) +{ + int output; + + output = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0600); + ATF_REQUIRE_MSG(output != -1, "Failed to create %s", path); + write(output, &value, sizeof(value)); + close(output); +} + + +/* Reads an integer from a file. To be used from the cleanup routines + * of the test cases below. */ +static int +read_int(const char *path) +{ + int input; + + input = open(path, O_RDONLY); + if (input == -1) + return -1; + else { + int value; + read(input, &value, sizeof(value)); + return value; + } +} + + +void +sigsys_handler(int signo) +{ + + did_sigsys = 1; +} + +void +sigchld_handler(int signo) +{ + int c_status; + + did_sigchild = 1; + /* + * Reap the child and return its status + */ + if (wait(&c_status) == -1) + child_status = -errno; + else + child_status = c_status; + + child_count--; +} + +key_t get_ftok(int id) +{ + int fd; + char token_key[64], token_dir[64]; + char *tmpdir; + key_t key; + + strlcpy(token_key, "/tmp/t_sysv.XXXXXX", sizeof(token_key)); + tmpdir = mkdtemp(token_key); + ATF_REQUIRE_MSG(tmpdir != NULL, "mkdtemp() failed: %d", errno); + + strlcpy(token_dir, tmpdir, sizeof(token_dir)); + strlcpy(token_key, tmpdir, sizeof(token_key)); + strlcat(token_key, "/token_key", sizeof(token_key)); + + /* Create the file, since ftok() requires it to exist! */ + + fd = open(token_key, O_RDWR | O_CREAT | O_EXCL); + if (fd == -1) { + rmdir(tmpdir); + atf_tc_fail("open() of temp file failed: %d", errno); + return (key_t)-1; + } else + close(fd); + + key = ftok(token_key, id); + + ATF_REQUIRE_MSG(unlink(token_key) != -1, "unlink() failed: %d", errno); + ATF_REQUIRE_MSG(rmdir(token_dir) != -1, "rmdir() failed: %d", errno); + + return key; +} + +ATF_TC_WITH_CLEANUP(msg); +ATF_TC_HEAD(msg, tc) +{ + + atf_tc_set_md_var(tc, "timeout", "3"); + atf_tc_set_md_var(tc, "descr", "Checks sysvmsg passing"); +} + +ATF_TC_BODY(msg, tc) +{ + struct sigaction sa; + struct msqid_ds m_ds; + struct mymsg m; + sigset_t sigmask; + int sender_msqid; + int loop; + int c_status; + + /* + * Install a SIGSYS handler so that we can exit gracefully if + * System V Message Queue support isn't in the kernel. + */ + did_sigsys = 0; + sa.sa_handler = sigsys_handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + ATF_REQUIRE_MSG(sigaction(SIGSYS, &sa, NULL) != -1, + "sigaction SIGSYS: %d", errno); + + /* + * Install a SIGCHLD handler to deal with all possible exit + * conditions of the receiver. + */ + did_sigchild = 0; + child_count = 0; + sa.sa_handler = sigchld_handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + ATF_REQUIRE_MSG(sigaction(SIGCHLD, &sa, NULL) != -1, + "sigaction SIGCHLD: %d", errno); + + msgkey = get_ftok(4160); + ATF_REQUIRE_MSG(msgkey != (key_t)-1, "get_ftok failed"); + + sender_msqid = msgget(msgkey, IPC_CREAT | 0640); + ATF_REQUIRE_MSG(sender_msqid != -1, "msgget: %d", errno); + write_int("sender_msqid", sender_msqid); + + if (did_sigsys) { + atf_tc_skip("SYSV Message Queue not supported"); + return; + } + + ATF_REQUIRE_MSG(msgctl(sender_msqid, IPC_STAT, &m_ds) != -1, + "msgctl IPC_STAT 1: %d", errno); + + print_msqid_ds(&m_ds, 0640); + + m_ds.msg_perm.mode = (m_ds.msg_perm.mode & ~0777) | 0600; + + ATF_REQUIRE_MSG(msgctl(sender_msqid, IPC_SET, &m_ds) != -1, + "msgctl IPC_SET: %d", errno); + + memset(&m_ds, 0, sizeof(m_ds)); + + ATF_REQUIRE_MSG(msgctl(sender_msqid, IPC_STAT, &m_ds) != -1, + "msgctl IPC_STAT 2: %d", errno); + + ATF_REQUIRE_MSG((m_ds.msg_perm.mode & 0777) == 0600, + "IPC_SET of mode didn't hold"); + + print_msqid_ds(&m_ds, 0600); + + switch ((child_pid = fork())) { + case -1: + atf_tc_fail("fork: %d", errno); + return; + + case 0: + child_count++; + receiver(); + break; + + default: + break; + } + + for (loop = 0; loop < maxloop; loop++) { + /* + * Send the first message to the receiver and wait for the ACK. + */ + m.mtype = MTYPE_1; + strcpy(m.mtext, m1_str); + ATF_REQUIRE_MSG(msgsnd(sender_msqid, &m, MESSAGE_TEXT_LEN, + 0) != -1, "sender: msgsnd 1: %d", errno); + + ATF_REQUIRE_MSG(msgrcv(sender_msqid, &m, MESSAGE_TEXT_LEN, + MTYPE_1_ACK, 0) == MESSAGE_TEXT_LEN, + "sender: msgrcv 1 ack: %d", errno); + + print_msqid_ds(&m_ds, 0600); + + /* + * Send the second message to the receiver and wait for the ACK. + */ + m.mtype = MTYPE_2; + strcpy(m.mtext, m2_str); + ATF_REQUIRE_MSG(msgsnd(sender_msqid, &m, MESSAGE_TEXT_LEN, 0) != -1, + "sender: msgsnd 2: %d", errno); + + ATF_REQUIRE_MSG(msgrcv(sender_msqid, &m, MESSAGE_TEXT_LEN, + MTYPE_2_ACK, 0) == MESSAGE_TEXT_LEN, + "sender: msgrcv 2 ack: %d", errno); + } + + /* + * Wait for child to finish + */ + sigemptyset(&sigmask); + (void) sigsuspend(&sigmask); + + /* + * ...and any other signal is an unexpected error. + */ + if (did_sigchild) { + c_status = child_status; + if (c_status < 0) + atf_tc_fail("waitpid: %d", -c_status); + else if (WIFEXITED(c_status) == 0) + atf_tc_fail("child abnormal exit: %d", c_status); + else if (WEXITSTATUS(c_status) != 0) + atf_tc_fail("c status: %d", WEXITSTATUS(c_status)); + else { + ATF_REQUIRE_MSG(msgctl(sender_msqid, IPC_STAT, &m_ds) + != -1, "msgctl IPC_STAT: %d", errno); + + print_msqid_ds(&m_ds, 0600); + atf_tc_pass(); + } + } else + atf_tc_fail("sender: received unexpected signal"); +} + +ATF_TC_CLEANUP(msg, tc) +{ + int sender_msqid; + + /* + * Remove the message queue if it exists. + */ + sender_msqid = read_int("sender_msqid"); + if (sender_msqid != -1) + if (msgctl(sender_msqid, IPC_RMID, NULL) == -1) + err(1, "msgctl IPC_RMID"); +} + +void +print_msqid_ds(mp, mode) + struct msqid_ds *mp; + mode_t mode; +{ + uid_t uid = geteuid(); + gid_t gid = getegid(); + + printf("PERM: uid %d, gid %d, cuid %d, cgid %d, mode 0%o\n", + mp->msg_perm.uid, mp->msg_perm.gid, + mp->msg_perm.cuid, mp->msg_perm.cgid, + mp->msg_perm.mode & 0777); + + printf("qnum %lu, qbytes %lu, lspid %d, lrpid %d\n", + mp->msg_qnum, (u_long)mp->msg_qbytes, mp->msg_lspid, + mp->msg_lrpid); + + printf("stime: %s", ctime(&mp->msg_stime)); + printf("rtime: %s", ctime(&mp->msg_rtime)); + printf("ctime: %s", ctime(&mp->msg_ctime)); + + /* + * Sanity check a few things. + */ + + ATF_REQUIRE_MSG(mp->msg_perm.uid == uid && mp->msg_perm.cuid == uid, + "uid mismatch"); + + ATF_REQUIRE_MSG(mp->msg_perm.gid == gid && mp->msg_perm.cgid == gid, + "gid mismatch"); + + ATF_REQUIRE_MSG((mp->msg_perm.mode & 0777) == mode, "mode mismatch"); +} + +void +receiver() +{ + struct mymsg m; + int msqid, loop; + + if ((msqid = msgget(msgkey, 0)) == -1) + err(1, "receiver: msgget"); + + for (loop = 0; loop < maxloop; loop++) { + /* + * Receive the first message, print it, and send an ACK. + */ + if (msgrcv(msqid, &m, MESSAGE_TEXT_LEN, MTYPE_1, 0) != MESSAGE_TEXT_LEN) + err(1, "receiver: msgrcv 1"); + + printf("%s\n", m.mtext); + if (strcmp(m.mtext, m1_str) != 0) + err(1, "receiver: message 1 data isn't correct"); + + m.mtype = MTYPE_1_ACK; + + if (msgsnd(msqid, &m, MESSAGE_TEXT_LEN, 0) == -1) + err(1, "receiver: msgsnd ack 1"); + + /* + * Receive the second message, print it, and send an ACK. + */ + + if (msgrcv(msqid, &m, MESSAGE_TEXT_LEN, MTYPE_2, 0) != MESSAGE_TEXT_LEN) + err(1, "receiver: msgrcv 2"); + + printf("%s\n", m.mtext); + if (strcmp(m.mtext, m2_str) != 0) + err(1, "receiver: message 2 data isn't correct"); + + m.mtype = MTYPE_2_ACK; + + if (msgsnd(msqid, &m, MESSAGE_TEXT_LEN, 0) == -1) + err(1, "receiver: msgsnd ack 2"); + } + + exit(0); +} + +/* + * Test the SVID-compatible Semaphore facility. + */ + +ATF_TC_WITH_CLEANUP(sem); +ATF_TC_HEAD(sem, tc) +{ + + atf_tc_set_md_var(tc, "timeout", "3"); + atf_tc_set_md_var(tc, "descr", "Checks sysvmsg passing"); +} + +ATF_TC_BODY(sem, tc) +{ + struct sigaction sa; + union semun sun; + struct semid_ds s_ds; + sigset_t sigmask; + int sender_semid; + int i; + int c_status; + + /* + * Install a SIGSYS handler so that we can exit gracefully if + * System V Semaphore support isn't in the kernel. + */ + did_sigsys = 0; + sa.sa_handler = sigsys_handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + ATF_REQUIRE_MSG(sigaction(SIGSYS, &sa, NULL) != -1, + "sigaction SIGSYS: %d", errno); + + /* + * Install a SIGCHLD handler to deal with all possible exit + * conditions of the receiver. + */ + did_sigchild = 0; + child_count = 0; + sa.sa_handler = sigchld_handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + ATF_REQUIRE_MSG(sigaction(SIGCHLD, &sa, NULL) != -1, + "sigaction SIGCHLD: %d", errno); + + semkey = get_ftok(4160); + ATF_REQUIRE_MSG(semkey != (key_t)-1, "get_ftok failed"); + + sender_semid = semget(semkey, 1, IPC_CREAT | 0640); + ATF_REQUIRE_MSG(sender_semid != -1, "semget: %d", errno); + write_int("sender_semid", sender_semid); + + if (did_sigsys) { + atf_tc_skip("SYSV Semaphore not supported"); + return; + } + + sun.buf = &s_ds; + ATF_REQUIRE_MSG(semctl(sender_semid, 0, IPC_STAT, sun) != -1, + "semctl IPC_STAT: %d", errno); + + print_semid_ds(&s_ds, 0640); + + s_ds.sem_perm.mode = (s_ds.sem_perm.mode & ~0777) | 0600; + + sun.buf = &s_ds; + ATF_REQUIRE_MSG(semctl(sender_semid, 0, IPC_SET, sun) != -1, + "semctl IPC_SET: %d", errno); + + memset(&s_ds, 0, sizeof(s_ds)); + + sun.buf = &s_ds; + ATF_REQUIRE_MSG(semctl(sender_semid, 0, IPC_STAT, sun) != -1, + "semctl IPC_STAT: %d", errno); + + ATF_REQUIRE_MSG((s_ds.sem_perm.mode & 0777) == 0600, + "IPC_SET of mode didn't hold"); + + print_semid_ds(&s_ds, 0600); + + for (child_count = 0; child_count < 5; child_count++) { + switch ((child_pid = fork())) { + case -1: + atf_tc_fail("fork: %d", errno); + return; + + case 0: + waiter(); + break; + + default: + break; + } + } + + /* + * Wait for all of the waiters to be attempting to acquire the + * semaphore. + */ + for (;;) { + i = semctl(sender_semid, 0, GETNCNT); + if (i == -1) + atf_tc_fail("semctl GETNCNT: %d", i); + if (i == 5) + break; + } + + /* + * Now set the thundering herd in motion by initializing the + * semaphore to the value 1. + */ + sun.val = 1; + ATF_REQUIRE_MSG(semctl(sender_semid, 0, SETVAL, sun) != -1, + "sender: semctl SETVAL to 1: %d", errno); + + /* + * Wait for all children to finish + */ + sigemptyset(&sigmask); + for (;;) { + (void) sigsuspend(&sigmask); + if (did_sigchild) { + c_status = child_status; + if (c_status < 0) + atf_tc_fail("waitpid: %d", -c_status); + else if (WIFEXITED(c_status) == 0) + atf_tc_fail("c abnormal exit: %d", c_status); + else if (WEXITSTATUS(c_status) != 0) + atf_tc_fail("c status: %d", + WEXITSTATUS(c_status)); + else { + sun.buf = &s_ds; + ATF_REQUIRE_MSG(semctl(sender_semid, 0, + IPC_STAT, sun) != -1, + "semctl IPC_STAT: %d", errno); + + print_semid_ds(&s_ds, 0600); + atf_tc_pass(); + } + if (child_count <= 0) + break; + did_sigchild = 0; + } else { + atf_tc_fail("sender: received unexpected signal"); + break; + } + } +} + +ATF_TC_CLEANUP(sem, tc) +{ + int sender_semid; + + /* + * Remove the semaphore if it exists + */ + sender_semid = read_int("sender_semid"); + if (sender_semid != -1) + if (semctl(sender_semid, 0, IPC_RMID) == -1) + err(1, "semctl IPC_RMID"); +} + +void +print_semid_ds(sp, mode) + struct semid_ds *sp; + mode_t mode; +{ + uid_t uid = geteuid(); + gid_t gid = getegid(); + + printf("PERM: uid %d, gid %d, cuid %d, cgid %d, mode 0%o\n", + sp->sem_perm.uid, sp->sem_perm.gid, + sp->sem_perm.cuid, sp->sem_perm.cgid, + sp->sem_perm.mode & 0777); + + printf("nsems %u\n", sp->sem_nsems); + + printf("otime: %s", ctime(&sp->sem_otime)); + printf("ctime: %s", ctime(&sp->sem_ctime)); + + /* + * Sanity check a few things. + */ + + ATF_REQUIRE_MSG(sp->sem_perm.uid == uid && sp->sem_perm.cuid == uid, + "uid mismatch"); + + ATF_REQUIRE_MSG(sp->sem_perm.gid == gid && sp->sem_perm.cgid == gid, + "gid mismatch"); + + ATF_REQUIRE_MSG((sp->sem_perm.mode & 0777) == mode, + "mode mismatch %o != %o", (sp->sem_perm.mode & 0777), mode); +} + +void +waiter() +{ + struct sembuf s; + int semid; + + if ((semid = semget(semkey, 1, 0)) == -1) + err(1, "waiter: semget"); + + /* + * Attempt to acquire the semaphore. + */ + s.sem_num = 0; + s.sem_op = -1; + s.sem_flg = SEM_UNDO; + + if (semop(semid, &s, 1) == -1) + err(1, "waiter: semop -1"); + + printf("WOO! GOT THE SEMAPHORE!\n"); + sleep(1); + + /* + * Release the semaphore and exit. + */ + s.sem_num = 0; + s.sem_op = 1; + s.sem_flg = SEM_UNDO; + + if (semop(semid, &s, 1) == -1) + err(1, "waiter: semop +1"); + + exit(0); +} + +/* + * Test the SVID-compatible Shared Memory facility. + */ + +ATF_TC_WITH_CLEANUP(shm); +ATF_TC_HEAD(shm, tc) +{ + + atf_tc_set_md_var(tc, "timeout", "3"); + atf_tc_set_md_var(tc, "descr", "Checks sysv shared memory"); +} + +ATF_TC_BODY(shm, tc) +{ + struct sigaction sa; + struct shmid_ds s_ds; + sigset_t sigmask; + char *shm_buf; + int sender_shmid; + int c_status; + + /* + * Install a SIGSYS handler so that we can exit gracefully if + * System V Shared Memory support isn't in the kernel. + */ + did_sigsys = 0; + sa.sa_handler = sigsys_handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + ATF_REQUIRE_MSG(sigaction(SIGSYS, &sa, NULL) != -1, + "sigaction SIGSYS: %d", errno); + + /* + * Install a SIGCHLD handler to deal with all possible exit + * conditions of the sharer. + */ + did_sigchild = 0; + child_count = 0; + sa.sa_handler = sigchld_handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + ATF_REQUIRE_MSG(sigaction(SIGCHLD, &sa, NULL) != -1, + "sigaction SIGCHLD: %d", errno); + + pgsize = sysconf(_SC_PAGESIZE); + + shmkey = get_ftok(4160); + ATF_REQUIRE_MSG(shmkey != (key_t)-1, "get_ftok failed"); + + ATF_REQUIRE_MSG((sender_shmid = shmget(shmkey, pgsize, + IPC_CREAT | 0640)) != -1, + "shmget: %d", errno); + write_int("sender_shmid", sender_shmid); + + ATF_REQUIRE_MSG(shmctl(sender_shmid, IPC_STAT, &s_ds) != -1, + "shmctl IPC_STAT: %d", errno); + + print_shmid_ds(&s_ds, 0640); + + s_ds.shm_perm.mode = (s_ds.shm_perm.mode & ~0777) | 0600; + + ATF_REQUIRE_MSG(shmctl(sender_shmid, IPC_SET, &s_ds) != -1, + "shmctl IPC_SET: %d", errno); + + memset(&s_ds, 0, sizeof(s_ds)); + + ATF_REQUIRE_MSG(shmctl(sender_shmid, IPC_STAT, &s_ds) != -1, + "shmctl IPC_STAT: %d", errno); + + ATF_REQUIRE_MSG((s_ds.shm_perm.mode & 0777) == 0600, + "IPC_SET of mode didn't hold"); + + print_shmid_ds(&s_ds, 0600); + + shm_buf = shmat(sender_shmid, NULL, 0); + ATF_REQUIRE_MSG(shm_buf != (void *) -1, "sender: shmat: %d", errno); + + /* + * Write the test pattern into the shared memory buffer. + */ + strcpy(shm_buf, m2_str); + + switch ((child_pid = fork())) { + case -1: + atf_tc_fail("fork: %d", errno); + return; + + case 0: + sharer(); + break; + + default: + break; + } + + /* + * Wait for child to finish + */ + sigemptyset(&sigmask); + (void) sigsuspend(&sigmask); + + if (did_sigchild) { + c_status = child_status; + if (c_status < 0) + atf_tc_fail("waitpid: %d", -c_status); + else if (WIFEXITED(c_status) == 0) + atf_tc_fail("c abnormal exit: %d", c_status); + else if (WEXITSTATUS(c_status) != 0) + atf_tc_fail("c status: %d", WEXITSTATUS(c_status)); + else { + ATF_REQUIRE_MSG(shmctl(sender_shmid, IPC_STAT, + &s_ds) != -1, + "shmctl IPC_STAT: %d", errno); + + print_shmid_ds(&s_ds, 0600); + atf_tc_pass(); + } + } else + atf_tc_fail("sender: received unexpected signal"); +} + +ATF_TC_CLEANUP(shm, tc) +{ + int sender_shmid; + + /* + * Remove the shared memory area if it exists. + */ + sender_shmid = read_int("sender_shmid"); + if (sender_shmid != -1) + if (shmctl(sender_shmid, IPC_RMID, NULL) == -1) + err(1, "shmctl IPC_RMID"); +} + +void +print_shmid_ds(sp, mode) + struct shmid_ds *sp; + mode_t mode; +{ + uid_t uid = geteuid(); + gid_t gid = getegid(); + + printf("PERM: uid %d, gid %d, cuid %d, cgid %d, mode 0%o\n", + sp->shm_perm.uid, sp->shm_perm.gid, + sp->shm_perm.cuid, sp->shm_perm.cgid, + sp->shm_perm.mode & 0777); + + printf("segsz %lu, lpid %d, cpid %d, nattch %u\n", + (u_long)sp->shm_segsz, sp->shm_lpid, sp->shm_cpid, + sp->shm_nattch); + + printf("atime: %s", ctime(&sp->shm_atime)); + printf("dtime: %s", ctime(&sp->shm_dtime)); + printf("ctime: %s", ctime(&sp->shm_ctime)); + + /* + * Sanity check a few things. + */ + + ATF_REQUIRE_MSG(sp->shm_perm.uid == uid && sp->shm_perm.cuid == uid, + "uid mismatch"); + + ATF_REQUIRE_MSG(sp->shm_perm.gid == gid && sp->shm_perm.cgid == gid, + "gid mismatch"); + + ATF_REQUIRE_MSG((sp->shm_perm.mode & 0777) == mode, "mode mismatch"); +} + +void +sharer() +{ + int shmid; + void *shm_buf; + + shmid = shmget(shmkey, pgsize, 0); + ATF_REQUIRE_MSG(shmid != -1, "receiver: shmget:%d", errno); + + shm_buf = shmat(shmid, NULL, 0); + ATF_REQUIRE_MSG(shm_buf != (void *) -1, "receiver: shmat: %d", errno); + + printf("%s\n", (const char *)shm_buf); + + ATF_REQUIRE_MSG(strcmp((const char *)shm_buf, m2_str) == 0, + "receiver: data isn't correct"); + + exit(0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, msg); + ATF_TP_ADD_TC(tp, sem); + ATF_TP_ADD_TC(tp, shm); + + return atf_no_error(); +} + diff --git a/contrib/netbsd-tests/kernel/t_umount.sh b/contrib/netbsd-tests/kernel/t_umount.sh new file mode 100755 index 0000000..b62ba10 --- /dev/null +++ b/contrib/netbsd-tests/kernel/t_umount.sh @@ -0,0 +1,95 @@ +# $NetBSD: t_umount.sh,v 1.5 2010/11/07 17:51:19 jmmv Exp $ +# +# Copyright (c) 2008, 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. +# + +TMPMP=umount-f_mount +TMPIM=umount-f.im + +VND=vnd0 +BVND=/dev/${VND} +CVND=/dev/r${VND} +MPART=a + +atf_test_case umount cleanup +umount_head() +{ + atf_set "descr" "Checks forced unmounting" + atf_set "require.user" "root" +} +umount_body() +{ + cat >disktab <<EOF +floppy288|2.88MB 3.5in Extra High Density Floppy:\ + :ty=floppy:se#512:nt#2:rm#300:ns#36:nc#80:\ + :pa#5760:oa#0:ba#4096:fa#512:ta=4.2BSD:\ + :pb#5760:ob#0:\ + :pc#5760:oc#0: +EOF + + echo "*** Creating a dummy directory tree at" \ + "${TMPMP} mounted on ${TMPIM}" + + atf_check -o ignore -e ignore mkdir ${TMPMP} + atf_check -o ignore -e ignore touch ${TMPMP}/under_the_mount + atf_check -o ignore -e ignore dd if=/dev/zero of=${TMPIM} count=5860 + atf_check -o ignore -e ignore vnconfig -v ${VND} ${TMPIM} + atf_check -o ignore -e ignore disklabel -f disktab -rw ${VND} floppy288 + atf_check -o ignore -e ignore newfs -i 500 -b 8192 -f 1024 ${CVND}${MPART} + atf_check -o ignore -e ignore mount -o async ${BVND}${MPART} ${TMPMP} + atf_check -o ignore -e ignore touch ${TMPMP}/in_mounted_directory + + echo "*** Testing forced unmount" + test -e "${TMPMP}/in_mounted_directory" || \ + atf_fail "Test file not present in mounted directory!" + + mydir="`pwd`" + cd "${TMPMP}" + atf_check -o ignore -e ignore umount -f "${BVND}${MPART}" + + atf_check -s ne:0 -e inline:"ls: .: No such file or directory\n" ls . + atf_check -s ne:0 -e inline:"ls: ..: No such file or directory\n" ls .. + + atf_check -s ne:0 -e ignore -o inline:"cd: can't cd to .\n" \ + -x "cd . 2>&1" + atf_check -s ne:0 -e ignore -o inline:"cd: can't cd to ..\n" \ + -x "cd .. 2>&1" + + cd "${mydir}" + + test -e "${TMPMP}/under_the_mount" || \ + atf_fail "Original mount point dissapeared!" +} +umount_cleanup() +{ + echo "*** Cleaning up ${TMPMP}, ${TMPIM}." + umount -f "${TMPMP}" + vnconfig -u "${VND}" +} + +atf_init_test_cases() +{ + atf_add_test_case umount +} diff --git a/contrib/netbsd-tests/kernel/t_umountstress.sh b/contrib/netbsd-tests/kernel/t_umountstress.sh new file mode 100755 index 0000000..fd50a1d --- /dev/null +++ b/contrib/netbsd-tests/kernel/t_umountstress.sh @@ -0,0 +1,209 @@ +# $NetBSD: t_umountstress.sh,v 1.5 2013/05/31 14:40:48 gson Exp $ +# +# Copyright (c) 2013 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. +# + +TMPMP=umount-stress_mount +TMPIM=umount-stress.im + +VND=vnd0 +BVND=/dev/${VND} +CVND=/dev/r${VND} +MPART=a + +atf_test_case fileop cleanup +fileop_head() +{ + atf_set "descr" "Checks unmounting a filesystem doing file operations" + atf_set "require.user" "root" +} +fileop_body() +{ + cat >disktab <<EOF +floppy288|2.88MB 3.5in Extra High Density Floppy:\ + :ty=floppy:se#512:nt#2:rm#300:ns#36:nc#80:\ + :pa#5760:oa#0:ba#4096:fa#512:ta=4.2BSD:\ + :pb#5760:ob#0:\ + :pc#5760:oc#0: +EOF + + echo "*** Creating a dummy directory tree at" \ + "${TMPMP} mounted on ${TMPIM}" + + atf_check -o ignore -e ignore mkdir ${TMPMP} + atf_check -o ignore -e ignore dd if=/dev/zero of=${TMPIM} count=5860 + atf_check -o ignore -e ignore vnconfig -v ${VND} ${TMPIM} + atf_check -o ignore -e ignore disklabel -f disktab -rw ${VND} floppy288 + atf_check -o ignore -e ignore newfs -i 500 -b 8192 -f 1024 ${CVND}${MPART} + atf_check -o ignore -e ignore mount -o async ${BVND}${MPART} ${TMPMP} + + echo "*** Testing fileops" + + touch ${TMPMP}/hold + exec 9< ${TMPMP}/hold + + ( + for j in 0 1 2; do + for k in 0 1 2 3 4 5 6 7 8 9; do + if ! dd msgfmt=quiet if=/dev/zero \ + count=1 of=${TMPMP}/test$i$j$k; then + echo 1 >result + exit + fi + done + done + echo 0 >result + ) & + busypid=$! + + while ! test -f result; do + if err=$(umount ${TMPMP} 2>&1); then + kill $busypid + exec 9<&- + wait + atf_fail "Unmount succeeded while busy" + return + fi + + case $err in + *:\ Device\ busy) + ;; + *) + kill $busypid + exec 9<&- + wait + atf_fail "Unmount failed: $err" + return + ;; + esac + done + + exec 9<&- + wait + + rc=`cat result` + rm -f result + + case $rc in + 0) ;; + *) atf_fail "File operation failed" + esac +} +fileop_cleanup() +{ + echo "*** Cleaning up ${TMPMP}, ${TMPIM}." + umount -f "${TMPMP}" + vnconfig -u "${VND}" +} + +atf_test_case mountlist cleanup +mountlist_head() +{ + atf_set "descr" "Checks unmounting a filesystem using mountlist" + atf_set "require.user" "root" +} +mountlist_body() +{ + cat >disktab <<EOF +floppy288|2.88MB 3.5in Extra High Density Floppy:\ + :ty=floppy:se#512:nt#2:rm#300:ns#36:nc#80:\ + :pa#5760:oa#0:ba#4096:fa#512:ta=4.2BSD:\ + :pb#5760:ob#0:\ + :pc#5760:oc#0: +EOF + + echo "*** Creating a dummy directory tree at" \ + "${TMPMP} mounted on ${TMPIM}" + + atf_check -o ignore -e ignore mkdir ${TMPMP} + atf_check -o ignore -e ignore dd if=/dev/zero of=${TMPIM} count=5860 + atf_check -o ignore -e ignore vnconfig -v ${VND} ${TMPIM} + atf_check -o ignore -e ignore disklabel -f disktab -rw ${VND} floppy288 + atf_check -o ignore -e ignore newfs -i 500 -b 8192 -f 1024 ${CVND}${MPART} + atf_check -o ignore -e ignore mount -o async ${BVND}${MPART} ${TMPMP} + + echo "*** Testing mountlist" + + ( + for j in 0 1 2 3 4 5 6 7 8 9; do + for k in 0 1 2 3 4 5 6 7 8 9; do + if ! out=$(mount); then + echo 1 >result + exit + fi + done + done + echo 0 >result + ) & + busypid=$! + + while ! test -f result; do + if err=$(umount ${TMPMP} 2>&1); then + if ! mount -o async ${BVND}${MPART} ${TMPMP}; then + kill $busypid + exec 9<&- + wait + atf_fail "Remount failed" + return + fi + continue + fi + + case $err in + *:\ Device\ busy) + ;; + *) + kill $busypid + exec 9<&- + wait + atf_fail "Unmount failed: $err" + return + ;; + esac + done + + exec 9<&- + wait + + rc=`cat result` + rm -f result + + case $rc in + 0) ;; + *) atf_fail "Mountlist operation failed" + esac +} +mountlist_cleanup() +{ + echo "*** Cleaning up ${TMPMP}, ${TMPIM}." + umount -f "${TMPMP}" + vnconfig -u "${VND}" +} + +atf_init_test_cases() +{ + atf_add_test_case fileop + atf_add_test_case mountlist +} diff --git a/contrib/netbsd-tests/kernel/tty/t_pr.c b/contrib/netbsd-tests/kernel/tty/t_pr.c new file mode 100644 index 0000000..c590ea5 --- /dev/null +++ b/contrib/netbsd-tests/kernel/tty/t_pr.c @@ -0,0 +1,186 @@ +/* $NetBSD: t_pr.c,v 1.7 2011/04/26 20:42:01 martin Exp $ */ + +/*- + * Copyright (c) 2010, 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Antti Kantee <pooka@NetBSD.org> and Martin Husemann <martin@NetBSD.org>. + * + * 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/ioctl.h> +#include <sys/tty.h> + +#include <atf-c.h> +#include <fcntl.h> + +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <rump/rump.h> +#include <rump/rump_syscalls.h> + +static int +sendsome(int from, int to) +{ + size_t i; + ssize_t cnt; + static const char msg[] = "hello world\n"; + char buf[sizeof(msg)+10]; + + memset(buf, 0, sizeof(buf)); + rump_sys_write(from, msg, strlen(msg)); + cnt = rump_sys_read(to, buf, sizeof(buf)); + if (cnt < (ssize_t)strlen(msg)) { + printf("short message read: %zd chars: \"%s\"\n", cnt, buf); + return 1; + } + for (i = 0; i < sizeof(buf); i++) { + if (buf[i] == '\r' || buf[i] == '\n') { + buf[i] = '\n'; + buf[i+1] = '\0'; + break; + } + } + + return strcmp(buf, msg) != 0; +} + +static int +exercise_ptytty(int master, int slave) +{ + int error, flags; + + /* + * send a few bytes from master to slave and read them back + */ + error = sendsome(master, slave); + if (error) + return error; + + flags = FREAD|FWRITE; + rump_sys_ioctl(master, TIOCFLUSH, &flags); + + /* + * and the same in the other direction + */ + error = sendsome(slave, master); + if (error) + return error; + + flags = FREAD|FWRITE; + rump_sys_ioctl(master, TIOCFLUSH, &flags); + return 0; +} + +ATF_TC(client_first); +ATF_TC_HEAD(client_first, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "test basic tty/pty operation when opening client side first"); +} + +ATF_TC_BODY(client_first, tc) +{ + int master, slave, error, v; + + rump_init(); + slave = rump_sys_open("/dev/ttyp1", O_RDWR|O_NONBLOCK); + ATF_CHECK(slave != -1); + + master = rump_sys_open("/dev/ptyp1", O_RDWR); + ATF_CHECK(master != -1); + + v = 0; + rump_sys_ioctl(slave, FIOASYNC, &v); + error = exercise_ptytty(master, slave); + ATF_CHECK(error == 0); + + rump_sys_close(master); + rump_sys_close(slave); +} + +ATF_TC(master_first); +ATF_TC_HEAD(master_first, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "test basic tty/pty operation when opening master side first"); +} + +ATF_TC_BODY(master_first, tc) +{ + int master, slave, error; + + rump_init(); + master = rump_sys_open("/dev/ptyp1", O_RDWR); + ATF_CHECK(master != -1); + + slave = rump_sys_open("/dev/ttyp1", O_RDWR); + ATF_CHECK(slave != -1); + + error = exercise_ptytty(master, slave); + ATF_CHECK(error == 0); + + rump_sys_close(master); + rump_sys_close(slave); +} + +ATF_TC(ptyioctl); +ATF_TC_HEAD(ptyioctl, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "ioctl on pty with client side not open"); +} + +ATF_TC_BODY(ptyioctl, tc) +{ + struct termios tio; + int fd; + + rump_init(); + fd = rump_sys_open("/dev/ptyp1", O_RDWR); + ATF_CHECK(fd != -1); + + /* + * This used to die with null deref under ptcwakeup() + * atf_tc_expect_signal(-1, "PR kern/40688"); + */ + rump_sys_ioctl(fd, TIOCGETA, &tio); + + rump_sys_close(fd); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, ptyioctl); + ATF_TP_ADD_TC(tp, client_first); + ATF_TP_ADD_TC(tp, master_first); + + return atf_no_error(); +} |