Use transaction start/cancel for persistent writes to avoid leaving the database...
authorRonnie Sahlberg <ronniesahlberg@gmail.com>
Fri, 18 Jul 2008 08:50:16 +0000 (18:50 +1000)
committerMichael Adam <obnox@samba.org>
Wed, 13 Aug 2008 09:54:06 +0000 (11:54 +0200)
Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
(This used to be commit 09329f1f9114af44fc4e5e4f29a7315912313125)

source3/include/ctdbd_conn.h
source3/lib/ctdbd_conn.c
source3/lib/dbwrap_ctdb.c

index 6e1b2f737abe187ac4cd6c46bcae1db2d7b6b16f..3ea895d133e5c74be69e3395dd4128984c9b9d93 100644 (file)
@@ -66,5 +66,7 @@ NTSTATUS ctdbd_register_ips(struct ctdbd_connection *conn,
 NTSTATUS ctdbd_register_reconfigure(struct ctdbd_connection *conn);
 
 NTSTATUS ctdbd_persistent_store(struct ctdbd_connection *conn, uint32_t db_id, TDB_DATA key, TDB_DATA data);
+NTSTATUS ctdbd_start_persistent_update(struct ctdbd_connection *conn, uint32_t db_id, TDB_DATA key, TDB_DATA data);
+NTSTATUS ctdbd_cancel_persistent_update(struct ctdbd_connection *conn, uint32_t db_id, TDB_DATA key, TDB_DATA data);
 
 #endif /* _CTDBD_CONN_H */
index e8d3fd1159ec59ce0cbae04993a12666137b00c0..51fefa93d420c2b95ef46c4150606964719764ec 100644 (file)
@@ -1207,9 +1207,9 @@ NTSTATUS ctdbd_register_reconfigure(struct ctdbd_connection *conn)
 }
 
 /*
-  persstent store. Used when we update a record in a persistent database
+  persistent call. Used to start, store or cancel persistent updates.
  */
-NTSTATUS ctdbd_persistent_store(struct ctdbd_connection *conn, uint32_t db_id, TDB_DATA key, TDB_DATA data)
+static NTSTATUS ctdbd_persistent_call(struct ctdbd_connection *conn, uint32_t opcode, uint32_t db_id, TDB_DATA key, TDB_DATA data)
 {
        int cstatus=0;
        struct ctdb_rec_data *rec;
@@ -1232,8 +1232,7 @@ NTSTATUS ctdbd_persistent_store(struct ctdbd_connection *conn, uint32_t db_id, T
        recdata.dptr  = (uint8_t *)rec;
        recdata.dsize = length;
 
-       status = ctdbd_control(conn, CTDB_CURRENT_NODE, 
-                              CTDB_CONTROL_PERSISTENT_STORE, 
+       status = ctdbd_control(conn, CTDB_CURRENT_NODE, opcode,
                               0, recdata, NULL, NULL, &cstatus);
        if (cstatus != 0) {
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
@@ -1241,6 +1240,40 @@ NTSTATUS ctdbd_persistent_store(struct ctdbd_connection *conn, uint32_t db_id, T
        return status;
 }
 
+/*
+  persistent store. Used when we update a record in a persistent database
+ */
+NTSTATUS ctdbd_persistent_store(struct ctdbd_connection *conn, uint32_t db_id, TDB_DATA key, TDB_DATA data)
+{
+       return ctdbd_persistent_call(conn,
+                               CTDB_CONTROL_PERSISTENT_STORE, 
+                               db_id, key, data);
+}
+
+/*
+  tell the ctdb daemon that we are starting a persistent update operation.
+  If we terminate/disconnect from the daemon without first performing
+  either a persistent_store or a cancel ctdbd will perform recovery.
+ */
+NTSTATUS ctdbd_start_persistent_update(struct ctdbd_connection *conn, uint32_t db_id, TDB_DATA key, TDB_DATA data)
+{
+       return ctdbd_persistent_call(conn,
+                               CTDB_CONTROL_START_PERSISTENT_UPDATE, 
+                               db_id, key, data);
+                              
+}
+
+/*
+  Cancel a persistent update operation. This is used if we have started a
+  persistent update  but we want to abort it before we have made changes to
+  the tdb database.
+ */
+NTSTATUS ctdbd_cancel_persistent_update(struct ctdbd_connection *conn, uint32_t db_id, TDB_DATA key, TDB_DATA data)
+{
+       return ctdbd_persistent_call(conn,
+                               CTDB_CONTROL_CANCEL_PERSISTENT_UPDATE, 
+                               db_id, key, data);
+}
 
 #else
 
index cb4c573eb06698d2a50733c588ded6a6c68bd45f..aa2f9d371ca36c0437c4f0651a3f76c29c361e10 100644 (file)
@@ -79,12 +79,19 @@ static NTSTATUS db_ctdb_store_persistent(struct db_record *rec, TDB_DATA data, i
        memcpy(cdata.dptr, &crec->header, sizeof(crec->header));
        memcpy(cdata.dptr + sizeof(crec->header), data.dptr, data.dsize);
 
-       ret = tdb_store(crec->ctdb_ctx->wtdb->tdb, rec->key, cdata, TDB_REPLACE);
-       status = (ret == 0) ? NT_STATUS_OK : NT_STATUS_INTERNAL_DB_CORRUPTION;
+       status = ctdbd_start_persistent_update(messaging_ctdbd_connection(), crec->ctdb_ctx->db_id, rec->key, cdata);
        
+       /* now tell ctdbd to update this record on all other nodes */
+       if (NT_STATUS_IS_OK(status)) {
+               ret = tdb_store(crec->ctdb_ctx->wtdb->tdb, rec->key, cdata, TDB_REPLACE);
+               status = (ret == 0) ? NT_STATUS_OK : NT_STATUS_INTERNAL_DB_CORRUPTION;
+       }
+
        /* now tell ctdbd to update this record on all other nodes */
        if (NT_STATUS_IS_OK(status)) {
                status = ctdbd_persistent_store(messaging_ctdbd_connection(), crec->ctdb_ctx->db_id, rec->key, cdata);
+       } else {
+               ctdbd_cancel_persistent_update(messaging_ctdbd_connection(), crec->ctdb_ctx->db_id, rec->key, cdata);
        }
 
        SAFE_FREE(cdata.dptr);