Merge pull request #14576 from LabNConsulting/chopps/short-circuit-guarantee

lib: msg: make short-circuit connections guaranteed
This commit is contained in:
Igor Ryzhov 2023-10-13 12:13:20 +03:00 committed by GitHub
commit 032d4835b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 33 additions and 14 deletions

View File

@ -634,7 +634,7 @@ static void msg_client_sched_connect(struct msg_client *client,
&client->conn_retry_tmr); &client->conn_retry_tmr);
} }
static bool msg_client_connect_short_circuit(struct msg_client *client) static int msg_client_connect_short_circuit(struct msg_client *client)
{ {
struct msg_conn *server_conn; struct msg_conn *server_conn;
struct msg_server *server; struct msg_server *server;
@ -648,10 +648,9 @@ static bool msg_client_connect_short_circuit(struct msg_client *client)
break; break;
if (!server) { if (!server) {
MGMT_MSG_DBG(dbgtag, MGMT_MSG_DBG(dbgtag,
"no short-circuit connection available for %s", "no short-circuit server available yet for %s",
client->sopath); client->sopath);
return -1;
return false;
} }
if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets)) { if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets)) {
@ -659,7 +658,7 @@ static bool msg_client_connect_short_circuit(struct msg_client *client)
&client->conn.mstate, &client->conn.mstate,
"socketpair failed trying to short-circuit connection on %s: %s", "socketpair failed trying to short-circuit connection on %s: %s",
client->sopath, safe_strerror(errno)); client->sopath, safe_strerror(errno));
return false; return -1;
} }
/* client side */ /* client side */
@ -687,7 +686,7 @@ static bool msg_client_connect_short_circuit(struct msg_client *client)
client->sopath, client->conn.mstate.idtag, client->conn.fd, client->sopath, client->conn.mstate.idtag, client->conn.fd,
server_conn->mstate.idtag, server_conn->fd); server_conn->mstate.idtag, server_conn->fd);
return true; return 0;
} }
@ -697,11 +696,12 @@ static void msg_client_connect(struct msg_client *client)
struct msg_conn *conn = &client->conn; struct msg_conn *conn = &client->conn;
const char *dbgtag = conn->debug ? conn->mstate.idtag : NULL; const char *dbgtag = conn->debug ? conn->mstate.idtag : NULL;
if (!client->short_circuit_ok || if (!client->short_circuit_ok)
!msg_client_connect_short_circuit(client))
conn->fd = conn->fd =
mgmt_msg_connect(client->sopath, MSG_CONN_SEND_BUF_SIZE, mgmt_msg_connect(client->sopath, MSG_CONN_SEND_BUF_SIZE,
MSG_CONN_RECV_BUF_SIZE, dbgtag); MSG_CONN_RECV_BUF_SIZE, dbgtag);
else if (msg_client_connect_short_circuit(client))
conn->fd = -1;
if (conn->fd == -1) if (conn->fd == -1)
/* retry the connection */ /* retry the connection */
@ -741,7 +741,6 @@ void msg_client_init(struct msg_client *client, struct event_loop *tm,
mgmt_msg_init(&conn->mstate, max_read_buf, max_write_buf, max_msg_sz, mgmt_msg_init(&conn->mstate, max_read_buf, max_write_buf, max_msg_sz,
idtag); idtag);
/* XXX maybe just have client kick this off */
/* Start trying to connect to server */ /* Start trying to connect to server */
msg_client_sched_connect(client, 0); msg_client_sched_connect(client, 0);
} }

View File

@ -136,6 +136,10 @@ struct msg_client {
extern void msg_client_cleanup(struct msg_client *client); extern void msg_client_cleanup(struct msg_client *client);
/* /*
* If `short_circuit_ok` is true, then the client-server connection will use a
* socketpair() rather than a unix-domain socket. This must be passed true if
* you wish to send messages short-circuit later.
*
* `notify_disconnect` is not called when the user `msg_client_cleanup` is * `notify_disconnect` is not called when the user `msg_client_cleanup` is
* called for a client which is currently connected. The socket is closed * called for a client which is currently connected. The socket is closed
* but there is no notification. * but there is no notification.

View File

@ -52,17 +52,26 @@ void mgmt_init(void)
/* Initialize the MGMTD Frontend Adapter Module */ /* Initialize the MGMTD Frontend Adapter Module */
mgmt_fe_adapter_init(mm->master); mgmt_fe_adapter_init(mm->master);
/* Initialize the CLI frontend client */ /*
* Initialize the CLI frontend client -- this queues an event for the
* client to short-circuit connect to the server (ourselves).
*/
vty_init_mgmt_fe(); vty_init_mgmt_fe();
/* MGMTD VTY commands installation. */ /*
* MGMTD VTY commands installation -- the frr lib code will queue an
* event to read the config files which needs to happen after the
* connect from above is made.
*/
mgmt_vty_init(); mgmt_vty_init();
/* /*
* Initialize the MGMTD Backend Adapter Module * Initialize the MGMTD Backend Adapter Module
* *
* We do this after the FE stuff so that we always read our config file * We do this after the FE stuff so that we have read our config file
* prior to any BE connection. * prior to any BE connection. Setting up the server will queue a
* "socket read" event to accept BE connections. So the code is counting
* on the above 2 events to run prior to any `accept` event from here.
*/ */
mgmt_be_adapter_init(mm->master); mgmt_be_adapter_init(mm->master);
} }

View File

@ -452,7 +452,14 @@ DEFPY(debug_mgmt, debug_mgmt_cmd,
static void mgmt_config_read_in(struct event *event) static void mgmt_config_read_in(struct event *event)
{ {
mgmt_vty_read_configs(); if (vty_mgmt_fe_enabled())
mgmt_vty_read_configs();
else {
zlog_warn("%s: no connection to front-end server, retry in 1s",
__func__);
event_add_timer(mm->master, mgmt_config_read_in, NULL, 1,
&mgmt_daemon_info->read_in);
}
} }
void mgmt_vty_init(void) void mgmt_vty_init(void)