diff options
Diffstat (limited to 'ctdb/server/ctdb_ltdb_server.c')
-rw-r--r-- | ctdb/server/ctdb_ltdb_server.c | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/ctdb/server/ctdb_ltdb_server.c b/ctdb/server/ctdb_ltdb_server.c index a0fe2c529c..b76ae6a622 100644 --- a/ctdb/server/ctdb_ltdb_server.c +++ b/ctdb/server/ctdb_ltdb_server.c @@ -49,6 +49,27 @@ static int ctdb_fetch_func(struct ctdb_call_info *call) return 0; } +/* + this is a plain fetch procedure that all databases support + this returns the full record including the ltdb header +*/ +static int ctdb_fetch_with_header_func(struct ctdb_call_info *call) +{ + call->reply_data = talloc(call, TDB_DATA); + if (call->reply_data == NULL) { + return -1; + } + call->reply_data->dsize = sizeof(struct ctdb_ltdb_header) + call->record_data.dsize; + call->reply_data->dptr = talloc_size(call->reply_data, call->reply_data->dsize); + if (call->reply_data->dptr == NULL) { + return -1; + } + memcpy(call->reply_data->dptr, call->header, sizeof(struct ctdb_ltdb_header)); + memcpy(&call->reply_data->dptr[sizeof(struct ctdb_ltdb_header)], call->record_data.dptr, call->record_data.dsize); + + return 0; +} + /** * write a record to a normal database @@ -702,6 +723,44 @@ int32_t ctdb_control_db_get_health(struct ctdb_context *ctdb, return 0; } + +int ctdb_set_db_readonly(struct ctdb_context *ctdb, struct ctdb_db_context *ctdb_db) +{ + char *ropath; + + DEBUG(DEBUG_ERR,("XXX set db readonly %s\n", ctdb_db->db_name)); + + if (ctdb_db->readonly) { + return 0; + } + + if (ctdb_db->persistent) { + DEBUG(DEBUG_ERR,("Trying to set persistent database with readonly property\n")); + return -1; + } + + ropath = talloc_asprintf(ctdb_db, "%s.RO", ctdb_db->db_path); + if (ropath == NULL) { + DEBUG(DEBUG_CRIT,("Failed to asprintf the tracking database\n")); + return -1; + } + ctdb_db->rottdb = tdb_open(ropath, + ctdb->tunable.database_hash_size, + TDB_NOLOCK|TDB_CLEAR_IF_FIRST|TDB_NOSYNC, + O_CREAT|O_RDWR, 0); + if (ctdb_db->rottdb == NULL) { + DEBUG(DEBUG_CRIT,("Failed to open/create the tracking database '%s'\n", ropath)); + talloc_free(ropath); + return -1; + } + + DEBUG(DEBUG_NOTICE,("OPENED tracking database : '%s'\n", ropath)); + + ctdb_db->readonly = true; + talloc_free(ropath); + return 0; +} + /* attach to a database, handling both persistent and non-persistent databases return 0 on success, -1 on failure @@ -932,6 +991,17 @@ again: return -1; } + /* + all databases support the "fetch_with_header" function. we need this + for efficient readonly record fetches + */ + ret = ctdb_daemon_set_call(ctdb, ctdb_db->db_id, ctdb_fetch_with_header_func, CTDB_FETCH_WITH_HEADER_FUNC); + if (ret != 0) { + DEBUG(DEBUG_CRIT,("Failed to setup fetch function for '%s'\n", ctdb_db->db_name)); + talloc_free(ctdb_db); + return -1; + } + ret = ctdb_vacuum_init(ctdb_db); if (ret != 0) { DEBUG(DEBUG_CRIT,("Failed to setup vacuuming for " |