s3/doc: document the ignore system acls option of vfs_acl_xattr and vfs_acl_tdb
[Samba/gebeck_regimport.git] / lib / tdb2 / test / api-82-lockattr.c
blob048feacfa5ed665bb8154aaf98c04ed805f467fb
1 #include <ccan/tdb2/private.h> // for tdb_fcntl_unlock
2 #include <ccan/tdb2/tdb2.h>
3 #include <ccan/tap/tap.h>
4 #include <sys/types.h>
5 #include <sys/stat.h>
6 #include <fcntl.h>
7 #include <errno.h>
8 #include "logging.h"
10 static int mylock(int fd, int rw, off_t off, off_t len, bool waitflag,
11 void *_err)
13 int *lock_err = _err;
14 struct flock fl;
15 int ret;
17 if (*lock_err) {
18 errno = *lock_err;
19 return -1;
22 do {
23 fl.l_type = rw;
24 fl.l_whence = SEEK_SET;
25 fl.l_start = off;
26 fl.l_len = len;
28 if (waitflag)
29 ret = fcntl(fd, F_SETLKW, &fl);
30 else
31 ret = fcntl(fd, F_SETLK, &fl);
32 } while (ret != 0 && errno == EINTR);
34 return ret;
37 static int trav_err;
38 static int trav(struct tdb_context *tdb, TDB_DATA k, TDB_DATA d, int *err)
40 *err = trav_err;
41 return 0;
44 int main(int argc, char *argv[])
46 unsigned int i;
47 struct tdb_context *tdb;
48 int flags[] = { TDB_DEFAULT, TDB_NOMMAP,
49 TDB_CONVERT, TDB_NOMMAP|TDB_CONVERT,
50 TDB_VERSION1, TDB_NOMMAP|TDB_VERSION1,
51 TDB_CONVERT|TDB_VERSION1,
52 TDB_NOMMAP|TDB_CONVERT|TDB_VERSION1 };
53 union tdb_attribute lock_attr;
54 struct tdb_data key = tdb_mkdata("key", 3);
55 struct tdb_data data = tdb_mkdata("data", 4);
56 int lock_err;
58 lock_attr.base.attr = TDB_ATTRIBUTE_FLOCK;
59 lock_attr.base.next = &tap_log_attr;
60 lock_attr.flock.lock = mylock;
61 lock_attr.flock.unlock = tdb_fcntl_unlock;
62 lock_attr.flock.data = &lock_err;
64 plan_tests(sizeof(flags) / sizeof(flags[0]) * 80);
66 for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) {
67 struct tdb_data d;
68 unsigned int num_oom_messages;
70 /* TDB1 double logs here. */
71 if (flags[i] & TDB_VERSION1) {
72 num_oom_messages = 2;
73 } else {
74 num_oom_messages = 1;
77 /* Nonblocking open; expect no error message. */
78 lock_err = EAGAIN;
79 tdb = tdb_open("run-82-lockattr.tdb", flags[i],
80 O_RDWR|O_CREAT|O_TRUNC, 0600, &lock_attr);
81 ok(errno == lock_err, "Errno is %u", errno);
82 ok1(!tdb);
83 ok1(tap_log_messages == 0);
85 lock_err = EINTR;
86 tdb = tdb_open("run-82-lockattr.tdb", flags[i],
87 O_RDWR|O_CREAT|O_TRUNC, 0600, &lock_attr);
88 ok(errno == lock_err, "Errno is %u", errno);
89 ok1(!tdb);
90 ok1(tap_log_messages == 0);
92 /* Forced fail open. */
93 lock_err = ENOMEM;
94 tdb = tdb_open("run-82-lockattr.tdb", flags[i],
95 O_RDWR|O_CREAT|O_TRUNC, 0600, &lock_attr);
96 ok1(errno == lock_err);
97 ok1(!tdb);
98 ok1(tap_log_messages == 1);
99 tap_log_messages = 0;
101 lock_err = 0;
102 tdb = tdb_open("run-82-lockattr.tdb", flags[i],
103 O_RDWR|O_CREAT|O_TRUNC, 0600, &lock_attr);
104 if (!ok1(tdb))
105 continue;
106 ok1(tap_log_messages == 0);
108 /* Nonblocking store. */
109 lock_err = EAGAIN;
110 ok1(tdb_store(tdb, key, data, TDB_REPLACE) == TDB_ERR_LOCK);
111 ok1(tap_log_messages == 0);
112 lock_err = EINTR;
113 ok1(tdb_store(tdb, key, data, TDB_REPLACE) == TDB_ERR_LOCK);
114 ok1(tap_log_messages == 0);
115 lock_err = ENOMEM;
116 ok1(tdb_store(tdb, key, data, TDB_REPLACE) == TDB_ERR_LOCK);
117 ok1(tap_log_messages == num_oom_messages);
118 tap_log_messages = 0;
120 /* Nonblocking fetch. */
121 lock_err = EAGAIN;
122 ok1(!tdb_exists(tdb, key));
123 ok1(tap_log_messages == 0);
124 lock_err = EINTR;
125 ok1(!tdb_exists(tdb, key));
126 ok1(tap_log_messages == 0);
127 lock_err = ENOMEM;
128 ok1(!tdb_exists(tdb, key));
129 ok1(tap_log_messages == num_oom_messages);
130 tap_log_messages = 0;
132 lock_err = EAGAIN;
133 ok1(tdb_fetch(tdb, key, &d) == TDB_ERR_LOCK);
134 ok1(tap_log_messages == 0);
135 lock_err = EINTR;
136 ok1(tdb_fetch(tdb, key, &d) == TDB_ERR_LOCK);
137 ok1(tap_log_messages == 0);
138 lock_err = ENOMEM;
139 ok1(tdb_fetch(tdb, key, &d) == TDB_ERR_LOCK);
140 ok1(tap_log_messages == num_oom_messages);
141 tap_log_messages = 0;
143 /* Nonblocking delete. */
144 lock_err = EAGAIN;
145 ok1(tdb_delete(tdb, key) == TDB_ERR_LOCK);
146 ok1(tap_log_messages == 0);
147 lock_err = EINTR;
148 ok1(tdb_delete(tdb, key) == TDB_ERR_LOCK);
149 ok1(tap_log_messages == 0);
150 lock_err = ENOMEM;
151 ok1(tdb_delete(tdb, key) == TDB_ERR_LOCK);
152 ok1(tap_log_messages == num_oom_messages);
153 tap_log_messages = 0;
155 /* Nonblocking locks. */
156 lock_err = EAGAIN;
157 ok1(tdb_chainlock(tdb, key) == TDB_ERR_LOCK);
158 ok1(tap_log_messages == 0);
159 lock_err = EINTR;
160 ok1(tdb_chainlock(tdb, key) == TDB_ERR_LOCK);
161 ok1(tap_log_messages == 0);
162 lock_err = ENOMEM;
163 ok1(tdb_chainlock(tdb, key) == TDB_ERR_LOCK);
164 ok1(tap_log_messages == num_oom_messages);
165 tap_log_messages = 0;
167 lock_err = EAGAIN;
168 ok1(tdb_chainlock_read(tdb, key) == TDB_ERR_LOCK);
169 ok1(tap_log_messages == 0);
170 lock_err = EINTR;
171 ok1(tdb_chainlock_read(tdb, key) == TDB_ERR_LOCK);
172 ok1(tap_log_messages == 0);
173 lock_err = ENOMEM;
174 ok1(tdb_chainlock_read(tdb, key) == TDB_ERR_LOCK);
175 ok1(tap_log_messages == num_oom_messages);
176 tap_log_messages = 0;
178 lock_err = EAGAIN;
179 ok1(tdb_lockall(tdb) == TDB_ERR_LOCK);
180 ok1(tap_log_messages == 0);
181 lock_err = EINTR;
182 ok1(tdb_lockall(tdb) == TDB_ERR_LOCK);
183 ok1(tap_log_messages == 0);
184 lock_err = ENOMEM;
185 ok1(tdb_lockall(tdb) == TDB_ERR_LOCK);
186 /* This actually does divide and conquer. */
187 ok1(tap_log_messages > 0);
188 tap_log_messages = 0;
190 lock_err = EAGAIN;
191 ok1(tdb_lockall_read(tdb) == TDB_ERR_LOCK);
192 ok1(tap_log_messages == 0);
193 lock_err = EINTR;
194 ok1(tdb_lockall_read(tdb) == TDB_ERR_LOCK);
195 ok1(tap_log_messages == 0);
196 lock_err = ENOMEM;
197 ok1(tdb_lockall_read(tdb) == TDB_ERR_LOCK);
198 ok1(tap_log_messages > 0);
199 tap_log_messages = 0;
201 /* Nonblocking traverse; go nonblock partway through. */
202 lock_err = 0;
203 ok1(tdb_store(tdb, key, data, TDB_REPLACE) == 0);
204 trav_err = EAGAIN;
205 ok1(tdb_traverse(tdb, trav, &lock_err) == TDB_ERR_LOCK);
206 ok1(tap_log_messages == 0);
207 trav_err = EINTR;
208 lock_err = 0;
209 ok1(tdb_traverse(tdb, trav, &lock_err) == TDB_ERR_LOCK);
210 ok1(tap_log_messages == 0);
211 trav_err = ENOMEM;
212 lock_err = 0;
213 ok1(tdb_traverse(tdb, trav, &lock_err) == TDB_ERR_LOCK);
214 ok1(tap_log_messages == num_oom_messages);
215 tap_log_messages = 0;
217 /* Nonblocking transactions. */
218 lock_err = EAGAIN;
219 ok1(tdb_transaction_start(tdb) == TDB_ERR_LOCK);
220 ok1(tap_log_messages == 0);
221 lock_err = EINTR;
222 ok1(tdb_transaction_start(tdb) == TDB_ERR_LOCK);
223 ok1(tap_log_messages == 0);
224 lock_err = ENOMEM;
225 ok1(tdb_transaction_start(tdb) == TDB_ERR_LOCK);
226 ok1(tap_log_messages == 1);
227 tap_log_messages = 0;
229 /* Nonblocking transaction prepare. */
230 lock_err = 0;
231 ok1(tdb_transaction_start(tdb) == 0);
232 ok1(tdb_delete(tdb, key) == 0);
234 lock_err = EAGAIN;
235 ok1(tdb_transaction_prepare_commit(tdb) == TDB_ERR_LOCK);
236 ok1(tap_log_messages == 0);
238 lock_err = 0;
239 ok1(tdb_transaction_prepare_commit(tdb) == 0);
240 ok1(tdb_transaction_commit(tdb) == 0);
242 /* And the transaction was committed, right? */
243 ok1(!tdb_exists(tdb, key));
244 tdb_close(tdb);
245 ok1(tap_log_messages == 0);
247 return exit_status();