1 #include "private.h" // for ntdb_fcntl_unlock
3 #include "tap-interface.h"
7 static int mylock(int fd
, int rw
, off_t off
, off_t len
, bool waitflag
,
21 fl
.l_whence
= SEEK_SET
;
26 ret
= fcntl(fd
, F_SETLKW
, &fl
);
28 ret
= fcntl(fd
, F_SETLK
, &fl
);
29 } while (ret
!= 0 && errno
== EINTR
);
35 static int trav(struct ntdb_context
*ntdb
, NTDB_DATA k
, NTDB_DATA d
, int *terr
)
41 int main(int argc
, char *argv
[])
44 struct ntdb_context
*ntdb
;
45 int flags
[] = { NTDB_DEFAULT
, NTDB_NOMMAP
,
46 NTDB_CONVERT
, NTDB_NOMMAP
|NTDB_CONVERT
};
47 union ntdb_attribute lock_attr
;
48 NTDB_DATA key
= ntdb_mkdata("key", 3);
49 NTDB_DATA data
= ntdb_mkdata("data", 4);
52 lock_attr
.base
.attr
= NTDB_ATTRIBUTE_FLOCK
;
53 lock_attr
.base
.next
= &tap_log_attr
;
54 lock_attr
.flock
.lock
= mylock
;
55 lock_attr
.flock
.unlock
= ntdb_fcntl_unlock
;
56 lock_attr
.flock
.data
= &lock_err
;
58 plan_tests(sizeof(flags
) / sizeof(flags
[0]) * 81);
60 for (i
= 0; i
< sizeof(flags
) / sizeof(flags
[0]); i
++) {
63 /* Nonblocking open; expect no error message. */
65 ntdb
= ntdb_open("run-82-lockattr.ntdb", flags
[i
]|MAYBE_NOSYNC
,
66 O_RDWR
|O_CREAT
|O_TRUNC
, 0600, &lock_attr
);
67 ok(errno
== lock_err
, "Errno is %u", errno
);
69 ok1(tap_log_messages
== 0);
72 ntdb
= ntdb_open("run-82-lockattr.ntdb", flags
[i
]|MAYBE_NOSYNC
,
73 O_RDWR
|O_CREAT
|O_TRUNC
, 0600, &lock_attr
);
74 ok(errno
== lock_err
, "Errno is %u", errno
);
76 ok1(tap_log_messages
== 0);
78 /* Forced fail open. */
80 ntdb
= ntdb_open("run-82-lockattr.ntdb", flags
[i
]|MAYBE_NOSYNC
,
81 O_RDWR
|O_CREAT
|O_TRUNC
, 0600, &lock_attr
);
82 ok1(errno
== lock_err
);
84 ok1(tap_log_messages
== 1);
88 ntdb
= ntdb_open("run-82-lockattr.ntdb", flags
[i
]|MAYBE_NOSYNC
,
89 O_RDWR
|O_CREAT
|O_TRUNC
, 0600, &lock_attr
);
92 ok1(tap_log_messages
== 0);
94 /* Nonblocking store. */
96 ok1(ntdb_store(ntdb
, key
, data
, NTDB_REPLACE
) == NTDB_ERR_LOCK
);
97 ok1(tap_log_messages
== 0);
99 ok1(ntdb_store(ntdb
, key
, data
, NTDB_REPLACE
) == NTDB_ERR_LOCK
);
100 ok1(tap_log_messages
== 0);
102 ok1(ntdb_store(ntdb
, key
, data
, NTDB_REPLACE
) == NTDB_ERR_LOCK
);
103 ok1(tap_log_messages
== 1);
104 tap_log_messages
= 0;
106 /* Nonblocking fetch. */
108 ok1(!ntdb_exists(ntdb
, key
));
109 ok1(tap_log_messages
== 0);
111 ok1(!ntdb_exists(ntdb
, key
));
112 ok1(tap_log_messages
== 0);
114 ok1(!ntdb_exists(ntdb
, key
));
115 ok1(tap_log_messages
== 1);
116 tap_log_messages
= 0;
119 ok1(ntdb_fetch(ntdb
, key
, &d
) == NTDB_ERR_LOCK
);
120 ok1(tap_log_messages
== 0);
122 ok1(ntdb_fetch(ntdb
, key
, &d
) == NTDB_ERR_LOCK
);
123 ok1(tap_log_messages
== 0);
125 ok1(ntdb_fetch(ntdb
, key
, &d
) == NTDB_ERR_LOCK
);
126 ok1(tap_log_messages
== 1);
127 tap_log_messages
= 0;
129 /* Nonblocking delete. */
131 ok1(ntdb_delete(ntdb
, key
) == NTDB_ERR_LOCK
);
132 ok1(tap_log_messages
== 0);
134 ok1(ntdb_delete(ntdb
, key
) == NTDB_ERR_LOCK
);
135 ok1(tap_log_messages
== 0);
137 ok1(ntdb_delete(ntdb
, key
) == NTDB_ERR_LOCK
);
138 ok1(tap_log_messages
== 1);
139 tap_log_messages
= 0;
141 /* Nonblocking locks. */
143 ok1(ntdb_chainlock(ntdb
, key
) == NTDB_ERR_LOCK
);
144 ok1(tap_log_messages
== 0);
146 ok1(ntdb_chainlock(ntdb
, key
) == NTDB_ERR_LOCK
);
147 ok1(tap_log_messages
== 0);
149 ok1(ntdb_chainlock(ntdb
, key
) == NTDB_ERR_LOCK
);
150 ok1(tap_log_messages
== 1);
151 tap_log_messages
= 0;
154 ok1(ntdb_chainlock_read(ntdb
, key
) == NTDB_ERR_LOCK
);
155 ok1(tap_log_messages
== 0);
157 ok1(ntdb_chainlock_read(ntdb
, key
) == NTDB_ERR_LOCK
);
158 ok1(tap_log_messages
== 0);
160 ok1(ntdb_chainlock_read(ntdb
, key
) == NTDB_ERR_LOCK
);
161 ok1(tap_log_messages
== 1);
162 tap_log_messages
= 0;
165 ok1(ntdb_lockall(ntdb
) == NTDB_ERR_LOCK
);
166 ok1(tap_log_messages
== 0);
168 ok1(ntdb_lockall(ntdb
) == NTDB_ERR_LOCK
);
169 ok1(tap_log_messages
== 0);
171 ok1(ntdb_lockall(ntdb
) == NTDB_ERR_LOCK
);
172 /* This actually does divide and conquer. */
173 ok1(tap_log_messages
> 0);
174 tap_log_messages
= 0;
177 ok1(ntdb_lockall_read(ntdb
) == NTDB_ERR_LOCK
);
178 ok1(tap_log_messages
== 0);
180 ok1(ntdb_lockall_read(ntdb
) == NTDB_ERR_LOCK
);
181 ok1(tap_log_messages
== 0);
183 ok1(ntdb_lockall_read(ntdb
) == NTDB_ERR_LOCK
);
184 ok1(tap_log_messages
> 0);
185 tap_log_messages
= 0;
187 /* Nonblocking traverse; go nonblock partway through. */
189 ok1(ntdb_store(ntdb
, key
, data
, NTDB_REPLACE
) == 0);
190 /* Need two entries to ensure two lock attempts! */
191 ok1(ntdb_store(ntdb
, ntdb_mkdata("key2", 4), data
,
194 ok1(ntdb_traverse(ntdb
, trav
, &lock_err
) == NTDB_ERR_LOCK
);
195 ok1(tap_log_messages
== 0);
198 ok1(ntdb_traverse(ntdb
, trav
, &lock_err
) == NTDB_ERR_LOCK
);
199 ok1(tap_log_messages
== 0);
202 ok1(ntdb_traverse(ntdb
, trav
, &lock_err
) == NTDB_ERR_LOCK
);
203 ok1(tap_log_messages
== 1);
204 tap_log_messages
= 0;
206 /* Nonblocking transactions. */
208 ok1(ntdb_transaction_start(ntdb
) == NTDB_ERR_LOCK
);
209 ok1(tap_log_messages
== 0);
211 ok1(ntdb_transaction_start(ntdb
) == NTDB_ERR_LOCK
);
212 ok1(tap_log_messages
== 0);
214 ok1(ntdb_transaction_start(ntdb
) == NTDB_ERR_LOCK
);
215 ok1(tap_log_messages
== 1);
216 tap_log_messages
= 0;
218 /* Nonblocking transaction prepare. */
220 ok1(ntdb_transaction_start(ntdb
) == 0);
221 ok1(ntdb_delete(ntdb
, key
) == 0);
224 ok1(ntdb_transaction_prepare_commit(ntdb
) == NTDB_ERR_LOCK
);
225 ok1(tap_log_messages
== 0);
228 ok1(ntdb_transaction_prepare_commit(ntdb
) == 0);
229 ok1(ntdb_transaction_commit(ntdb
) == 0);
231 /* And the transaction was committed, right? */
232 ok1(!ntdb_exists(ntdb
, key
));
234 ok1(tap_log_messages
== 0);
236 return exit_status();