mirror of
https://github.com/samba-team/samba.git
synced 2025-02-03 13:47:25 +03:00
merge from tridge
(This used to be ctdb commit d045dff2c68d6d7fcf8e7c5037908fab3d55a16f)
This commit is contained in:
commit
d7c8c15d72
@ -217,6 +217,21 @@ uint32_t ctdb_get_num_nodes(struct ctdb_context *ctdb)
|
||||
return ctdb->num_nodes;
|
||||
}
|
||||
|
||||
/*
|
||||
return the number of connected nodes
|
||||
*/
|
||||
uint32_t ctdb_get_num_connected_nodes(struct ctdb_context *ctdb)
|
||||
{
|
||||
int i;
|
||||
uint32_t count=0;
|
||||
for (i=0;i<ctdb->vnn_map->size;i++) {
|
||||
if (ctdb->nodes[i]->flags & NODE_FLAGS_CONNECTED) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
called by the transport layer when a packet comes in
|
||||
|
@ -705,13 +705,6 @@ int ctdb_control(struct ctdb_context *ctdb, uint32_t destnode, uint64_t srvid,
|
||||
ctdb_socket_connect(ctdb);
|
||||
}
|
||||
|
||||
/* if the caller specified a timeout it makes no sense for the
|
||||
daemon to requeue the packet if the destination is unavailable
|
||||
*/
|
||||
if (timeout) {
|
||||
flags |= CTDB_CTRL_FLAG_NOREQUEUE;
|
||||
}
|
||||
|
||||
state = talloc_zero(ctdb, struct ctdb_client_control_state);
|
||||
CTDB_NO_MEMORY(ctdb, state);
|
||||
|
||||
|
@ -32,6 +32,7 @@ struct ctdb_control_state {
|
||||
uint32_t reqid;
|
||||
ctdb_control_callback_fn_t callback;
|
||||
void *private_data;
|
||||
unsigned flags;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -362,19 +363,15 @@ static void ctdb_control_timeout(struct event_context *ev, struct timed_event *t
|
||||
struct timeval t, void *private_data)
|
||||
{
|
||||
struct ctdb_control_state *state = talloc_get_type(private_data, struct ctdb_control_state);
|
||||
struct ctdb_req_control *c = (struct ctdb_req_control *)state->private_data;
|
||||
TALLOC_CTX *tmp_ctx = talloc_new(ev);
|
||||
|
||||
state->ctdb->status.timeouts.control++;
|
||||
|
||||
talloc_steal(tmp_ctx, state);
|
||||
|
||||
/* Dont retry the control if the caller asked for NOREQUEUE */
|
||||
if (!(c->flags & CTDB_CTRL_FLAG_NOREQUEUE)) {
|
||||
state->callback(state->ctdb, -1, tdb_null,
|
||||
"ctdb_control timed out",
|
||||
state->private_data);
|
||||
}
|
||||
state->callback(state->ctdb, -1, tdb_null,
|
||||
"ctdb_control timed out",
|
||||
state->private_data);
|
||||
talloc_free(tmp_ctx);
|
||||
}
|
||||
|
||||
@ -398,6 +395,15 @@ int ctdb_daemon_send_control(struct ctdb_context *ctdb, uint32_t destnode,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (destnode != CTDB_BROADCAST_VNNMAP && destnode != CTDB_BROADCAST_VNNMAP &&
|
||||
(!ctdb_validate_vnn(ctdb, destnode) ||
|
||||
!(ctdb->nodes[destnode]->flags & NODE_FLAGS_CONNECTED))) {
|
||||
if (!(flags & CTDB_CTRL_FLAG_NOREPLY)) {
|
||||
callback(ctdb, -1, tdb_null, "ctdb_control to disconnected node", private_data);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* the state is made a child of private_data if possible. This means any reply
|
||||
will be discarded if the private_data goes away */
|
||||
state = talloc(private_data?private_data:ctdb, struct ctdb_control_state);
|
||||
@ -407,6 +413,7 @@ int ctdb_daemon_send_control(struct ctdb_context *ctdb, uint32_t destnode,
|
||||
state->callback = callback;
|
||||
state->private_data = private_data;
|
||||
state->ctdb = ctdb;
|
||||
state->flags = flags;
|
||||
|
||||
talloc_set_destructor(state, ctdb_control_destructor);
|
||||
|
||||
|
@ -447,6 +447,8 @@ static int do_recovery(struct ctdb_context *ctdb,
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* send a message to all clients telling them that the cluster has been reconfigured */
|
||||
ctdb_send_message(ctdb, CTDB_BROADCAST_ALL, CTDB_SRVID_RECONFIGURE, tdb_null);
|
||||
|
||||
DEBUG(0, (__location__ " Recovery complete\n"));
|
||||
return 0;
|
||||
@ -465,7 +467,6 @@ static int send_election_request(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx,
|
||||
uint64_t srvid;
|
||||
|
||||
srvid = CTDB_SRVTYPE_RECOVERY;
|
||||
srvid <<= 32;
|
||||
|
||||
emsg.vnn = vnn;
|
||||
|
||||
@ -857,7 +858,6 @@ int ctdb_start_recoverd(struct ctdb_context *ctdb)
|
||||
|
||||
/* register a message port for recovery elections */
|
||||
srvid = CTDB_SRVTYPE_RECOVERY;
|
||||
srvid <<= 32;
|
||||
ctdb_set_message_handler(ctdb, srvid, election_handler, NULL);
|
||||
|
||||
monitor_cluster(ctdb);
|
||||
|
@ -365,7 +365,7 @@ int32_t ctdb_control_traverse_data(struct ctdb_context *ctdb, TDB_DATA data, TDB
|
||||
|
||||
if (key.dsize == 0 && data.dsize == 0) {
|
||||
state->null_count++;
|
||||
if (state->null_count != ctdb_get_num_nodes(ctdb)) {
|
||||
if (state->null_count != ctdb_get_num_connected_nodes(ctdb)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -56,10 +56,16 @@ struct ctdb_call_info {
|
||||
a message handler ID meaning "give me all messages"
|
||||
*/
|
||||
#define CTDB_SRVID_ALL (~(uint64_t)0)
|
||||
|
||||
/*
|
||||
srvid type : RECOVERY
|
||||
*/
|
||||
#define CTDB_SRVTYPE_RECOVERY 0x64766372
|
||||
#define CTDB_SRVTYPE_RECOVERY 0xF100000000000000LL
|
||||
|
||||
/*
|
||||
a message handler ID meaning that the cluster has been reconfigured
|
||||
*/
|
||||
#define CTDB_SRVID_RECONFIGURE 0xF200000000000000LL
|
||||
|
||||
struct event_context;
|
||||
|
||||
|
@ -295,8 +295,8 @@ struct ctdb_db_context {
|
||||
re-issue the call */
|
||||
#define CTDB_CALL_TIMEOUT 2
|
||||
|
||||
/* timeout for ctdb control calls */
|
||||
#define CTDB_CONTROL_TIMEOUT 10
|
||||
/* maximum timeout for ctdb control calls */
|
||||
#define CTDB_CONTROL_TIMEOUT 60
|
||||
|
||||
/* timeout for ctdb traverse calls. When this is reached we cut short
|
||||
the traverse */
|
||||
@ -520,7 +520,6 @@ struct ctdb_req_control {
|
||||
uint64_t srvid;
|
||||
uint32_t client_id;
|
||||
#define CTDB_CTRL_FLAG_NOREPLY 1
|
||||
#define CTDB_CTRL_FLAG_NOREQUEUE 2
|
||||
uint32_t flags;
|
||||
uint32_t datalen;
|
||||
uint8_t data[1];
|
||||
@ -803,4 +802,6 @@ int32_t ctdb_control_thaw(struct ctdb_context *ctdb);
|
||||
|
||||
int ctdb_start_recoverd(struct ctdb_context *ctdb);
|
||||
|
||||
uint32_t ctdb_get_num_connected_nodes(struct ctdb_context *ctdb);
|
||||
|
||||
#endif
|
||||
|
@ -33,6 +33,7 @@
|
||||
|
||||
#include "includes.h"
|
||||
#include "system/filesys.h"
|
||||
#include "system/network.h"
|
||||
#include "lib/util/dlinklist.h"
|
||||
#include "lib/events/events.h"
|
||||
#include "lib/events/events_internal.h"
|
||||
@ -48,6 +49,9 @@ struct aio_event_context {
|
||||
/* a pointer back to the generic event_context */
|
||||
struct event_context *ev;
|
||||
|
||||
/* list of filedescriptor events */
|
||||
struct fd_event *fd_events;
|
||||
|
||||
/* number of registered fd event handlers */
|
||||
int num_fd_events;
|
||||
|
||||
@ -61,6 +65,7 @@ struct aio_event_context {
|
||||
|
||||
int epoll_fd;
|
||||
int is_epoll_set;
|
||||
pid_t pid;
|
||||
};
|
||||
|
||||
struct aio_event {
|
||||
@ -92,6 +97,33 @@ static int aio_ctx_destructor(struct aio_event_context *aio_ev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void epoll_add_event(struct aio_event_context *aio_ev, struct fd_event *fde);
|
||||
|
||||
/*
|
||||
reopen the epoll handle when our pid changes
|
||||
see http://junkcode.samba.org/ftp/unpacked/junkcode/epoll_fork.c for an
|
||||
demonstration of why this is needed
|
||||
*/
|
||||
static void epoll_check_reopen(struct aio_event_context *aio_ev)
|
||||
{
|
||||
struct fd_event *fde;
|
||||
|
||||
if (aio_ev->pid == getpid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
close(aio_ev->epoll_fd);
|
||||
aio_ev->epoll_fd = epoll_create(MAX_AIO_QUEUE_DEPTH);
|
||||
if (aio_ev->epoll_fd == -1) {
|
||||
DEBUG(0,("Failed to recreate epoll handle after fork\n"));
|
||||
return;
|
||||
}
|
||||
aio_ev->pid = getpid();
|
||||
for (fde=aio_ev->fd_events;fde;fde=fde->next) {
|
||||
epoll_add_event(aio_ev, fde);
|
||||
}
|
||||
}
|
||||
|
||||
#define EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT (1<<0)
|
||||
#define EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR (1<<1)
|
||||
#define EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR (1<<2)
|
||||
@ -127,6 +159,9 @@ static void epoll_add_event(struct aio_event_context *aio_ev, struct fd_event *f
|
||||
static void epoll_del_event(struct aio_event_context *aio_ev, struct fd_event *fde)
|
||||
{
|
||||
struct epoll_event event;
|
||||
|
||||
DLIST_REMOVE(aio_ev->fd_events, fde);
|
||||
|
||||
if (aio_ev->epoll_fd == -1) return;
|
||||
|
||||
fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
|
||||
@ -185,6 +220,7 @@ static void epoll_change_event(struct aio_event_context *aio_ev, struct fd_event
|
||||
|
||||
/* there's no aio_event attached to the fde */
|
||||
if (want_read || (want_write && !got_error)) {
|
||||
DLIST_ADD(aio_ev->fd_events, fde);
|
||||
epoll_add_event(aio_ev, fde);
|
||||
return;
|
||||
}
|
||||
@ -334,6 +370,7 @@ static int aio_event_context_init(struct event_context *ev)
|
||||
talloc_free(aio_ev);
|
||||
return -1;
|
||||
}
|
||||
aio_ev->pid = getpid();
|
||||
|
||||
talloc_set_destructor(aio_ev, aio_ctx_destructor);
|
||||
|
||||
@ -382,6 +419,8 @@ static struct fd_event *aio_event_add_fd(struct event_context *ev, TALLOC_CTX *m
|
||||
struct aio_event_context);
|
||||
struct fd_event *fde;
|
||||
|
||||
epoll_check_reopen(aio_ev);
|
||||
|
||||
fde = talloc(mem_ctx?mem_ctx:ev, struct fd_event);
|
||||
if (!fde) return NULL;
|
||||
|
||||
@ -396,6 +435,7 @@ static struct fd_event *aio_event_add_fd(struct event_context *ev, TALLOC_CTX *m
|
||||
aio_ev->num_fd_events++;
|
||||
talloc_set_destructor(fde, aio_event_fd_destructor);
|
||||
|
||||
DLIST_ADD(aio_ev->fd_events, fde);
|
||||
epoll_add_event(aio_ev, fde);
|
||||
|
||||
return fde;
|
||||
@ -425,6 +465,8 @@ static void aio_event_set_fd_flags(struct fd_event *fde, uint16_t flags)
|
||||
|
||||
fde->flags = flags;
|
||||
|
||||
epoll_check_reopen(aio_ev);
|
||||
|
||||
epoll_change_event(aio_ev, fde);
|
||||
}
|
||||
|
||||
@ -442,6 +484,8 @@ static int aio_event_loop_once(struct event_context *ev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
epoll_check_reopen(aio_ev);
|
||||
|
||||
return aio_event_loop(aio_ev, &tval);
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
#include "includes.h"
|
||||
#include "system/filesys.h"
|
||||
#include "system/network.h"
|
||||
#include "lib/util/dlinklist.h"
|
||||
#include "lib/events/events.h"
|
||||
#include "lib/events/events_internal.h"
|
||||
@ -32,6 +33,9 @@ struct epoll_event_context {
|
||||
/* a pointer back to the generic event_context */
|
||||
struct event_context *ev;
|
||||
|
||||
/* list of filedescriptor events */
|
||||
struct fd_event *fd_events;
|
||||
|
||||
/* number of registered fd event handlers */
|
||||
int num_fd_events;
|
||||
|
||||
@ -45,6 +49,8 @@ struct epoll_event_context {
|
||||
|
||||
/* when using epoll this is the handle from epoll_create */
|
||||
int epoll_fd;
|
||||
|
||||
pid_t pid;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -86,9 +92,37 @@ static int epoll_ctx_destructor(struct epoll_event_context *epoll_ev)
|
||||
static void epoll_init_ctx(struct epoll_event_context *epoll_ev)
|
||||
{
|
||||
epoll_ev->epoll_fd = epoll_create(64);
|
||||
epoll_ev->pid = getpid();
|
||||
talloc_set_destructor(epoll_ev, epoll_ctx_destructor);
|
||||
}
|
||||
|
||||
static void epoll_add_event(struct epoll_event_context *epoll_ev, struct fd_event *fde);
|
||||
|
||||
/*
|
||||
reopen the epoll handle when our pid changes
|
||||
see http://junkcode.samba.org/ftp/unpacked/junkcode/epoll_fork.c for an
|
||||
demonstration of why this is needed
|
||||
*/
|
||||
static void epoll_check_reopen(struct epoll_event_context *epoll_ev)
|
||||
{
|
||||
struct fd_event *fde;
|
||||
|
||||
if (epoll_ev->pid == getpid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
close(epoll_ev->epoll_fd);
|
||||
epoll_ev->epoll_fd = epoll_create(64);
|
||||
if (epoll_ev->epoll_fd == -1) {
|
||||
DEBUG(0,("Failed to recreate epoll handle after fork\n"));
|
||||
return;
|
||||
}
|
||||
epoll_ev->pid = getpid();
|
||||
for (fde=epoll_ev->fd_events;fde;fde=fde->next) {
|
||||
epoll_add_event(epoll_ev, fde);
|
||||
}
|
||||
}
|
||||
|
||||
#define EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT (1<<0)
|
||||
#define EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR (1<<1)
|
||||
#define EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR (1<<2)
|
||||
@ -99,6 +133,7 @@ static void epoll_init_ctx(struct epoll_event_context *epoll_ev)
|
||||
static void epoll_add_event(struct epoll_event_context *epoll_ev, struct fd_event *fde)
|
||||
{
|
||||
struct epoll_event event;
|
||||
|
||||
if (epoll_ev->epoll_fd == -1) return;
|
||||
|
||||
fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
|
||||
@ -126,6 +161,9 @@ static void epoll_add_event(struct epoll_event_context *epoll_ev, struct fd_even
|
||||
static void epoll_del_event(struct epoll_event_context *epoll_ev, struct fd_event *fde)
|
||||
{
|
||||
struct epoll_event event;
|
||||
|
||||
DLIST_REMOVE(epoll_ev->fd_events, fde);
|
||||
|
||||
if (epoll_ev->epoll_fd == -1) return;
|
||||
|
||||
fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
|
||||
@ -193,6 +231,7 @@ static void epoll_change_event(struct epoll_event_context *epoll_ev, struct fd_e
|
||||
|
||||
/* there's no epoll_event attached to the fde */
|
||||
if (want_read || (want_write && !got_error)) {
|
||||
DLIST_ADD(epoll_ev->fd_events, fde);
|
||||
epoll_add_event(epoll_ev, fde);
|
||||
return;
|
||||
}
|
||||
@ -329,6 +368,8 @@ static struct fd_event *epoll_event_add_fd(struct event_context *ev, TALLOC_CTX
|
||||
struct epoll_event_context);
|
||||
struct fd_event *fde;
|
||||
|
||||
epoll_check_reopen(epoll_ev);
|
||||
|
||||
fde = talloc(mem_ctx?mem_ctx:ev, struct fd_event);
|
||||
if (!fde) return NULL;
|
||||
|
||||
@ -343,6 +384,7 @@ static struct fd_event *epoll_event_add_fd(struct event_context *ev, TALLOC_CTX
|
||||
epoll_ev->num_fd_events++;
|
||||
talloc_set_destructor(fde, epoll_event_fd_destructor);
|
||||
|
||||
DLIST_ADD(epoll_ev->fd_events, fde);
|
||||
epoll_add_event(epoll_ev, fde);
|
||||
|
||||
return fde;
|
||||
@ -372,6 +414,8 @@ static void epoll_event_set_fd_flags(struct fd_event *fde, uint16_t flags)
|
||||
|
||||
fde->flags = flags;
|
||||
|
||||
epoll_check_reopen(epoll_ev);
|
||||
|
||||
epoll_change_event(epoll_ev, fde);
|
||||
}
|
||||
|
||||
@ -389,6 +433,8 @@ static int epoll_event_loop_once(struct event_context *ev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
epoll_check_reopen(epoll_ev);
|
||||
|
||||
return epoll_event_loop(epoll_ev, &tval);
|
||||
}
|
||||
|
||||
|
@ -30,6 +30,7 @@
|
||||
|
||||
#include "includes.h"
|
||||
#include "system/filesys.h"
|
||||
#include "system/network.h"
|
||||
#include "system/select.h" /* needed for HAVE_EVENTS_EPOLL */
|
||||
#include "lib/util/dlinklist.h"
|
||||
#include "lib/events/events.h"
|
||||
@ -58,6 +59,9 @@ struct std_event_context {
|
||||
|
||||
/* when using epoll this is the handle from epoll_create */
|
||||
int epoll_fd;
|
||||
|
||||
/* our pid at the time the epoll_fd was created */
|
||||
pid_t pid;
|
||||
};
|
||||
|
||||
/* use epoll if it is available */
|
||||
@ -90,7 +94,9 @@ static uint32_t epoll_map_flags(uint16_t flags)
|
||||
*/
|
||||
static int epoll_ctx_destructor(struct std_event_context *std_ev)
|
||||
{
|
||||
close(std_ev->epoll_fd);
|
||||
if (std_ev->epoll_fd != -1) {
|
||||
close(std_ev->epoll_fd);
|
||||
}
|
||||
std_ev->epoll_fd = -1;
|
||||
return 0;
|
||||
}
|
||||
@ -101,9 +107,37 @@ static int epoll_ctx_destructor(struct std_event_context *std_ev)
|
||||
static void epoll_init_ctx(struct std_event_context *std_ev)
|
||||
{
|
||||
std_ev->epoll_fd = epoll_create(64);
|
||||
std_ev->pid = getpid();
|
||||
talloc_set_destructor(std_ev, epoll_ctx_destructor);
|
||||
}
|
||||
|
||||
static void epoll_add_event(struct std_event_context *std_ev, struct fd_event *fde);
|
||||
|
||||
/*
|
||||
reopen the epoll handle when our pid changes
|
||||
see http://junkcode.samba.org/ftp/unpacked/junkcode/epoll_fork.c for an
|
||||
demonstration of why this is needed
|
||||
*/
|
||||
static void epoll_check_reopen(struct std_event_context *std_ev)
|
||||
{
|
||||
struct fd_event *fde;
|
||||
|
||||
if (std_ev->pid == getpid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
close(std_ev->epoll_fd);
|
||||
std_ev->epoll_fd = epoll_create(64);
|
||||
if (std_ev->epoll_fd == -1) {
|
||||
DEBUG(0,("Failed to recreate epoll handle after fork\n"));
|
||||
return;
|
||||
}
|
||||
std_ev->pid = getpid();
|
||||
for (fde=std_ev->fd_events;fde;fde=fde->next) {
|
||||
epoll_add_event(std_ev, fde);
|
||||
}
|
||||
}
|
||||
|
||||
#define EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT (1<<0)
|
||||
#define EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR (1<<1)
|
||||
#define EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR (1<<2)
|
||||
@ -294,6 +328,7 @@ static int epoll_event_loop(struct std_event_context *std_ev, struct timeval *tv
|
||||
#define epoll_del_event(std_ev,fde)
|
||||
#define epoll_change_event(std_ev,fde)
|
||||
#define epoll_event_loop(std_ev,tvalp) (-1)
|
||||
#define epoll_check_reopen(std_ev)
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -374,6 +409,8 @@ static struct fd_event *std_event_add_fd(struct event_context *ev, TALLOC_CTX *m
|
||||
struct std_event_context);
|
||||
struct fd_event *fde;
|
||||
|
||||
epoll_check_reopen(std_ev);
|
||||
|
||||
fde = talloc(mem_ctx?mem_ctx:ev, struct fd_event);
|
||||
if (!fde) return NULL;
|
||||
|
||||
@ -421,6 +458,8 @@ static void std_event_set_fd_flags(struct fd_event *fde, uint16_t flags)
|
||||
|
||||
fde->flags = flags;
|
||||
|
||||
epoll_check_reopen(std_ev);
|
||||
|
||||
epoll_change_event(std_ev, fde);
|
||||
}
|
||||
|
||||
@ -517,6 +556,8 @@ static int std_event_loop_once(struct event_context *ev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
epoll_check_reopen(std_ev);
|
||||
|
||||
if (epoll_event_loop(std_ev, &tval) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user