source: vendor/current/lib/tdb/test/run-mutex-die.c

Last change on this file was 988, checked in by Silvan Scherrer, 9 years ago

Samba Server: update vendor to version 4.4.3

File size: 4.9 KB
Line 
1#include "../common/tdb_private.h"
2#include "lock-tracking.h"
3static ssize_t pwrite_check(int fd, const void *buf, size_t count, off_t offset);
4static ssize_t write_check(int fd, const void *buf, size_t count);
5static int ftruncate_check(int fd, off_t length);
6
7#define pwrite pwrite_check
8#define write write_check
9#define fcntl fcntl_with_lockcheck
10#define ftruncate ftruncate_check
11
12#include "../common/io.c"
13#include "../common/tdb.c"
14#include "../common/lock.c"
15#include "../common/freelist.c"
16#include "../common/traverse.c"
17#include "../common/transaction.c"
18#include "../common/error.c"
19#include "../common/open.c"
20#include "../common/check.c"
21#include "../common/hash.c"
22#include "../common/mutex.c"
23#include "tap-interface.h"
24#include <stdlib.h>
25#include <stdbool.h>
26#include <stdarg.h>
27#include "external-agent.h"
28#include "logging.h"
29
30#undef write
31#undef pwrite
32#undef fcntl
33#undef ftruncate
34
35static int target, current;
36#define TEST_DBNAME "run-mutex-die.tdb"
37#define KEY_STRING "helloworld"
38
39static void maybe_die(int fd)
40{
41 if (target == 0) {
42 return;
43 }
44 current += 1;
45 if (current == target) {
46 _exit(1);
47 }
48}
49
50static ssize_t pwrite_check(int fd,
51 const void *buf, size_t count, off_t offset)
52{
53 ssize_t ret;
54
55 maybe_die(fd);
56
57 ret = pwrite(fd, buf, count, offset);
58 if (ret != count)
59 return ret;
60
61 maybe_die(fd);
62 return ret;
63}
64
65static ssize_t write_check(int fd, const void *buf, size_t count)
66{
67 ssize_t ret;
68
69 maybe_die(fd);
70
71 ret = write(fd, buf, count);
72 if (ret != count)
73 return ret;
74
75 maybe_die(fd);
76 return ret;
77}
78
79static int ftruncate_check(int fd, off_t length)
80{
81 int ret;
82
83 maybe_die(fd);
84
85 ret = ftruncate(fd, length);
86
87 maybe_die(fd);
88 return ret;
89}
90
91static enum agent_return flakey_ops(struct agent *a)
92{
93 enum agent_return ret;
94
95 /*
96 * Run in the external agent child
97 */
98
99 ret = external_agent_operation(a, OPEN_WITH_CLEAR_IF_FIRST, TEST_DBNAME);
100 if (ret != SUCCESS) {
101 fprintf(stderr, "Agent failed to open: %s\n",
102 agent_return_name(ret));
103 return ret;
104 }
105 ret = external_agent_operation(a, UNMAP, "");
106 if (ret != SUCCESS) {
107 fprintf(stderr, "Agent failed to unmap: %s\n",
108 agent_return_name(ret));
109 return ret;
110 }
111 ret = external_agent_operation(a, STORE, "xyz");
112 if (ret != SUCCESS) {
113 fprintf(stderr, "Agent failed to store: %s\n",
114 agent_return_name(ret));
115 return ret;
116 }
117 ret = external_agent_operation(a, STORE, KEY_STRING);
118 if (ret != SUCCESS) {
119 fprintf(stderr, "Agent failed store: %s\n",
120 agent_return_name(ret));
121 return ret;
122 }
123 ret = external_agent_operation(a, FETCH, KEY_STRING);
124 if (ret != SUCCESS) {
125 fprintf(stderr, "Agent failed find key: %s\n",
126 agent_return_name(ret));
127 return ret;
128 }
129 ret = external_agent_operation(a, PING, "");
130 if (ret != SUCCESS) {
131 fprintf(stderr, "Agent failed ping: %s\n",
132 agent_return_name(ret));
133 return ret;
134 }
135 return ret;
136}
137
138static bool prep_db(void) {
139 struct tdb_context *tdb;
140 TDB_DATA key;
141 TDB_DATA data;
142
143 key.dptr = discard_const_p(uint8_t, KEY_STRING);
144 key.dsize = strlen((char *)key.dptr);
145 data.dptr = discard_const_p(uint8_t, "foo");
146 data.dsize = strlen((char *)data.dptr);
147
148 unlink(TEST_DBNAME);
149
150 tdb = tdb_open_ex(
151 TEST_DBNAME, 2,
152 TDB_INCOMPATIBLE_HASH|TDB_MUTEX_LOCKING|TDB_CLEAR_IF_FIRST,
153 O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL);
154 if (tdb == NULL) {
155 return false;
156 }
157
158 if (tdb_store(tdb, key, data, TDB_INSERT) != 0) {
159 return false;
160 }
161
162 tdb_close(tdb);
163 tdb = NULL;
164
165 forget_locking();
166
167 return true;
168}
169
170static bool test_db(void) {
171 struct tdb_context *tdb;
172 int ret;
173
174 tdb = tdb_open_ex(
175 TEST_DBNAME, 1024, TDB_INCOMPATIBLE_HASH,
176 O_RDWR, 0600, &taplogctx, NULL);
177
178 if (tdb == NULL) {
179 perror("tdb_open_ex failed");
180 return false;
181 }
182
183 ret = tdb_traverse(tdb, NULL, NULL);
184 if (ret == -1) {
185 perror("traverse failed");
186 goto fail;
187 }
188
189 tdb_close(tdb);
190
191 forget_locking();
192
193 return true;
194
195fail:
196 tdb_close(tdb);
197 return false;
198}
199
200static bool test_one(void)
201{
202 enum agent_return ret;
203
204 ret = AGENT_DIED;
205 target = 19;
206
207 while (ret != SUCCESS) {
208 struct agent *agent;
209
210 {
211 int child_target = target;
212 bool pret;
213 target = 0;
214 pret = prep_db();
215 ok1(pret);
216 target = child_target;
217 }
218
219 agent = prepare_external_agent();
220
221 ret = flakey_ops(agent);
222
223 diag("Agent (target=%d) returns %s",
224 target, agent_return_name(ret));
225
226 if (ret == SUCCESS) {
227 ok((target > 19), "At least one AGENT_DIED expected");
228 } else {
229 ok(ret == AGENT_DIED, "AGENT_DIED expected");
230 }
231
232 shutdown_agent(agent);
233
234 {
235 int child_target = target;
236 bool tret;
237 target = 0;
238 tret = test_db();
239 ok1(tret);
240 target = child_target;
241 }
242
243 target += 1;
244 }
245
246 return true;
247}
248
249int main(int argc, char *argv[])
250{
251 bool ret;
252 bool runtime_support;
253
254 runtime_support = tdb_runtime_check_for_robust_mutexes();
255
256 if (!runtime_support) {
257 skip(1, "No robust mutex support");
258 return exit_status();
259 }
260
261 plan_tests(12);
262 unlock_callback = maybe_die;
263
264 ret = test_one();
265 ok1(ret);
266
267 diag("done");
268 return exit_status();
269}
Note: See TracBrowser for help on using the repository browser.