1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-22 13:34:15 +03:00

added a ctdb control message, and tool

(This used to be ctdb commit 0d7a71f35bb8ce95231f8ca1e8e3e4024fe657e5)
This commit is contained in:
Andrew Tridgell 2007-04-26 14:27:49 +02:00
parent c1a4b3c687
commit d955485e7b
16 changed files with 674 additions and 48 deletions

View File

@ -20,9 +20,11 @@ LIB_FLAGS=@LDFLAGS@ -Llib @LIBS@ -lpopt @INFINIBAND_LIBS@
EVENTS_OBJ = lib/events/events.o lib/events/events_standard.o
CTDB_COMMON_OBJ = common/ctdb.o common/ctdb_daemon.o common/ctdb_client.o common/ctdb_io.o common/util.o common/ctdb_util.o \
common/ctdb_call.o common/ctdb_ltdb.o common/ctdb_lockwait.o common/ctdb_message.o \
common/cmdline.o lib/util/idtree.o lib/util/db_wrap.o lib/util/debug.o
CTDB_COMMON_OBJ = common/ctdb.o common/ctdb_daemon.o common/ctdb_client.o \
common/ctdb_io.o common/util.o common/ctdb_util.o \
common/ctdb_call.o common/ctdb_ltdb.o common/ctdb_lockwait.o \
common/ctdb_message.o common/cmdline.o common/ctdb_control.o \
lib/util/idtree.o lib/util/db_wrap.o lib/util/debug.o
CTDB_TCP_OBJ = tcp/tcp_connect.o tcp/tcp_io.o tcp/tcp_init.o
@ -30,7 +32,7 @@ CTDB_OBJ = $(CTDB_COMMON_OBJ) $(CTDB_TCP_OBJ)
OBJS = @TDBOBJ@ @TALLOCOBJ@ @LIBREPLACEOBJ@ @INFINIBAND_WRAPPER_OBJ@ $(EXTRA_OBJ) $(EVENTS_OBJ) $(CTDB_OBJ)
BINS = bin/ctdbd bin/ctdbd_test bin/ctdb_test bin/ctdb_bench bin/ctdb_messaging bin/ctdb_fetch bin/ctdb_fetch1 bin/lockwait bin/ctdb_status bin/ctdb_dump @INFINIBAND_BINS@
BINS = bin/ctdbd bin/ctdbd_test bin/ctdb_test bin/ctdb_bench bin/ctdb_messaging bin/ctdb_fetch bin/ctdb_fetch1 bin/lockwait bin/ctdb_status bin/ctdb_control bin/ctdb_dump @INFINIBAND_BINS@
DIRS = lib bin
@ -61,6 +63,10 @@ bin/ctdb_status: $(OBJS) tools/ctdb_status.o
@echo Linking $@
@$(CC) $(CFLAGS) -o $@ tools/ctdb_status.o $(OBJS) $(LIB_FLAGS)
bin/ctdb_control: $(OBJS) tools/ctdb_control.o
@echo Linking $@
@$(CC) $(CFLAGS) -o $@ tools/ctdb_control.o $(OBJS) $(LIB_FLAGS)
bin/ctdb_dump: $(OBJS) tools/ctdb_dump.o
@echo Linking $@
@$(CC) $(CFLAGS) -o $@ tools/ctdb_dump.o $(OBJS) $(LIB_FLAGS)

View File

