1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-22 02:50:28 +03:00

merge from tridge

(This used to be ctdb commit 8c5e6836280499243c0cd247093844a891f00da3)
This commit is contained in:
Ronnie Sahlberg 2007-05-10 09:44:28 +10:00
commit 325f321409
7 changed files with 133 additions and 73 deletions

View File

@ -89,7 +89,7 @@ struct poptOption popt_ctdb_cmdline[] = {
struct ctdb_context *ctdb_cmdline_init(struct event_context *ev)
{
struct ctdb_context *ctdb;
int i, ret;
int ret;
if (ctdb_cmdline.nlist == NULL) {
printf("You must provide a node list with --nlist\n");
@ -156,26 +156,6 @@ struct ctdb_context *ctdb_cmdline_init(struct event_context *ev)
}
}
/* initialize the vnn mapping table */
/*
XXX we currently initialize it to the maximum number of nodes to
XXX make it behave the same way as previously.
XXX Once we have recovery working we should initialize this always to
XXX generation==0 (==invalid) and let the recovery tool populate this
XXX table for the daemons.
*/
ctdb->vnn_map = talloc_zero_size(ctdb, offsetof(struct ctdb_vnn_map, map) + 4*ctdb->num_nodes);
if (ctdb->vnn_map == NULL) {
DEBUG(0,(__location__ " Unable to allocate vnn_map structure\n"));
exit(1);
}
ctdb->vnn_map->generation = 1;
ctdb->vnn_map->size = ctdb->num_nodes;
for(i=0;i<ctdb->vnn_map->size;i++){
ctdb->vnn_map->map[i] = i%ctdb->num_nodes;
}
return ctdb;
}

View File

@ -152,6 +152,26 @@ int ctdb_set_nlist(struct ctdb_context *ctdb, const char *nlist)
return -1;
}
}
/* initialize the vnn mapping table now that we have num_nodes setup */
/*
XXX we currently initialize it to the maximum number of nodes to
XXX make it behave the same way as previously.
XXX Once we have recovery working we should initialize this always to
XXX generation==0 (==invalid) and let the recovery tool populate this
XXX table for the daemons.
*/
ctdb->vnn_map = talloc(ctdb, struct ctdb_vnn_map);
CTDB_NO_MEMORY(ctdb, ctdb->vnn_map);
ctdb->vnn_map->generation = 1;
ctdb->vnn_map->size = ctdb->num_nodes;
ctdb->vnn_map->map = talloc_array(ctdb->vnn_map, uint32_t, ctdb->vnn_map->size);
CTDB_NO_MEMORY(ctdb, ctdb->vnn_map->map);
for(i=0;i<ctdb->vnn_map->size;i++) {
ctdb->vnn_map->map[i] = i;
}
talloc_free(lines);
return 0;

View File

