| @@ -1,140 +1,140 @@ | | | @@ -1,140 +1,140 @@ |
1 | /* $NetBSD: t_kern.c,v 1.5 2017/05/03 12:09:41 pgoyette Exp $ */ | | 1 | /* $NetBSD: t_kern.c,v 1.6 2020/08/28 19:29:58 martin Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2011 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 2011 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
15 | * | | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND | | 16 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND |
17 | * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, | | 17 | * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, |
18 | * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | | 18 | * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
19 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | | 19 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
20 | * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY | | 20 | * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY |
21 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | | 21 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE | | 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE |
23 | * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | 23 | * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER | | 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER |
25 | * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | | 25 | * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR |
26 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN | | 26 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN |
27 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | | 27 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
28 | */ | | 28 | */ |
29 | | | 29 | |
30 | #include <sys/types.h> | | 30 | #include <sys/types.h> |
31 | #include <sys/signal.h> | | 31 | #include <sys/signal.h> |
32 | #include <sys/wait.h> | | 32 | #include <sys/wait.h> |
33 | | | 33 | |
34 | #include <rump/rump.h> | | 34 | #include <rump/rump.h> |
35 | | | 35 | |
36 | #include <atf-c.h> | | 36 | #include <atf-c.h> |
37 | #include <stdio.h> | | 37 | #include <stdio.h> |
38 | #include <stdlib.h> | | 38 | #include <stdlib.h> |
39 | #include <unistd.h> | | 39 | #include <unistd.h> |
40 | #include <regex.h> | | 40 | #include <regex.h> |
41 | | | 41 | |
42 | #include "h_macros.h" | | 42 | #include "h_macros.h" |
43 | #include "../kernspace/kernspace.h" | | 43 | #include "../kernspace/kernspace.h" |
44 | | | 44 | |
45 | #define LOCKFUN(_name_, _descr_,_needld_, _expect_) \ | | 45 | #define LOCKFUN(_name_, _descr_,_needld_, _expect_) \ |
46 | ATF_TC(lockme_##_name_); \ | | 46 | ATF_TC(lockme_##_name_); \ |
47 | ATF_TC_HEAD(lockme_##_name_, tc) { \ | | 47 | ATF_TC_HEAD(lockme_##_name_, tc) { \ |
48 | atf_tc_set_md_var(tc, "descr", _descr_); \ | | 48 | atf_tc_set_md_var(tc, "descr", _descr_); \ |
49 | } \ | | 49 | } \ |
50 | ATF_TC_BODY(lockme_##_name_, tc) { \ | | 50 | ATF_TC_BODY(lockme_##_name_, tc) { \ |
51 | locktest(tc, LOCKME_##_name_, _needld_, _expect_); \ | | 51 | locktest(tc, LOCKME_##_name_, _needld_, _expect_); \ |
52 | } | | 52 | } |
53 | | | 53 | |
54 | static void | | 54 | static void |
55 | locktest(const atf_tc_t *tc, enum locktest lt, int needld, const char *expect) | | 55 | locktest(const atf_tc_t *tc, enum locktest lt, int needld, const char *expect) |
56 | { | | 56 | { |
57 | extern const int rump_lockdebug; | | 57 | extern const int rump_lockdebug; |
58 | int pipetti[2]; | | 58 | int pipetti[2]; |
59 | int status; | | 59 | int status; |
60 | ssize_t len; | | 60 | ssize_t len; |
61 | regex_t preg; | | 61 | regex_t preg; |
62 | | | 62 | |
63 | if (needld && !rump_lockdebug) | | 63 | if (needld && !rump_lockdebug) |
64 | atf_tc_skip("test requires LOCKDEBUG kernel"); | | 64 | atf_tc_skip("test requires LOCKDEBUG kernel"); |
65 | RL(pipe(pipetti)); | | 65 | RL(pipe(pipetti)); |
66 | | | 66 | |
67 | switch (fork()) { | | 67 | switch (fork()) { |
68 | case 0: | | 68 | case 0: |
69 | RL(dup2(pipetti[1], STDOUT_FILENO)); | | 69 | RL(dup2(pipetti[1], STDOUT_FILENO)); |
70 | RL(dup2(pipetti[1], STDOUT_FILENO)); | | 70 | RL(dup2(pipetti[1], STDOUT_FILENO)); |
71 | rump_init(); | | 71 | rump_init(); |
72 | rump_schedule(); | | 72 | rump_schedule(); |
73 | rumptest_lockme(lt); | | 73 | rumptest_lockme(lt); |
74 | rump_unschedule(); | | 74 | rump_unschedule(); |
75 | break; | | 75 | break; |
76 | default: | | 76 | default: |
77 | RL(wait(&status)); | | 77 | RL(wait(&status)); |
78 | ATF_REQUIRE(WIFSIGNALED(status) && WTERMSIG(status) == SIGABRT); | | 78 | ATF_REQUIRE(WIFSIGNALED(status) && WTERMSIG(status) == SIGABRT); |
79 | if (rump_lockdebug) { | | 79 | if (rump_lockdebug) { |
80 | char buf[8192]; | | 80 | char buf[8192]; |
81 | | | 81 | |
82 | len = read(pipetti[0], buf, sizeof(buf) - 1); | | 82 | len = read(pipetti[0], buf, sizeof(buf) - 1); |
83 | ATF_REQUIRE(len > 0); | | 83 | ATF_REQUIRE(len > 0); |
84 | buf[len] = '\0'; | | 84 | buf[len] = '\0'; |
85 | /* | | 85 | /* |
86 | * We use regex matching here, since the rump | | 86 | * We use regex matching here, since the rump |
87 | * kernel messages include routine names and line | | 87 | * kernel messages include routine names and line |
88 | * numbers which may not remain constant. | | 88 | * numbers which may not remain constant. |
89 | */ | | 89 | */ |
90 | if ((status = regcomp(&preg, expect, REG_BASIC)) != 0) { | | 90 | if ((status = regcomp(&preg, expect, REG_BASIC)) != 0) { |
91 | regerror(status, &preg, buf, sizeof(buf)); | | 91 | regerror(status, &preg, buf, sizeof(buf)); |
92 | printf("regcomp error: %s\n", buf); | | 92 | printf("regcomp error: %s\n", buf); |
93 | atf_tc_fail("regcomp failed"); | | 93 | atf_tc_fail("regcomp failed"); |
94 | } | | 94 | } |
95 | if ((status = regexec(&preg, buf, 0, NULL, 0)) != 0) { | | 95 | if ((status = regexec(&preg, buf, 0, NULL, 0)) != 0) { |
96 | printf("expected: \"%s\"\n", expect); | | 96 | printf("expected: \"%s\"\n", expect); |
97 | printf("received: \"%s\"\n", buf); | | 97 | printf("received: \"%s\"\n", buf); |
98 | regerror(status, &preg, buf, sizeof(buf)); | | 98 | regerror(status, &preg, buf, sizeof(buf)); |
99 | printf("regexec error: %s\n", buf); | | 99 | printf("regexec error: %s\n", buf); |
100 | atf_tc_fail("unexpected output"); | | 100 | atf_tc_fail("unexpected output"); |
101 | } | | 101 | } |
102 | regfree(&preg); | | 102 | regfree(&preg); |
103 | } | | 103 | } |
104 | break; | | 104 | break; |
105 | case -1: | | 105 | case -1: |
106 | atf_tc_fail("fork"); | | 106 | atf_tc_fail("fork"); |
107 | } | | 107 | } |
108 | } | | 108 | } |
109 | | | 109 | |
110 | LOCKFUN(DESTROYHELD, "destroy lock while held", 0, | | 110 | LOCKFUN(DESTROYHELD, "destroy lock while held", 0, |
111 | "mutex error: mutex_destroy,.*: is locked or in use"); | | 111 | "mutex error: mutex_destroy,.*: is locked or in use"); |
112 | LOCKFUN(DOUBLEFREE, "free lock twice", 0, | | 112 | LOCKFUN(DOUBLEFREE, "free lock twice", 0, |
113 | "panic: mutex_destroy,.*: uninitialized lock"); | | 113 | "panic: mutex_destroy,.*: uninitialized lock"); |
114 | LOCKFUN(DOUBLEINIT, "init lock twice", 1, | | 114 | LOCKFUN(DOUBLEINIT, "init lock twice", 1, |
115 | "mutex error: mutex_init,.*: already initialized"); | | 115 | "mutex error: .*mutex_init,.*: already initialized"); |
116 | LOCKFUN(MEMFREE, "free memory active lock is in", 1, | | 116 | LOCKFUN(MEMFREE, "free memory active lock is in", 1, |
117 | "mutex error: kmem_intr_free,.*: allocation contains active lock"); | | 117 | "mutex error: kmem_intr_free,.*: allocation contains active lock"); |
118 | LOCKFUN(MTX, "locking-against-self mutex", 0, | | 118 | LOCKFUN(MTX, "locking-against-self mutex", 0, |
119 | "mutex error: mutex_enter,.*: locking against myself"); | | 119 | "mutex error: mutex_enter,.*: locking against myself"); |
120 | LOCKFUN(RWDOUBLEX, "locking-against-self exclusive rwlock", 0, | | 120 | LOCKFUN(RWDOUBLEX, "locking-against-self exclusive rwlock", 0, |
121 | "rwlock error: rw_enter,.*: locking against myself"); | | 121 | "rwlock error: rw_enter,.*: locking against myself"); |
122 | LOCKFUN(RWRX, "rw: first shared, then exclusive", 1, | | 122 | LOCKFUN(RWRX, "rw: first shared, then exclusive", 1, |
123 | "rwlock error: rw_enter,.*: locking against myself"); | | 123 | "rwlock error: rw_enter,.*: locking against myself"); |
124 | LOCKFUN(RWXR, "rw: first execusive, then shared", 0, | | 124 | LOCKFUN(RWXR, "rw: first execusive, then shared", 0, |
125 | "rwlock error: rw_enter,.*: locking against myself"); | | 125 | "rwlock error: rw_enter,.*: locking against myself"); |
126 | | | 126 | |
127 | ATF_TP_ADD_TCS(tp) | | 127 | ATF_TP_ADD_TCS(tp) |
128 | { | | 128 | { |
129 | | | 129 | |
130 | ATF_TP_ADD_TC(tp, lockme_MTX); | | 130 | ATF_TP_ADD_TC(tp, lockme_MTX); |
131 | ATF_TP_ADD_TC(tp, lockme_RWDOUBLEX); | | 131 | ATF_TP_ADD_TC(tp, lockme_RWDOUBLEX); |
132 | ATF_TP_ADD_TC(tp, lockme_RWRX); | | 132 | ATF_TP_ADD_TC(tp, lockme_RWRX); |
133 | ATF_TP_ADD_TC(tp, lockme_RWXR); | | 133 | ATF_TP_ADD_TC(tp, lockme_RWXR); |
134 | ATF_TP_ADD_TC(tp, lockme_DOUBLEINIT); | | 134 | ATF_TP_ADD_TC(tp, lockme_DOUBLEINIT); |
135 | ATF_TP_ADD_TC(tp, lockme_DOUBLEFREE); | | 135 | ATF_TP_ADD_TC(tp, lockme_DOUBLEFREE); |
136 | ATF_TP_ADD_TC(tp, lockme_DESTROYHELD); | | 136 | ATF_TP_ADD_TC(tp, lockme_DESTROYHELD); |
137 | ATF_TP_ADD_TC(tp, lockme_MEMFREE); | | 137 | ATF_TP_ADD_TC(tp, lockme_MEMFREE); |
138 | | | 138 | |
139 | return atf_no_error(); | | 139 | return atf_no_error(); |
140 | } | | 140 | } |