@ -32,6 +32,7 @@ static struct {
const char *nlist;
const char *transport;
const char *myaddress;
const char *socketname;
int self_connect;
const char *db_dir;
int torture;
@ -39,6 +40,7 @@ static struct {
.nlist = NULL,
.transport = "tcp",
.myaddress = NULL,
.socketname = CTDB_PATH,
.self_connect = 0,
.db_dir = NULL,
.torture = 0
@ -48,6 +50,7 @@ static struct {
struct poptOption popt_ctdb_cmdline[] = {
{ "nlist", 0, POPT_ARG_STRING, &ctdb_cmdline.nlist, 0, "node list file", "filename" },
{ "listen", 0, POPT_ARG_STRING, &ctdb_cmdline.myaddress, 0, "address to listen on", "address" },
{ "socket", 0, POPT_ARG_STRING, &ctdb_cmdline.socketname, 0, "local socket name", "filename" },
{ "transport", 0, POPT_ARG_STRING, &ctdb_cmdline.transport, 0, "protocol transport", NULL },
{ "self-connect", 0, POPT_ARG_NONE, &ctdb_cmdline.self_connect, 0, "enable self connect", "boolean" },
{ "debug", 'd', POPT_ARG_INT, &LogLevel, 0, "debug level"},
@ -97,6 +100,13 @@ struct ctdb_context *ctdb_cmdline_init(struct event_context *ev)
exit(1);
}
/* tell ctdb the socket address */
ret = ctdb_set_socketname(ctdb, ctdb_cmdline.socketname);
if (ret == -1) {
printf("ctdb_set_socketname failed - %s\n", ctdb_errstr(ctdb));
exit(1);
}
/* tell ctdb what nodes are available */
ret = ctdb_set_nlist(ctdb, ctdb_cmdline.nlist);
if (ret == -1) {
@ -117,7 +127,7 @@ struct ctdb_context *ctdb_cmdline_init(struct event_context *ev)
/*
startup a client only ctdb context
*/
struct ctdb_context *ctdb_cmdline_client(struct event_context *ev, const char *ctdb_socket)
struct ctdb_context *ctdb_cmdline_client(struct event_context *ev)
{
struct ctdb_context *ctdb;
int ret;
@ -129,7 +139,12 @@ struct ctdb_context *ctdb_cmdline_client(struct event_context *ev, const char *c
exit(1);
}
ctdb->daemon.name = talloc_strdup(ctdb, ctdb_socket);
/* tell ctdb the socket address */
ret = ctdb_set_socketname(ctdb, ctdb_cmdline.socketname);
if (ret == -1) {
printf("ctdb_set_socketname failed - %s\n", ctdb_errstr(ctdb));
exit(1);
}
ret = ctdb_socket_connect(ctdb);
if (ret != 0) {

View File

@ -171,6 +171,16 @@ int ctdb_set_address(struct ctdb_context *ctdb, const char *address)
return 0;
}
/*
setup the local socket name
*/
int ctdb_set_socketname(struct ctdb_context *ctdb, const char *socketname)
{
ctdb->daemon.name = talloc_strdup(ctdb, socketname);
return 0;
}
/*
add a node to the list of active nodes
*/
@ -285,6 +295,16 @@ void ctdb_recv_pkt(struct ctdb_context *ctdb, uint8_t *data, uint32_t length)
ctdb_request_finished(ctdb, hdr);
break;
case CTDB_REQ_CONTROL:
ctdb->status.count.req_control++;
ctdb_request_control(ctdb, hdr);
break;
case CTDB_REPLY_CONTROL:
ctdb->status.count.reply_control++;
ctdb_reply_control(ctdb, hdr);
break;
default:
DEBUG(0,("%s: Packet with unknown operation %d\n",
__location__, hdr->operation));

View File

@ -93,6 +93,7 @@ static void ctdb_client_reply_call(struct ctdb_context *ctdb, struct ctdb_req_he
static void ctdb_reply_status(struct ctdb_context *ctdb, struct ctdb_req_header *hdr);
static void ctdb_reply_getdbpath(struct ctdb_context *ctdb, struct ctdb_req_header *hdr);
static void ctdb_client_reply_control(struct ctdb_context *ctdb, struct ctdb_req_header *hdr);
/*
this is called in the client, when data comes in from the daemon
@ -156,6 +157,10 @@ static void ctdb_client_read_cb(uint8_t *data, size_t cnt, void *args)
ctdb_reply_getdbpath(ctdb, hdr);
break;
case CTDB_REPLY_CONTROL:
ctdb_client_reply_control(ctdb, hdr);
break;
default:
DEBUG(0,("bogus operation code:%d\n",hdr->operation));
}
@ -422,7 +427,7 @@ int ctdb_send_message(struct ctdb_context *ctdb, uint32_t vnn,
int len, res;
len = offsetof(struct ctdb_req_message, data) + data.dsize;
r = ctdb->methods->allocate_pkt(ctdb, len);
r = ctdbd_allocate_pkt(ctdb, len);
CTDB_NO_MEMORY(ctdb, r);
talloc_set_name_const(r, "req_message packet");
@ -771,3 +776,134 @@ int ctdb_getdbpath(struct ctdb_db_context *ctdb_db, TDB_DATA *path)
return 0;
}
struct ctdb_client_control_state {
uint32_t reqid;
int32_t status;
TDB_DATA outdata;
enum call_state state;
};
/*
called when a CTDB_REPLY_CONTROL packet comes in in the client
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,
struct ctdb_req_header *hdr)
{
struct ctdb_reply_control *c = (struct ctdb_reply_control *)hdr;
struct ctdb_client_control_state *state;
state = ctdb_reqid_find(ctdb, hdr->reqid, struct ctdb_client_control_state);
if (state == NULL) {
DEBUG(0,(__location__ " reqid %d not found\n", hdr->reqid));
return;
}
if (hdr->reqid != state->reqid) {
/* we found a record but it was the wrong one */
DEBUG(0, ("Dropped orphaned reply control with reqid:%d\n",hdr->reqid));
return;
}
state->outdata.dptr = c->data;
state->outdata.dsize = c->datalen;
state->status = c->status;
talloc_steal(state, c);
state->state = CTDB_CALL_DONE;
}
/*
send a ctdb control message
*/
int ctdb_control(struct ctdb_context *ctdb, uint32_t destnode, uint32_t srvid,
uint32_t opcode, TDB_DATA data,
TALLOC_CTX *mem_ctx, TDB_DATA *outdata, int32_t *status)
{
struct ctdb_client_control_state *state;
struct ctdb_req_control *c;
size_t len;
int ret;
/* if the domain socket is not yet open, open it */
if (ctdb->daemon.sd==-1) {
ctdb_socket_connect(ctdb);
}
state = talloc_zero(ctdb, struct ctdb_client_control_state);
CTDB_NO_MEMORY(ctdb, state);
state->reqid = ctdb_reqid_new(ctdb, state);
state->state = CTDB_CALL_WAIT;
len = offsetof(struct ctdb_req_control, data) + data.dsize;
c = ctdbd_allocate_pkt(state, len);
memset(c, 0, len);
c->hdr.length = len;
c->hdr.ctdb_magic = CTDB_MAGIC;
c->hdr.ctdb_version = CTDB_VERSION;
c->hdr.operation = CTDB_REQ_CONTROL;
c->hdr.reqid = state->reqid;
c->hdr.destnode = destnode;
c->hdr.srcnode = ctdb->vnn;
c->hdr.reqid = state->reqid;
c->opcode = opcode;
c->srvid = srvid;
c->datalen = data.dsize;
if (data.dsize) {
memcpy(&c->data[0], data.dptr, data.dsize);
}
ret = ctdb_client_queue_pkt(ctdb, &(c->hdr));
if (ret != 0) {
talloc_free(state);
return -1;
}
/* semi-async operation */
while (state->state == CTDB_CALL_WAIT) {
event_loop_once(ctdb->ev);
}
if (outdata) {
*outdata = state->outdata;
outdata->dptr = talloc_steal(mem_ctx, outdata->dptr);
}
*status = state->status;
talloc_free(state);
return 0;
}
/*
a process exists call. Returns 0 if process exists, -1 otherwise
*/
int ctdb_process_exists(struct ctdb_context *ctdb, uint32_t destnode, pid_t pid)
{
int ret;
TDB_DATA data;
int32_t status;
data.dptr = (uint8_t*)&pid;
data.dsize = sizeof(pid);
ret = ctdb_control(ctdb, destnode, 0,
CTDB_CONTROL_PROCESS_EXISTS, data,
NULL, NULL, &status);
if (ret != 0) {
DEBUG(0,(__location__ " ctdb_control failed\n"));
return -1;
}
return status;
}

182
ctdb/common/ctdb_control.c Normal file
View File

@ -0,0 +1,182 @@
/*
ctdb_control protocol code
Copyright (C) Andrew Tridgell 2007
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "includes.h"
#include "lib/events/events.h"
#include "lib/tdb/include/tdb.h"
#include "system/network.h"
#include "system/filesys.h"
#include "system/wait.h"
#include "../include/ctdb_private.h"
#include "lib/util/dlinklist.h"
struct ctdb_control_state {
struct ctdb_context *ctdb;
uint32_t reqid;
ctdb_control_callback_fn_t callback;
void *private_data;
};
/*
process a control request
*/
static int32_t ctdb_control_dispatch(struct ctdb_context *ctdb,
uint32_t opcode, TDB_DATA indata,
TDB_DATA *outdata)
{
switch (opcode) {
case CTDB_CONTROL_PROCESS_EXISTS: {
pid_t pid;
if (indata.dsize != sizeof(pid_t)) {
DEBUG(0,(__location__ " Invalid data in CTDB_CONTROL_PROCESS_EXISTS\n"));
return -1;
}
pid = *(pid_t *)indata.dptr;
return kill(pid, 0);
}
default:
DEBUG(0,(__location__ " Unknown CTDB control opcode %u\n", opcode));
return -1;
}
}
/*
called when a CTDB_REQ_CONTROL packet comes in
*/
void ctdb_request_control(struct ctdb_context *ctdb, struct ctdb_req_header *hdr)
{
struct ctdb_req_control *c = (struct ctdb_req_control *)hdr;
TDB_DATA data, outdata;
struct ctdb_reply_control *r;
int32_t status;
size_t len;
data.dptr = &c->data[0];
data.dsize = c->datalen;
ZERO_STRUCT(outdata);
status = ctdb_control_dispatch(ctdb, c->opcode, data, &outdata);
len = offsetof(struct ctdb_reply_control, data) + outdata.dsize;
r = ctdb->methods->allocate_pkt(ctdb, len);
CTDB_NO_MEMORY_VOID(ctdb, r);
talloc_set_name_const(r, "ctdb_reply_control packet");
r->hdr.length = len;
r->hdr.ctdb_magic = CTDB_MAGIC;
r->hdr.ctdb_version = CTDB_VERSION;
r->hdr.operation = CTDB_REPLY_CONTROL;
r->hdr.destnode = hdr->srcnode;
r->hdr.srcnode = ctdb->vnn;
r->hdr.reqid = hdr->reqid;
r->status = status;
c->datalen = outdata.dsize;
if (outdata.dsize) {
memcpy(&r->data[0], outdata.dptr, outdata.dsize);
}
ctdb_queue_packet(ctdb, &r->hdr);
talloc_free(r);
}
/*
called when a CTDB_REPLY_CONTROL packet comes in
*/
void ctdb_reply_control(struct ctdb_context *ctdb, struct ctdb_req_header *hdr)
{
struct ctdb_reply_control *c = (struct ctdb_reply_control *)hdr;
TDB_DATA data;
struct ctdb_control_state *state;
state = ctdb_reqid_find(ctdb, hdr->reqid, struct ctdb_control_state);
if (state == NULL) {
return;
}
if (hdr->reqid != state->reqid) {
/* we found a record but it was the wrong one */
DEBUG(0, ("Dropped orphaned control reply with reqid:%d\n", hdr->reqid));
return;
}
data.dptr = &c->data[0];
data.dsize = c->datalen;
state->callback(ctdb, c->status, data, state->private_data);
talloc_free(state);
}
static int ctdb_control_destructor(struct ctdb_control_state *state)
{
ctdb_reqid_remove(state->ctdb, state->reqid);
return 0;
}
/*
send a control message to a node
*/
int ctdb_daemon_send_control(struct ctdb_context *ctdb, uint32_t destnode,
uint32_t srvid, uint32_t opcode, TDB_DATA data,
ctdb_control_callback_fn_t callback,
void *private_data)
{
struct ctdb_req_control *c;
struct ctdb_control_state *state;
size_t len;
state = talloc(ctdb, struct ctdb_control_state);
CTDB_NO_MEMORY(ctdb, state);
state->reqid = ctdb_reqid_new(ctdb, state);
state->callback = callback;
state->private_data = private_data;
state->ctdb = ctdb;
talloc_set_destructor(state, ctdb_control_destructor);
len = offsetof(struct ctdb_req_control, data) + data.dsize;
c = ctdb->methods->allocate_pkt(state, len);
CTDB_NO_MEMORY(ctdb, c);
talloc_set_name_const(c, "ctdb_req_control packet");
c->hdr.length = len;
c->hdr.ctdb_magic = CTDB_MAGIC;
c->hdr.ctdb_version = CTDB_VERSION;
c->hdr.operation = CTDB_REQ_CONTROL;
c->hdr.destnode = destnode;
c->hdr.srcnode = ctdb->vnn;
c->hdr.reqid = state->reqid;
c->opcode = opcode;
c->srvid = srvid;
c->datalen = data.dsize;
if (data.dsize) {
memcpy(&c->data[0], data.dptr, data.dsize);
}
ctdb_queue_packet(ctdb, &c->hdr);
#if CTDB_REQ_TIMEOUT
event_add_timed(ctdb->ev, state, timeval_current_ofs(CTDB_REQ_TIMEOUT, 0),
ctdb_control_timeout, state);
#endif
talloc_free(c);
return 0;
}

View File

@ -482,6 +482,10 @@ static void daemon_request_call_from_client(struct ctdb_client *client,
state->async.private_data = dstate;
}
static void daemon_request_control_from_client(struct ctdb_client *client,
struct ctdb_req_control *c);
/* data contains a packet from the client */
static void daemon_incoming_packet(void *p, uint8_t *data, uint32_t nread)
{
@ -518,6 +522,7 @@ static void daemon_incoming_packet(void *p, uint8_t *data, uint32_t nread)
daemon_request_register_message_handler(client,
(struct ctdb_req_register *)hdr);
break;
case CTDB_REQ_MESSAGE:
ctdb->status.client.req_message++;
daemon_request_message_from_client(client, (struct ctdb_req_message *)hdr);
@ -542,6 +547,11 @@ static void daemon_incoming_packet(void *p, uint8_t *data, uint32_t nread)
daemon_request_getdbpath(client, (struct ctdb_req_getdbpath *)hdr);
break;
case CTDB_REQ_CONTROL:
ctdb->status.client.req_control++;
daemon_request_control_from_client(client, (struct ctdb_req_control *)hdr);
break;
default:
DEBUG(0,(__location__ " daemon: unrecognized operation %d\n",
hdr->operation));
@ -694,8 +704,6 @@ int ctdb_start(struct ctdb_context *ctdb)
struct fd_event *fde;
const char *domain_socket_name;
/* generate a name to use for our local socket */
ctdb->daemon.name = talloc_asprintf(ctdb, "%s.%s", CTDB_PATH, ctdb->address.address);
/* get rid of any old sockets */
unlink(ctdb->daemon.name);
@ -758,3 +766,70 @@ void ctdb_request_finished(struct ctdb_context *ctdb, struct ctdb_req_header *hd
{
ctdb->num_finished++;
}
struct daemon_control_state {
struct ctdb_client *client;
struct ctdb_req_control *c;
};
/*
callback when a control reply comes in
*/
static void daemon_control_callback(struct ctdb_context *ctdb,
uint32_t status, TDB_DATA data,
void *private_data)
{
struct daemon_control_state *state = talloc_get_type(private_data,
struct daemon_control_state);
struct ctdb_client *client = state->client;
struct ctdb_reply_control *r;
size_t len;
/* construct a message to send to the client containing the data */
len = offsetof(struct ctdb_req_control, data) + data.dsize;
r = ctdbd_allocate_pkt(client, len);
talloc_set_name_const(r, "reply_control packet");
memset(r, 0, offsetof(struct ctdb_req_message, data));
r->hdr.length = len;
r->hdr.ctdb_magic = CTDB_MAGIC;
r->hdr.ctdb_version = CTDB_VERSION;
r->hdr.operation = CTDB_REPLY_CONTROL;
r->status = status;
r->datalen = data.dsize;
memcpy(&r->data[0], data.dptr, data.dsize);
daemon_queue_send(client, &r->hdr);
talloc_free(state);
}
/*
this is called when the ctdb daemon received a ctdb request control
from a local client over the unix domain socket
*/
static void daemon_request_control_from_client(struct ctdb_client *client,
struct ctdb_req_control *c)
{
TDB_DATA data;
int res;
struct daemon_control_state *state;
state = talloc(client, struct daemon_control_state);
CTDB_NO_MEMORY_VOID(client->ctdb, state);
state->client = client;
state->c = talloc_steal(state, c);
data.dptr = &c->data[0];
data.dsize = c->datalen;
res = ctdb_daemon_send_control(client->ctdb, c->hdr.destnode,
c->srvid, c->opcode, data, daemon_control_callback,
state);
if (res != 0) {
DEBUG(0,(__location__ " Failed to send control to remote node %u\n",
c->hdr.destnode));
}
}

View File

@ -95,6 +95,8 @@ void ctdb_set_max_lacount(struct ctdb_context *ctdb, unsigned count);
*/
int ctdb_set_address(struct ctdb_context *ctdb, const char *address);
int ctdb_set_socketname(struct ctdb_context *ctdb, const char *socketname);
/*
tell ctdb what nodes are available. This takes a filename, which will contain
1 node address per line, in a transport specific format
@ -208,11 +210,13 @@ int ctdb_register_message_handler(struct ctdb_context *ctdb,
struct ctdb_db_context *find_ctdb_db(struct ctdb_context *ctdb, uint32_t id);
struct ctdb_context *ctdb_cmdline_client(struct event_context *ev, const char *ctdb_socket);
struct ctdb_context *ctdb_cmdline_client(struct event_context *ev);
struct ctdb_status;
int ctdb_status(struct ctdb_context *ctdb, struct ctdb_status *status);
int ctdb_getdbpath(struct ctdb_db_context *ctdb_db, TDB_DATA *path);
int ctdb_process_exists(struct ctdb_context *ctdb, uint32_t destnode, pid_t pid);
#endif

View File

@ -61,6 +61,10 @@ struct ctdb_address {
typedef void (*ctdb_queue_cb_fn_t)(uint8_t *data, size_t length,
void *private_data);
/* used for callbacks in ctdb_control requests */
typedef void (*ctdb_control_callback_fn_t)(struct ctdb_context *,
uint32_t status, TDB_DATA data,
void *private_data);
/*
state associated with one node
@ -131,6 +135,8 @@ struct ctdb_status {
uint32_t reply_error;
uint32_t req_message;
uint32_t req_finished;
uint32_t req_control;
uint32_t reply_control;
} count;
struct {
uint32_t req_call;
@ -140,6 +146,7 @@ struct ctdb_status {
uint32_t req_connect_wait;
uint32_t req_shutdown;
uint32_t req_status;
uint32_t req_control;
} client;
uint32_t total_calls;
uint32_t pending_calls;
@ -189,6 +196,10 @@ struct ctdb_db_context {
ctdb_set_error(ctdb, "Out of memory at %s:%d", __FILE__, __LINE__); \
return -1; }} while (0)
#define CTDB_NO_MEMORY_VOID(ctdb, p) do { if (!(p)) { \
ctdb_set_error(ctdb, "Out of memory at %s:%d", __FILE__, __LINE__); \
}} while (0)
#define CTDB_NO_MEMORY_NULL(ctdb, p) do { if (!(p)) { \
ctdb_set_error(ctdb, "Out of memory at %s:%d", __FILE__, __LINE__); \
return NULL; }} while (0)
@ -217,6 +228,8 @@ struct ctdb_ltdb_header {
uint32_t lacount;
};
enum {CTDB_CONTROL_PROCESS_EXISTS};
enum call_state {CTDB_CALL_WAIT, CTDB_CALL_DONE, CTDB_CALL_ERROR};
/*
@ -259,6 +272,8 @@ enum ctdb_operation {
CTDB_REPLY_ERROR = 5,
CTDB_REQ_MESSAGE = 6,
CTDB_REQ_FINISHED = 7,
CTDB_REQ_CONTROL = 8,
CTDB_REPLY_CONTROL = 9,
/* only used on the domain socket */
CTDB_REQ_REGISTER = 1000,
@ -381,6 +396,22 @@ struct ctdb_reply_status {
struct ctdb_status status;
};
struct ctdb_req_control {
struct ctdb_req_header hdr;
uint32_t opcode;
uint32_t srvid;
uint32_t datalen;
uint8_t data[1];
};
struct ctdb_reply_control {
struct ctdb_req_header hdr;
int32_t status;
uint32_t datalen;
uint8_t data[1];
};
/* internal prototypes */
void ctdb_set_error(struct ctdb_context *ctdb, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
void ctdb_fatal(struct ctdb_context *ctdb, const char *msg);
@ -529,4 +560,12 @@ uint32_t ctdb_reqid_new(struct ctdb_context *ctdb, void *state);
void *_ctdb_reqid_find(struct ctdb_context *ctdb, uint32_t reqid, const char *type, const char *location);
void ctdb_reqid_remove(struct ctdb_context *ctdb, uint32_t reqid);
void ctdb_request_control(struct ctdb_context *ctdb, struct ctdb_req_header *hdr);
void ctdb_reply_control(struct ctdb_context *ctdb, struct ctdb_req_header *hdr);
int ctdb_daemon_send_control(struct ctdb_context *ctdb, uint32_t destnode,
uint32_t srvid, uint32_t opcode, TDB_DATA data,
ctdb_control_callback_fn_t callback,
void *private_data);
#endif

View File

@ -33,9 +33,9 @@ echo "Starting nodes"
i=0
for h in $nodes; do
if [ $i -eq `expr $count - 1` ]; then
ssh $h $dir/bin/ctdb_bench --nlist $dir/nodes-ssh.txt --listen $h:9001 $options
ssh $h $dir/bin/ctdb_bench --nlist $dir/nodes-ssh.txt --listen $h:9001 --socket $h$options
else
ssh -f $h $dir/bin/ctdb_bench --nlist $dir/nodes-ssh.txt --listen $h:9001 $options
ssh -f $h $dir/bin/ctdb_bench --nlist $dir/nodes-ssh.txt --listen $h:9001 --socket $h $options
fi
i=`expr $i + 1`
done

View File

@ -2,8 +2,20 @@
killall -q ctdb_bench
echo "Trying 2 nodes"
$VALGRIND bin/ctdb_bench --nlist tests/nodes.txt --listen 127.0.0.2:9001 $* &
$VALGRIND bin/ctdb_bench --nlist tests/nodes.txt --listen 127.0.0.1:9001 $*
wait
NUMNODES=2
if [ $# -gt 0 ]; then
NUMNODES=$1
fi
rm -f nodes.txt
for i in `seq 1 $NUMNODES`; do
echo 127.0.0.$i:9001 >> nodes.txt
done
killall -9 ctdb_bench
echo "Trying $NUMNODES nodes"
for i in `seq 1 $NUMNODES`; do
$VALGRIND bin/ctdb_bench --nlist nodes.txt --listen 127.0.0.$i:9001 --socket /tmp/ctdb.127.0.0.$i $* &
done
wait

View File

@ -1,7 +0,0 @@
#!/bin/sh
killall -q ctdb_bench
echo "Trying 1 nodes"
bin/ctdb_bench --nlist tests/1node.txt --listen 127.0.0.2:9001 $*
wait

View File

@ -1,15 +1,18 @@
#!/bin/sh
killall -q ctdb_fetch
NUMNODES=2
if [ $# -gt 0 ]; then
NUMNODES=$1
fi
echo "Trying 2 nodes"
$VALGRIND bin/ctdb_fetch --nlist tests/nodes.txt --listen 127.0.0.2:9001 $* &
$VALGRIND bin/ctdb_fetch --nlist tests/nodes.txt --listen 127.0.0.1:9001 $*
wait
rm -f nodes.txt
for i in `seq 1 $NUMNODES`; do
echo 127.0.0.$i:9001 >> nodes.txt
done
echo "Trying 4 nodes"
$VALGRIND bin/ctdb_fetch --nlist tests/4nodes.txt --listen 127.0.0.4:9001 $* &
$VALGRIND bin/ctdb_fetch --nlist tests/4nodes.txt --listen 127.0.0.3:9001 $* &
$VALGRIND bin/ctdb_fetch --nlist tests/4nodes.txt --listen 127.0.0.2:9001 $* &
$VALGRIND bin/ctdb_fetch --nlist tests/4nodes.txt --listen 127.0.0.1:9001 $*
killall -9 ctdb_fetch
echo "Trying $NUMNODES nodes"
for i in `seq 1 $NUMNODES`; do
$VALGRIND bin/ctdb_fetch --nlist nodes.txt --listen 127.0.0.$i:9001 --socket /tmp/ctdb.127.0.0.$i $* &
done
wait

View File

@ -1,8 +1,23 @@
#!/bin/sh
#!/bin/sh
killall -q ctdb_messaging
echo "Trying 2 nodes"
bin/ctdb_messaging --nlist tests/nodes.txt --listen 127.0.0.2:9001 $* &
bin/ctdb_messaging --nlist tests/nodes.txt --listen 127.0.0.1:9001 $*
NUMNODES=2
if [ $# -gt 0 ]; then
NUMNODES=$1
fi
rm -f nodes.txt
for i in `seq 1 $NUMNODES`; do
echo 127.0.0.$i:9001 >> nodes.txt
done
killall -9 ctdb_messaging
echo "Trying $NUMNODES nodes"
for i in `seq 1 $NUMNODES`; do
$VALGRIND bin/ctdb_messaging --nlist nodes.txt --listen 127.0.0.$i:9001 --socket /tmp/ctdb.127.0.0.$i $* &
done
wait

View File

@ -1,17 +1,24 @@
#!/bin/sh
#!/bin/sh
killall -q ctdb_test
NUMNODES=2
if [ $# -gt 0 ]; then
NUMNODES=$1
shift
fi
rm -f nodes.txt
for i in `seq 1 $NUMNODES`; do
echo 127.0.0.$i:9001 >> nodes.txt
done
killall -9 ctdb_test
echo "Trying $NUMNODES nodes"
for i in `seq 1 $NUMNODES`; do
$VALGRIND bin/ctdb_test --nlist nodes.txt --listen 127.0.0.$i:9001 --socket /tmp/ctdb.127.0.0.$i $* &
done
echo "Trying 2 nodes ..."
$VALGRIND bin/ctdb_test --nlist tests/nodes.txt --listen 127.0.0.1:9001 &
$VALGRIND bin/ctdb_test --nlist tests/nodes.txt --listen 127.0.0.2:9001
wait
echo "Trying 4 nodes ..."
$VALGRIND bin/ctdb_test --nlist tests/4nodes.txt --listen 127.0.0.1:9001 &
$VALGRIND bin/ctdb_test --nlist tests/4nodes.txt --listen 127.0.0.2:9001 &
$VALGRIND bin/ctdb_test --nlist tests/4nodes.txt --listen 127.0.0.3:9001 &
$VALGRIND bin/ctdb_test --nlist tests/4nodes.txt --listen 127.0.0.4:9001
wait

119
ctdb/tools/ctdb_control.c Normal file
View File

@ -0,0 +1,119 @@
/*
ctdb control tool
Copyright (C) Andrew Tridgell 2007
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "includes.h"
#include "lib/events/events.h"
#include "system/filesys.h"
#include "popt.h"
#include "cmdline.h"
#include "../include/ctdb_private.h"
/*
show usage message
*/
static void usage(void)
{
printf("Usage: ctdb_control [options] <control>\n");
exit(1);
}
static int control_process_exists(struct ctdb_context *ctdb, int argc, const char **argv)
{
uint32_t srvid;
pid_t pid;
int ret;
if (argc < 2) {
usage();
}
srvid = strtoul(argv[0], NULL, 0);
pid = strtoul(argv[1], NULL, 0);
ret = ctdb_process_exists(ctdb, srvid, pid);
if (ret == 0) {
printf("%u:%u exists\n", srvid, pid);
} else {
printf("%u:%u does not exist\n", srvid, pid);
}
return ret;
}
/*
main program
*/
int main(int argc, const char *argv[])
{
struct ctdb_context *ctdb;
struct poptOption popt_options[] = {
POPT_AUTOHELP
POPT_CTDB_CMDLINE
POPT_TABLEEND
};
int opt;
const char **extra_argv;
int extra_argc = 0;
int ret;
poptContext pc;
struct event_context *ev;
const char *control;
pc = poptGetContext(argv[0], argc, argv, popt_options, POPT_CONTEXT_KEEP_FIRST);
while ((opt = poptGetNextOpt(pc)) != -1) {
switch (opt) {
default:
fprintf(stderr, "Invalid option %s: %s\n",
poptBadOption(pc, 0), poptStrerror(opt));
exit(1);
}
}
/* setup the remaining options for the main program to use */
extra_argv = poptGetArgs(pc);
if (extra_argv) {
extra_argv++;
while (extra_argv[extra_argc]) extra_argc++;
}
if (extra_argc < 1) {
usage();
}
control = extra_argv[0];
ev = event_context_init(NULL);
/* initialise ctdb */
ctdb = ctdb_cmdline_client(ev);
if (ctdb == NULL) {
printf("Failed to init ctdb\n");
exit(1);
}
if (strcmp(control, "process-exists") == 0) {
ret = control_process_exists(ctdb, extra_argc-1, extra_argv+1);
} else {
printf("Unknown control '%s'\n", control);
exit(1);
}
return ret;
}

View File

@ -117,7 +117,7 @@ int main(int argc, const char *argv[])
ev = event_context_init(NULL);
/* initialise ctdb */
ctdb = ctdb_cmdline_client(ev, ctdb_socket);
ctdb = ctdb_cmdline_client(ev);
if (ctdb == NULL) {
printf("Failed to init ctdb\n");
exit(1);