From a884d68e00766028c812976bd3f2ed52110603ff Mon Sep 17 00:00:00 2001 From: Amitay Isaacs Date: Thu, 1 Jun 2017 16:03:43 +1000 Subject: [PATCH] ctdb-client: Document ctdb client API Signed-off-by: Amitay Isaacs Reviewed-by: Martin Schwenke Autobuild-User(master): Martin Schwenke Autobuild-Date(master): Wed Jun 7 20:19:06 CEST 2017 on sn-devel-144 --- ctdb/client/client.h | 897 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 857 insertions(+), 40 deletions(-) diff --git a/ctdb/client/client.h b/ctdb/client/client.h index 6d3d91172d6..b7b657c35f0 100644 --- a/ctdb/client/client.h +++ b/ctdb/client/client.h @@ -26,58 +26,265 @@ #include "protocol/protocol.h" #include "common/srvid.h" +/** + * @file client.h + * + * @brief Client api to talk to ctdb daemon + * + * This API allows to connect to ctdb daemon, perform various database + * operations, send controls to ctdb daemon and send messages to other ctdb + * clients. + */ + +/** + * @brief The abstract context that holds client connection to ctdb daemon + */ struct ctdb_client_context; + +/** + * @brief The abstract context that represents a clustered database + */ struct ctdb_db_context; + +/** + * @brief The abstract context that represents a record from a distributed + * database + */ struct ctdb_record_handle; +/** + * @brief The abstract context that represents a transaction on a replicated + * database + */ +struct ctdb_transaction_handle; + +/** + * @brief Client callback function + * + * This function can be registered to be invoked in case of ctdb daemon going + * away. + */ typedef void (*ctdb_client_callback_func_t)(void *private_data); -/* from client/client_connect.c */ - +/** + * @brief Initialize and connect to ctdb daemon + * + * This returns a ctdb client context. Freeing this context will free the + * connection to ctdb daemon and any memory associated with it. + * + * If the connection to ctdb daemon is lost, the client will terminate + * automatically as the library will call exit(). If the client code + * wants to perform cleanup or wants to re-establish a new connection, + * the client should register a disconnect callback function. + * + * @see ctdb_client_set_disconnect_callback + * + * When a disconnect callback function is registered, client library will + * not call exit(). It is the responsibility of the client code to take + * appropriate action. + * + * @param[in] mem_ctx Talloc memory context + * @param[in] ev Tevent context + * @param[in] sockpath Path to ctdb daemon unix domain socket + * @param[out] result The new ctdb client context + * @return 0 on succcess, errno on failure + */ int ctdb_client_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev, - const char *sockpath, struct ctdb_client_context **ret); - + const char *sockpath, + struct ctdb_client_context **result); + +/** + * @brief Register a callback in case of client disconnection + * + * This allows client code to know if the connection to ctdb daemon is lost. + * This is useful if the client wants to re-establish a new connection to ctdb + * daemon. + * + * @param[in] client Client connection context + * @param[in] func Callback function + * @param[in] private_data private data for callback function + */ void ctdb_client_set_disconnect_callback(struct ctdb_client_context *client, ctdb_client_callback_func_t func, void *private_data); +/** + * @brief Get the node number of the current node + * + * @param[in] client Client connection context + * return node number on success, CTDB_UNKNOWN_PNN on error + */ uint32_t ctdb_client_pnn(struct ctdb_client_context *client); +/** + * @brief Client event loop waiting for a flag + * + * This can used to wait for asynchronous comptuations to complete. + * When this function is called, it will run tevent event loop and wait + * till the done flag is set to true. This function will block and will + * not return as long as the done flag is false. + * + * @param[in] ev Tevent context + * @param[in] done Boolean flag to indicate when to stop waiting + */ void ctdb_client_wait(struct tevent_context *ev, bool *done); +/** + * @brief Client event loop waiting for a flag with timeout + * + * This can be used to wait for asynchronous computations to complete. + * When this function is called, it will run tevent event loop and wait + * till the done flag is set to true or if the timeout occurs. + * + * This function will return when either + * - done flag is set to true, or + * - timeout has occurred. + * + * @param[in] ev Tevent context + * @param[in] done Boolean flag to indicate when to stop waiting + * @param[in] timeout How long to wait + * @return 0 on succes, ETIME on timeout, and errno on failure + */ int ctdb_client_wait_timeout(struct tevent_context *ev, bool *done, struct timeval timeout); +/** + * @brief Async computation start to wait till recovery is completed + * + * CTDB deamon does not perform many operations while in recovery (specially + * database operations). This computation allows to wait till ctdb daemon has + * finished recovery. + * + * @param[in] mem_ctx Talloc memory context + * @param[in] ev Tevent context + * @param[in] client Client connection context + * @return new tevent request, or NULL on failure + */ struct tevent_req *ctdb_recovery_wait_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct ctdb_client_context *client); +/** + * @brief Async computation end to wait till recovery is completed + * + * @param[in] req Tevent request + * @param[out] perr errno in case of failure + * @return true on success, false on failure + */ bool ctdb_recovery_wait_recv(struct tevent_req *req, int *perr); +/** + * @brief Sync wrapper for ctdb_recovery_wait computation + * + * @param[in] ev Tevent context + * @param[in] client Client connection context + * @return true on success, false on failure + */ bool ctdb_recovery_wait(struct tevent_context *ev, struct ctdb_client_context *client); -/* from client/client_call.c */ - +/** + * @brief Async computation start to migrate a database record + * + * This sends a request to ctdb daemon to migrate a database record to + * the local node. CTDB daemon will locate the data master for the record + * and will migrate record (and the data master) to the current node. + * + * @see ctdb_fetch_lock_send + * + * @param[in] mem_ctx Talloc memory context + * @param[in] ev Tevent context + * @param[in] client Client connection context + * @param[in] request CTDB request data + * @return a new tevent req, or NULL on failure + */ struct tevent_req *ctdb_client_call_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct ctdb_client_context *client, struct ctdb_req_call *request); +/** + * @brief Async computation end to migrate a database record + * + * @param[in] req Tevent request + * @param[in] mem_ctx Talloc memory context + * @param[out] reply CTDB reply data + * @param[out] perr errno in case of failure + * @return true on success, false on failure + */ bool ctdb_client_call_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, struct ctdb_reply_call **reply, int *perr); -/* from client/client_message.c */ - +/** + * @brief Async computation start to send a message to remote client(s) + * + * This sends a message to ctdb clients on a remote node. All the + * messages are associated with a specific SRVID. All the clients on the + * remote node listening to that SRVID, will get the message. + * + * Clients can register and deregister for messages for a SRVID using + * ctdb_client_set_message_handler() and ctdb_client_remove_message_handler(). + * + * @see ctdb_client_set_message_handler_send, + * ctdb_client_remove_message_handler_send + * + * @param[in] mem_ctx Talloc memory context + * @param[in] ev Tevent context + * @param[in] client Client connection context + * @param[in] destnode Remote node id + * @param[in] message Message to send + * @return a new tevent req on success, NULL on failure + */ struct tevent_req *ctdb_client_message_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct ctdb_client_context *client, uint32_t destnode, struct ctdb_req_message *message); +/** + * @brief Async computation end to send a message to remote client(s) + * + * @param[in] req Tevent request + * @param[out] perr errno in case of failure + * @return true on success, false on failure + */ bool ctdb_client_message_recv(struct tevent_req *req, int *perr); +/** + * @brief Sync wrapper to send a message to client(s) on remote node + * + * @param[in] mem_ctx Talloc memory context + * @param[in] ev Tevent context + * @param[in] client Client connection context + * @param[in] destnode Node id + * @param[in] message Message to send + */ +int ctdb_client_message(TALLOC_CTX *mem_ctx, struct tevent_context *ev, + struct ctdb_client_context *client, + uint32_t destnode, struct ctdb_req_message *message); + +/** + * @brief Async computation start to send a message to multiple nodes + * + * This sends a message to ctdb clients on multiple remote nodes. All the + * messages are associated with a specific SRVID. All the clients on remote + * nodes listening to that SRVID, will get the message. + * + * Clients can register and deregister for messages for a SRVID using + * ctdb_client_set_message_handler() and ctdb_client_remove_message_handler(). + * + * @see ctdb_client_set_message_handler_send, + * ctdb_client_remove_message_handler_send + * + * @param[in] mem_ctx Talloc memory context + * @param[in] ev Tevent context + * @param[in] client Client connection context + * @param[in] pnn_list List of node ids + * @param[in] count Number of node ids + * @param[in] message Message to send + * @return a new tevent req on success, NULL on failure + */ struct tevent_req *ctdb_client_message_multi_send( TALLOC_CTX *mem_ctx, struct tevent_context *ev, @@ -85,13 +292,34 @@ struct tevent_req *ctdb_client_message_multi_send( uint32_t *pnn_list, int count, struct ctdb_req_message *message); +/** + * @brief Async computation end to send a message to multiple nodes + * + * @param[in] req Tevent request + * @param[out] perr errno in case of failure + * @param[in] mem_ctx Talloc memory context + * @param[out] perr_list The status from each node id + * @return true on success, false on failure + * + * If perr_list is not NULL, then the status (0 on success, errno on failure) + * of sending message to each of the node in the specified node list. The + * perr_list is an array of the same size as of pnn_list. + */ bool ctdb_client_message_multi_recv(struct tevent_req *req, int *perr, TALLOC_CTX *mem_ctx, int **perr_list); -int ctdb_client_message(TALLOC_CTX *mem_ctx, struct tevent_context *ev, - struct ctdb_client_context *client, - uint32_t destnode, struct ctdb_req_message *message); - +/** + * @brief Sync wrapper to send a message to multiple nodes + * + * @param[in] mem_ctx Talloc memory context + * @param[in] ev Tevent context + * @param[in] client Client connection context + * @param[in] pnn_list List of node ids + * @param[in] count Number of node ids + * @param[in] message Message to send + * @param[out] perr_list The status from each node id + * @return 0 on success, errno on failure + */ int ctdb_client_message_multi(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct ctdb_client_context *client, @@ -99,6 +327,20 @@ int ctdb_client_message_multi(TALLOC_CTX *mem_ctx, struct ctdb_req_message *message, int **perr_list); +/** + * @brief Async computation start to receive messages for a SRVID + * + * This computation informs ctdb that the client is interested in all messages + * for a specific SRVID. + * + * @param[in] mem_ctx Talloc memory context + * @param[in] ev Tevent context + * @param[in] client Client connection context + * @param[in] srvid SRVID + * @param[in] handler Callback function to call when a message is received + * @param[in] private_data Private data for callback + * @return a new tevent req on success, NULL on failure + */ struct tevent_req *ctdb_client_set_message_handler_send( TALLOC_CTX *mem_ctx, struct tevent_context *ev, @@ -106,28 +348,85 @@ struct tevent_req *ctdb_client_set_message_handler_send( uint64_t srvid, srvid_handler_fn handler, void *private_data); + +/** + * @brief Async computation end to receive messages for a SRVID + * + * @param[in] req Tevent request + * @param[out] perr errno in case of failure + * @return true on success, false on failure + */ bool ctdb_client_set_message_handler_recv(struct tevent_req *req, int *perr); +/** + * Sync wrapper to receive messages for a SRVID + * + * @param[in] ev Tevent context + * @param[in] client Client connection context + * @param[in] srvid SRVID + * @param[in] handler Callback function to call when a message is received + * @param[in] private_data Private data for callback + * @return 0 on success, errno on failure + */ +int ctdb_client_set_message_handler(struct tevent_context *ev, + struct ctdb_client_context *client, + uint64_t srvid, srvid_handler_fn handler, + void *private_data); + +/** + * @brief Async computation start to stop receiving messages for a SRVID + * + * This computation informs ctdb that the client is no longer interested in + * messages for a specific SRVID. + * + * @param[in] mem_ctx Talloc memory context + * @param[in] ev Tevent context + * @param[in] client Client connection context + * @param[in] srvid SRVID + * @param[in] private_data Private data used to register callback + * @return a new tevent req on success, NULL on failure + */ struct tevent_req *ctdb_client_remove_message_handler_send( TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct ctdb_client_context *client, uint64_t srvid, void *private_data); + +/** + * @brief Async computation end to stop receiving messages for a SRVID + * + * @param[in] req Tevent request + * @param[out] perr errno in case of failure + * @return true on success, false on failure + */ bool ctdb_client_remove_message_handler_recv(struct tevent_req *req, int *perr); -int ctdb_client_set_message_handler(struct tevent_context *ev, - struct ctdb_client_context *client, - uint64_t srvid, srvid_handler_fn handler, - void *private_data); - +/** + * Sync wrapper to stop receiving messages for a SRVID + * + * @param[in] ev Tevent context + * @param[in] client Client connection context + * @param[in] srvid SRVID + * @param[in] private_data Private data used to register callback + * @return 0 on success, errno on failure + */ int ctdb_client_remove_message_handler(struct tevent_context *ev, struct ctdb_client_context *client, uint64_t srvid, void *private_data); -/* from client/client_control.c */ - +/** + * @brief Async computation start to send a control to ctdb daemon + * + * @param[in] mem_ctx Talloc memory context + * @param[in] ev Tevent context + * @param[in] client Client connection context + * @param[in] destnode Node id + * @param[in] timeout How long to wait + * @param[in] request Control request + * @return a new tevent req on success, NULL on failure + */ struct tevent_req *ctdb_client_control_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct ctdb_client_context *client, @@ -135,10 +434,51 @@ struct tevent_req *ctdb_client_control_send(TALLOC_CTX *mem_ctx, struct timeval timeout, struct ctdb_req_control *request); +/** + * @brief Async computation end to send a control to ctdb daemon + * + * @param[in] req Tevent request + * @param[out] perr errno in case of failure + * @param[in] mem_ctx Talloc memory context + * @param[out] preply Control reply + * @return true on success, false on failure + */ bool ctdb_client_control_recv(struct tevent_req *req, int *perr, TALLOC_CTX *mem_ctx, struct ctdb_reply_control **preply); +/** + * @brief Sync wrapper to send a control to ctdb daemon + * + * @param[in] mem_ctx Talloc memory context + * @param[in] ev Tevent context + * @param[in] client Client connection context + * @param[in] destnode Node id + * @param[in] timeout How long to wait + * @param[in] request Control request + * @param[out] preply Control reply + * @return 0 on success, errno on failure + */ +int ctdb_client_control(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct ctdb_client_context *client, + uint32_t destnode, + struct timeval timeout, + struct ctdb_req_control *request, + struct ctdb_reply_control **preply); + +/** + * @brief Async computation start to send a control to multiple nodes + * + * @param[in] mem_ctx Talloc memory context + * @param[in] ev Tevent context + * @param[in] client Client connection context + * @param[in] pnn_list List of node ids + * @param[in] count Number of node ids + * @param[in] timeout How long to wait + * @param[in] request Control request + * @return a new tevent req on success, NULL on failure + */ struct tevent_req *ctdb_client_control_multi_send( TALLOC_CTX *mem_ctx, struct tevent_context *ev, @@ -147,64 +487,201 @@ struct tevent_req *ctdb_client_control_multi_send( struct timeval timeout, struct ctdb_req_control *request); +/** + * @brief Async computation end to send a control to multiple nodes + * + * @param[in] req Tevent request + * @param[out] perr errno in case of failure + * @param[in] mem_ctx Talloc memory context + * @param[out] perr_list Status from each node + * @param[out] preply Control reply from each node + * @return true on success, false on failure + */ bool ctdb_client_control_multi_recv(struct tevent_req *req, int *perr, TALLOC_CTX *mem_ctx, int **perr_list, struct ctdb_reply_control ***preply); -int ctdb_client_control_multi_error(uint32_t *pnn_list, int count, - int *err_list, uint32_t *pnn); - -int ctdb_client_control(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct ctdb_client_context *client, - uint32_t destnode, - struct timeval timeout, - struct ctdb_req_control *c, - struct ctdb_reply_control **preply); - +/** + * @brief Sync wrapper to send a control to multiple nodes + * + * @param[in] mem_ctx Talloc memory context + * @param[in] ev Tevent context + * @param[in] client Client connection context + * @param[in] pnn_list List of node ids + * @param[in] count Number of node ids + * @param[in] timeout How long to wait + * @param[in] request Control request + * @param[out] perr_list Status from each node + * @param[out] preply Control reply from each node + * @return 0 on success, errno on failure + */ int ctdb_client_control_multi(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct ctdb_client_context *client, uint32_t *pnn_list, int count, struct timeval timeout, struct ctdb_req_control *request, - int **perr, + int **perr_list, struct ctdb_reply_control ***preply); -/* from client/client_db.c */ +/** + * @brief Check err_list for errors + * + * This is a convenience function to parse the err_list returned from + * functions that send requests to multiple nodes. + * + * If status from any of the node is non-zero, then return first non-zero + * status. + * + * If status from all the nodes is 0, then return 0. + * + * @param[in] pnn_list List of node ids + * @param[in] count Number of node ids + * @param[in] err_list Status from each node + * @param[out] pnn Node id in case of failure + * @return 0 if no failures, status from first failure + */ +int ctdb_client_control_multi_error(uint32_t *pnn_list, int count, + int *err_list, uint32_t *pnn); +/** + * @brief Async computation start to attach a database + * + * @param[in] mem_ctx Talloc memory context + * @param[in] ev Tevent context + * @param[in[ client Client connection context + * @param[in] timeout How long to wait + * @param[in] db_name Name of the database + * @param[in] db_flags Database flags + * @return a new tevent req on success, NULL on failure + */ struct tevent_req *ctdb_attach_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct ctdb_client_context *client, struct timeval timeout, const char *db_name, uint8_t db_flags); +/** + * @brief Async computation end to attach a database + * + * @param[in] req Tevent request + * @param[out] perr errno in case of failure + * @param[out] result New database context + * @return true on success, false on failure + */ bool ctdb_attach_recv(struct tevent_req *req, int *perr, - struct ctdb_db_context **out); - + struct ctdb_db_context **result); + +/** + * @brief Sync wrapper to attach a database + * + * @param[in] ev Tevent context + * @param[in[ client Client connection context + * @param[in] timeout How long to wait + * @param[in] db_name Name of the database + * @param[in] db_flags Database flags + * @param[out] result New database context + * @return 0 on success, errno on failure + */ int ctdb_attach(struct tevent_context *ev, struct ctdb_client_context *client, struct timeval timeout, const char *db_name, uint8_t db_flags, - struct ctdb_db_context **out); - + struct ctdb_db_context **result); + +/** + * @brief Async computation start to detach a database + * + * Only volatile databases can be detached at runtime. + * + * @param[in] mem_ctx Talloc memory context + * @param[in] ev Tevent context + * @param[in[ client Client connection context + * @param[in] timeout How long to wait + * @param[in] db_id Database id + * @return a new tevent req on success, NULL on failure + */ struct tevent_req *ctdb_detach_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct ctdb_client_context *client, struct timeval timeout, uint32_t db_id); +/** + * @brief Async computation end to detach a database + * + * @param[in] req Tevent request + * @param[out] perr errno in case of failure + * @return true on success, false on failure + */ bool ctdb_detach_recv(struct tevent_req *req, int *perr); +/** + * @brief Sync wrapper to detach a database + * + * Only volatile databases can be detached at runtime. + * + * @param[in] ev Tevent context + * @param[in[ client Client connection context + * @param[in] timeout How long to wait + * @param[in] db_id Database id + * @return 0 on success, errno on failure + */ int ctdb_detach(struct tevent_context *ev, struct ctdb_client_context *client, struct timeval timeout, uint32_t db_id); + +/** + * @brief Get database id from database context + * + * @param[in] db Database context + * @return database id + */ uint32_t ctdb_db_id(struct ctdb_db_context *db); +/** + * @brief Traverse a database locally on the node + * + * This function traverses a database locally on the node and for each record + * calls the parser function. If the parser function returns 1, the traverse + * will terminate. If parser function returns 0, the traverse will continue + * till all records in database are parsed. + * + * This is useful for replicated databases, since each node has exactly the + * same records. + * + * @param[in] db Database context + * @param[in] readonly Is the traversal for reading or updating + * @param[in] extract_header Whether to extract ltdb header from record data + * @param[in] parser Record parsing function + * @param[in] private_data Private data for parser function + * @return 0 on success, non-zero return value from parser function + */ int ctdb_db_traverse_local(struct ctdb_db_context *db, bool readonly, bool extract_header, ctdb_rec_parser_func_t parser, void *private_data); +/** + * @brief Async computation start to a cluster-wide database traverse + * + * This function traverses a database on all the nodes and for each record + * calls the parser function. If the parser function returns 1, the traverse + * will terminate. If parser function returns 0, the traverse will continue + * till all records all on nodes are parsed. + * + * This is useful for distributed databases as the records are distributed + * among the cluster nodes. + * + * @param[in] mem_ctx Talloc memory context + * @param[in] ev Tevent context + * @param[in] client Client connection context + * @param[in] db Database context + * @param[in] destnode Node id + * @param[in] timeout How long to wait + * @param[in] parser Record parser function + * @param[in] private_data Private data for parser + * @return a new tevent req on success, NULL on failure + */ struct tevent_req *ctdb_db_traverse_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct ctdb_client_context *client, @@ -214,45 +691,180 @@ struct tevent_req *ctdb_db_traverse_send(TALLOC_CTX *mem_ctx, ctdb_rec_parser_func_t parser, void *private_data); +/** + * @brief Async computation end to a cluster-wide database traverse + * + * @param[in] req Tevent request + * @param[out] perr errno in case of failure + * @return true on success, false on failure + */ bool ctdb_db_traverse_recv(struct tevent_req *req, int *perr); +/** + * @brief Sync wrapper for a cluster-wide database traverse + * + * @param[in] mem_ctx Talloc memory context + * @param[in] ev Tevent context + * @param[in] client Client connection context + * @param[in] db Database context + * @param[in] destnode Node id + * @param[in] timeout How long to wait + * @param[in] parser Record parser function + * @param[in] private_data Private data for parser + * @return 0 on success, errno on failure or non-zero status from parser + */ int ctdb_db_traverse(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct ctdb_client_context *client, struct ctdb_db_context *db, uint32_t destnode, struct timeval timeout, ctdb_rec_parser_func_t parser, void *private_data); +/** + * @brief Fetch a record from a local database + * + * This function is primarily for internal use. + * Clients should use ctdb_fetch_lock() instead. + * + * @param[in] db Database context + * @param[in] key Record key + * @param[out] header Record header + * @param[in] mem_ctx Talloc memory context + * @param[out] data Record data + */ int ctdb_ltdb_fetch(struct ctdb_db_context *db, TDB_DATA key, struct ctdb_ltdb_header *header, TALLOC_CTX *mem_ctx, TDB_DATA *data); +/** + * @brief Async computation start to fetch a locked record + * + * This function is used to fetch a record from a distributed database. + * + * If the record is already available on the local node, then lock the + * record and return the record handle. + * + * If the record is not available on the local node, send a CTDB request to + * migrate the record. Once the record is migrated to the local node, lock + * the record and return the record handle. + * + * At the end of the computation, a record handle is returned which holds + * the record lock. When the record handle is freed, the record is unlocked. + * + * @param[in] mem_ctx Talloc memory context + * @param[in] ev Tevent context + * @param[in] client Client context + * @param[in] db Database context + * @param[in] key Record key + * @param[in] readonly Whether to request readonly copy of the record + * @return a new tevent req on success, NULL on failure + */ struct tevent_req *ctdb_fetch_lock_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct ctdb_client_context *client, struct ctdb_db_context *db, TDB_DATA key, bool readonly); +/** + * @brief Async computation end to fetch a locked record + * + * @param[in] req Tevent request + * @param[out] header Record header + * @param[in] mem_ctx Talloc memory context + * @param[out] data Record data + * @param[out] perr errno in case of failure + * @return a new record handle, NULL on failure + */ struct ctdb_record_handle *ctdb_fetch_lock_recv(struct tevent_req *req, struct ctdb_ltdb_header *header, TALLOC_CTX *mem_ctx, TDB_DATA *data, int *perr); +/** + * @brief Sync wrapper to fetch a locked record + * + * @see ctdb_fetch_lock_send + * + * @param[in] mem_ctx Talloc memory context + * @param[in] ev Tevent context + * @param[in] client Client context + * @param[in] db Database context + * @param[in] key Record key + * @param[in] readonly Whether to request readonly copy of the record + * @param[out] header Record header + * @param[out] data Record data + * return 0 on success, errno on failure + */ int ctdb_fetch_lock(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct ctdb_client_context *client, struct ctdb_db_context *db, TDB_DATA key, bool readonly, struct ctdb_record_handle **out, struct ctdb_ltdb_header *header, TDB_DATA *data); +/** + * @brief Update a locked record + * + * This function is used to update a record in a distributed database. + * + * This function should NOT be used to store null data, instead use + * ctdb_delete_record(). + * + * @param[in] h Record handle + * @param[in] data New record data + * @return 0 on success, errno on failure + */ int ctdb_store_record(struct ctdb_record_handle *h, TDB_DATA data); +/** + * @brief Async computation start to delete a locked record + * + * This function is used to delete a record in a distributed database + * + * @param[in] mem_ctx Talloc memory context + * @param[in] ev Tevent context + * @param[in] h Record handle + * @return a new tevent req on success, NULL on failure + */ struct tevent_req *ctdb_delete_record_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct ctdb_record_handle *h); +/** + * @brief Async computation end to delete a locked record + * + * @param[in] req Tevent request + * @param[out] perr errno in case of failure + * @return true on success, false on failure + */ bool ctdb_delete_record_recv(struct tevent_req *req, int *perr); +/** + * @brief Sync wrapper to delete a locked record + * + * @see ctdb_delete_record_send + * + * @param[in] h Record handle + * @return 0 on success, errno on failure + */ int ctdb_delete_record(struct ctdb_record_handle *h); +/** + * @brief Async computation start to get a global database lock + * + * Functions related to global locks are primarily used internally for + * implementing transaction api. + * + * Clients should use transaction api directly. + * @see ctdb_transaction_start_send + * + * @param[in] mem_ctx Talloc memory context + * @param[in] ev Tevent context + * @param[in] client Client context + * @param[in] db Database context for g_lock.tdb + * @param[in] keyname Record key + * @param[in] sid Server id + * @param[in] readonly Lock type + * @return a new tevent req on success, NULL on failure + */ struct tevent_req *ctdb_g_lock_lock_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct ctdb_client_context *client, @@ -261,8 +873,26 @@ struct tevent_req *ctdb_g_lock_lock_send(TALLOC_CTX *mem_ctx, struct ctdb_server_id *sid, bool readonly); +/** + * @brief Async computation end to get a global database lock + * + * @param[in] req Tevent request + * @param[out] perr errno in case of failure + * @return true on success, false on failure + */ bool ctdb_g_lock_lock_recv(struct tevent_req *req, int *perr); +/** + * @brief Async computation start to release a global database lock + * + * @param[in] mem_ctx Talloc memory context + * @param[in] ev Tevent context + * @param[in] client Client connection context + * @param[in] db Database context + * @param[in] keyname Record key + * @param[in] sid Server id + * @return a new tevent req on success, NULL on failure + */ struct tevent_req *ctdb_g_lock_unlock_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct ctdb_client_context *client, @@ -270,8 +900,42 @@ struct tevent_req *ctdb_g_lock_unlock_send(TALLOC_CTX *mem_ctx, const char *keyname, struct ctdb_server_id sid); +/** + * @brief Async computation end to release a global database lock + * + * @param[in] req Tevent request + * @param[out] perr errno in case of failure + * @return true on success, false on failure + */ bool ctdb_g_lock_unlock_recv(struct tevent_req *req, int *perr); +/** + * @brief Async computation start to start a transaction + * + * This function is used to start a transaction on a replicated database. + * + * To perform any updates on a replicated database + * - start transaction + * - fetch record (ctdb_transaction_fetch_record) + * - store record (ctdb_transaction_store_record) + * - delete record (ctdb_transaction_delete_record) + * - commit transaction (ctdb_transaction_commit_send), or + * - cancel transaction (ctdb_transaction_cancel_send) + * + * Starting a transaction will return a transaction handle. This is used + * for updating records under a transaction. This handle is automatically + * freed once the transacion is committed or cancelled. + * + * Clients should NOT free the transaction handle. + * + * @param[in] mem_ctx Talloc memory context + * @param[in] ev Tevent context + * @param[in] client Client connection context + * @param[in] timeout How long to wait + * @param[in] db Database context + * @param[in] readonly Is transaction readonly + * @return a new tevent req on success, NULL on failure + */ struct tevent_req *ctdb_transaction_start_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct ctdb_client_context *client, @@ -279,66 +943,219 @@ struct tevent_req *ctdb_transaction_start_send(TALLOC_CTX *mem_ctx, struct ctdb_db_context *db, bool readonly); +/** + * @brief Async computation end to start a transaction + * + * @param[in] req Tevent request + * @param[out] perr errno in case of failure + * @return a new transaction handle on success, NULL on failure + */ struct ctdb_transaction_handle *ctdb_transaction_start_recv( struct tevent_req *req, int *perr); +/** + * @brief Sync wrapper to start a transaction + * + * @see ctdb_transaction_start_send + * + * @param[in] mem_ctx Talloc memory context + * @param[in] ev Tevent context + * @param[in] client Client connection context + * @param[in] timeout How long to wait + * @param[in] db Database context + * @param[in] readonly Is transaction readonly + * @param[out] result a new transaction handle + * @return 0 on success, errno on failure + */ int ctdb_transaction_start(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct ctdb_client_context *client, struct timeval timeout, struct ctdb_db_context *db, bool readonly, - struct ctdb_transaction_handle **out); - + struct ctdb_transaction_handle **result); + +/** + * @brief Fetch a record under a transaction + * + * @see ctdb_transaction_start_send + * + * @param[in] h Transaction handle + * @param[in] key Record key + * @param[in] mem_ctx Talloc memory context + * @param[out] data Record data + * @return 0 on success, errno on failure + */ int ctdb_transaction_fetch_record(struct ctdb_transaction_handle *h, TDB_DATA key, TALLOC_CTX *mem_ctx, TDB_DATA *data); +/** + * @brief Store a record under a transaction + * + * @see ctdb_transaction_start_send + * + * @param[in] h Transaction handle + * @param[in] key Record key + * @param[in] data New record data + * @return 0 on success, errno on failure + */ int ctdb_transaction_store_record(struct ctdb_transaction_handle *h, TDB_DATA key, TDB_DATA data); +/** + * @brief Delete a record under a transaction + * + * @see ctdb_transaction_start_send + * + * @param[in] h Transaction handle + * @param[in] key Record key + * @return 0 on success, errno on failure + */ int ctdb_transaction_delete_record(struct ctdb_transaction_handle *h, TDB_DATA key); +/** + * @brief Async computation start to commit a transaction + * + * @see ctdb_transaction_start_send + * + * @param[in] mem_ctx Talloc memory context + * @param[in] ev Tevent context + * @param[in] timeout How long to wait + * @param[in] h Transaction handle + * @return a new tevent req on success, NULL on failure + */ struct tevent_req *ctdb_transaction_commit_send( TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct timeval timeout, struct ctdb_transaction_handle *h); +/** + * @brief Async computation end to commit a transaction + * + * @param[in] req Tevent request + * @param[out] perr errno in case of failure + * @return true on success, false on failure + */ bool ctdb_transaction_commit_recv(struct tevent_req *req, int *perr); +/** + * @brief Sync wrapper to commit a transaction + * + * @see ctdb_transaction_commit_send + * + * @param[in] h Transaction handle + * @return 0 on success, errno on failure + */ int ctdb_transaction_commit(struct ctdb_transaction_handle *h); +/** + * @brief Async computation start to cancel a transaction + * + * @see ctdb_transaction_start_send + * + * @param[in] mem_ctx Talloc memory context + * @param[in] ev Tevent context + * @param[in] timeout How long to wait + * @param[in] h Transaction handle + * @return a new tevent req on success, NULL on failure + */ struct tevent_req *ctdb_transaction_cancel_send( TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct timeval timeout, struct ctdb_transaction_handle *h); +/** + * @brief Async computation end to cancel a transaction + * + * @param[in] req Tevent request + * @param[out] perr errno in case of failure + * @return true on success, false on failure + */ bool ctdb_transaction_cancel_recv(struct tevent_req *req, int *perr); +/** + * @brief Sync wrapper to cancel a transaction + * + * @see ctdb_transaction_cancel_send + * + * @param[in] h Transaction handle + * @return 0 on success, errno on failure + */ int ctdb_transaction_cancel(struct ctdb_transaction_handle *h); -/* from client/client_util.c */ - +/** + * @brief Utility function to extract a list of node ids from nodemap + * + * @param[in] nodemap Node map + * @param[in] flags_mask Flags to match on + * @param[in] exclude_pnn Node id to exclude from the list + * @param[in] mem_ctx Talloc memory context + * @param[out] pnn_list List of node ids + * @return number of node ids on success, -1 on failure + */ int list_of_nodes(struct ctdb_node_map *nodemap, uint32_t flags_mask, uint32_t exclude_pnn, TALLOC_CTX *mem_ctx, uint32_t **pnn_list); +/** + * @brief Utility function to extract a list of node ids for active nodes + * + * @param[in] nodemap Node map + * @param[in] exclude_pnn Node id to exclude from the list + * @param[in] mem_ctx Talloc memory context + * @param[out] pnn_list List of node ids + * @return number of node ids on success, -1 on failure + */ int list_of_active_nodes(struct ctdb_node_map *nodemap, uint32_t exclude_pnn, TALLOC_CTX *mem_ctx, uint32_t **pnn_list); +/** + * @brief Utility function to extract a list of node ids for connected nodes + * + * @param[in] nodemap Node map + * @param[in] exclude_pnn Node id to exclude from the list + * @param[in] mem_ctx Talloc memory context + * @param[out] pnn_list List of node ids + * @return number of node ids on success, -1 on failure + */ int list_of_connected_nodes(struct ctdb_node_map *nodemap, uint32_t exclude_pnn, TALLOC_CTX *mem_ctx, uint32_t **pnn_list); +/** + * @brief Construct a new server id + * + * @param[in] client Client connection context + * @param[in] task_id Task id + * @return a new server id + */ struct ctdb_server_id ctdb_client_get_server_id( struct ctdb_client_context *client, uint32_t task_id); +/** + * @brief Check if two server ids are the same + * + * @param[in] sid1 Server id 1 + * @param[in] sid2 Server id 2 + * @return true if the server ids are same, false otherwise + */ bool ctdb_server_id_equal(struct ctdb_server_id *sid1, struct ctdb_server_id *sid2); +/** + * @brief Check if the process with server id exists + * + * @param[in] mem_ctx Talloc memory context + * @param[in] ev Tevent context + * @param[in] client Client connection context + * @param[in] sid Server id + * @param[out] exists Boolean flag to indicate if the process exists + * @return 0 on success, errno on failure + */ int ctdb_server_id_exists(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct ctdb_client_context *client, struct ctdb_server_id *sid, bool *exists); -- 2.34.1