]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3:g_lock: add callback function to g_lock_lock()
authorStefan Metzmacher <metze@samba.org>
Sun, 28 Aug 2022 11:08:48 +0000 (13:08 +0200)
committerJeremy Allison <jra@samba.org>
Tue, 20 Sep 2022 00:34:35 +0000 (00:34 +0000)
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>
source3/include/g_lock.h
source3/lib/dbwrap/dbwrap_ctdb.c
source3/lib/g_lock.c
source3/libsmb/trusts_util.c
source3/locking/share_mode_lock.c
source3/smbd/server.c
source3/torture/test_g_lock.c
source3/utils/net_g_lock.c
source3/utils/net_registry.c

index c96431346a6e60bab2532af595f17b3b189e2730..d6c1521a52c415548616d9800406f8437f63836c 100644 (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(
index 1f0907c91a88d36de29e46b374178638f66ea3c1..46165e8fbfb08ce7db56a1ab23cfbda355aa238f 100644 (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);
index a22f9dcad0667338a91a14794b458dac75e1f9eb..40687f47526ae44e6fe7b5570b6126e5203f9f02 100644 (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
index 356366b6a9d1be4086fa996f891477212f9bdf0f..c86bceac7d6bf3d2c96969611cb94416ba7147c8 100644 (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));
index 347223c5853f386e6d8fb1766b9d42312e1f9e60..4575792942c080be2cdc513a47371ed5c4b629b7 100644 (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));
index 25cb84ab9d06c6117b70a1b737c0e9f7a4fc515b..9b211238c118108436dfa9ce77e9f00a234fb561 100644 (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));
index 57899e9e33787e2599afe54e991264a3d952d6de..ad3793633f3ec804342c31e609c98e52829ed681 100644 (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));
index 2a3b105b2760a0174011f0c868ed974425414e2b..a1000284102c56ffe6857bd0b55e9cc05241b90a 100644 (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"),
index 23e1dc0adbd53c66345ca83c79affd170542e10d..5d1314ec37a5ebe4b4ba065d29afd8bf42e24f5f 100644 (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));