ctdb-daemon: Add implementation for CTDB_CONTROL_DB_ATTACH_REPLICATED control
[sfrench/samba-autobuild/.git] / ctdb / server / ctdb_ltdb_server.c
index 2790dd6ea7ed9b86bc177b635b9c4809fdf3efb7..d83783854a09a31b10558cbf1a2a9e3d828ffeb5 100644 (file)
@@ -143,7 +143,7 @@ static int ctdb_ltdb_store_server(struct ctdb_db_context *ctdb_db,
        }
 
        if (keep) {
-               if (!ctdb_db->persistent &&
+               if (ctdb_db_volatile(ctdb_db) &&
                    (ctdb_db->ctdb->pnn == header->dmaster) &&
                    !(header->flags & CTDB_REC_RO_FLAGS))
                {
@@ -607,7 +607,7 @@ int ctdb_recheck_persistent_health(struct ctdb_context *ctdb)
        int fail = 0;
 
        for (ctdb_db = ctdb->db_list; ctdb_db; ctdb_db = ctdb_db->next) {
-               if (!ctdb_db->persistent) {
+               if (!ctdb_db_persistent(ctdb_db)) {
                        continue;
                }
 
@@ -718,12 +718,13 @@ int ctdb_set_db_readonly(struct ctdb_context *ctdb, struct ctdb_db_context *ctdb
 {
        char *ropath;
 
-       if (ctdb_db->readonly) {
+       if (ctdb_db_readonly(ctdb_db)) {
                return 0;
        }
 
-       if (ctdb_db->persistent) {
-               DEBUG(DEBUG_ERR,("Persistent databases do not support readonly property\n"));
+       if (! ctdb_db_volatile(ctdb_db)) {
+               DEBUG(DEBUG_ERR,
+                     ("Non-volatile databases do not support readonly flag\n"));
                return -1;
        }
 
@@ -744,7 +745,7 @@ int ctdb_set_db_readonly(struct ctdb_context *ctdb, struct ctdb_db_context *ctdb
 
        DEBUG(DEBUG_NOTICE,("OPENED tracking database : '%s'\n", ropath));
 
-       ctdb_db->readonly = true;
+       ctdb_db_set_readonly(ctdb_db);
 
        DEBUG(DEBUG_NOTICE, ("Readonly property set on DB %s\n", ctdb_db->db_name));
 
@@ -757,8 +758,7 @@ int ctdb_set_db_readonly(struct ctdb_context *ctdb, struct ctdb_db_context *ctdb
   return 0 on success, -1 on failure
  */
 static int ctdb_local_attach(struct ctdb_context *ctdb, const char *db_name,
-                            bool persistent, const char *unhealthy_reason,
-                            bool jenkinshash, bool mutexes)
+                            uint8_t db_flags, const char *unhealthy_reason)
 {
        struct ctdb_db_context *ctdb_db, *tmp_db;
        int ret;
@@ -766,7 +766,6 @@ static int ctdb_local_attach(struct ctdb_context *ctdb, const char *db_name,
        int tdb_flags;
        int mode = 0600;
        int remaining_tries = 0;
-       uint8_t db_flags = 0;
 
        ctdb_db = talloc_zero(ctdb, struct ctdb_db_context);
        CTDB_NO_MEMORY(ctdb, ctdb_db);
@@ -778,9 +777,9 @@ static int ctdb_local_attach(struct ctdb_context *ctdb, const char *db_name,
        key.dsize = strlen(db_name)+1;
        key.dptr  = discard_const(db_name);
        ctdb_db->db_id = ctdb_hash(&key);
-       ctdb_db->persistent = persistent;
+       ctdb_db->db_flags = db_flags;
 
-       if (!ctdb_db->persistent) {
+       if (ctdb_db_volatile(ctdb_db)) {
                ctdb_db->delete_queue = trbt_create(ctdb_db, 0);
                if (ctdb_db->delete_queue == NULL) {
                        CTDB_NO_MEMORY(ctdb, ctdb_db->delete_queue);
@@ -799,7 +798,7 @@ static int ctdb_local_attach(struct ctdb_context *ctdb, const char *db_name,
                }
        }
 
-       if (persistent) {
+       if (ctdb_db_persistent(ctdb_db)) {
                if (unhealthy_reason) {
                        ret = ctdb_update_persistent_health(ctdb, ctdb_db,
                                                            unhealthy_reason, 0);
@@ -841,14 +840,12 @@ static int ctdb_local_attach(struct ctdb_context *ctdb, const char *db_name,
        }
 
        /* open the database */
-       ctdb_db->db_path = talloc_asprintf(ctdb_db, "%s/%s.%u", 
-                                          persistent?ctdb->db_directory_persistent:ctdb->db_directory, 
+       ctdb_db->db_path = talloc_asprintf(ctdb_db, "%s/%s.%u",
+                                          ctdb_db_persistent(ctdb_db) ?
+                                               ctdb->db_directory_persistent :
+                                               ctdb->db_directory,
                                           db_name, ctdb->pnn);
 
-       if (persistent) {
-               db_flags = CTDB_DB_FLAGS_PERSISTENT;
-       }
-
        tdb_flags = ctdb_db_tdb_flags(db_flags, ctdb->valgrinding,
                                      ctdb->tunable.mutex_enabled);
 
@@ -861,7 +858,7 @@ again:
                struct stat st;
                int saved_errno = errno;
 
-               if (!persistent) {
+               if (! ctdb_db_persistent(ctdb_db)) {
                        DEBUG(DEBUG_CRIT,("Failed to open tdb '%s': %d - %s\n",
                                          ctdb_db->db_path,
                                          saved_errno,
@@ -907,7 +904,7 @@ again:
                goto again;
        }
 
-       if (!persistent) {
+       if (!ctdb_db_persistent(ctdb_db)) {
                ctdb_check_db_empty(ctdb_db);
        } else {
                ret = tdb_check(ctdb_db->ltdb->tdb, NULL, NULL);
@@ -1110,7 +1107,7 @@ int ctdb_process_deferred_attach(struct ctdb_context *ctdb)
  */
 int32_t ctdb_control_db_attach(struct ctdb_context *ctdb, TDB_DATA indata,
                               TDB_DATA *outdata,
-                              bool persistent, uint32_t client_id,
+                              uint8_t db_flags, uint32_t client_id,
                               struct ctdb_req_control_old *c,
                               bool *async_reply)
 {
@@ -1118,7 +1115,7 @@ int32_t ctdb_control_db_attach(struct ctdb_context *ctdb, TDB_DATA indata,
        struct ctdb_db_context *db;
        struct ctdb_node *node = ctdb->nodes[ctdb->pnn];
        struct ctdb_client *client = NULL;
-       bool with_jenkinshash, with_mutexes;
+       uint32_t opcode;
 
        if (ctdb->tunable.allow_client_db_attach == 0) {
                DEBUG(DEBUG_ERR, ("DB Attach to database %s denied by tunable "
@@ -1172,10 +1169,11 @@ int32_t ctdb_control_db_attach(struct ctdb_context *ctdb, TDB_DATA indata,
        /* see if we already have this name */
        db = ctdb_db_handle(ctdb, db_name);
        if (db) {
-               if (db->persistent != persistent) {
-                       DEBUG(DEBUG_ERR, ("ERROR: DB Attach %spersistent to %spersistent "
-                                         "database %s\n", persistent ? "" : "non-",
-                                         db-> persistent ? "" : "non-", db_name));
+               if ((db->db_flags & db_flags) != db_flags) {
+                       DEBUG(DEBUG_ERR,
+                             ("Error: Failed to re-attach with 0x%x flags,"
+                              " database has 0x%x flags\n", db_flags,
+                              db->db_flags));
                        return -1;
                }
                outdata->dptr  = (uint8_t *)&db->db_id;
@@ -1183,11 +1181,7 @@ int32_t ctdb_control_db_attach(struct ctdb_context *ctdb, TDB_DATA indata,
                return 0;
        }
 
-       with_jenkinshash = persistent ? false : true;
-       with_mutexes = (ctdb->tunable.mutex_enabled == 1) ? true : false;
-
-       if (ctdb_local_attach(ctdb, db_name, persistent, NULL,
-                             with_jenkinshash, with_mutexes) != 0) {
+       if (ctdb_local_attach(ctdb, db_name, db_flags, NULL) != 0) {
                return -1;
        }
 
@@ -1203,10 +1197,16 @@ int32_t ctdb_control_db_attach(struct ctdb_context *ctdb, TDB_DATA indata,
        /* Try to ensure it's locked in mem */
        lockdown_memory(ctdb->valgrinding);
 
+       if (ctdb_db_persistent(db)) {
+               opcode = CTDB_CONTROL_DB_ATTACH_PERSISTENT;
+       } else if (ctdb_db_replicated(db)) {
+               opcode = CTDB_CONTROL_DB_ATTACH_REPLICATED;
+       } else {
+               opcode = CTDB_CONTROL_DB_ATTACH;
+       }
+
        /* tell all the other nodes about this database */
-       ctdb_daemon_send_control(ctdb, CTDB_BROADCAST_ALL, 0,
-                                persistent?CTDB_CONTROL_DB_ATTACH_PERSISTENT:
-                                               CTDB_CONTROL_DB_ATTACH,
+       ctdb_daemon_send_control(ctdb, CTDB_BROADCAST_ALL, 0, opcode,
                                 0, CTDB_CTRL_FLAG_NOREPLY,
                                 indata, NULL, NULL);
 
@@ -1240,9 +1240,10 @@ int32_t ctdb_control_db_detach(struct ctdb_context *ctdb, TDB_DATA indata,
                return -1;
        }
 
-       if (ctdb_db->persistent) {
-               DEBUG(DEBUG_ERR, ("DB detach from persistent database %s "
-                                 "denied\n", ctdb_db->db_name));
+       if (! ctdb_db_volatile(ctdb_db)) {
+               DEBUG(DEBUG_ERR,
+                     ("Detaching non-volatile database %s denied\n",
+                      ctdb_db->db_name));
                return -1;
        }
 
@@ -1296,7 +1297,7 @@ int32_t ctdb_control_db_detach(struct ctdb_context *ctdb, TDB_DATA indata,
        }
 
        /* Free readonly tracking database */
-       if (ctdb_db->readonly) {
+       if (ctdb_db_readonly(ctdb_db)) {
                talloc_free(ctdb_db->rottdb);
        }
 
@@ -1357,7 +1358,7 @@ static int ctdb_attach_persistent(struct ctdb_context *ctdb,
                }
                p[4] = 0;
 
-               if (ctdb_local_attach(ctdb, s, true, unhealthy_reason, false, false) != 0) {
+               if (ctdb_local_attach(ctdb, s, CTDB_DB_FLAGS_PERSISTENT, unhealthy_reason) != 0) {
                        DEBUG(DEBUG_ERR,("Failed to attach to persistent database '%s'\n", de->d_name));
                        closedir(d);
                        talloc_free(s);
@@ -1574,18 +1575,19 @@ int32_t ctdb_ltdb_enable_seqnum(struct ctdb_context *ctdb, uint32_t db_id)
 
 int ctdb_set_db_sticky(struct ctdb_context *ctdb, struct ctdb_db_context *ctdb_db)
 {
-       if (ctdb_db->sticky) {
+       if (ctdb_db_sticky(ctdb_db)) {
                return 0;
        }
 
-       if (ctdb_db->persistent) {
-               DEBUG(DEBUG_ERR,("Trying to set persistent database with sticky property\n"));
+       if (! ctdb_db_volatile(ctdb_db)) {
+               DEBUG(DEBUG_ERR,
+                     ("Non-volatile databases do not support sticky flag\n"));
                return -1;
        }
 
        ctdb_db->sticky_records = trbt_create(ctdb_db, 0);
 
-       ctdb_db->sticky = true;
+       ctdb_db_set_sticky(ctdb_db);
 
        DEBUG(DEBUG_NOTICE,("set db sticky %s\n", ctdb_db->db_name));