-/*
+/*
ctdb daemon code
Copyright (C) Andrew Tridgell 2007
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
allocate a packet for use in client<->daemon communication
*/
struct ctdb_req_header *_ctdbd_allocate_pkt(struct ctdb_context *ctdb,
- TALLOC_CTX *mem_ctx,
- enum ctdb_operation operation,
+ TALLOC_CTX *mem_ctx,
+ enum ctdb_operation operation,
size_t length, size_t slength,
const char *type)
{
struct ctdb_call_info *c;
struct ctdb_registered_call *fn;
struct ctdb_context *ctdb = ctdb_db->ctdb;
-
+
c = talloc_zero(mem_ctx, struct ctdb_call_info);
CTDB_NO_MEMORY(ctdb, c);
goto done;
}
if (cnt != hdr->length) {
- ctdb_set_error(ctdb, "Bad header length %u expected %u in client\n",
+ ctdb_set_error(ctdb, "Bad header length %u expected %u in client\n",
(unsigned)hdr->length, (unsigned)cnt);
goto done;
}
set_close_on_exec(ctdb->daemon.sd);
- ctdb->daemon.queue = ctdb_queue_setup(ctdb, ctdb, ctdb->daemon.sd,
- CTDB_DS_ALIGNMENT,
+ ctdb->daemon.queue = ctdb_queue_setup(ctdb, ctdb, ctdb->daemon.sd,
+ CTDB_DS_ALIGNMENT,
ctdb_client_read_cb, ctdb, "to-ctdbd");
return 0;
}
/*
make a recv call to the local ctdb daemon - called from client context
- This is called when the program wants to wait for a ctdb_call to complete and get the
+ This is called when the program wants to wait for a ctdb_call to complete and get the
results. This call will block unless the call has already completed.
*/
int ctdb_call_recv(struct ctdb_client_call_state *state, struct ctdb_call *call)
/*
destroy a ctdb_call in client
*/
-static int ctdb_client_call_destructor(struct ctdb_client_call_state *state)
+static int ctdb_client_call_destructor(struct ctdb_client_call_state *state)
{
reqid_remove(state->ctdb_db->ctdb->idr, state->reqid);
return 0;
this is used so that locally processed ctdb_call requests are processed
in an event driven manner
*/
-static struct ctdb_client_call_state *ctdb_client_call_local_send(struct ctdb_db_context *ctdb_db,
+static struct ctdb_client_call_state *ctdb_client_call_local_send(struct ctdb_db_context *ctdb_db,
struct ctdb_call *call,
struct ctdb_ltdb_header *header,
TDB_DATA *data)
/*
make a ctdb call to the local daemon - async send. Called from client context.
- This constructs a ctdb_call request and queues it for processing.
+ This constructs a ctdb_call request and queues it for processing.
This call never blocks.
*/
-struct ctdb_client_call_state *ctdb_call_send(struct ctdb_db_context *ctdb_db,
+struct ctdb_client_call_state *ctdb_call_send(struct ctdb_db_context *ctdb_db,
struct ctdb_call *call)
{
struct ctdb_client_call_state *state;
c->keylen = call->key.dsize;
c->calldatalen = call->call_data.dsize;
memcpy(&c->data[0], call->key.dptr, call->key.dsize);
- memcpy(&c->data[call->key.dsize],
+ memcpy(&c->data[call->key.dsize],
call->call_data.dptr, call->call_data.dsize);
*(state->call) = *call;
state->call->call_data.dptr = &c->data[call->key.dsize];
int len, res;
len = offsetof(struct ctdb_req_message_old, data) + data.dsize;
- r = ctdbd_allocate_pkt(ctdb, ctdb, CTDB_REQ_MESSAGE,
+ r = ctdbd_allocate_pkt(ctdb, ctdb, CTDB_REQ_MESSAGE,
len, struct ctdb_req_message_old);
CTDB_NO_MEMORY(ctdb, r);
r->srvid = srvid;
r->datalen = data.dsize;
memcpy(&r->data[0], data.dptr, data.dsize);
-
+
res = ctdb_client_queue_pkt(ctdb, &r->hdr);
talloc_free(r);
return res;
talloc_steal(tmp_ctx, state);
ret = ctdb_control_recv(state->ctdb, state, state,
- NULL,
- NULL,
+ NULL,
+ NULL,
NULL);
if (ret != 0) {
DEBUG(DEBUG_DEBUG,("ctdb_control_recv() failed, ignoring return code %d\n", ret));
This packet comes in response to a CTDB_REQ_CONTROL request packet. It
contains any reply data from the control
*/
-static void ctdb_client_reply_control(struct ctdb_context *ctdb,
+static void ctdb_client_reply_control(struct ctdb_context *ctdb,
struct ctdb_req_header *hdr)
{
struct ctdb_reply_control_old *c = (struct ctdb_reply_control_old *)hdr;
state->outdata.dsize = c->datalen;
state->status = c->status;
if (c->errorlen) {
- state->errormsg = talloc_strndup(state,
- (char *)&c->data[c->datalen],
+ state->errormsg = talloc_strndup(state,
+ (char *)&c->data[c->datalen],
c->errorlen);
}
}
/* async version of send control request */
-struct ctdb_client_control_state *ctdb_control_send(struct ctdb_context *ctdb,
- uint32_t destnode, uint64_t srvid,
- uint32_t opcode, uint32_t flags, TDB_DATA data,
+struct ctdb_client_control_state *ctdb_control_send(struct ctdb_context *ctdb,
+ uint32_t destnode, uint64_t srvid,
+ uint32_t opcode, uint32_t flags, TDB_DATA data,
TALLOC_CTX *mem_ctx,
struct timeval *timeout,
char **errormsg)
talloc_set_destructor(state, ctdb_client_control_destructor);
len = offsetof(struct ctdb_req_control_old, data) + data.dsize;
- c = ctdbd_allocate_pkt(ctdb, state, CTDB_REQ_CONTROL,
+ c = ctdbd_allocate_pkt(ctdb, state, CTDB_REQ_CONTROL,
len, struct ctdb_req_control_old);
- state->c = c;
+ state->c = c;
CTDB_NO_MEMORY_NULL(ctdb, c);
c->hdr.reqid = state->reqid;
c->hdr.destnode = destnode;
/* async version of receive control reply */
-int ctdb_control_recv(struct ctdb_context *ctdb,
- struct ctdb_client_control_state *state,
+int ctdb_control_recv(struct ctdb_context *ctdb,
+ struct ctdb_client_control_state *state,
TALLOC_CTX *mem_ctx,
TDB_DATA *outdata, int32_t *status, char **errormsg)
{
timeout specifies how long we should wait for a reply.
if timeout is NULL we wait indefinitely
*/
-int ctdb_control(struct ctdb_context *ctdb, uint32_t destnode, uint64_t srvid,
- uint32_t opcode, uint32_t flags, TDB_DATA data,
+int ctdb_control(struct ctdb_context *ctdb, uint32_t destnode, uint64_t srvid,
+ uint32_t opcode, uint32_t flags, TDB_DATA data,
TALLOC_CTX *mem_ctx, TDB_DATA *outdata, int32_t *status,
struct timeval *timeout,
char **errormsg)
{
struct ctdb_client_control_state *state;
- state = ctdb_control_send(ctdb, destnode, srvid, opcode,
+ state = ctdb_control_send(ctdb, destnode, srvid, opcode,
flags, data, mem_ctx,
timeout, errormsg);
return 0;
}
- return ctdb_control_recv(ctdb, state, mem_ctx, outdata, status,
+ return ctdb_control_recv(ctdb, state, mem_ctx, outdata, status,
errormsg);
}
int32_t res;
struct ctdb_vnn_map_wire *map;
- ret = ctdb_control(ctdb, destnode, 0,
- CTDB_CONTROL_GETVNNMAP, 0, tdb_null,
+ ret = ctdb_control(ctdb, destnode, 0,
+ CTDB_CONTROL_GETVNNMAP, 0, tdb_null,
mem_ctx, &outdata, &res, &timeout, NULL);
if (ret != 0 || res != 0) {
DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getvnnmap failed\n"));
return -1;
}
-
+
map = (struct ctdb_vnn_map_wire *)outdata.dptr;
if (outdata.dsize < offsetof(struct ctdb_vnn_map_wire, map) ||
outdata.dsize != map->size*sizeof(uint32_t) + offsetof(struct ctdb_vnn_map_wire, map)) {
CTDB_NO_MEMORY(ctdb, (*vnnmap)->map);
memcpy((*vnnmap)->map, map->map, sizeof(uint32_t)*map->size);
talloc_free(outdata.dptr);
-
+
return 0;
}
struct ctdb_client_control_state *
ctdb_ctrl_getrecmode_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode)
{
- return ctdb_control_send(ctdb, destnode, 0,
- CTDB_CONTROL_GET_RECMODE, 0, tdb_null,
+ return ctdb_control_send(ctdb, destnode, 0,
+ CTDB_CONTROL_GET_RECMODE, 0, tdb_null,
mem_ctx, &timeout, NULL);
}
data.dsize = sizeof(uint32_t);
data.dptr = (unsigned char *)&recmode;
- ret = ctdb_control(ctdb, destnode, 0,
- CTDB_CONTROL_SET_RECMODE, 0, data,
+ ret = ctdb_control(ctdb, destnode, 0,
+ CTDB_CONTROL_SET_RECMODE, 0, data,
NULL, NULL, &res, &timeout, NULL);
if (ret != 0 || res != 0) {
DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setrecmode failed\n"));
get the recovery master of a remote node
*/
struct ctdb_client_control_state *
-ctdb_ctrl_getrecmaster_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx,
+ctdb_ctrl_getrecmaster_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx,
struct timeval timeout, uint32_t destnode)
{
- return ctdb_control_send(ctdb, destnode, 0,
- CTDB_CONTROL_GET_RECMASTER, 0, tdb_null,
+ return ctdb_control_send(ctdb, destnode, 0,
+ CTDB_CONTROL_GET_RECMASTER, 0, tdb_null,
mem_ctx, &timeout, NULL);
}
data.dsize = sizeof(uint32_t);
data.dptr = (unsigned char *)&recmaster;
- ret = ctdb_control(ctdb, destnode, 0,
- CTDB_CONTROL_SET_RECMASTER, 0, data,
+ ret = ctdb_control(ctdb, destnode, 0,
+ CTDB_CONTROL_SET_RECMASTER, 0, data,
NULL, NULL, &res, &timeout, NULL);
if (ret != 0 || res != 0) {
DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setrecmaster failed\n"));
/*
get a list of databases off a remote node
*/
-int ctdb_ctrl_getdbmap(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode,
+int ctdb_ctrl_getdbmap(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode,
TALLOC_CTX *mem_ctx, struct ctdb_dbid_map_old **dbmap)
{
int ret;
TDB_DATA outdata;
int32_t res;
- ret = ctdb_control(ctdb, destnode, 0,
- CTDB_CONTROL_GET_DBMAP, 0, tdb_null,
+ ret = ctdb_control(ctdb, destnode, 0,
+ CTDB_CONTROL_GET_DBMAP, 0, tdb_null,
mem_ctx, &outdata, &res, &timeout, NULL);
if (ret != 0 || res != 0) {
DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getdbmap failed ret:%d res:%d\n", ret, res));
*dbmap = (struct ctdb_dbid_map_old *)talloc_memdup(mem_ctx, outdata.dptr, outdata.dsize);
talloc_free(outdata.dptr);
-
+
return 0;
}
/*
get a list of nodes (vnn and flags ) from a remote node
*/
-int ctdb_ctrl_getnodemap(struct ctdb_context *ctdb,
- struct timeval timeout, uint32_t destnode,
+int ctdb_ctrl_getnodemap(struct ctdb_context *ctdb,
+ struct timeval timeout, uint32_t destnode,
TALLOC_CTX *mem_ctx, struct ctdb_node_map_old **nodemap)
{
int ret;
data.dptr = (uint8_t *)&dbid;
data.dsize = sizeof(dbid);
- ret = ctdb_control(ctdb, destnode, 0,
+ ret = ctdb_control(ctdb, destnode, 0,
CTDB_CONTROL_GETDBPATH, 0, data,
mem_ctx, &data, &res, &timeout, NULL);
if (ret != 0 || res != 0) {
}
/*
- find the name of a db
+ find the name of a db
*/
-int ctdb_ctrl_getdbname(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t dbid, TALLOC_CTX *mem_ctx,
+int ctdb_ctrl_getdbname(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t dbid, TALLOC_CTX *mem_ctx,
const char **name)
{
int ret;
data.dptr = (uint8_t *)&dbid;
data.dsize = sizeof(dbid);
- ret = ctdb_control(ctdb, destnode, 0,
- CTDB_CONTROL_GET_DBNAME, 0, data,
+ ret = ctdb_control(ctdb, destnode, 0,
+ CTDB_CONTROL_GET_DBNAME, 0, data,
mem_ctx, &data, &res, &timeout, NULL);
if (ret != 0 || res != 0) {
return -1;
int32_t res;
TDB_DATA data;
- ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_GET_DEBUG, 0, tdb_null,
+ ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_GET_DEBUG, 0, tdb_null,
ctdb, &data, &res, NULL, NULL);
if (ret != 0 || res != 0) {
return -1;
int ret;
int32_t res;
- ret = ctdb_control(ctdb, destnode, 0,
- CTDB_CONTROL_GET_PNN, 0, tdb_null,
+ ret = ctdb_control(ctdb, destnode, 0,
+ CTDB_CONTROL_GET_PNN, 0, tdb_null,
NULL, NULL, &res, &timeout, NULL);
if (ret != 0) {
DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getpnn failed\n"));
/*
set/clear the permanent disabled bit on a remote node
*/
-int ctdb_ctrl_modflags(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode,
+int ctdb_ctrl_modflags(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode,
uint32_t set, uint32_t clear)
{
int ret;
return ctdb->pnn;
}
-/*
+/*
callback for the async helpers used when sending the same control
to multiple nodes in parallell.
*/
}
return;
}
-
+
state->async.fn = NULL;
ret = ctdb_control_recv(ctdb, state, data, &outdata, &res, NULL);
/* set up the callback functions */
state->async.fn = async_callback;
state->async.private_data = data;
-
+
/* one more control to wait for to complete */
data->count++;
}
}
if (data->fail_count != 0) {
if (!data->dont_log_errors) {
- DEBUG(DEBUG_ERR,("Async wait failed - fail_count=%u\n",
+ DEBUG(DEBUG_ERR,("Async wait failed - fail_count=%u\n",
data->fail_count));
}
return -1;
}
-/*
+/*
perform a simple control on the listed nodes
The control cannot return data
*/
for (j=0; j<num_nodes; j++) {
uint32_t pnn = nodes[j];
- state = ctdb_control_send(ctdb, pnn, srvid, opcode,
+ state = ctdb_control_send(ctdb, pnn, srvid, opcode,
0, data, async_data, &timeout, NULL);
if (state == NULL) {
DEBUG(DEBUG_ERR,(__location__ " Failed to call async control %u\n", (unsigned)opcode));
talloc_free(async_data);
return -1;
}
-
+
ctdb_client_async_add(async_data, state);
}
continue;
}
num_nodes++;
- }
+ }
nodes = talloc_array(mem_ctx, uint32_t, num_nodes);
CTDB_NO_MEMORY_FATAL(ctdb, nodes);
continue;
}
nodes[j++] = vnn_map->map[i];
- }
+ }
return nodes;
}
continue;
}
num_nodes++;
- }
+ }
nodes = talloc_array(mem_ctx, uint32_t, num_nodes);
CTDB_NO_MEMORY_FATAL(ctdb, nodes);
continue;
}
nodes[j++] = node_map->nodes[i].pnn;
- }
+ }
return nodes;
}
struct ctdb_client_control_state *
ctdb_ctrl_getcapabilities_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode)
{
- return ctdb_control_send(ctdb, destnode, 0,
- CTDB_CONTROL_GET_CAPABILITIES, 0, tdb_null,
+ return ctdb_control_send(ctdb, destnode, 0,
+ CTDB_CONTROL_GET_CAPABILITIES, 0, tdb_null,
mem_ctx, &timeout, NULL);
}