server: add CTDB_CONTROL_DB_SET_HEALTHY and CTDB_CONTROL_DB_GET_HEALTH
authorStefan Metzmacher <metze@samba.org>
Wed, 2 Dec 2009 11:48:22 +0000 (12:48 +0100)
committerStefan Metzmacher <metze@samba.org>
Wed, 16 Dec 2009 07:08:29 +0000 (08:08 +0100)
metze

include/ctdb_private.h
server/ctdb_control.c
server/ctdb_ltdb_server.c

index f29e5dec41f29c458a58bdd73dfa63d81c3f5f80..fdd205d050f6dfab31c3d83843e992d33cbac4f4 100644 (file)
@@ -633,6 +633,8 @@ enum ctdb_controls {CTDB_CONTROL_PROCESS_EXISTS          = 0,
                    CTDB_CONTROL_CLEAR_LOG               = 118,
                    CTDB_CONTROL_TRANS3_COMMIT           = 119,
                    CTDB_CONTROL_GET_DB_SEQNUM           = 120,
+                   CTDB_CONTROL_DB_SET_HEALTHY          = 121,
+                   CTDB_CONTROL_DB_GET_HEALTH           = 122,
 };     
 
 /*
@@ -1442,6 +1444,10 @@ int32_t ctdb_control_transaction_start(struct ctdb_context *ctdb, uint32_t id);
 int32_t ctdb_control_transaction_commit(struct ctdb_context *ctdb, uint32_t id);
 int32_t ctdb_control_transaction_cancel(struct ctdb_context *ctdb);
 int32_t ctdb_control_wipe_database(struct ctdb_context *ctdb, TDB_DATA indata);
+int32_t ctdb_control_db_set_healthy(struct ctdb_context *ctdb, TDB_DATA indata);
+int32_t ctdb_control_db_get_health(struct ctdb_context *ctdb,
+                                  TDB_DATA indata,
+                                  TDB_DATA *outdata);
 
 
 int ctdb_vacuum(struct ctdb_context *ctdb, int argc, const char **argv);
index 3382fae39aac964481068c369021b3588dc13437..a87855030951b9f9dddaebaa907e93774b0fba3a 100644 (file)
@@ -560,6 +560,14 @@ static int32_t ctdb_control_dispatch(struct ctdb_context *ctdb,
                CHECK_CONTROL_DATA_SIZE(sizeof(uint64_t));
                return ctdb_control_get_db_seqnum(ctdb, indata, outdata);
 
+       case CTDB_CONTROL_DB_SET_HEALTHY:
+               CHECK_CONTROL_DATA_SIZE(sizeof(uint32_t));
+               return ctdb_control_db_set_healthy(ctdb, indata);
+
+       case CTDB_CONTROL_DB_GET_HEALTH:
+               CHECK_CONTROL_DATA_SIZE(sizeof(uint32_t));
+               return ctdb_control_db_get_health(ctdb, indata, outdata);
+
        default:
                DEBUG(DEBUG_CRIT,(__location__ " Unknown CTDB control opcode %u\n", opcode));
                return -1;
index b966386b1391ac8974db3e416f51b7248f72ce3e..47a2d6a693c2d2c488391a86ecdf53cc80bee1a1 100644 (file)
@@ -436,6 +436,75 @@ int ctdb_recheck_persistent_health(struct ctdb_context *ctdb)
        return 0;
 }
 
+
+/*
+  mark a database - as healthy
+ */
+int32_t ctdb_control_db_set_healthy(struct ctdb_context *ctdb, TDB_DATA indata)
+{
+       uint32_t db_id = *(uint32_t *)indata.dptr;
+       struct ctdb_db_context *ctdb_db;
+       int ret;
+       bool may_recover = false;
+
+       ctdb_db = find_ctdb_db(ctdb, db_id);
+       if (!ctdb_db) {
+               DEBUG(DEBUG_ERR,(__location__ " Unknown db 0x%x\n", db_id));
+               return -1;
+       }
+
+       if (ctdb_db->unhealthy_reason) {
+               may_recover = true;
+       }
+
+       ret = ctdb_update_persistent_health(ctdb, ctdb_db, NULL, 1);
+       if (ret != 0) {
+               DEBUG(DEBUG_ERR,(__location__
+                                " ctdb_update_persistent_health(%s) failed\n",
+                                ctdb_db->db_name));
+               return -1;
+       }
+
+       if (may_recover && !ctdb->done_startup) {
+               DEBUG(DEBUG_ERR, (__location__ " db %s become healthy  - force recovery for startup\n",
+                                 ctdb_db->db_name));
+               ctdb->recovery_mode = CTDB_RECOVERY_ACTIVE;
+       }
+
+       return 0;
+}
+
+int32_t ctdb_control_db_get_health(struct ctdb_context *ctdb,
+                                  TDB_DATA indata,
+                                  TDB_DATA *outdata)
+{
+       uint32_t db_id = *(uint32_t *)indata.dptr;
+       struct ctdb_db_context *ctdb_db;
+       int ret;
+
+       ctdb_db = find_ctdb_db(ctdb, db_id);
+       if (!ctdb_db) {
+               DEBUG(DEBUG_ERR,(__location__ " Unknown db 0x%x\n", db_id));
+               return -1;
+       }
+
+       ret = ctdb_load_persistent_health(ctdb, ctdb_db);
+       if (ret != 0) {
+               DEBUG(DEBUG_ERR,(__location__
+                                " ctdb_load_persistent_health(%s) failed\n",
+                                ctdb_db->db_name));
+               return -1;
+       }
+
+       *outdata = tdb_null;
+       if (ctdb_db->unhealthy_reason) {
+               outdata->dptr = (uint8_t *)ctdb_db->unhealthy_reason;
+               outdata->dsize = strlen(ctdb_db->unhealthy_reason)+1;
+       }
+
+       return 0;
+}
+
 /*
   attach to a database, handling both persistent and non-persistent databases
   return 0 on success, -1 on failure