diff --git a/source3/include/g_lock.h b/source3/include/g_lock.h index c96431346a6..d6c1521a52c 100644 --- a/source3/include/g_lock.h +++ b/source3/include/g_lock.h @@ -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( diff --git a/source3/lib/dbwrap/dbwrap_ctdb.c b/source3/lib/dbwrap/dbwrap_ctdb.c index 1f0907c91a8..46165e8fbfb 100644 --- a/source3/lib/dbwrap/dbwrap_ctdb.c +++ b/source3/lib/dbwrap/dbwrap_ctdb.c @@ -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); diff --git a/source3/lib/g_lock.c b/source3/lib/g_lock.c index a22f9dcad06..40687f47526 100644 --- a/source3/lib/g_lock.c +++ b/source3/lib/g_lock.c @@ -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 diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index 356366b6a9d..c86bceac7d6 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -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)); diff --git a/source3/locking/share_mode_lock.c b/source3/locking/share_mode_lock.c index 347223c5853..4575792942c 100644 --- a/source3/locking/share_mode_lock.c +++ b/source3/locking/share_mode_lock.c @@ -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)); diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 25cb84ab9d0..9b211238c11 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -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)); diff --git a/source3/torture/test_g_lock.c b/source3/torture/test_g_lock.c index 57899e9e337..ad3793633f3 100644 --- a/source3/torture/test_g_lock.c +++ b/source3/torture/test_g_lock.c @@ -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)); diff --git a/source3/utils/net_g_lock.c b/source3/utils/net_g_lock.c index 2a3b105b276..a1000284102 100644 --- a/source3/utils/net_g_lock.c +++ b/source3/utils/net_g_lock.c @@ -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"), diff --git a/source3/utils/net_registry.c b/source3/utils/net_registry.c index 23e1dc0adbd..5d1314ec37a 100644 --- a/source3/utils/net_registry.c +++ b/source3/utils/net_registry.c @@ -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));