1 #include "private.h" // for tdb_fcntl_unlock
3 #include "tap-interface.h"
10 static int mylock(int fd, int rw, off_t off, off_t len, bool waitflag,
24 fl.l_whence = SEEK_SET;
29 ret = fcntl(fd, F_SETLKW, &fl);
31 ret = fcntl(fd, F_SETLK, &fl);
32 } while (ret != 0 && errno == EINTR);
38 static int trav(struct tdb_context *tdb, TDB_DATA k, TDB_DATA d, int *terr)
44 int main(int argc, char *argv[])
47 struct tdb_context *tdb;
48 int flags[] = { TDB_DEFAULT, TDB_NOMMAP,
49 TDB_CONVERT, TDB_NOMMAP|TDB_CONVERT };
50 union tdb_attribute lock_attr;
51 struct tdb_data key = tdb_mkdata("key", 3);
52 struct tdb_data data = tdb_mkdata("data", 4);
55 lock_attr.base.attr = TDB_ATTRIBUTE_FLOCK;
56 lock_attr.base.next = &tap_log_attr;
57 lock_attr.flock.lock = mylock;
58 lock_attr.flock.unlock = tdb_fcntl_unlock;
59 lock_attr.flock.data = &lock_err;
61 plan_tests(sizeof(flags) / sizeof(flags[0]) * 80);
63 for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) {
66 /* Nonblocking open; expect no error message. */
68 tdb = tdb_open("run-82-lockattr.tdb", flags[i],
69 O_RDWR|O_CREAT|O_TRUNC, 0600, &lock_attr);
70 ok(errno == lock_err, "Errno is %u", errno);
72 ok1(tap_log_messages == 0);
75 tdb = tdb_open("run-82-lockattr.tdb", flags[i],
76 O_RDWR|O_CREAT|O_TRUNC, 0600, &lock_attr);
77 ok(errno == lock_err, "Errno is %u", errno);
79 ok1(tap_log_messages == 0);
81 /* Forced fail open. */
83 tdb = tdb_open("run-82-lockattr.tdb", flags[i],
84 O_RDWR|O_CREAT|O_TRUNC, 0600, &lock_attr);
85 ok1(errno == lock_err);
87 ok1(tap_log_messages == 1);
91 tdb = tdb_open("run-82-lockattr.tdb", flags[i],
92 O_RDWR|O_CREAT|O_TRUNC, 0600, &lock_attr);
95 ok1(tap_log_messages == 0);
97 /* Nonblocking store. */
99 ok1(tdb_store(tdb, key, data, TDB_REPLACE) == TDB_ERR_LOCK);
100 ok1(tap_log_messages == 0);
102 ok1(tdb_store(tdb, key, data, TDB_REPLACE) == TDB_ERR_LOCK);
103 ok1(tap_log_messages == 0);
105 ok1(tdb_store(tdb, key, data, TDB_REPLACE) == TDB_ERR_LOCK);
106 ok1(tap_log_messages == 1);
107 tap_log_messages = 0;
109 /* Nonblocking fetch. */
111 ok1(!tdb_exists(tdb, key));
112 ok1(tap_log_messages == 0);
114 ok1(!tdb_exists(tdb, key));
115 ok1(tap_log_messages == 0);
117 ok1(!tdb_exists(tdb, key));
118 ok1(tap_log_messages == 1);
119 tap_log_messages = 0;
122 ok1(tdb_fetch(tdb, key, &d) == TDB_ERR_LOCK);
123 ok1(tap_log_messages == 0);
125 ok1(tdb_fetch(tdb, key, &d) == TDB_ERR_LOCK);
126 ok1(tap_log_messages == 0);
128 ok1(tdb_fetch(tdb, key, &d) == TDB_ERR_LOCK);
129 ok1(tap_log_messages == 1);
130 tap_log_messages = 0;
132 /* Nonblocking delete. */
134 ok1(tdb_delete(tdb, key) == TDB_ERR_LOCK);
135 ok1(tap_log_messages == 0);
137 ok1(tdb_delete(tdb, key) == TDB_ERR_LOCK);
138 ok1(tap_log_messages == 0);
140 ok1(tdb_delete(tdb, key) == TDB_ERR_LOCK);
141 ok1(tap_log_messages == 1);
142 tap_log_messages = 0;
144 /* Nonblocking locks. */
146 ok1(tdb_chainlock(tdb, key) == TDB_ERR_LOCK);
147 ok1(tap_log_messages == 0);
149 ok1(tdb_chainlock(tdb, key) == TDB_ERR_LOCK);
150 ok1(tap_log_messages == 0);
152 ok1(tdb_chainlock(tdb, key) == TDB_ERR_LOCK);
153 ok1(tap_log_messages == 1);
154 tap_log_messages = 0;
157 ok1(tdb_chainlock_read(tdb, key) == TDB_ERR_LOCK);
158 ok1(tap_log_messages == 0);
160 ok1(tdb_chainlock_read(tdb, key) == TDB_ERR_LOCK);
161 ok1(tap_log_messages == 0);
163 ok1(tdb_chainlock_read(tdb, key) == TDB_ERR_LOCK);
164 ok1(tap_log_messages == 1);
165 tap_log_messages = 0;
168 ok1(tdb_lockall(tdb) == TDB_ERR_LOCK);
169 ok1(tap_log_messages == 0);
171 ok1(tdb_lockall(tdb) == TDB_ERR_LOCK);
172 ok1(tap_log_messages == 0);
174 ok1(tdb_lockall(tdb) == TDB_ERR_LOCK);
175 /* This actually does divide and conquer. */
176 ok1(tap_log_messages > 0);
177 tap_log_messages = 0;
180 ok1(tdb_lockall_read(tdb) == TDB_ERR_LOCK);
181 ok1(tap_log_messages == 0);
183 ok1(tdb_lockall_read(tdb) == TDB_ERR_LOCK);
184 ok1(tap_log_messages == 0);
186 ok1(tdb_lockall_read(tdb) == TDB_ERR_LOCK);
187 ok1(tap_log_messages > 0);
188 tap_log_messages = 0;
190 /* Nonblocking traverse; go nonblock partway through. */
192 ok1(tdb_store(tdb, key, data, TDB_REPLACE) == 0);
194 ok1(tdb_traverse(tdb, trav, &lock_err) == TDB_ERR_LOCK);
195 ok1(tap_log_messages == 0);
198 ok1(tdb_traverse(tdb, trav, &lock_err) == TDB_ERR_LOCK);
199 ok1(tap_log_messages == 0);
202 ok1(tdb_traverse(tdb, trav, &lock_err) == TDB_ERR_LOCK);
203 ok1(tap_log_messages == 1);
204 tap_log_messages = 0;
206 /* Nonblocking transactions. */
208 ok1(tdb_transaction_start(tdb) == TDB_ERR_LOCK);
209 ok1(tap_log_messages == 0);
211 ok1(tdb_transaction_start(tdb) == TDB_ERR_LOCK);
212 ok1(tap_log_messages == 0);
214 ok1(tdb_transaction_start(tdb) == TDB_ERR_LOCK);
215 ok1(tap_log_messages == 1);
216 tap_log_messages = 0;
218 /* Nonblocking transaction prepare. */
220 ok1(tdb_transaction_start(tdb) == 0);
221 ok1(tdb_delete(tdb, key) == 0);
224 ok1(tdb_transaction_prepare_commit(tdb) == TDB_ERR_LOCK);
225 ok1(tap_log_messages == 0);
228 ok1(tdb_transaction_prepare_commit(tdb) == 0);
229 ok1(tdb_transaction_commit(tdb) == 0);
231 /* And the transaction was committed, right? */
232 ok1(!tdb_exists(tdb, key));
234 ok1(tap_log_messages == 0);
236 return exit_status();