Rev 91: merged tridge's branch again in
http://samba.org/~tridge/psomogyi/
psomogyi at gamax.hu
psomogyi at gamax.hu
Sun Apr 29 14:28:54 GMT 2007
------------------------------------------------------------
revno: 91
revision-id: psomogyi at gamax.hu-20070429142835-4pd7m24sjko801ye
parent: psomogyi at gamax.hu-20070429142748-xzhvikj20c14dnaf
parent: tridge at samba.org-20070429141940-kxbij0fq3pj33qvn
committer: Peter Somogyi <psomogyi at gamax.hu>
branch nick: ctdb
timestamp: Sun 2007-04-29 16:28:35 +0200
message:
merged tridge's branch again
modified:
common/ctdb_call.c ctdb_call.c-20061128065342-to93h6eejj5kon81-1
common/ctdb_client.c ctdb_client.c-20070411010216-3kd8v37k61steeya-1
common/ctdb_control.c ctdb_control.c-20070426122724-j6gkpiofhbwdin63-1
common/ctdb_daemon.c ctdb_daemon.c-20070409200331-3el1kqgdb9m4ib0g-1
common/ctdb_io.c ctdb_io.c-20070409200335-dzfc7f3rra5rcf60-1
common/ctdb_util.c ctdb_util.c-20061128065342-to93h6eejj5kon81-3
direct/ctdbd.c ctdbd.c-20070411085044-dqmhr6mfeexnyt4m-1
include/ctdb.h ctdb.h-20061117234101-o3qt14umlg9en8z0-11
include/ctdb_private.h ctdb_private.h-20061117234101-o3qt14umlg9en8z0-13
tools/ctdb_control.c ctdb_control.c-20070426122705-9ehj1l5lu2gn9kuj-1
------------------------------------------------------------
revno: 44.1.177
merged: tridge at samba.org-20070429141940-kxbij0fq3pj33qvn
parent: tridge at samba.org-20070428171336-4yw1gh5qfslqan73
committer: Andrew Tridgell <tridge at samba.org>
branch nick: tridge
timestamp: Sun 2007-04-29 16:19:40 +0200
message:
yay! finally fixed the bug that volker, ronnie and I have been chasing
for 2 days.
The main bug was in smbd, but there was a secondary (and more subtle)
bug in ctdb that the bug in smbd exposed. When we get send a dmaster
reply, we have to correctly update the dmaster in the recipient even
if the original requst has timed out, otherwise ctdbd can get into a
loop fighting over who will handle a key.
This patch also cleans up the packet allocation, and makes ctdbd
become a real daemon.
------------------------------------------------------------
revno: 44.1.176
merged: tridge at samba.org-20070428171336-4yw1gh5qfslqan73
parent: tridge at samba.org-20070428165537-dq8tirclx8okd1ec
committer: Andrew Tridgell <tridge at samba.org>
branch nick: tridge
timestamp: Sat 2007-04-28 19:13:36 +0200
message:
added reset status control
------------------------------------------------------------
revno: 44.1.175
merged: tridge at samba.org-20070428165537-dq8tirclx8okd1ec
parent: tridge at samba.org-20070428161833-g1jbj1dibtxk28ih
committer: Andrew Tridgell <tridge at samba.org>
branch nick: tridge
timestamp: Sat 2007-04-28 18:55:37 +0200
message:
removed unnecessary variable
=== modified file 'common/ctdb_call.c'
--- a/common/ctdb_call.c 2007-04-28 16:18:33 +0000
+++ b/common/ctdb_call.c 2007-04-29 14:19:40 +0000
@@ -211,15 +211,19 @@
tmp_ctx = talloc_new(ctdb);
/* send the CTDB_REPLY_DMASTER */
- len = offsetof(struct ctdb_reply_dmaster, data) + data.dsize;
+ len = offsetof(struct ctdb_reply_dmaster, data) + key.dsize + data.dsize;
r = ctdb_transport_allocate(ctdb, tmp_ctx, CTDB_REPLY_DMASTER, len,
struct ctdb_reply_dmaster);
CTDB_NO_MEMORY_FATAL(ctdb, r);
r->hdr.destnode = new_dmaster;
r->hdr.reqid = reqid;
+ r->rsn = header->rsn;
+ r->keylen = key.dsize;
r->datalen = data.dsize;
- memcpy(&r->data[0], data.dptr, data.dsize);
+ r->db_id = ctdb_db->db_id;
+ memcpy(&r->data[0], key.dptr, key.dsize);
+ memcpy(&r->data[key.dsize], data.dptr, data.dsize);
ctdb_queue_packet(ctdb, &r->hdr);
@@ -256,6 +260,7 @@
r->hdr.destnode = lmaster;
r->hdr.reqid = c->hdr.reqid;
r->db_id = c->db_id;
+ r->rsn = header->rsn;
r->dmaster = c->hdr.srcnode;
r->keylen = key->dsize;
r->datalen = data->dsize;
@@ -276,39 +281,43 @@
must be called with the chainlock held. This function releases the chainlock
*/
-static void ctdb_become_dmaster(struct ctdb_context *ctdb,
- uint32_t reqid, TDB_DATA data)
+static void ctdb_become_dmaster(struct ctdb_db_context *ctdb_db,
+ uint32_t reqid, TDB_DATA key, TDB_DATA data,
+ uint64_t rsn)
{
struct ctdb_call_state *state;
- struct ctdb_db_context *ctdb_db;
+ struct ctdb_context *ctdb = ctdb_db->ctdb;
+ struct ctdb_ltdb_header header;
+
+ DEBUG(2,("vnn %u dmaster response %08x\n", ctdb->vnn, ctdb_hash(&key)));
+
+ ZERO_STRUCT(header);
+ header.rsn = rsn;
+ header.dmaster = ctdb->vnn;
+
+ if (ctdb_ltdb_store(ctdb_db, key, &header, data) != 0) {
+ ctdb_fatal(ctdb, "ctdb_reply_dmaster store failed\n");
+ ctdb_ltdb_unlock(ctdb_db, key);
+ return;
+ }
state = ctdb_reqid_find(ctdb, reqid, struct ctdb_call_state);
if (state == NULL) {
+ DEBUG(0,("vnn %u Invalid reqid %u in ctdb_become_dmaster\n",
+ ctdb->vnn, reqid));
+ ctdb_ltdb_unlock(ctdb_db, key);
return;
}
if (reqid != state->reqid) {
/* we found a record but it was the wrong one */
- DEBUG(0, ("Dropped orphaned dmaster reply with reqid:%d\n",reqid));
- return;
- }
-
- ctdb_db = state->ctdb_db;
-
- DEBUG(2,("vnn %u dmaster response %08x\n",
- ctdb->vnn, ctdb_hash(&state->call.key)));
-
- /* we're now the dmaster - update our local ltdb with new header
- and data */
- state->header.dmaster = ctdb->vnn;
-
- if (ctdb_ltdb_store(ctdb_db, state->call.key, &state->header, data) != 0) {
- ctdb_fatal(ctdb, "ctdb_reply_dmaster store failed\n");
- return;
- }
-
- ctdb_call_local(ctdb_db, &state->call, &state->header, &data, ctdb->vnn);
+ DEBUG(0, ("Dropped orphan in ctdb_become_dmaster with reqid:%d\n",reqid));
+ ctdb_ltdb_unlock(ctdb_db, key);
+ return;
+ }
+
+ ctdb_call_local(ctdb_db, &state->call, &header, &data, ctdb->vnn);
ctdb_ltdb_unlock(ctdb_db, state->call.key);
@@ -381,7 +390,7 @@
/* check if the new dmaster is the lmaster, in which case we
skip the dmaster reply */
if (c->dmaster == ctdb->vnn) {
- ctdb_become_dmaster(ctdb, hdr->reqid, data);
+ ctdb_become_dmaster(ctdb_db, hdr->reqid, key, data, c->rsn);
} else {
ctdb_send_dmaster_reply(ctdb_db, &header, key, data, c->dmaster, hdr->reqid);
ctdb_ltdb_unlock(ctdb_db, key);
@@ -434,8 +443,8 @@
/* if we are not the dmaster, then send a redirect to the
requesting node */
if (header.dmaster != ctdb->vnn) {
+ talloc_free(data.dptr);
ctdb_call_send_redirect(ctdb, call.key, c, &header);
- talloc_free(data.dptr);
ctdb_ltdb_unlock(ctdb_db, call.key);
return;
}
@@ -465,7 +474,6 @@
struct ctdb_reply_call);
CTDB_NO_MEMORY_FATAL(ctdb, r);
r->hdr.destnode = hdr->srcnode;
- r->hdr.srcnode = hdr->destnode;
r->hdr.reqid = hdr->reqid;
r->status = call.status;
r->datalen = call.reply_data.dsize;
@@ -498,7 +506,7 @@
if (hdr->reqid != state->reqid) {
/* we found a record but it was the wrong one */
- DEBUG(0, ("Dropped orphaned dmaster reply with reqid:%d\n",hdr->reqid));
+ DEBUG(0, ("Dropped orphaned call reply with reqid:%d\n",hdr->reqid));
return;
}
@@ -525,26 +533,22 @@
void ctdb_reply_dmaster(struct ctdb_context *ctdb, struct ctdb_req_header *hdr)
{
struct ctdb_reply_dmaster *c = (struct ctdb_reply_dmaster *)hdr;
- struct ctdb_call_state *state;
struct ctdb_db_context *ctdb_db;
- TDB_DATA data;
+ TDB_DATA key, data;
int ret;
- state = ctdb_reqid_find(ctdb, hdr->reqid, struct ctdb_call_state);
-
- if (state == NULL) {
- return;
- }
-
- if (hdr->reqid != state->reqid) {
- /* we found a record but it was the wrong one */
- DEBUG(0, ("Dropped orphaned dmaster reply with reqid:%d\n",hdr->reqid));
- return;
- }
-
- ctdb_db = state->ctdb_db;
-
- ret = ctdb_ltdb_lock_requeue(ctdb_db, state->call.key, hdr,
+ ctdb_db = find_ctdb_db(ctdb, c->db_id);
+ if (ctdb_db == NULL) {
+ DEBUG(0,("Unknown db_id 0x%x in ctdb_reply_dmaster\n", c->db_id));
+ return;
+ }
+
+ key.dptr = c->data;
+ key.dsize = c->keylen;
+ data.dptr = &c->data[key.dsize];
+ data.dsize = c->datalen;
+
+ ret = ctdb_ltdb_lock_requeue(ctdb_db, key, hdr,
ctdb_recv_raw_pkt, ctdb);
if (ret == -2) {
return;
@@ -554,10 +558,7 @@
return;
}
- data.dptr = c->data;
- data.dsize = c->datalen;
-
- ctdb_become_dmaster(ctdb, hdr->reqid, data);
+ ctdb_become_dmaster(ctdb_db, hdr->reqid, key, data, c->rsn);
}
@@ -571,12 +572,14 @@
state = ctdb_reqid_find(ctdb, hdr->reqid, struct ctdb_call_state);
if (state == NULL) {
+ DEBUG(0,("vnn %u Invalid reqid %u in ctdb_reply_error\n",
+ ctdb->vnn, hdr->reqid));
return;
}
if (hdr->reqid != state->reqid) {
/* we found a record but it was the wrong one */
- DEBUG(0, ("Dropped orphaned dmaster reply with reqid:%d\n",hdr->reqid));
+ DEBUG(0, ("Dropped orphaned error reply with reqid:%d\n",hdr->reqid));
return;
}
@@ -595,7 +598,7 @@
*/
static int ctdb_call_destructor(struct ctdb_call_state *state)
{
- ctdb_reqid_remove(state->node->ctdb, state->reqid);
+ ctdb_reqid_remove(state->ctdb_db->ctdb, state->reqid);
return 0;
}
@@ -609,7 +612,7 @@
struct ctdb_call_state *state = talloc_get_type(private_data, struct ctdb_call_state);
DEBUG(0,(__location__ " call timeout for reqid %d\n", state->c->hdr.reqid));
state->state = CTDB_CALL_ERROR;
- ctdb_set_error(state->node->ctdb, "ctdb_call %u timed out",
+ ctdb_set_error(state->ctdb_db->ctdb, "ctdb_call %u timed out",
state->c->hdr.reqid);
if (state->async.fn) {
state->async.fn(state);
@@ -650,7 +653,6 @@
talloc_steal(state, data->dptr);
state->state = CTDB_CALL_DONE;
- state->node = ctdb->nodes[ctdb->vnn];
state->call = *call;
state->ctdb_db = ctdb_db;
@@ -711,9 +713,7 @@
state->call.call_data.dptr = &state->c->data[call->key.dsize];
state->call.key.dptr = &state->c->data[0];
- state->node = ctdb->nodes[header->dmaster];
state->state = CTDB_CALL_WAIT;
- state->header = *header;
state->ctdb_db = ctdb_db;
ctdb_queue_packet(ctdb, &state->c->hdr);
@@ -734,16 +734,16 @@
int ctdb_daemon_call_recv(struct ctdb_call_state *state, struct ctdb_call *call)
{
while (state->state < CTDB_CALL_DONE) {
- event_loop_once(state->node->ctdb->ev);
+ event_loop_once(state->ctdb_db->ctdb->ev);
}
if (state->state != CTDB_CALL_DONE) {
- ctdb_set_error(state->node->ctdb, "%s", state->errmsg);
+ ctdb_set_error(state->ctdb_db->ctdb, "%s", state->errmsg);
talloc_free(state);
return -1;
}
if (state->call.reply_data.dsize) {
- call->reply_data.dptr = talloc_memdup(state->node->ctdb,
+ call->reply_data.dptr = talloc_memdup(state->ctdb_db->ctdb,
state->call.reply_data.dptr,
state->call.reply_data.dsize);
call->reply_data.dsize = state->call.reply_data.dsize;
=== modified file 'common/ctdb_client.c'
--- a/common/ctdb_client.c 2007-04-28 15:42:40 +0000
+++ b/common/ctdb_client.c 2007-04-29 14:19:40 +0000
@@ -78,7 +78,7 @@
if (hdr->reqid != state->reqid) {
/* we found a record but it was the wrong one */
- DEBUG(0, ("Dropped orphaned reply with reqid:%d\n",hdr->reqid));
+ DEBUG(0, ("Dropped client call reply with reqid:%d\n",hdr->reqid));
return;
}
@@ -414,7 +414,6 @@
CTDB_NO_MEMORY(ctdb, r);
r->hdr.destnode = vnn;
- r->hdr.srcnode = ctdb->vnn;
r->srvid = srvid;
r->datalen = data.dsize;
memcpy(&r->data[0], data.dptr, data.dsize);
@@ -674,7 +673,6 @@
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;
@@ -1054,3 +1052,24 @@
talloc_free(map);
return nodes;
}
+
+
+/*
+ reset remote status
+ */
+int ctdb_status_reset(struct ctdb_context *ctdb, uint32_t destnode)
+{
+ int ret;
+ TDB_DATA data;
+ int32_t res;
+
+ ZERO_STRUCT(data);
+ ret = ctdb_control(ctdb, destnode, 0,
+ CTDB_CONTROL_STATUS_RESET, data,
+ NULL, NULL, &res);
+ if (ret != 0 || res != 0) {
+ DEBUG(0,(__location__ " ctdb_control for reset status failed\n"));
+ return -1;
+ }
+ return 0;
+}
=== modified file 'common/ctdb_control.c'
--- a/common/ctdb_control.c 2007-04-28 13:15:21 +0000
+++ b/common/ctdb_control.c 2007-04-29 14:19:40 +0000
@@ -80,6 +80,12 @@
return 0;
}
+ case CTDB_CONTROL_STATUS_RESET: {
+ CHECK_CONTROL_DATA_SIZE(0);
+ ZERO_STRUCT(ctdb->status);
+ return 0;
+ }
+
case CTDB_CONTROL_GETVNNMAP: {
uint32_t i, len;
CHECK_CONTROL_DATA_SIZE(0);
@@ -242,6 +248,8 @@
state = ctdb_reqid_find(ctdb, hdr->reqid, struct ctdb_control_state);
if (state == NULL) {
+ DEBUG(0,("vnn %u Invalid reqid %u in ctdb_reply_control\n",
+ ctdb->vnn, hdr->reqid));
return;
}
=== modified file 'common/ctdb_daemon.c'
--- a/common/ctdb_daemon.c 2007-04-28 13:15:21 +0000
+++ b/common/ctdb_daemon.c 2007-04-29 14:19:40 +0000
@@ -673,6 +673,48 @@
return 0;
}
+
+/*
+ start the protocol going as a daemon
+*/
+int ctdb_start_daemon(struct ctdb_context *ctdb)
+{
+ int res;
+ struct fd_event *fde;
+ const char *domain_socket_name;
+
+ /* get rid of any old sockets */
+ unlink(ctdb->daemon.name);
+
+ /* create a unix domain stream socket to listen to */
+ res = ux_socket_bind(ctdb);
+ if (res!=0) {
+ DEBUG(0,(__location__ " Failed to open CTDB unix domain socket\n"));
+ exit(10);
+ }
+
+ if (fork()) {
+ return 0;
+ }
+
+ tdb_reopen_all(False);
+
+ setsid();
+ block_signal(SIGPIPE);
+ block_signal(SIGCHLD);
+
+ /* ensure the socket is deleted on exit of the daemon */
+ domain_socket_name = talloc_strdup(talloc_autofree_context(), ctdb->daemon.name);
+ talloc_set_destructor(domain_socket_name, unlink_destructor);
+
+ ctdb->ev = event_context_init(NULL);
+ fde = event_add_fd(ctdb->ev, ctdb, ctdb->daemon.sd, EVENT_FD_READ,
+ ctdb_accept_client, ctdb);
+ ctdb_main_loop(ctdb);
+
+ return 0;
+}
+
/*
allocate a packet for use in client<->daemon communication
*/
@@ -685,6 +727,7 @@
int size;
struct ctdb_req_header *hdr;
size = ((length+1)+(CTDB_DS_ALIGNMENT-1)) & ~(CTDB_DS_ALIGNMENT-1);
+
hdr = (struct ctdb_req_header *)talloc_size(mem_ctx, size);
if (hdr == NULL) {
DEBUG(0,("Unable to allocate packet for operation %u of length %u\n",
@@ -692,11 +735,12 @@
return NULL;
}
talloc_set_name_const(hdr, type);
- memset(hdr, 0, slength);
+ memset(hdr, 0, size);
hdr->operation = operation;
- hdr->length = length;
+ hdr->length = size;
hdr->ctdb_magic = CTDB_MAGIC;
hdr->ctdb_version = CTDB_VERSION;
+ hdr->srcnode = ctdb->vnn;
if (ctdb->vnn_map) {
hdr->generation = ctdb->vnn_map->generation;
}
@@ -724,9 +768,9 @@
return NULL;
}
talloc_set_name_const(hdr, type);
- memset(hdr, 0, slength);
+ memset(hdr, 0, size);
hdr->operation = operation;
- hdr->length = length;
+ hdr->length = size;
hdr->ctdb_magic = CTDB_MAGIC;
hdr->ctdb_version = CTDB_VERSION;
hdr->generation = ctdb->vnn_map->generation;
=== modified file 'common/ctdb_io.c'
--- a/common/ctdb_io.c 2007-04-16 00:21:44 +0000
+++ b/common/ctdb_io.c 2007-04-29 14:19:40 +0000
@@ -64,8 +64,10 @@
ssize_t nread;
uint8_t *data, *data_base;
- if (ioctl(queue->fd, FIONREAD, &num_ready) != 0 ||
- num_ready == 0) {
+ if (ioctl(queue->fd, FIONREAD, &num_ready) != 0) {
+ return;
+ }
+ if (num_ready == 0) {
/* the descriptor has been closed */
goto failed;
}
@@ -75,11 +77,14 @@
num_ready + queue->partial.length);
if (queue->partial.data == NULL) {
+ DEBUG(0,("read error alloc failed for %u\n",
+ num_ready + queue->partial.length));
goto failed;
}
nread = read(queue->fd, queue->partial.data + queue->partial.length, num_ready);
if (nread <= 0) {
+ DEBUG(0,("read error nread=%d\n", nread));
goto failed;
}
@@ -106,6 +111,7 @@
len = *(uint32_t *)data;
d2 = talloc_memdup(queue, data, len);
if (d2 == NULL) {
+ DEBUG(0,("read error memdup failed for %u\n", len));
/* sigh */
goto failed;
}
@@ -122,6 +128,8 @@
} else {
queue->partial.data = talloc_memdup(queue, data, nread);
if (queue->partial.data == NULL) {
+ DEBUG(0,("read error memdup partial failed for %u\n",
+ nread));
goto failed;
}
queue->partial.length = nread;
@@ -155,8 +163,11 @@
while (queue->out_queue) {
struct ctdb_queue_pkt *pkt = queue->out_queue;
ssize_t n;
-
- n = write(queue->fd, pkt->data, pkt->length);
+ if (queue->ctdb->flags & CTDB_FLAG_TORTURE) {
+ n = write(queue->fd, pkt->data, 1);
+ } else {
+ n = write(queue->fd, pkt->data, pkt->length);
+ }
if (n == -1 && errno != EAGAIN && errno != EWOULDBLOCK) {
event_add_timed(queue->ctdb->ev, queue, timeval_zero(),
@@ -213,7 +224,8 @@
/* if the queue is empty then try an immediate write, avoiding
queue overhead. This relies on non-blocking sockets */
- if (queue->out_queue == NULL && queue->fd != -1) {
+ if (queue->out_queue == NULL && queue->fd != -1 &&
+ !(queue->ctdb->flags & CTDB_FLAG_TORTURE)) {
ssize_t n = write(queue->fd, data, length2);
if (n == -1 && errno != EAGAIN && errno != EWOULDBLOCK) {
event_add_timed(queue->ctdb->ev, queue, timeval_zero(),
=== modified file 'common/ctdb_util.c'
--- a/common/ctdb_util.c 2007-04-28 08:50:32 +0000
+++ b/common/ctdb_util.c 2007-04-29 14:19:40 +0000
@@ -129,6 +129,51 @@
}
}
+#if 0
+struct idr_fake {
+ uint32_t size;
+ void **ptrs;
+};
+
+static void idr_fake_init(struct ctdb_context *ctdb)
+{
+ if (ctdb->fidr) return;
+ ctdb->fidr = talloc(ctdb, struct idr_fake);
+ ctdb->fidr->size = 0x10000;
+ ctdb->fidr->ptrs = talloc_zero_array(ctdb->fidr, void *,
+ ctdb->fidr->size);
+}
+
+uint32_t ctdb_reqid_new(struct ctdb_context *ctdb, void *state)
+{
+ uint32_t i;
+ idr_fake_init(ctdb);
+ for (i=0;i<ctdb->fidr->size;i++) {
+ if (ctdb->fidr->ptrs[i] == NULL) {
+ ctdb->fidr->ptrs[i] = state;
+ return i;
+ }
+ }
+ return (uint32_t)-1;
+}
+
+void *_ctdb_reqid_find(struct ctdb_context *ctdb, uint32_t reqid, const char *type, const char *location)
+{
+ idr_fake_init(ctdb);
+ if (ctdb->fidr->ptrs[reqid] == NULL) {
+ DEBUG(0,("bad fidr id %u\n", reqid));
+ }
+ return ctdb->fidr->ptrs[reqid];
+}
+
+
+void ctdb_reqid_remove(struct ctdb_context *ctdb, uint32_t reqid)
+{
+ idr_fake_init(ctdb);
+ ctdb->fidr->ptrs[reqid] = NULL;
+}
+
+#else
uint32_t ctdb_reqid_new(struct ctdb_context *ctdb, void *state)
{
uint32_t id;
@@ -161,3 +206,4 @@
}
}
+#endif
=== modified file 'direct/ctdbd.c'
--- a/direct/ctdbd.c 2007-04-18 23:14:25 +0000
+++ b/direct/ctdbd.c 2007-04-29 14:19:40 +0000
@@ -56,7 +56,6 @@
int opt;
const char **extra_argv;
int extra_argc = 0;
- int ret;
poptContext pc;
struct event_context *ev;
@@ -91,22 +90,13 @@
ctdb_db = ctdb_attach(ctdb, tok, TDB_DEFAULT,
O_RDWR|O_CREAT|O_TRUNC, 0666);
if (!ctdb_db) {
- printf("ctdb_attach to '%s'failed - %s\n", tok,
- ctdb_errstr(ctdb));
+ DEBUG(0,("ctdb_attach to '%s'failed - %s\n", tok,
+ ctdb_errstr(ctdb)));
exit(1);
}
- printf("Attached to database '%s'\n", tok);
- }
-
- /* start the protocol running */
- ret = ctdb_start(ctdb);
-
-/* event_loop_wait(ev);*/
- while (1) {
- event_loop_once(ev);
- }
-
- /* shut it down */
- talloc_free(ev);
- return 0;
+ DEBUG(1, ("Attached to database '%s'\n", tok));
+ }
+
+ /* start the protocol running (as a child) */
+ return ctdb_start_daemon(ctdb);
}
=== modified file 'include/ctdb.h'
--- a/include/ctdb.h 2007-04-28 15:42:40 +0000
+++ b/include/ctdb.h 2007-04-29 14:19:40 +0000
@@ -107,6 +107,7 @@
start the ctdb protocol
*/
int ctdb_start(struct ctdb_context *ctdb);
+int ctdb_start_daemon(struct ctdb_context *ctdb);
/*
attach to a ctdb database
@@ -256,4 +257,6 @@
uint32_t *ctdb_get_connected_nodes(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx,
uint32_t *num_nodes);
+int ctdb_status_reset(struct ctdb_context *ctdb, uint32_t destnode);
+
#endif
=== modified file 'include/ctdb_private.h'
--- a/include/ctdb_private.h 2007-04-28 16:18:33 +0000
+++ b/include/ctdb_private.h 2007-04-29 14:19:40 +0000
@@ -195,6 +195,7 @@
struct ctdb_status status;
struct ctdb_vnn_map *vnn_map;
uint32_t num_clients;
+ struct idr_fake *fidr;
};
struct ctdb_db_context {
@@ -251,7 +252,8 @@
CTDB_CONTROL_GET_DEBUG,
CTDB_CONTROL_SET_DEBUG,
CTDB_CONTROL_GET_DBMAP,
- CTDB_CONTROL_GET_NODEMAP};
+ CTDB_CONTROL_GET_NODEMAP,
+ CTDB_CONTROL_STATUS_RESET};
enum call_state {CTDB_CALL_WAIT, CTDB_CALL_DONE, CTDB_CALL_ERROR};
@@ -263,10 +265,8 @@
uint32_t reqid;
struct ctdb_req_call *c;
struct ctdb_db_context *ctdb_db;
- struct ctdb_node *node;
const char *errmsg;
struct ctdb_call call;
- struct ctdb_ltdb_header header;
struct {
void (*fn)(struct ctdb_call_state *);
void *private_data;
@@ -347,6 +347,7 @@
struct ctdb_req_dmaster {
struct ctdb_req_header hdr;
uint32_t db_id;
+ uint64_t rsn;
uint32_t dmaster;
uint32_t keylen;
uint32_t datalen;
@@ -355,6 +356,9 @@
struct ctdb_reply_dmaster {
struct ctdb_req_header hdr;
+ uint32_t db_id;
+ uint64_t rsn;
+ uint32_t keylen;
uint32_t datalen;
uint8_t data[1];
};
=== modified file 'tools/ctdb_control.c'
--- a/tools/ctdb_control.c 2007-04-28 16:18:33 +0000
+++ b/tools/ctdb_control.c 2007-04-28 17:13:36 +0000
@@ -36,6 +36,7 @@
printf(" ping\n");
printf(" process-exists <vnn:pid> see if a process exists\n");
printf(" status <vnn|all> show ctdb status on a node\n");
+ printf(" statusreset <vnn|all> reset status on a node\n");
printf(" debug <vnn|all> <level> set ctdb debug level on a node\n");
printf(" debuglevel display ctdb debug levels\n");
printf(" getvnnmap <vnn> display ctdb vnnmap\n");
@@ -170,6 +171,56 @@
return 0;
}
+
+/*
+ reset status on all nodes
+ */
+static int control_status_reset_all(struct ctdb_context *ctdb)
+{
+ int ret, i;
+ uint32_t *nodes;
+ uint32_t num_nodes;
+
+ nodes = ctdb_get_connected_nodes(ctdb, ctdb, &num_nodes);
+ CTDB_NO_MEMORY(ctdb, nodes);
+
+ for (i=0;i<num_nodes;i++) {
+ ret = ctdb_status_reset(ctdb, nodes[i]);
+ if (ret != 0) {
+ printf("Unable to reset status on node %u\n", nodes[i]);
+ return ret;
+ }
+ }
+ talloc_free(nodes);
+ return 0;
+}
+
+
+/*
+ reset remote ctdb status
+ */
+static int control_status_reset(struct ctdb_context *ctdb, int argc, const char **argv)
+{
+ uint32_t vnn;
+ int ret;
+ if (argc < 1) {
+ usage();
+ }
+
+ if (strcmp(argv[0], "all") == 0) {
+ return control_status_reset_all(ctdb);
+ }
+
+ vnn = strtoul(argv[0], NULL, 0);
+
+ ret = ctdb_status_reset(ctdb, vnn);
+ if (ret != 0) {
+ printf("Unable to reset status on node %u\n", vnn);
+ return ret;
+ }
+ return 0;
+}
+
/*
display remote ctdb vnn map
*/
@@ -441,6 +492,8 @@
ret = control_process_exists(ctdb, extra_argc-1, extra_argv+1);
} else if (strcmp(control, "status") == 0) {
ret = control_status(ctdb, extra_argc-1, extra_argv+1);
+ } else if (strcmp(control, "statusreset") == 0) {
+ ret = control_status_reset(ctdb, extra_argc-1, extra_argv+1);
} else if (strcmp(control, "getvnnmap") == 0) {
ret = control_getvnnmap(ctdb, extra_argc-1, extra_argv+1);
} else if (strcmp(control, "getdbmap") == 0) {
More information about the samba-cvs
mailing list