1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-10 01:18:15 +03:00

s3:g_lock: add callback function to g_lock_lock()

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15125

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
This commit is contained in:
Stefan Metzmacher 2022-08-28 13:08:48 +02:00 committed by Jeremy Allison
parent 37c9600ff1
commit 17e496c6f9
9 changed files with 98 additions and 42 deletions

View File

@ -79,7 +79,9 @@ struct tevent_req *g_lock_lock_send(TALLOC_CTX *mem_ctx,
void *cb_private);
NTSTATUS g_lock_lock_recv(struct tevent_req *req);
NTSTATUS g_lock_lock(struct g_lock_ctx *ctx, TDB_DATA key,
enum g_lock_type lock_type, struct timeval timeout);
enum g_lock_type lock_type, struct timeval timeout,
g_lock_lock_cb_fn_t cb_fn,
void *cb_private);
NTSTATUS g_lock_unlock(struct g_lock_ctx *ctx, TDB_DATA key);
NTSTATUS g_lock_writev_data(

View File

@ -382,7 +382,7 @@ static int db_ctdb_transaction_start(struct db_context *db)
* Wait a day, i.e. forever...
*/
status = g_lock_lock(ctx->lock_ctx, string_term_tdb_data(h->lock_name),
G_LOCK_WRITE, timeval_set(86400, 0));
G_LOCK_WRITE, timeval_set(86400, 0), NULL, NULL);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0, ("g_lock_lock failed: %s\n", nt_errstr(status)));
TALLOC_FREE(h);

View File

