2 * Unix SMB/CIFS implementation.
4 * Copyright (C) Volker Lendecke 2017
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "torture/proto.h"
22 #include "system/filesys.h"
25 #include "lib/util/server_id.h"
27 static bool get_g_lock_ctx(TALLOC_CTX
*mem_ctx
,
28 struct tevent_context
**ev
,
29 struct messaging_context
**msg
,
30 struct g_lock_ctx
**ctx
)
32 *ev
= samba_tevent_context_init(mem_ctx
);
34 fprintf(stderr
, "tevent_context_init failed\n");
37 *msg
= messaging_init(*ev
, *ev
);
39 fprintf(stderr
, "messaging_init failed\n");
43 *ctx
= g_lock_ctx_init(*ev
, *msg
);
45 fprintf(stderr
, "g_lock_ctx_init failed\n");
54 bool run_g_lock1(int dummy
)
56 struct tevent_context
*ev
= NULL
;
57 struct messaging_context
*msg
= NULL
;
58 struct g_lock_ctx
*ctx
= NULL
;
59 const char *lockname
= "lock1";
64 ok
= get_g_lock_ctx(talloc_tos(), &ev
, &msg
, &ctx
);
69 status
= g_lock_lock(ctx
, lockname
, G_LOCK_READ
,
70 (struct timeval
) { .tv_sec
= 1 });
71 if (!NT_STATUS_IS_OK(status
)) {
72 fprintf(stderr
, "g_lock_lock failed: %s\n",
77 status
= g_lock_lock(ctx
, lockname
, G_LOCK_READ
,
78 (struct timeval
) { .tv_sec
= 1 });
79 if (!NT_STATUS_EQUAL(status
, NT_STATUS_WAS_LOCKED
)) {
80 fprintf(stderr
, "Double lock got %s\n",
85 status
= g_lock_unlock(ctx
, lockname
);
86 if (!NT_STATUS_IS_OK(status
)) {
87 fprintf(stderr
, "g_lock_unlock failed: %s\n",
92 status
= g_lock_unlock(ctx
, lockname
);
93 if (!NT_STATUS_EQUAL(status
, NT_STATUS_NOT_FOUND
)) {
94 fprintf(stderr
, "g_lock_unlock returned: %s\n",
107 struct lock2_parser_state
{
112 static void lock2_parser(const struct g_lock_rec
*locks
,
118 struct lock2_parser_state
*state
= private_data
;
120 if (datalen
!= sizeof(uint8_t)) {
123 *state
->rdata
= *data
;
128 * Test g_lock_write_data
131 bool run_g_lock2(int dummy
)
133 struct tevent_context
*ev
= NULL
;
134 struct messaging_context
*msg
= NULL
;
135 struct g_lock_ctx
*ctx
= NULL
;
136 const char *lockname
= "lock2";
139 struct lock2_parser_state state
= { .rdata
= &rdata
};
144 ok
= get_g_lock_ctx(talloc_tos(), &ev
, &msg
, &ctx
);
149 status
= g_lock_write_data(ctx
, lockname
, &data
, sizeof(data
));
150 if (!NT_STATUS_EQUAL(status
, NT_STATUS_NOT_LOCKED
)) {
151 fprintf(stderr
, "unlocked g_lock_write_data returned %s\n",
156 status
= g_lock_lock(ctx
, lockname
, G_LOCK_WRITE
,
157 (struct timeval
) { .tv_sec
= 1 });
158 if (!NT_STATUS_IS_OK(status
)) {
159 fprintf(stderr
, "g_lock_lock returned %s\n",
164 status
= g_lock_write_data(ctx
, lockname
, &data
, sizeof(data
));
165 if (!NT_STATUS_IS_OK(status
)) {
166 fprintf(stderr
, "g_lock_write_data failed: %s\n",
171 status
= g_lock_unlock(ctx
, lockname
);
172 if (!NT_STATUS_IS_OK(status
)) {
173 fprintf(stderr
, "g_lock_unlock failed: %s\n",
178 status
= g_lock_dump(ctx
, lockname
, lock2_parser
, &state
);
179 if (!NT_STATUS_IS_OK(status
)) {
180 fprintf(stderr
, "g_lock_dump failed: %s\n",
186 fprintf(stderr
, "Could not parse data\n");
190 fprintf(stderr
, "Returned %"PRIu8
", expected %"PRIu8
"\n",
203 struct lock3_parser_state
{
204 struct server_id self
;
205 enum g_lock_type lock_type
;
209 static void lock3_parser(const struct g_lock_rec
*locks
,
215 struct lock3_parser_state
*state
= private_data
;
218 fprintf(stderr
, "datalen=%zu\n", datalen
);
221 if (num_locks
!= 1) {
222 fprintf(stderr
, "num_locks=%zu\n", num_locks
);
225 if (locks
[0].lock_type
!= state
->lock_type
) {
226 fprintf(stderr
, "found type %d, expected %d\n",
227 (int)locks
[0].lock_type
, (int)state
->lock_type
);
230 if (!server_id_equal(&locks
[0].pid
, &state
->self
)) {
231 struct server_id_buf tmp1
, tmp2
;
232 fprintf(stderr
, "found pid %s, expected %s\n",
233 server_id_str_buf(locks
[0].pid
, &tmp1
),
234 server_id_str_buf(state
->self
, &tmp2
));
242 * Test lock upgrade/downgrade
245 bool run_g_lock3(int dummy
)
247 struct tevent_context
*ev
= NULL
;
248 struct messaging_context
*msg
= NULL
;
249 struct g_lock_ctx
*ctx
= NULL
;
250 const char *lockname
= "lock3";
251 struct lock3_parser_state state
;
256 ok
= get_g_lock_ctx(talloc_tos(), &ev
, &msg
, &ctx
);
261 state
.self
= messaging_server_id(msg
);
263 status
= g_lock_lock(ctx
, lockname
, G_LOCK_READ
,
264 (struct timeval
) { .tv_sec
= 1 });
265 if (!NT_STATUS_IS_OK(status
)) {
266 fprintf(stderr
, "g_lock_lock returned %s\n",
271 status
= g_lock_lock(ctx
, lockname
, G_LOCK_READ
,
272 (struct timeval
) { .tv_sec
= 1 });
273 if (!NT_STATUS_EQUAL(status
, NT_STATUS_WAS_LOCKED
)) {
274 fprintf(stderr
, "g_lock_lock returned %s, expected %s\n",
275 nt_errstr(status
), nt_errstr(NT_STATUS_WAS_LOCKED
));
279 state
.lock_type
= G_LOCK_READ
;
282 status
= g_lock_dump(ctx
, lockname
, lock3_parser
, &state
);
283 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OK
)) {
284 fprintf(stderr
, "g_lock_dump returned %s\n",
292 status
= g_lock_lock(ctx
, lockname
, G_LOCK_WRITE
,
293 (struct timeval
) { .tv_sec
= 1 });
294 if (!NT_STATUS_IS_OK(status
)) {
295 fprintf(stderr
, "g_lock_lock returned %s\n",
300 state
.lock_type
= G_LOCK_WRITE
;
303 status
= g_lock_dump(ctx
, lockname
, lock3_parser
, &state
);
304 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OK
)) {
305 fprintf(stderr
, "g_lock_dump returned %s\n",