diff options
| author | Quentin Young <qlyoung@users.noreply.github.com> | 2018-05-25 14:09:44 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-05-25 14:09:44 -0400 |
| commit | cfb3b1a37d0339e79bd1b11314f679d8c15d62d7 (patch) | |
| tree | 9eece9c9798263068ce67e77ae7bbe9f9d535e31 | |
| parent | cd126147a3a8d74929aa255c3e9691cc148ea2eb (diff) | |
| parent | 67736451c55347849909cb3a05c706d5f9e2c29a (diff) | |
Merge pull request #2272 from msablic/vtysh_reconnect
vtysh: reconnect to daemons when connection lost
| -rw-r--r-- | vtysh/vtysh.c | 48 | ||||
| -rw-r--r-- | vtysh/vtysh.h | 2 |
2 files changed, 47 insertions, 3 deletions
diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c index ca372778d6..90c387b48c 100644 --- a/vtysh/vtysh.c +++ b/vtysh/vtysh.c @@ -86,6 +86,8 @@ struct vtysh_client vtysh_client[] = { enum vtysh_write_integrated vtysh_write_integrated = WRITE_INTEGRATED_UNSPECIFIED; +static int vtysh_reconnect(struct vtysh_client *vclient); + static void vclient_close(struct vtysh_client *vclient) { if (vclient->fd >= 0) { @@ -93,7 +95,8 @@ static void vclient_close(struct vtysh_client *vclient) "Warning: closing connection to %s because of an I/O error!\n", vclient->name); close(vclient->fd); - vclient->fd = -1; + /* indicate as candidate for reconnect */ + vclient->fd = VTYSH_WAS_ACTIVE; } } @@ -120,12 +123,28 @@ static int vtysh_client_run(struct vtysh_client *vclient, const char *line, char *bufvalid, *end = NULL; char terminator[3] = {0, 0, 0}; + /* vclinet was previously active, try to reconnect */ + if (vclient->fd == VTYSH_WAS_ACTIVE) { + ret = vtysh_reconnect(vclient); + if (ret < 0) + goto out_err; + } + if (vclient->fd < 0) return CMD_SUCCESS; ret = write(vclient->fd, line, strlen(line) + 1); - if (ret <= 0) - goto out_err; + if (ret <= 0) { + /* close connection and try to reconnect */ + vclient_close(vclient); + ret = vtysh_reconnect(vclient); + if (ret < 0) + goto out_err; + /* retry line */ + ret = write(vclient->fd, line, strlen(line) + 1); + if (ret <= 0) + goto out_err; + } bufvalid = buf; do { @@ -490,6 +509,13 @@ static int vtysh_execute_func(const char *line, int pager) if (cmd->daemon & vtysh_client[i].flag) { if (vtysh_client[i].fd < 0 && (cmd->daemon == vtysh_client[i].flag)) { + for (vc = &vtysh_client[i]; vc; + vc = vc->next) + if (vc->fd < 0) + vtysh_reconnect(vc); + } + if (vtysh_client[i].fd < 0 + && (cmd->daemon == vtysh_client[i].flag)) { bool any_inst = false; for (vc = &vtysh_client[i]; vc; vc = vc->next) @@ -3117,6 +3143,22 @@ static int vtysh_connect(struct vtysh_client *vclient) return 0; } +static int vtysh_reconnect(struct vtysh_client *vclient) +{ + int ret; + + fprintf(stderr, "Warning: connecting to %s...", vclient->name); + ret = vtysh_connect(vclient); + if (ret < 0) { + fprintf(stderr, "failed!\n"); + return ret; + } + fprintf(stderr, "success!\n"); + if (vtysh_client_execute(vclient, "enable", NULL) < 0) + return -1; + return vtysh_execute_no_pager("end"); +} + /* Return true if str ends with suffix, else return false */ static int ends_with(const char *str, const char *suffix) { diff --git a/vtysh/vtysh.h b/vtysh/vtysh.h index ccfdd6557b..cbfc1b5b23 100644 --- a/vtysh/vtysh.h +++ b/vtysh/vtysh.h @@ -40,6 +40,8 @@ DECLARE_MGROUP(MVTYSH) #define VTYSH_SHARPD 0x2000 #define VTYSH_PBRD 0x4000 +#define VTYSH_WAS_ACTIVE (-2) + /* commands in REALLYALL are crucial to correct vtysh operation */ #define VTYSH_REALLYALL ~0U /* watchfrr is not in ALL since library CLI functions should not be |
