[SCM] CTDB repository - branch master-readonly-records updated - ctdb-1.10-453-g908a07c
Ronnie Sahlberg
sahlberg at samba.org
Wed Aug 31 19:32:31 MDT 2011
The branch, master-readonly-records has been updated
via 908a07c42e5135a3ba30a625fc4f4e4916de197a (commit)
via 4cac9ad7d9c9ca657a247a6c215476399c7d2210 (commit)
via 7462761638d25880ad46024ad4ef21667eb99a98 (commit)
from 8d363d3ce105b78c94f8e50184b6579b25b237f6 (commit)
http://gitweb.samba.org/?p=ctdb.git;a=shortlog;h=master-readonly-records
- Log -----------------------------------------------------------------
commit 908a07c42e5135a3ba30a625fc4f4e4916de197a
Author: Ronnie Sahlberg <ronniesahlberg at gmail.com>
Date: Thu Sep 1 11:08:18 2011 +1000
ReadOnly: add a new control to activate readonly lock capability for a database.
let all databases default to not support this until enabled through this control
commit 4cac9ad7d9c9ca657a247a6c215476399c7d2210
Author: Ronnie Sahlberg <ronniesahlberg at gmail.com>
Date: Thu Sep 1 10:28:15 2011 +1000
ReadOnly: add a readonly flag to the getdbmap control and show the readonly setting in ctdb getdbmap output
commit 7462761638d25880ad46024ad4ef21667eb99a98
Author: Ronnie Sahlberg <ronniesahlberg at gmail.com>
Date: Thu Sep 1 10:21:55 2011 +1000
ReadOnly: Change the ctdb_db structure to keep a uint8_t for flags instead of a boolean for
the persistent flag.
This is the same size as the original boolean but allows ut to add additional flags for the database
-----------------------------------------------------------------------
Summary of changes:
client/ctdb_client.c | 42 ++++++++++++++++++++++++++++
include/ctdb_client.h | 10 ++++++-
include/ctdb_private.h | 2 +
include/ctdb_protocol.h | 1 +
server/ctdb_control.c | 10 +++++++
server/ctdb_ltdb_server.c | 67 +++++++++++++++++++++++++-------------------
server/ctdb_recover.c | 8 +++++-
server/ctdb_recoverd.c | 9 +++---
tools/ctdb.c | 56 +++++++++++++++++++++++++++++--------
tools/ctdb_vacuum.c | 4 +-
10 files changed, 160 insertions(+), 49 deletions(-)
Changeset truncated at 500 lines:
diff --git a/client/ctdb_client.c b/client/ctdb_client.c
index f9d5e24..b3061a8 100644
--- a/client/ctdb_client.c
+++ b/client/ctdb_client.c
@@ -4593,3 +4593,45 @@ ctdb_ctrl_updaterecord(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct ti
return ctdb_ctrl_updaterecord_recv(ctdb, state);
}
+
+
+
+
+
+/*
+ set a database to be readonly
+ */
+struct ctdb_client_control_state *
+ctdb_ctrl_set_db_readonly_send(struct ctdb_context *ctdb, uint32_t destnode, uint32_t dbid)
+{
+ TDB_DATA data;
+
+ data.dptr = (uint8_t *)&dbid;
+ data.dsize = sizeof(dbid);
+
+ return ctdb_control_send(ctdb, destnode, 0,
+ CTDB_CONTROL_SET_DB_READONLY, 0, data,
+ ctdb, NULL, NULL);
+}
+
+int ctdb_ctrl_set_db_readonly_recv(struct ctdb_context *ctdb, struct ctdb_client_control_state *state)
+{
+ int ret;
+ int32_t res;
+
+ ret = ctdb_control_recv(ctdb, state, ctdb, NULL, &res, NULL);
+ if (ret != 0 || res != 0) {
+ DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_set_db_readonly_recv failed ret:%d res:%d\n", ret, res));
+ return -1;
+ }
+
+ return 0;
+}
+
+int ctdb_ctrl_set_db_readonly(struct ctdb_context *ctdb, uint32_t destnode, uint32_t dbid)
+{
+ struct ctdb_client_control_state *state;
+
+ state = ctdb_ctrl_set_db_readonly_send(ctdb, destnode, dbid);
+ return ctdb_ctrl_set_db_readonly_recv(ctdb, state);
+}
diff --git a/include/ctdb_client.h b/include/ctdb_client.h
index 720f073..ad31d24 100644
--- a/include/ctdb_client.h
+++ b/include/ctdb_client.h
@@ -211,7 +211,9 @@ struct ctdb_dbid_map {
uint32_t num;
struct ctdb_dbid {
uint32_t dbid;
- bool persistent;
+#define CTDB_DB_FLAGS_PERSISTENT 0x01
+#define CTDB_DB_FLAGS_READONLY 0x02
+ uint8_t flags;
} dbs[1];
};
int ctdb_ctrl_getdbmap(struct ctdb_context *ctdb,
@@ -597,4 +599,10 @@ int ctdb_ctrl_updaterecord_recv(struct ctdb_context *ctdb, struct ctdb_client_co
int
ctdb_ctrl_updaterecord(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode, struct ctdb_db_context *ctdb_db, TDB_DATA key, struct ctdb_ltdb_header *header, TDB_DATA data);
+
+struct ctdb_client_control_state *
+ctdb_ctrl_set_db_readonly_send(struct ctdb_context *ctdb, uint32_t destnode, uint32_t dbid);
+int ctdb_ctrl_set_db_readonly_recv(struct ctdb_context *ctdb, struct ctdb_client_control_state *state);
+int ctdb_ctrl_set_db_readonly(struct ctdb_context *ctdb, uint32_t destnode, uint32_t dbid);
+
#endif /* _CTDB_CLIENT_H */
diff --git a/include/ctdb_private.h b/include/ctdb_private.h
index 4cf3709..6a8ed18 100644
--- a/include/ctdb_private.h
+++ b/include/ctdb_private.h
@@ -1461,4 +1461,6 @@ typedef void (*deferred_requeue_fn)(void *call_context, struct ctdb_req_header *
int ctdb_add_revoke_deferred_call(struct ctdb_context *ctdb, struct ctdb_db_context *ctdb_db, TDB_DATA key, struct ctdb_req_header *hdr, deferred_requeue_fn fn, void *call_context);
+int ctdb_set_db_readonly(struct ctdb_context *ctdb, struct ctdb_db_context *ctdb_db);
+
#endif
diff --git a/include/ctdb_protocol.h b/include/ctdb_protocol.h
index be7e768..f4019ab 100644
--- a/include/ctdb_protocol.h
+++ b/include/ctdb_protocol.h
@@ -366,6 +366,7 @@ enum ctdb_controls {CTDB_CONTROL_PROCESS_EXISTS = 0,
CTDB_CONTROL_TCP_ADD_DELAYED_UPDATE = 126,
CTDB_CONTROL_GET_STAT_HISTORY = 127,
CTDB_CONTROL_SCHEDULE_FOR_DELETION = 128,
+ CTDB_CONTROL_SET_DB_READONLY = 129,
};
/*
diff --git a/server/ctdb_control.c b/server/ctdb_control.c
index 748907f..9c2f742 100644
--- a/server/ctdb_control.c
+++ b/server/ctdb_control.c
@@ -194,6 +194,16 @@ static int32_t ctdb_control_dispatch(struct ctdb_context *ctdb,
CHECK_CONTROL_DATA_SIZE(0);
return ctdb->statistics.num_clients;
+ case CTDB_CONTROL_SET_DB_READONLY: {
+ uint32_t db_id;
+ struct ctdb_db_context *ctdb_db;
+
+ CHECK_CONTROL_DATA_SIZE(sizeof(db_id));
+ db_id = *(uint32_t *)indata.dptr;
+ ctdb_db = find_ctdb_db(ctdb, db_id);
+ if (ctdb_db == NULL) return -1;
+ return ctdb_set_db_readonly(ctdb, ctdb_db);
+ }
case CTDB_CONTROL_GET_DBNAME: {
uint32_t db_id;
struct ctdb_db_context *ctdb_db;
diff --git a/server/ctdb_ltdb_server.c b/server/ctdb_ltdb_server.c
index 3c41bb1..555d949 100644
--- a/server/ctdb_ltdb_server.c
+++ b/server/ctdb_ltdb_server.c
@@ -723,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
@@ -926,35 +964,6 @@ again:
}
}
- /* Assume all non-persistent databases support read only delegations */
- if (!ctdb_db->persistent) {
- ctdb_db->readonly = true;
- }
-
- if (ctdb_db->readonly) {
- char *ropath;
-
- ropath = talloc_asprintf(ctdb_db, "%s.RO", ctdb_db->db_path);
- if (ropath == NULL) {
- DEBUG(DEBUG_CRIT,("Failed to asprintf the tracking database\n"));
- ctdb_db->readonly = false;
- talloc_free(ctdb_db);
- 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));
- ctdb_db->readonly = false;
- talloc_free(ctdb_db);
- return -1;
- }
- DEBUG(DEBUG_NOTICE,("OPENED tracking database : '%s'\n", ropath));
- }
-
-
DLIST_ADD(ctdb->db_list, ctdb_db);
/* setting this can help some high churn databases */
diff --git a/server/ctdb_recover.c b/server/ctdb_recover.c
index f865dba..5d98c44 100644
--- a/server/ctdb_recover.c
+++ b/server/ctdb_recover.c
@@ -187,7 +187,12 @@ ctdb_control_getdbmap(struct ctdb_context *ctdb, uint32_t opcode, TDB_DATA indat
dbid_map->num = len;
for (i=0,ctdb_db=ctdb->db_list;ctdb_db;i++,ctdb_db=ctdb_db->next){
dbid_map->dbs[i].dbid = ctdb_db->db_id;
- dbid_map->dbs[i].persistent = ctdb_db->persistent;
+ if (ctdb_db->persistent != 0) {
+ dbid_map->dbs[i].flags |= CTDB_DB_FLAGS_PERSISTENT;
+ }
+ if (ctdb_db->readonly != 0) {
+ dbid_map->dbs[i].flags |= CTDB_DB_FLAGS_READONLY;
+ }
}
return 0;
@@ -1319,3 +1324,4 @@ int32_t ctdb_control_continue_node(struct ctdb_context *ctdb)
return 0;
}
+
diff --git a/server/ctdb_recoverd.c b/server/ctdb_recoverd.c
index 2db9109..44a9e4b 100644
--- a/server/ctdb_recoverd.c
+++ b/server/ctdb_recoverd.c
@@ -439,7 +439,8 @@ static int create_missing_remote_databases(struct ctdb_context *ctdb, struct ctd
return -1;
}
ctdb_ctrl_createdb(ctdb, CONTROL_TIMEOUT(), nodemap->nodes[j].pnn,
- mem_ctx, name, dbmap->dbs[db].persistent);
+ mem_ctx, name,
+ dbmap->dbs[db].flags & CTDB_DB_FLAGS_PERSISTENT);
if (ret != 0) {
DEBUG(DEBUG_ERR, (__location__ " Unable to create remote db:%s\n", name));
return -1;
@@ -502,7 +503,7 @@ static int create_missing_local_databases(struct ctdb_context *ctdb, struct ctdb
return -1;
}
ctdb_ctrl_createdb(ctdb, CONTROL_TIMEOUT(), pnn, mem_ctx, name,
- remote_dbmap->dbs[db].persistent);
+ remote_dbmap->dbs[db].flags & CTDB_DB_FLAGS_PERSISTENT);
if (ret != 0) {
DEBUG(DEBUG_ERR, (__location__ " Unable to create local db:%s\n", name));
return -1;
@@ -823,7 +824,7 @@ static void vacuum_fetch_handler(struct ctdb_context *ctdb, uint64_t srvid,
for (i=0;i<dbmap->num;i++) {
if (dbmap->dbs[i].dbid == recs->db_id) {
- persistent = dbmap->dbs[i].persistent;
+ persistent = dbmap->dbs[i].flags & CTDB_DB_FLAGS_PERSISTENT;
break;
}
}
@@ -1515,7 +1516,7 @@ static int do_recovery(struct ctdb_recoverd *rec,
for (i=0;i<dbmap->num;i++) {
ret = recover_database(rec, mem_ctx,
dbmap->dbs[i].dbid,
- dbmap->dbs[i].persistent,
+ dbmap->dbs[i].flags & CTDB_DB_FLAGS_PERSISTENT,
pnn, nodemap, generation);
if (ret != 0) {
DEBUG(DEBUG_ERR, (__location__ " Failed to recover database 0x%x\n", dbmap->dbs[i].dbid));
diff --git a/tools/ctdb.c b/tools/ctdb.c
index 4f915d9..331392c 100644
--- a/tools/ctdb.c
+++ b/tools/ctdb.c
@@ -123,7 +123,7 @@ static int db_exists(struct ctdb_context *ctdb, const char *db_name, bool *persi
ctdb_ctrl_getdbname(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, ctdb, &name);
if (!strcmp(name, db_name)) {
if (persistent) {
- *persistent = dbmap->dbs[i].persistent;
+ *persistent = dbmap->dbs[i].flags & CTDB_DB_FLAGS_PERSISTENT;
}
return 0;
}
@@ -3554,12 +3554,13 @@ static int control_getdbmap(struct ctdb_context *ctdb, int argc, const char **ar
}
if(options.machinereadable){
- printf(":ID:Name:Path:Persistent:Unhealthy:\n");
+ printf(":ID:Name:Path:Persistent:Unhealthy:ReadOnly:\n");
for(i=0;i<dbmap->num;i++){
const char *path;
const char *name;
const char *health;
bool persistent;
+ bool readonly;
ctdb_ctrl_getdbpath(ctdb, TIMELIMIT(), options.pnn,
dbmap->dbs[i].dbid, ctdb, &path);
@@ -3567,10 +3568,11 @@ static int control_getdbmap(struct ctdb_context *ctdb, int argc, const char **ar
dbmap->dbs[i].dbid, ctdb, &name);
ctdb_ctrl_getdbhealth(ctdb, TIMELIMIT(), options.pnn,
dbmap->dbs[i].dbid, ctdb, &health);
- persistent = dbmap->dbs[i].persistent;
- printf(":0x%08X:%s:%s:%d:%d:\n",
+ persistent = dbmap->dbs[i].flags & CTDB_DB_FLAGS_PERSISTENT;
+ readonly = dbmap->dbs[i].flags & CTDB_DB_FLAGS_READONLY;
+ printf(":0x%08X:%s:%s:%d:%d:%d:\n",
dbmap->dbs[i].dbid, name, path,
- !!(persistent), !!(health));
+ !!(persistent), !!(health), !!(readonly));
}
return 0;
}
@@ -3581,14 +3583,17 @@ static int control_getdbmap(struct ctdb_context *ctdb, int argc, const char **ar
const char *name;
const char *health;
bool persistent;
+ bool readonly;
ctdb_ctrl_getdbpath(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, ctdb, &path);
ctdb_ctrl_getdbname(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, ctdb, &name);
ctdb_ctrl_getdbhealth(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, ctdb, &health);
- persistent = dbmap->dbs[i].persistent;
- printf("dbid:0x%08x name:%s path:%s%s%s\n",
+ persistent = dbmap->dbs[i].flags & CTDB_DB_FLAGS_PERSISTENT;
+ readonly = dbmap->dbs[i].flags & CTDB_DB_FLAGS_READONLY;
+ printf("dbid:0x%08x name:%s path:%s%s%s%s\n",
dbmap->dbs[i].dbid, name, path,
persistent?" PERSISTENT":"",
+ readonly?" READONLY":"",
health?" UNHEALTHY":"");
}
@@ -3621,6 +3626,7 @@ static int control_getdbstatus(struct ctdb_context *ctdb, int argc, const char *
const char *name;
const char *health;
bool persistent;
+ bool readonly;
ctdb_ctrl_getdbname(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, ctdb, &name);
if (strcmp(name, db_name) != 0) {
@@ -3629,10 +3635,12 @@ static int control_getdbstatus(struct ctdb_context *ctdb, int argc, const char *
ctdb_ctrl_getdbpath(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, ctdb, &path);
ctdb_ctrl_getdbhealth(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, ctdb, &health);
- persistent = dbmap->dbs[i].persistent;
- printf("dbid: 0x%08x\nname: %s\npath: %s\nPERSISTENT: %s\nHEALTH: %s\n",
+ persistent = dbmap->dbs[i].flags & CTDB_DB_FLAGS_PERSISTENT;
+ readonly = dbmap->dbs[i].flags & CTDB_DB_FLAGS_READONLY;
+ printf("dbid: 0x%08x\nname: %s\npath: %s\nPERSISTENT: %s\nREADONLY: %s\nHEALTH: %s\n",
dbmap->dbs[i].dbid, name, path,
persistent?"yes":"no",
+ readonly?"yes":"no",
health?health:"OK");
return 0;
}
@@ -4074,6 +4082,29 @@ static int control_getdbprio(struct ctdb_context *ctdb, int argc, const char **a
}
/*
+ set the readonly capability for a database
+ */
+static int control_setdbreadonly(struct ctdb_context *ctdb, int argc, const char **argv)
+{
+ uint32_t db_id;
+ int ret;
+
+ if (argc < 1) {
+ usage();
+ }
+
+ db_id = strtoul(argv[0], NULL, 0);
+
+ ret = ctdb_ctrl_set_db_readonly(ctdb, options.pnn, db_id);
+ if (ret != 0) {
+ DEBUG(DEBUG_ERR,("Unable to set db to support readonly\n"));
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
run an eventscript on a node
*/
static int control_eventscript(struct ctdb_context *ctdb, int argc, const char **argv)
@@ -4223,7 +4254,7 @@ static int control_backupdb(struct ctdb_context *ctdb, int argc, const char **ar
allow_unhealthy));
}
- ctdb_db = ctdb_attach(ctdb, argv[0], dbmap->dbs[i].persistent, 0);
+ ctdb_db = ctdb_attach(ctdb, argv[0], dbmap->dbs[i].flags & CTDB_DB_FLAGS_PERSISTENT, 0);
if (ctdb_db == NULL) {
DEBUG(DEBUG_ERR,("Unable to attach to database '%s'\n", argv[0]));
talloc_free(tmp_ctx);
@@ -4275,7 +4306,7 @@ static int control_backupdb(struct ctdb_context *ctdb, int argc, const char **ar
dbhdr.version = DB_VERSION;
dbhdr.timestamp = time(NULL);
- dbhdr.persistent = dbmap->dbs[i].persistent;
+ dbhdr.persistent = dbmap->dbs[i].flags & CTDB_DB_FLAGS_PERSISTENT;
dbhdr.size = bd->len;
if (strlen(argv[0]) >= MAX_DB_NAME) {
DEBUG(DEBUG_ERR,("Too long dbname\n"));
@@ -4622,7 +4653,7 @@ static int control_wipedb(struct ctdb_context *ctdb, int argc,
return -1;
}
- ctdb_db = ctdb_attach(ctdb, argv[0], dbmap->dbs[i].persistent, 0);
+ ctdb_db = ctdb_attach(ctdb, argv[0], dbmap->dbs[i].flags & CTDB_DB_FLAGS_PERSISTENT, 0);
if (ctdb_db == NULL) {
DEBUG(DEBUG_ERR, ("Unable to attach to database '%s'\n",
argv[0]));
@@ -5064,6 +5095,7 @@ static const struct {
{ "setrecmasterrole", control_setrecmasterrole, false, false, "Set RECMASTER role to on/off", "{on|off}"},
{ "setdbprio", control_setdbprio, false, false, "Set DB priority", "<dbid> <prio:1-3>"},
{ "getdbprio", control_getdbprio, false, false, "Get DB priority", "<dbid>"},
+ { "setdbreadonly", control_setdbreadonly, false, false, "Set DB readonly capable", "<dbid>"},
{ "msglisten", control_msglisten, false, false, "Listen on a srvid port for messages", "<msg srvid>"},
{ "msgsend", control_msgsend, false, false, "Send a message to srvid", "<srvid> <message>"},
{ "sync", control_ipreallocate, false, false, "wait until ctdbd has synced all state changes" },
diff --git a/tools/ctdb_vacuum.c b/tools/ctdb_vacuum.c
index bd75a69..cbe3c5c 100644
--- a/tools/ctdb_vacuum.c
+++ b/tools/ctdb_vacuum.c
@@ -467,7 +467,7 @@ int ctdb_vacuum(struct ctdb_context *ctdb, int argc, const char **argv)
for (i=0;i<dbmap->num;i++) {
if (ctdb_vacuum_db(ctdb, dbmap->dbs[i].dbid, nodemap,
- dbmap->dbs[i].persistent, vacuum_limit) != 0) {
+ dbmap->dbs[i].flags & CTDB_DB_FLAGS_PERSISTENT, vacuum_limit) != 0) {
DEBUG(DEBUG_ERR,("Failed to vacuum db 0x%x\n", dbmap->dbs[i].dbid));
return -1;
}
@@ -630,7 +630,7 @@ int ctdb_repack(struct ctdb_context *ctdb, int argc, const char **argv)
for (i=0;i<dbmap->num;i++) {
if (ctdb_repack_db(ctdb, dbmap->dbs[i].dbid,
- dbmap->dbs[i].persistent, repack_limit) != 0) {
+ dbmap->dbs[i].flags & CTDB_DB_FLAGS_PERSISTENT, repack_limit) != 0) {
DEBUG(DEBUG_ERR,("Failed to repack db 0x%x\n", dbmap->dbs[i].dbid));
return -1;
}
--
CTDB repository
More information about the samba-cvs
mailing list