summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRonnie Sahlberg <ronniesahlberg@gmail.com>2011-07-20 11:27:05 +1000
committerRonnie Sahlberg <ronniesahlberg@gmail.com>2011-08-23 10:06:59 +1000
commit00a870f759f8d387dec48d2651540a838f78766c (patch)
tree4c29e98146086254094574a524d04ab518abca1e
parent1cf1670f0a78aa30f0f177b3a7c012543edae87b (diff)
downloadsamba-00a870f759f8d387dec48d2651540a838f78766c.tar.gz
samba-00a870f759f8d387dec48d2651540a838f78766c.tar.xz
samba-00a870f759f8d387dec48d2651540a838f78766c.zip
ReadOnly records: Add a new RPC function FETCH_WITH_HEADER.
This function differs from the old FETCH in that this function will also fetch the record header and not just the record data (This used to be ctdb commit c7196d16e8e03bb2a64be164d15a7502300eae0e)
-rw-r--r--ctdb/client/ctdb_client.c23
-rw-r--r--ctdb/include/ctdb_protocol.h6
-rw-r--r--ctdb/server/ctdb_ltdb_server.c32
3 files changed, 59 insertions, 2 deletions
diff --git a/ctdb/client/ctdb_client.c b/ctdb/client/ctdb_client.c
index 55c32735d9..d5c2f55997 100644
--- a/ctdb/client/ctdb_client.c
+++ b/ctdb/client/ctdb_client.c
@@ -89,6 +89,7 @@ int ctdb_call_local(struct ctdb_db_context *ctdb_db, struct ctdb_call *call,
c->new_data = NULL;
c->reply_data = NULL;
c->status = 0;
+ c->header = header;
for (fn=ctdb_db->calls;fn;fn=fn->next) {
if (fn->id == call->call_id) break;
@@ -1694,6 +1695,27 @@ static int ctdb_fetch_func(struct ctdb_call_info *call)
}
/*
+ 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;
+}
+
+/*
attach to a specific database - client call
*/
struct ctdb_db_context *ctdb_attach(struct ctdb_context *ctdb, const char *name, bool persistent, uint32_t tdb_flags)
@@ -1758,6 +1780,7 @@ struct ctdb_db_context *ctdb_attach(struct ctdb_context *ctdb, const char *name,
/* add well known functions */
ctdb_set_call(ctdb_db, ctdb_null_func, CTDB_NULL_FUNC);
ctdb_set_call(ctdb_db, ctdb_fetch_func, CTDB_FETCH_FUNC);
+ ctdb_set_call(ctdb_db, ctdb_fetch_with_header_func, CTDB_FETCH_WITH_HEADER_FUNC);
return ctdb_db;
}
diff --git a/ctdb/include/ctdb_protocol.h b/ctdb/include/ctdb_protocol.h
index 0422afeb7b..b805182b6f 100644
--- a/ctdb/include/ctdb_protocol.h
+++ b/ctdb/include/ctdb_protocol.h
@@ -30,8 +30,9 @@
#define CTDB_DS_ALIGNMENT 8
-#define CTDB_NULL_FUNC 0xFF000001
-#define CTDB_FETCH_FUNC 0xFF000002
+#define CTDB_NULL_FUNC 0xFF000001
+#define CTDB_FETCH_FUNC 0xFF000002
+#define CTDB_FETCH_WITH_HEADER_FUNC 0xFF000003
struct ctdb_call {
@@ -50,6 +51,7 @@ struct ctdb_call {
*/
struct ctdb_call_info {
TDB_DATA key; /* record key */
+ struct ctdb_ltdb_header *header;
TDB_DATA record_data; /* current data in the record */
TDB_DATA *new_data; /* optionally updated record data */
TDB_DATA *call_data; /* optionally passed from caller */
diff --git a/ctdb/server/ctdb_ltdb_server.c b/ctdb/server/ctdb_ltdb_server.c
index a93e2fa0c9..f04b7de4a3 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
@@ -932,6 +953,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 "