fix(ha-bootstrap): register listener with iomgr epoll before election
vote_request_thread connects to peers via SSL. iomgr was started before election but c->ep was only registered with epoll inside cluster_start(), which runs after election. The TCP connect succeeded (kernel accepts it) but SSL_accept was never called server-side, so SSL_connect failed immediately — both vote threads went to deny in <1ms and ctrl-a could never win a quorum. Fix: add cluster_register_listener() that wires c->ep into iomgr's epoll watch. Call it from myapp_run() right after iomgr_start/vtaskmgr_start, before election. cluster_start() still calls iomgr_monitor again (idempotent via EPOLL_CTL_MOD).
This commit is contained in:
parent
6753b364c8
commit
fe37f4d692
3 changed files with 30 additions and 0 deletions
|
|
@ -1095,6 +1095,22 @@ static int check_workers_timeout(void* args)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* cluster_register_listener: wire c->ep into iomgr's epoll watch.
|
||||||
|
*
|
||||||
|
* Called before election from myapp_run() so that incoming OP_requestVote
|
||||||
|
* SSL connections are accepted and dispatched during the election phase.
|
||||||
|
* cluster_start() is idempotent — it calls iomgr_monitor again but
|
||||||
|
* iomgr_monitor is safe to call twice (epoll EPOLL_CTL_MOD handles it).
|
||||||
|
*/
|
||||||
|
int cluster_register_listener(cluster_t *c)
|
||||||
|
{
|
||||||
|
endpoint_set_owner(&(c->ep), c);
|
||||||
|
endpoint_set_conn_handler(&(c->ep), (conn_handler_t)handle_connection);
|
||||||
|
c->ep.iomgr = &(c->iomgr);
|
||||||
|
return iomgr_monitor(&(c->ep));
|
||||||
|
}
|
||||||
|
|
||||||
int cluster_start(cluster_t* c)
|
int cluster_start(cluster_t* c)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ typedef int (*collect_check_fn_t)(void*);
|
||||||
extern int check_controller(void*);
|
extern int check_controller(void*);
|
||||||
extern int cluster_init_phase1(cluster_t*);
|
extern int cluster_init_phase1(cluster_t*);
|
||||||
extern int cluster_open_listener(cluster_t*);
|
extern int cluster_open_listener(cluster_t*);
|
||||||
|
extern int cluster_register_listener(cluster_t*);
|
||||||
extern int cluster_init_phase2(cluster_t*);
|
extern int cluster_init_phase2(cluster_t*);
|
||||||
extern int cluster_init(cluster_t*);
|
extern int cluster_init(cluster_t*);
|
||||||
extern int cluster_start(cluster_t*);
|
extern int cluster_start(cluster_t*);
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,19 @@ int myapp_run(myconf_t* myconf)
|
||||||
iomgr_start(&(c.iomgr));
|
iomgr_start(&(c.iomgr));
|
||||||
vtaskmgr_start(&(c.vtaskmgr));
|
vtaskmgr_start(&(c.vtaskmgr));
|
||||||
|
|
||||||
|
/* Register the listener socket with epoll NOW so that iomgr can accept
|
||||||
|
* and dispatch incoming OP_requestVote connections during the election.
|
||||||
|
* Without this, iomgr runs but has no fd to watch — SSL_connect from
|
||||||
|
* peers succeeds at TCP level but hangs waiting for SSL_accept. */
|
||||||
|
{
|
||||||
|
int monitor_rc = cluster_register_listener(&c);
|
||||||
|
if (monitor_rc < 0) {
|
||||||
|
ERROR("cluster_register_listener: %s", strerror(-monitor_rc));
|
||||||
|
cluster_fini(&c);
|
||||||
|
return monitor_rc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Pre-load config from disk if a local config file exists, so that this
|
/* Pre-load config from disk if a local config file exists, so that this
|
||||||
* node's config_tag is known before election. This allows the freshness gate
|
* node's config_tag is known before election. This allows the freshness gate
|
||||||
* in am_i_primary_quorum() (Req 2.4) to work correctly: a node with a valid
|
* in am_i_primary_quorum() (Req 2.4) to work correctly: a node with a valid
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue