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:
commit
325f321409
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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];
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user