lib: Add g_lock_set_lock_order()
authorVolker Lendecke <vl@samba.org>
Thu, 21 Nov 2019 14:20:07 +0000 (15:20 +0100)
committerJeremy Allison <jra@samba.org>
Fri, 15 May 2020 00:48:32 +0000 (00:48 +0000)
Optionally allow a database with g_lock format to participate in the dbwarp
lock order check. Will be used once locking.tdb is based upon g_lock.c

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
source3/include/g_lock.h
source3/lib/g_lock.c

index b44586d912373a5b37a5162e9560f344b805bdaf..e35ba4b2d3143e023f5e0d19a2c2ce39efc61303 100644 (file)
@@ -36,6 +36,8 @@ struct g_lock_ctx *g_lock_ctx_init_backend(
        TALLOC_CTX *mem_ctx,
        struct messaging_context *msg,
        struct db_context **backend);
+void g_lock_set_lock_order(struct g_lock_ctx *ctx,
+                          enum dbwrap_lock_order lock_order);
 struct g_lock_ctx *g_lock_ctx_init(TALLOC_CTX *mem_ctx,
                                   struct messaging_context *msg);
 
index 8789b43feeeccd3bd994ee0c8f195a01b2f046a6..65dc3e76f26f4897611b9693b4e6a0a63d35d1d1 100644 (file)
@@ -36,6 +36,7 @@
 struct g_lock_ctx {
        struct db_context *db;
        struct messaging_context *msg;
+       enum dbwrap_lock_order lock_order;
 };
 
 struct g_lock {
@@ -193,6 +194,7 @@ struct g_lock_ctx *g_lock_ctx_init_backend(
                return NULL;
        }
        result->msg = msg;
+       result->lock_order = DBWRAP_LOCK_ORDER_NONE;
 
        result->db = db_open_watched(result, backend, msg);
        if (result->db == NULL) {
@@ -203,6 +205,12 @@ struct g_lock_ctx *g_lock_ctx_init_backend(
        return result;
 }
 
+void g_lock_set_lock_order(struct g_lock_ctx *ctx,
+                          enum dbwrap_lock_order lock_order)
+{
+       ctx->lock_order = lock_order;
+}
+
 struct g_lock_ctx *g_lock_ctx_init(TALLOC_CTX *mem_ctx,
                                   struct messaging_context *msg)
 {
@@ -690,7 +698,23 @@ static void g_lock_lock_retry(struct tevent_req *subreq)
 
 NTSTATUS g_lock_lock_recv(struct tevent_req *req)
 {
-       return tevent_req_simple_recv_ntstatus(req);
+       struct g_lock_lock_state *state = tevent_req_data(
+               req, struct g_lock_lock_state);
+       struct g_lock_ctx *ctx = state->ctx;
+       NTSTATUS status;
+
+       if (tevent_req_is_nterror(req, &status)) {
+               return status;
+       }
+
+       if ((ctx->lock_order != DBWRAP_LOCK_ORDER_NONE) &&
+           ((state->type == G_LOCK_READ) ||
+            (state->type == G_LOCK_WRITE))) {
+               const char *name = dbwrap_name(ctx->db);
+               dbwrap_lock_order_lock(name, ctx->lock_order);
+       }
+
+       return NT_STATUS_OK;
 }
 
 struct g_lock_lock_simple_state {
@@ -769,6 +793,10 @@ NTSTATUS g_lock_lock(struct g_lock_ctx *ctx, TDB_DATA key,
                        return status;
                }
                if (NT_STATUS_IS_OK(state.status)) {
+                       if (ctx->lock_order != DBWRAP_LOCK_ORDER_NONE) {
+                               const char *name = dbwrap_name(ctx->db);
+                               dbwrap_lock_order_lock(name, ctx->lock_order);
+                       }
                        return NT_STATUS_OK;
                }
                if (!NT_STATUS_EQUAL(
@@ -889,6 +917,11 @@ NTSTATUS g_lock_unlock(struct g_lock_ctx *ctx, TDB_DATA key)
                return state.status;
        }
 
+       if (ctx->lock_order != DBWRAP_LOCK_ORDER_NONE) {
+               const char *name = dbwrap_name(ctx->db);
+               dbwrap_lock_order_unlock(name, ctx->lock_order);
+       }
+
        return NT_STATUS_OK;
 }