The branch, master-readonly-records has been updated via 231f16b3e0c9c44fc85c95bde7951ccfab50af91 (commit) via 0893fa0f3257f50d54896ffa78ec12ee11e8c6d2 (commit) from 01314c2cb3a480917d6a632b83c39f0a48bba0e7 (commit)
http://gitweb.samba.org/?p=ctdb.git;a=shortlog;h=master-readonly-records - Log ----------------------------------------------------------------- commit 231f16b3e0c9c44fc85c95bde7951ccfab50af91 Author: Ronnie Sahlberg <ronniesahlb...@gmail.com> Date: Tue Aug 23 15:13:40 2011 +1000 LibCTDB : change the ctdb_fetch_lock_once test tool to use libctdb instead of the old client commit 0893fa0f3257f50d54896ffa78ec12ee11e8c6d2 Author: Ronnie Sahlberg <ronniesahlb...@gmail.com> Date: Tue Aug 23 15:00:27 2011 +1000 LibCTDB : add support for getrecmode ----------------------------------------------------------------------- Summary of changes: Makefile.in | 4 +- include/ctdb.h | 50 ++++++++++++++++++++++ libctdb/control.c | 28 ++++++++++++ libctdb/sync.c | 17 +++++++ tests/src/ctdb_fetch_lock_once.c | 86 ++++++++++++++++++++++++-------------- 5 files changed, 152 insertions(+), 33 deletions(-) Changeset truncated at 500 lines: diff --git a/Makefile.in b/Makefile.in index e6421f8..80b0a02 100755 --- a/Makefile.in +++ b/Makefile.in @@ -169,9 +169,9 @@ tests/bin/ctdb_fetch_one: $(CTDB_CLIENT_OBJ) tests/src/ctdb_fetch_one.o @echo Linking $@ @$(CC) $(CFLAGS) -o $@ tests/src/ctdb_fetch_one.o $(CTDB_CLIENT_OBJ) $(LIB_FLAGS) -tests/bin/ctdb_fetch_lock_once: $(CTDB_CLIENT_OBJ) tests/src/ctdb_fetch_lock_once.o +tests/bin/ctdb_fetch_lock_once: libctdb/libctdb.a tests/src/ctdb_fetch_lock_once.o @echo Linking $@ - @$(CC) $(CFLAGS) -o $@ tests/src/ctdb_fetch_lock_once.o $(CTDB_CLIENT_OBJ) $(LIB_FLAGS) + @$(CC) $(CFLAGS) -o $@ tests/src/ctdb_fetch_lock_once.o libctdb/libctdb.a -ltdb $(LIB_FLAGS) tests/bin/ctdb_fetch_readonly_once: $(CTDB_CLIENT_OBJ) tests/src/ctdb_fetch_readonly_once.o @echo Linking $@ diff --git a/include/ctdb.h b/include/ctdb.h index fad3233..484902f 100644 --- a/include/ctdb.h +++ b/include/ctdb.h @@ -552,6 +552,35 @@ bool ctdb_getrecmaster_recv(struct ctdb_connection *ctdb, uint32_t *recmaster); /** + * ctdb_getrecmode_send - read the recovery mode of a node + * @ctdb: the ctdb_connection from ctdb_connect. + * @destnode: the destination node (see below) + * @callback: the callback when ctdb replies to our message (typesafe) + * @cbdata: the argument to callback() + * + * There are several special values for destnode, detailed in + * ctdb_protocol.h, particularly CTDB_CURRENT_NODE which means the + * local ctdbd. + */ +struct ctdb_request * +ctdb_getrecmode_send(struct ctdb_connection *ctdb, + uint32_t destnode, + ctdb_callback_t callback, void *cbdata); + +/** + * ctdb_getrecmode_recv - read an ctdb_getrecmode reply from ctdbd + * @ctdb: the ctdb_connection from ctdb_connect. + * @req: the completed request. + * @recmode: a pointer to the recmode to fill in + * + * This returns false if something went wrong, or otherwise fills in + * recmode. + */ +bool ctdb_getrecmode_recv(struct ctdb_connection *ctdb, + struct ctdb_request *handle, + uint32_t *recmode); + +/** * ctdb_cancel - cancel an uncompleted request * @ctdb: the ctdb_connection from ctdb_connect. * @req: the uncompleted request. @@ -669,6 +698,23 @@ bool ctdb_getrecmaster(struct ctdb_connection *ctdb, /** + * ctdb_getrecmode - read the recovery mode of a node (synchronous) + * @ctdb: the ctdb_connection from ctdb_connect. + * @destnode: the destination node (see below) + * @recmode: a pointer to the recmode to fill in + * + * There are several special values for destnode, detailed in + * ctdb_protocol.h, particularly CTDB_CURRENT_NODE which means the + * local ctdbd. + * + * Returns true and fills in *recmode on success. + */ +bool ctdb_getrecmode(struct ctdb_connection *ctdb, + uint32_t destnode, + uint32_t *recmode); + + +/** * ctdb_getnodemap - read the nodemap from a node (synchronous) * @ctdb: the ctdb_connection from ctdb_connect. * @destnode: the destination node (see below) @@ -775,6 +821,10 @@ void ctdb_free_publicips(struct ctdb_all_public_ips *ips); ctdb_getrecmaster_send((ctdb), (destnode), \ ctdb_sendcb((cb), (cbdata)), (cbdata)) +#define ctdb_getrecmode_send(ctdb, destnode, cb, cbdata) \ + ctdb_getrecmode_send((ctdb), (destnode), \ + ctdb_sendcb((cb), (cbdata)), (cbdata)) + #define ctdb_getnodemap_send(ctdb, destnode, cb, cbdata) \ ctdb_getnodemap_send((ctdb), (destnode), \ ctdb_sendcb((cb), (cbdata)), (cbdata)) diff --git a/libctdb/control.c b/libctdb/control.c index e18a44e..48add20 100644 --- a/libctdb/control.c +++ b/libctdb/control.c @@ -23,6 +23,7 @@ /* Remove type-safety macros. */ #undef ctdb_getrecmaster_send +#undef ctdb_getrecmode_send #undef ctdb_getpnn_send #undef ctdb_getnodemap_send #undef ctdb_getpublicips_send @@ -54,6 +55,33 @@ struct ctdb_request *ctdb_getrecmaster_send(struct ctdb_connection *ctdb, callback, private_data); } +bool ctdb_getrecmode_recv(struct ctdb_connection *ctdb, + struct ctdb_request *req, uint32_t *recmode) +{ + struct ctdb_reply_control *reply; + + reply = unpack_reply_control(req, CTDB_CONTROL_GET_RECMODE); + if (!reply) { + return false; + } + if (reply->status == -1) { + DEBUG(ctdb, LOG_ERR, "ctdb_getrecmode_recv: status -1"); + return false; + } + *recmode = reply->status; + return true; +} + +struct ctdb_request *ctdb_getrecmode_send(struct ctdb_connection *ctdb, + uint32_t destnode, + ctdb_callback_t callback, + void *private_data) +{ + return new_ctdb_control_request(ctdb, CTDB_CONTROL_GET_RECMODE, + destnode, NULL, 0, + callback, private_data); +} + bool ctdb_getpnn_recv(struct ctdb_connection *ctdb, struct ctdb_request *req, uint32_t *pnn) { diff --git a/libctdb/sync.c b/libctdb/sync.c index 0340a9e..f957514 100644 --- a/libctdb/sync.c +++ b/libctdb/sync.c @@ -83,6 +83,23 @@ bool ctdb_getrecmaster(struct ctdb_connection *ctdb, return ret; } +bool ctdb_getrecmode(struct ctdb_connection *ctdb, + uint32_t destnode, uint32_t *recmode) +{ + struct ctdb_request *req; + bool done = false; + bool ret = false; + + req = synchronous(ctdb, + ctdb_getrecmode_send(ctdb, destnode, set, &done), + &done); + if (req != NULL) { + ret = ctdb_getrecmode_recv(ctdb, req, recmode); + ctdb_request_free(req); + } + return ret; +} + struct ctdb_db *ctdb_attachdb(struct ctdb_connection *ctdb, const char *name, bool persistent, uint32_t tdb_flags) diff --git a/tests/src/ctdb_fetch_lock_once.c b/tests/src/ctdb_fetch_lock_once.c index ff131b8..b273b44 100644 --- a/tests/src/ctdb_fetch_lock_once.c +++ b/tests/src/ctdb_fetch_lock_once.c @@ -19,44 +19,68 @@ */ #include "includes.h" -#include "lib/tevent/tevent.h" #include "system/filesys.h" #include "popt.h" -#include "cmdline.h" - -static struct ctdb_db_context *ctdb_db; +#include <poll.h> +#include <err.h> +#include "ctdb.h" #define TESTKEY "testkey" +static void rrl_cb(struct ctdb_db *ctdb_db, + struct ctdb_lock *lock, TDB_DATA outdata, void *private) +{ + bool *rrl_cb_called = private; + + printf("Record fetchlocked.\n"); + printf("Press enter to release the record ...\n"); + (void)getchar(); + printf("Record released.\n"); + + *rrl_cb_called = true; + return; +} /* Just try locking/unlocking a single record once */ -static void fetch_lock_once(struct ctdb_context *ctdb, struct event_context *ev) +static void fetch_lock_once(struct ctdb_connection *ctdb, struct ctdb_db *ctdb_db) { - TALLOC_CTX *tmp_ctx = talloc_new(ctdb); - TDB_DATA key, data; - struct ctdb_record_handle *h; + TDB_DATA key; + bool rrl_cb_finished = false; key.dptr = discard_const(TESTKEY); key.dsize = strlen(TESTKEY); printf("Trying to fetch lock the record ...\n"); - h = ctdb_fetch_lock(ctdb_db, tmp_ctx, key, &data); - if (h == NULL) { - printf("Failed to fetch record '%s' on node %d\n", - (const char *)key.dptr, ctdb_get_pnn(ctdb)); - talloc_free(tmp_ctx); + /* In the non-contended case the callback might be invoked + * immediately, before ctdb_readrecordlock_async() returns. + * In the contended case the callback will be invoked later. + * + * Normally an application would not care whether the callback + * has already been invoked here or not, but if the application + * needs to know, it can use the *private_data pointer + * to pass data through to the callback and back. + */ + if (!ctdb_readrecordlock_async(ctdb_db, key, + rrl_cb, &rrl_cb_finished)) { + printf("Failed to send READRECORDLOCK\n"); exit(10); } - - printf("Record fetchlocked.\n"); - printf("Press enter to release the record ...\n"); - (void)getchar(); - - talloc_free(tmp_ctx); - printf("Record released.\n"); + while (!rrl_cb_finished) { + struct pollfd pfd; + + pfd.fd = ctdb_get_fd(ctdb); + pfd.events = ctdb_which_events(ctdb); + if (poll(&pfd, 1, -1) < 0) { + printf("Poll failed"); + exit(10); + } + if (ctdb_service(ctdb, pfd.revents) < 0) { + err(1, "Failed to service"); + } + } } /* @@ -64,18 +88,17 @@ static void fetch_lock_once(struct ctdb_context *ctdb, struct event_context *ev) */ int main(int argc, const char *argv[]) { - struct ctdb_context *ctdb; + struct ctdb_connection *ctdb; + struct ctdb_db *ctdb_db; struct poptOption popt_options[] = { POPT_AUTOHELP - POPT_CTDB_CMDLINE POPT_TABLEEND }; int opt; const char **extra_argv; int extra_argc = 0; poptContext pc; - struct event_context *ev; pc = poptGetContext(argv[0], argc, argv, popt_options, POPT_CONTEXT_KEEP_FIRST); @@ -95,26 +118,27 @@ int main(int argc, const char *argv[]) while (extra_argv[extra_argc]) extra_argc++; } - ev = event_context_init(NULL); - - ctdb = ctdb_cmdline_client(ev); + ctdb = ctdb_connect("/tmp/ctdb.socket", + ctdb_log_file, stderr); + if (!ctdb) + err(1, "Connecting to /tmp/ctdb.socket"); /* attach to a specific database */ - ctdb_db = ctdb_attach(ctdb, "test.tdb", false, 0); + ctdb_db = ctdb_attachdb(ctdb, "test.tdb", false, 0); if (!ctdb_db) { - printf("ctdb_attach failed - %s\n", ctdb_errstr(ctdb)); + printf("ctdb_attachdb failed\n"); exit(1); } printf("Waiting for cluster\n"); while (1) { uint32_t recmode=1; - ctdb_ctrl_getrecmode(ctdb, ctdb, timeval_zero(), CTDB_CURRENT_NODE, &recmode); + ctdb_getrecmode(ctdb, CTDB_CURRENT_NODE, &recmode); if (recmode == 0) break; - event_loop_once(ev); + sleep(1); } - fetch_lock_once(ctdb, ev); + fetch_lock_once(ctdb, ctdb_db); return 0; } -- CTDB repository