@ -1225,10 +1225,10 @@ not_granted:
}
NTSTATUS g_lock_lock(struct g_lock_ctx *ctx, TDB_DATA key,
enum g_lock_type type, struct timeval timeout)
enum g_lock_type type, struct timeval timeout,
g_lock_lock_cb_fn_t cb_fn,
void *cb_private)
{
g_lock_lock_cb_fn_t cb_fn = NULL;
void *cb_private = NULL;
TALLOC_CTX *frame;
struct tevent_context *ev;
struct tevent_req *req;
@ -1237,6 +1237,16 @@ NTSTATUS g_lock_lock(struct g_lock_ctx *ctx, TDB_DATA key,
SMB_ASSERT(!ctx->busy);
/*
* We allow a cn_fn only for G_LOCK_WRITE for now.
*
* It's all we currently need and it makes a few things
* easier to implement.
*/
if (unlikely(cb_fn != NULL && type != G_LOCK_WRITE)) {
return NT_STATUS_INVALID_PARAMETER_5;
}
if ((type == G_LOCK_READ) || (type == G_LOCK_WRITE)) {
/*
* This is an abstraction violation: Normally we do

View File

@ -201,7 +201,7 @@ NTSTATUS trust_pw_change(struct netlogon_creds_cli_context *context,
g_timeout = timeval_current_ofs(10, 0);
status = g_lock_lock(state->g_ctx,
string_term_tdb_data(state->g_lock_key),
G_LOCK_WRITE, g_timeout);
G_LOCK_WRITE, g_timeout, NULL, NULL);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("could not get g_lock on [%s]!\n",
state->g_lock_key));

View File

@ -887,7 +887,8 @@ static NTSTATUS get_share_mode_lock_internal(
lock_ctx,
key,
G_LOCK_WRITE,
(struct timeval) { .tv_sec = 3600 });
(struct timeval) { .tv_sec = 3600 },
NULL, NULL);
if (!NT_STATUS_IS_OK(status)) {
DBG_DEBUG("g_lock_lock failed: %s\n",
nt_errstr(status));

View File

@ -1471,8 +1471,12 @@ static NTSTATUS smbd_claim_version(struct messaging_context *msg,
return NT_STATUS_UNSUCCESSFUL;
}
status = g_lock_lock(
ctx, key, G_LOCK_READ, (struct timeval) { .tv_sec = 60 });
status = g_lock_lock(ctx,
key,
G_LOCK_READ,
(struct timeval) { .tv_sec = 60 },
NULL,
NULL);
if (!NT_STATUS_IS_OK(status)) {
DBG_WARNING("g_lock_lock(G_LOCK_READ) failed: %s\n",
nt_errstr(status));
@ -1500,8 +1504,12 @@ static NTSTATUS smbd_claim_version(struct messaging_context *msg,
return NT_STATUS_OK;
}
status = g_lock_lock(
ctx, key, G_LOCK_UPGRADE, (struct timeval) { .tv_sec = 60 });
status = g_lock_lock(ctx,
key,
G_LOCK_UPGRADE,
(struct timeval) { .tv_sec = 60 },
NULL,
NULL);
if (!NT_STATUS_IS_OK(status)) {
DBG_WARNING("g_lock_lock(G_LOCK_WRITE) failed: %s\n",
nt_errstr(status));
@ -1520,8 +1528,12 @@ static NTSTATUS smbd_claim_version(struct messaging_context *msg,
return status;
}
status = g_lock_lock(
ctx, key, G_LOCK_DOWNGRADE, (struct timeval) { .tv_sec = 60 });
status = g_lock_lock(ctx,
key,
G_LOCK_DOWNGRADE,
(struct timeval) { .tv_sec = 60 },
NULL,
NULL);
if (!NT_STATUS_IS_OK(status)) {
DBG_WARNING("g_lock_lock(G_LOCK_READ) failed: %s\n",
nt_errstr(status));

View File

@ -71,7 +71,8 @@ bool run_g_lock1(int dummy)
}
status = g_lock_lock(ctx, string_term_tdb_data(lockname), G_LOCK_WRITE,
(struct timeval) { .tv_sec = 1 });
(struct timeval) { .tv_sec = 1 },
NULL, NULL);
if (!NT_STATUS_IS_OK(status)) {
fprintf(stderr, "g_lock_lock failed: %s\n",
nt_errstr(status));
@ -79,7 +80,8 @@ bool run_g_lock1(int dummy)
}
status = g_lock_lock(ctx, string_term_tdb_data(lockname), G_LOCK_WRITE,
(struct timeval) { .tv_sec = 1 });
(struct timeval) { .tv_sec = 1 },
NULL, NULL);
if (!NT_STATUS_EQUAL(status, NT_STATUS_WAS_LOCKED)) {
fprintf(stderr, "Double lock got %s\n",
nt_errstr(status));
@ -160,7 +162,8 @@ bool run_g_lock2(int dummy)
}
status = g_lock_lock(ctx, string_term_tdb_data(lockname), G_LOCK_WRITE,
(struct timeval) { .tv_sec = 1 });
(struct timeval) { .tv_sec = 1 },
NULL, NULL);
if (!NT_STATUS_IS_OK(status)) {
fprintf(stderr, "g_lock_lock returned %s\n",
nt_errstr(status));
@ -282,7 +285,8 @@ bool run_g_lock3(int dummy)
state.self = messaging_server_id(msg);
status = g_lock_lock(ctx, string_term_tdb_data(lockname), G_LOCK_READ,
(struct timeval) { .tv_sec = 1 });
(struct timeval) { .tv_sec = 1 },
NULL, NULL);
if (!NT_STATUS_IS_OK(status)) {
fprintf(stderr, "g_lock_lock returned %s\n",
nt_errstr(status));
@ -304,7 +308,8 @@ bool run_g_lock3(int dummy)
}
status = g_lock_lock(ctx, string_term_tdb_data(lockname), G_LOCK_UPGRADE,
(struct timeval) { .tv_sec = 1 });
(struct timeval) { .tv_sec = 1 },
NULL, NULL);
if (!NT_STATUS_IS_OK(status)) {
fprintf(stderr, "g_lock_lock returned %s\n",
nt_errstr(status));
@ -355,7 +360,9 @@ static bool lock4_child(const char *lockname,
ctx,
string_term_tdb_data(lockname),
lock_type,
(struct timeval) { .tv_sec = 1 });
(struct timeval) { .tv_sec = 1 },
NULL,
NULL);
if (!NT_STATUS_IS_OK(status)) {
fprintf(stderr, "child: g_lock_lock returned %s\n",
nt_errstr(status));
@ -510,16 +517,18 @@ bool run_g_lock4(int dummy)
return false;
}
status = g_lock_lock(
ctx, key, G_LOCK_WRITE, (struct timeval) { .tv_usec = 1 });
status = g_lock_lock(ctx, key, G_LOCK_WRITE,
(struct timeval) { .tv_usec = 1 },
NULL, NULL);
if (!NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
fprintf(stderr, "g_lock_lock returned %s\n",
nt_errstr(status));
goto fail;
}
status = g_lock_lock(
ctx, key, G_LOCK_READ, (struct timeval) { .tv_usec = 1 });
status = g_lock_lock(ctx, key, G_LOCK_READ,
(struct timeval) { .tv_usec = 1 },
NULL, NULL);
if (!NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
fprintf(stderr, "g_lock_lock returned %s\n",
nt_errstr(status));
@ -633,16 +642,18 @@ bool run_g_lock4a(int dummy)
return false;
}
status = g_lock_lock(
ctx, key, G_LOCK_WRITE, (struct timeval) { .tv_usec = 1 });
status = g_lock_lock(ctx, key, G_LOCK_WRITE,
(struct timeval) { .tv_usec = 1 },
NULL, NULL);
if (!NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
fprintf(stderr, "g_lock_lock returned %s\n",
nt_errstr(status));
goto fail;
}
status = g_lock_lock(
ctx, key, G_LOCK_READ, (struct timeval) { .tv_usec = 1 });
status = g_lock_lock(ctx, key, G_LOCK_READ,
(struct timeval) { .tv_usec = 1 },
NULL, NULL);
if (!NT_STATUS_IS_OK(status)) {
fprintf(stderr, "g_lock_lock returned %s\n",
nt_errstr(status));
@ -778,7 +789,8 @@ bool run_g_lock5(int dummy)
status = g_lock_lock(ctx,
string_term_tdb_data(lockname),
G_LOCK_READ,
(struct timeval) { .tv_sec = 1 });
(struct timeval) { .tv_sec = 1 },
NULL, NULL);
if (!NT_STATUS_IS_OK(status)) {
fprintf(stderr,
"child g_lock_lock failed %s\n",
@ -835,7 +847,8 @@ bool run_g_lock5(int dummy)
status = g_lock_lock(ctx, string_term_tdb_data(lockname),
G_LOCK_READ,
(struct timeval) { .tv_sec = 1 });
(struct timeval) { .tv_sec = 1 },
NULL, NULL);
if (!NT_STATUS_IS_OK(status)) {
fprintf(stderr, "g_lock_lock failed %s\n",
nt_errstr(status));
@ -903,7 +916,8 @@ bool run_g_lock6(int dummy)
* CLEAR_IF_FIRST
*/
status = g_lock_lock(ctx, lockname, G_LOCK_WRITE,
(struct timeval) { .tv_sec = 1 });
(struct timeval) { .tv_sec = 1 },
NULL, NULL);
if (!NT_STATUS_IS_OK(status)) {
fprintf(stderr, "g_lock_lock failed: %s\n",
nt_errstr(status));
@ -947,7 +961,8 @@ bool run_g_lock6(int dummy)
status = g_lock_lock(ctx,
lockname,
G_LOCK_READ,
(struct timeval) { .tv_sec = 1 });
(struct timeval) { .tv_sec = 1 },
NULL, NULL);
if (!NT_STATUS_IS_OK(status)) {
fprintf(stderr,
"child g_lock_lock failed %s\n",
@ -1005,7 +1020,8 @@ bool run_g_lock6(int dummy)
status = g_lock_lock(ctx,
lockname,
G_LOCK_WRITE,
(struct timeval) { .tv_sec = 1 });
(struct timeval) { .tv_sec = 1 },
NULL, NULL);
if (!NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
fprintf(stderr, "g_lock_lock should have failed with %s - %s\n",
nt_errstr(NT_STATUS_IO_TIMEOUT),
@ -1014,7 +1030,8 @@ bool run_g_lock6(int dummy)
}
status = g_lock_lock(ctx, lockname, G_LOCK_READ,
(struct timeval) { .tv_sec = 1 });
(struct timeval) { .tv_sec = 1 },
NULL, NULL);
if (!NT_STATUS_IS_OK(status)) {
fprintf(stderr, "g_lock_lock failed: %s\n",
nt_errstr(status));
@ -1034,7 +1051,8 @@ bool run_g_lock6(int dummy)
}
status = g_lock_lock(ctx, lockname, G_LOCK_UPGRADE,
(struct timeval) { .tv_sec = 1 });
(struct timeval) { .tv_sec = 1 },
NULL, NULL);
if (!NT_STATUS_IS_OK(status)) {
fprintf(stderr, "g_lock_lock failed: %s\n",
nt_errstr(status));
@ -1102,7 +1120,8 @@ bool run_g_lock7(int dummy)
ctx,
key,
G_LOCK_READ,
(struct timeval) { .tv_usec = 1 });
(struct timeval) { .tv_usec = 1 },
NULL, NULL);
if (!NT_STATUS_IS_OK(status)) {
fprintf(stderr,
"g_lock_lock(READ) failed: %s\n",
@ -1169,7 +1188,8 @@ bool run_g_lock7(int dummy)
ctx,
key,
G_LOCK_READ,
(struct timeval) { .tv_usec = 1 });
(struct timeval) { .tv_usec = 1 },
NULL, NULL);
if (!NT_STATUS_IS_OK(status)) {
fprintf(stderr,
"g_lock_lock(READ) failed: %s\n",
@ -1194,7 +1214,8 @@ bool run_g_lock7(int dummy)
ctx,
key,
G_LOCK_UPGRADE,
(struct timeval) { .tv_sec = 10 });
(struct timeval) { .tv_sec = 10 },
NULL, NULL);
if (!NT_STATUS_EQUAL(status, NT_STATUS_POSSIBLE_DEADLOCK)) {
fprintf(stderr,
"g_lock_lock returned %s\n",
@ -1237,7 +1258,8 @@ bool run_g_lock8(int dummy)
ctx,
lockname,
G_LOCK_WRITE,
(struct timeval) { .tv_sec = 999 });
(struct timeval) { .tv_sec = 999 },
NULL, NULL);
if (!NT_STATUS_IS_OK(status)) {
fprintf(stderr,
"g_lock_lock failed: %s\n",
@ -1330,7 +1352,8 @@ bool run_g_lock_ping_pong(int dummy)
snprintf(name, sizeof(name), "ping_pong_%d", i);
status = g_lock_lock(ctx, string_term_tdb_data(name), G_LOCK_WRITE,
(struct timeval) { .tv_sec = 60 });
(struct timeval) { .tv_sec = 60 },
NULL, NULL);
if (!NT_STATUS_IS_OK(status)) {
fprintf(stderr, "g_lock_lock failed: %s\n",
nt_errstr(status));
@ -1343,7 +1366,8 @@ bool run_g_lock_ping_pong(int dummy)
status = g_lock_lock(ctx, string_term_tdb_data(name),
G_LOCK_WRITE,
(struct timeval) { .tv_sec = 60 });
(struct timeval) { .tv_sec = 60 },
NULL, NULL);
if (!NT_STATUS_IS_OK(status)) {
fprintf(stderr, "g_lock_lock failed: %s\n",
nt_errstr(status));

View File

@ -87,7 +87,9 @@ static int net_g_lock_do(struct net_context *c, int argc, const char **argv)
ctx,
key,
G_LOCK_WRITE,
timeval_set(timeout / 1000, timeout % 1000));
timeval_set(timeout / 1000, timeout % 1000),
NULL,
NULL);
if (!NT_STATUS_IS_OK(status)) {
d_fprintf(stderr,
_("g_lock_lock failed: %s\n"),

View File

@ -613,7 +613,12 @@ static int net_registry_increment(struct net_context *c, int argc,
goto done;
}
status = g_lock_lock(ctx, lock_key, G_LOCK_WRITE, timeval_set(600, 0));
status = g_lock_lock(ctx,
lock_key,
G_LOCK_WRITE,
timeval_set(600, 0),
NULL,
NULL);
if (!NT_STATUS_IS_OK(status)) {
d_fprintf(stderr, _("g_lock_lock failed: %s\n"),
nt_errstr(status));