1 #include "../private.h" // for ntdb_fcntl_unlock
3 #include "tap-interface.h"
6 #include "helpapi-external-agent.h"
8 static int mylock(int fd, int rw, off_t off, off_t len, bool waitflag,
22 fl.l_whence = SEEK_SET;
27 ret = fcntl(fd, F_SETLKW, &fl);
29 ret = fcntl(fd, F_SETLK, &fl);
30 } while (ret != 0 && errno == EINTR);
36 static int trav(struct ntdb_context *ntdb, NTDB_DATA k, NTDB_DATA d, int *terr)
42 int main(int argc, char *argv[])
45 struct ntdb_context *ntdb;
46 int flags[] = { NTDB_DEFAULT, NTDB_NOMMAP,
47 NTDB_CONVERT, NTDB_NOMMAP|NTDB_CONVERT };
48 union ntdb_attribute lock_attr;
49 NTDB_DATA key = ntdb_mkdata("key", 3);
50 NTDB_DATA data = ntdb_mkdata("data", 4);
53 lock_attr.base.attr = NTDB_ATTRIBUTE_FLOCK;
54 lock_attr.base.next = &tap_log_attr;
55 lock_attr.flock.lock = mylock;
56 lock_attr.flock.unlock = ntdb_fcntl_unlock;
57 lock_attr.flock.data = &lock_err;
59 plan_tests(sizeof(flags) / sizeof(flags[0]) * 81);
61 for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) {
64 /* Nonblocking open; expect no error message. */
66 ntdb = ntdb_open("run-82-lockattr.ntdb", flags[i]|MAYBE_NOSYNC,
67 O_RDWR|O_CREAT|O_TRUNC, 0600, &lock_attr);
68 ok(errno == lock_err, "Errno is %u", errno);
70 ok1(tap_log_messages == 0);
73 ntdb = ntdb_open("run-82-lockattr.ntdb", flags[i]|MAYBE_NOSYNC,
74 O_RDWR|O_CREAT|O_TRUNC, 0600, &lock_attr);
75 ok(errno == lock_err, "Errno is %u", errno);
77 ok1(tap_log_messages == 0);
79 /* Forced fail open. */
81 ntdb = ntdb_open("run-82-lockattr.ntdb", flags[i]|MAYBE_NOSYNC,
82 O_RDWR|O_CREAT|O_TRUNC, 0600, &lock_attr);
83 ok1(errno == lock_err);
85 ok1(tap_log_messages == 1);
89 ntdb = ntdb_open("run-82-lockattr.ntdb", flags[i]|MAYBE_NOSYNC,
90 O_RDWR|O_CREAT|O_TRUNC, 0600, &lock_attr);
93 ok1(tap_log_messages == 0);
95 /* Nonblocking store. */
97 ok1(ntdb_store(ntdb, key, data, NTDB_REPLACE) == NTDB_ERR_LOCK);
98 ok1(tap_log_messages == 0);
100 ok1(ntdb_store(ntdb, key, data, NTDB_REPLACE) == NTDB_ERR_LOCK);
101 ok1(tap_log_messages == 0);
103 ok1(ntdb_store(ntdb, key, data, NTDB_REPLACE) == NTDB_ERR_LOCK);
104 ok1(tap_log_messages == 1);
105 tap_log_messages = 0;
107 /* Nonblocking fetch. */
109 ok1(!ntdb_exists(ntdb, key));
110 ok1(tap_log_messages == 0);
112 ok1(!ntdb_exists(ntdb, key));
113 ok1(tap_log_messages == 0);
115 ok1(!ntdb_exists(ntdb, key));
116 ok1(tap_log_messages == 1);
117 tap_log_messages = 0;
120 ok1(ntdb_fetch(ntdb, key, &d) == NTDB_ERR_LOCK);
121 ok1(tap_log_messages == 0);
123 ok1(ntdb_fetch(ntdb, key, &d) == NTDB_ERR_LOCK);
124 ok1(tap_log_messages == 0);
126 ok1(ntdb_fetch(ntdb, key, &d) == NTDB_ERR_LOCK);
127 ok1(tap_log_messages == 1);
128 tap_log_messages = 0;
130 /* Nonblocking delete. */
132 ok1(ntdb_delete(ntdb, key) == NTDB_ERR_LOCK);
133 ok1(tap_log_messages == 0);
135 ok1(ntdb_delete(ntdb, key) == NTDB_ERR_LOCK);
136 ok1(tap_log_messages == 0);
138 ok1(ntdb_delete(ntdb, key) == NTDB_ERR_LOCK);
139 ok1(tap_log_messages == 1);
140 tap_log_messages = 0;
142 /* Nonblocking locks. */
144 ok1(ntdb_chainlock(ntdb, key) == NTDB_ERR_LOCK);
145 ok1(tap_log_messages == 0);
147 ok1(ntdb_chainlock(ntdb, key) == NTDB_ERR_LOCK);
148 ok1(tap_log_messages == 0);
150 ok1(ntdb_chainlock(ntdb, key) == NTDB_ERR_LOCK);
151 ok1(tap_log_messages == 1);
152 tap_log_messages = 0;
155 ok1(ntdb_chainlock_read(ntdb, key) == NTDB_ERR_LOCK);
156 ok1(tap_log_messages == 0);
158 ok1(ntdb_chainlock_read(ntdb, key) == NTDB_ERR_LOCK);
159 ok1(tap_log_messages == 0);
161 ok1(ntdb_chainlock_read(ntdb, key) == NTDB_ERR_LOCK);
162 ok1(tap_log_messages == 1);
163 tap_log_messages = 0;
166 ok1(ntdb_lockall(ntdb) == NTDB_ERR_LOCK);
167 ok1(tap_log_messages == 0);
169 ok1(ntdb_lockall(ntdb) == NTDB_ERR_LOCK);
170 ok1(tap_log_messages == 0);
172 ok1(ntdb_lockall(ntdb) == NTDB_ERR_LOCK);
173 /* This actually does divide and conquer. */
174 ok1(tap_log_messages > 0);
175 tap_log_messages = 0;
178 ok1(ntdb_lockall_read(ntdb) == NTDB_ERR_LOCK);
179 ok1(tap_log_messages == 0);
181 ok1(ntdb_lockall_read(ntdb) == NTDB_ERR_LOCK);
182 ok1(tap_log_messages == 0);
184 ok1(ntdb_lockall_read(ntdb) == NTDB_ERR_LOCK);
185 ok1(tap_log_messages > 0);
186 tap_log_messages = 0;
188 /* Nonblocking traverse; go nonblock partway through. */
190 ok1(ntdb_store(ntdb, key, data, NTDB_REPLACE) == 0);
191 /* Need two entries to ensure two lock attempts! */
192 ok1(ntdb_store(ntdb, ntdb_mkdata("key2", 4), data,
195 ok1(ntdb_traverse(ntdb, trav, &lock_err) == NTDB_ERR_LOCK);
196 ok1(tap_log_messages == 0);
199 ok1(ntdb_traverse(ntdb, trav, &lock_err) == NTDB_ERR_LOCK);
200 ok1(tap_log_messages == 0);
203 ok1(ntdb_traverse(ntdb, trav, &lock_err) == NTDB_ERR_LOCK);
204 ok1(tap_log_messages == 1);
205 tap_log_messages = 0;
207 /* Nonblocking transactions. */
209 ok1(ntdb_transaction_start(ntdb) == NTDB_ERR_LOCK);
210 ok1(tap_log_messages == 0);
212 ok1(ntdb_transaction_start(ntdb) == NTDB_ERR_LOCK);
213 ok1(tap_log_messages == 0);
215 ok1(ntdb_transaction_start(ntdb) == NTDB_ERR_LOCK);
216 ok1(tap_log_messages == 1);
217 tap_log_messages = 0;
219 /* Nonblocking transaction prepare. */
221 ok1(ntdb_transaction_start(ntdb) == 0);
222 ok1(ntdb_delete(ntdb, key) == 0);
225 ok1(ntdb_transaction_prepare_commit(ntdb) == NTDB_ERR_LOCK);
226 ok1(tap_log_messages == 0);
229 ok1(ntdb_transaction_prepare_commit(ntdb) == 0);
230 ok1(ntdb_transaction_commit(ntdb) == 0);
232 /* And the transaction was committed, right? */
233 ok1(!ntdb_exists(ntdb, key));
235 ok1(tap_log_messages == 0);
237 return exit_status();