@ -808,6 +808,7 @@ int ctdb_ctrl_getvnnmap(struct ctdb_context *ctdb, struct timeval timeout, uint3
int ret;
TDB_DATA data, outdata;
int32_t res;
struct ctdb_vnn_map_wire *map;
ZERO_STRUCT(data);
ret = ctdb_control(ctdb, destnode, 0,
@ -817,8 +818,22 @@ int ctdb_ctrl_getvnnmap(struct ctdb_context *ctdb, struct timeval timeout, uint3
DEBUG(0,(__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)) {
DEBUG(0,("Bad vnn map size received in ctdb_ctrl_getvnnmap\n"));
return -1;
}
*vnnmap = (struct ctdb_vnn_map *)talloc_memdup(mem_ctx, outdata.dptr, outdata.dsize);
(*vnnmap) = talloc(mem_ctx, struct ctdb_vnn_map);
CTDB_NO_MEMORY(ctdb, *vnnmap);
(*vnnmap)->generation = map->generation;
(*vnnmap)->size = map->size;
(*vnnmap)->map = talloc_array(*vnnmap, uint32_t, map->size);
CTDB_NO_MEMORY(ctdb, (*vnnmap)->map);
memcpy((*vnnmap)->map, map->map, sizeof(uint32_t)*map->size);
return 0;
}
@ -975,9 +990,19 @@ int ctdb_ctrl_setvnnmap(struct ctdb_context *ctdb, struct timeval timeout, uint3
int ret;
TDB_DATA data, outdata;
int32_t res;
struct ctdb_vnn_map_wire *map;
size_t len;
data.dsize = offsetof(struct ctdb_vnn_map, map) + 4*vnnmap->size;
data.dptr = (unsigned char *)vnnmap;
len = offsetof(struct ctdb_vnn_map_wire, map) + sizeof(uint32_t)*vnnmap->size;
map = talloc_size(mem_ctx, len);
CTDB_NO_MEMORY_VOID(ctdb, map);
map->generation = vnnmap->generation;
map->size = vnnmap->size;
memcpy(map->map, vnnmap->map, sizeof(uint32_t)*map->size);
data.dsize = len;
data.dptr = (uint8_t *)map;
ret = ctdb_control(ctdb, destnode, 0,
CTDB_CONTROL_SETVNNMAP, 0, data,
@ -987,6 +1012,8 @@ int ctdb_ctrl_setvnnmap(struct ctdb_context *ctdb, struct timeval timeout, uint3
return -1;
}
talloc_free(map);
return 0;
}

View File

@ -334,6 +334,30 @@ static void daemon_call_from_client_callback(struct ctdb_call_state *state)
}
struct ctdb_client_retry {
struct ctdb_client *client;
struct ctdb_req_call *call;
};
static void daemon_request_call_from_client(struct ctdb_client *client,
struct ctdb_req_call *c);
/*
triggered after a one second delay, retrying a client packet
that was deferred because of the daemon being in recovery mode
*/
static void retry_client_packet(struct event_context *ev, struct timed_event *te,
struct timeval t, void *private_data)
{
struct ctdb_client_retry *retry = talloc_get_type(private_data, struct ctdb_client_retry);
daemon_request_call_from_client(retry->client, retry->call);
talloc_free(retry);
}
/*
this is called when the ctdb daemon received a ctdb request call
from a local client over the unix domain socket
@ -350,6 +374,29 @@ static void daemon_request_call_from_client(struct ctdb_client *client,
int ret;
struct ctdb_context *ctdb = client->ctdb;
if (ctdb->recovery_mode != CTDB_RECOVERY_NORMAL) {
struct ctdb_client_retry *retry;
DEBUG(0,(__location__ " ctdb call %u from client"
" while we are in recovery mode. Deferring it\n",
c->hdr.reqid));
/* hang the event and the structure off client */
retry = talloc(client, struct ctdb_client_retry);
CTDB_NO_MEMORY_VOID(ctdb, retry);
retry->client = client;
retry->call = c;
/* this ensures that after the retry happens we
eventually free this request */
talloc_steal(retry, c);
event_add_timed(ctdb->ev, retry, timeval_current_ofs(1,0), retry_client_packet, retry);
return;
}
ctdb->status.total_calls++;
ctdb->status.pending_calls++;
@ -428,26 +475,6 @@ static void daemon_request_call_from_client(struct ctdb_client *client,
}
struct ctdb_client_retry {
void *p;
uint8_t *data;
uint32_t nread;
};
/*
triggered after a one second delay, retrying a client packet
that was deferred because of the daemon being in recovery mode
*/
static void retry_client_packet(struct event_context *ev, struct timed_event *te, struct timeval t, void *private_data)
{
struct ctdb_client_retry *retry = talloc_get_type(private_data, struct ctdb_client_retry);
daemon_incoming_packet(retry->p, retry->data, retry->nread);
talloc_free(retry);
}
static void daemon_request_control_from_client(struct ctdb_client *client,
struct ctdb_req_control *c);
@ -478,27 +505,6 @@ static void daemon_incoming_packet(void *p, uint8_t *data, uint32_t nread)
switch (hdr->operation) {
case CTDB_REQ_CALL:
if (ctdb->recovery_mode != CTDB_RECOVERY_NORMAL) {
struct ctdb_client_retry *retry;
DEBUG(0,(__location__ " ctdb request %d"
" length %d from client"
" while we are in recovery mode. Deferring it\n",
hdr->reqid, hdr->length));
/* hang the event and the structure off client */
retry = talloc(client, struct ctdb_client_retry);
retry->p = p;
retry->data = data;
retry->nread = nread;
/* cant let the mem_ctx free hdr below */
talloc_steal(retry, hdr);
event_add_timed(ctdb->ev, retry, timeval_current_ofs(1,0), retry_client_packet, retry);
break;
}
ctdb->status.client.req_call++;
daemon_request_call_from_client(client, (struct ctdb_req_call *)hdr);
break;
@ -715,7 +721,6 @@ int ctdb_start(struct ctdb_context *ctdb)
close(fd[1]);
ctdb->ev = event_context_init(NULL);
fde = event_add_fd(ctdb->ev, ctdb, fd[0], EVENT_FD_READ|EVENT_FD_AUTOCLOSE, ctdb_read_from_parent, &fd[0]);
fde = event_add_fd(ctdb->ev, ctdb, ctdb->daemon.sd, EVENT_FD_READ|EVENT_FD_AUTOCLOSE, ctdb_accept_client, ctdb);

View File

@ -32,9 +32,19 @@ int
ctdb_control_getvnnmap(struct ctdb_context *ctdb, uint32_t opcode, TDB_DATA indata, TDB_DATA *outdata)
{
CHECK_CONTROL_DATA_SIZE(0);
struct ctdb_vnn_map_wire *map;
size_t len;
outdata->dsize = offsetof(struct ctdb_vnn_map, map) + 4*ctdb->vnn_map->size;
outdata->dptr = (unsigned char *)ctdb->vnn_map;
len = offsetof(struct ctdb_vnn_map_wire, map) + sizeof(uint32_t)*ctdb->vnn_map->size;
map = talloc_size(outdata, len);
CTDB_NO_MEMORY_VOID(ctdb, map);
map->generation = ctdb->vnn_map->generation;
map->size = ctdb->vnn_map->size;
memcpy(map->map, ctdb->vnn_map->map, sizeof(uint32_t)*map->size);
outdata->dsize = len;
outdata->dptr = (uint8_t *)map;
return 0;
}
@ -42,12 +52,19 @@ ctdb_control_getvnnmap(struct ctdb_context *ctdb, uint32_t opcode, TDB_DATA inda
int
ctdb_control_setvnnmap(struct ctdb_context *ctdb, uint32_t opcode, TDB_DATA indata, TDB_DATA *outdata)
{
if (ctdb->vnn_map) {
talloc_free(ctdb->vnn_map);
ctdb->vnn_map = NULL;
}
struct ctdb_vnn_map_wire *map = (struct ctdb_vnn_map_wire *)indata.dptr;
ctdb->vnn_map = (struct ctdb_vnn_map *)talloc_memdup(ctdb, indata.dptr, indata.dsize);
talloc_free(ctdb->vnn_map);
ctdb->vnn_map = talloc(ctdb, struct ctdb_vnn_map);
CTDB_NO_MEMORY(ctdb, ctdb->vnn_map);
ctdb->vnn_map->generation = map->generation;
ctdb->vnn_map->size = map->size;
ctdb->vnn_map->map = talloc_array(ctdb->vnn_map, uint32_t, map->size);
CTDB_NO_MEMORY(ctdb, ctdb->vnn_map->map);
memcpy(ctdb->vnn_map->map, map->map, sizeof(uint32_t)*map->size);
return 0;
}

View File

@ -190,6 +190,15 @@ struct ctdb_status {
/* table that contains the mapping between a hash value and lmaster
*/
struct ctdb_vnn_map {
uint32_t generation;
uint32_t size;
uint32_t *map;
};
/*
a wire representation of the vnn map
*/
struct ctdb_vnn_map_wire {
uint32_t generation;
uint32_t size;
uint32_t map[1];

View File

@ -31,4 +31,6 @@ $VALGRIND bin/ctdb_control attach test2.tdb || exit 1
echo "Testing getdbmap"
$VALGRIND bin/ctdb_control getdbmap 0 || exit 1
echo "All done"
killall -q ctdbd