diff options
author | Chris Hall <chris.hall@highwayman.com> | 2012-06-08 15:01:11 +0100 |
---|---|---|
committer | Chris Hall <chris.hall@highwayman.com> | 2012-06-08 15:01:11 +0100 |
commit | 58b4a3411f12d3ef34ef52ab197729887074f321 (patch) | |
tree | e456eec427d977e2e723039b83d614d13edcf983 /lib/vty_command.c | |
parent | 12d01b8b9c68f5dc72f2accdb29a760feb31420a (diff) | |
download | quagga-ex25b.tar.bz2 quagga-ex25b.tar.xz |
Fix bugs in vty error handlingex25b
Advance version to 0.99.20ex25b.
Bug fixes:
* when closing a vty, if close() returned an error, the vtys would
fall into a loop trying to recover.
This was found on FreeBSD, which will return ECONNRESET on close(),
which is not standard POSIX behaviour.
* when closing a vty in response to EPIPE or ECONNRESET, managed to
leave the vty mutex locked.
This stopped the Routing Engine *dead* on the next CLI command
that required the Routing Engine. SIGTERM/SIGINT would not
stop bgpd -- a SIGKILL would be required.
Other changes:
* toned down the error reporting of EPIPE in the vty -- so no
longer looks like an error...
...closing a vty by "exit" command is logged as "closed"
...closing a vty in response to the client closing their end of
the connection is logged as "terminated: terminal closed",
and no longer logs an EPIPE error.
* changed error reporting on close() and shutdown() for vty, so
that nothing is logged if an i/o error has already logged...
...so that redundant error messages are suppressed.
* applied slightly finer jittering to bgpd timers.
* work in progress on new vtysh.
Diffstat (limited to 'lib/vty_command.c')
-rw-r--r-- | lib/vty_command.c | 61 |
1 files changed, 32 insertions, 29 deletions
diff --git a/lib/vty_command.c b/lib/vty_command.c index d55220a6..02897a5a 100644 --- a/lib/vty_command.c +++ b/lib/vty_command.c @@ -131,7 +131,7 @@ * Prototypes */ static bool uty_cmd_loop_prepare(vty_io vio) ; -static cmd_ret_t uty_cmd_hiatus(vty_io vio, cmd_ret_t ret) ; +static cmd_ret_t uty_cmd_hiatus(vty_io vio) ; static cmd_ret_t vty_cmd_auth(vty vty, node_type_t* p_next_node) ; static void uty_cmd_out_cancel(vty_io vio) ; static uint uty_show_error_context(vio_fifo ebuf, vio_vf vf) ; @@ -1295,9 +1295,6 @@ vty_cmd_hiatus(vty vty, cmd_ret_t ret) qassert((vio->cl_state == vcl_cq_running) || (vio->cl_state == vcl_running)) ; - if (vio->state & vst_final) - return CMD_STOP ; /* it is all over */ - /* Handle the return code, either: * * * nothing further required -- any exception will have updated the @@ -1306,26 +1303,31 @@ vty_cmd_hiatus(vty vty, cmd_ret_t ret) * * this is a command or parsing error, for which a vx_quash exception * must be raised, and suitable error message generated. */ - switch (ret) + if (vio->state & vst_final) + ret = CMD_STOP ; /* it is all over */ + else { - case CMD_SUCCESS: - case CMD_HIATUS: - case CMD_WAITING: - case CMD_STOP: - case CMD_CANCEL: - case CMD_IO_ERROR: - break ; + switch (ret) + { + case CMD_SUCCESS: + case CMD_HIATUS: + case CMD_WAITING: + case CMD_STOP: + case CMD_CANCEL: + case CMD_IO_ERROR: + break ; - case CMD_WARNING: - case CMD_ERROR: - case CMD_ERR_PARSING: - case CMD_ERR_NO_MATCH: - case CMD_ERR_AMBIGUOUS: - case CMD_ERR_INCOMPLETE: - default: /* assume some sort of error */ - uty_vio_exception(vio, vx_quash) ; - uty_cmd_failed(vio, ret) ; - break ; + case CMD_WARNING: + case CMD_ERROR: + case CMD_ERR_PARSING: + case CMD_ERR_NO_MATCH: + case CMD_ERR_AMBIGUOUS: + case CMD_ERR_INCOMPLETE: + default: /* assume some sort of error */ + uty_vio_exception(vio, vx_quash) ; + uty_cmd_failed(vio, ret) ; + break ; + } ; } ; /* The meat of the hiatus -- loop back as required. @@ -1342,11 +1344,12 @@ vty_cmd_hiatus(vty vty, cmd_ret_t ret) * position is a little complicated. In particular, changes on the output * side may affect whether is waiting in the CLI. */ - while (1) + do { vio->signal = CMD_SUCCESS ; /* we are here ! */ - ret = uty_cmd_hiatus(vio, ret) ; + if (ret != CMD_STOP) + ret = uty_cmd_hiatus(vio) ; switch (ret) { @@ -1384,10 +1387,8 @@ vty_cmd_hiatus(vty vty, cmd_ret_t ret) default: zabort("invalid return code from uty_cmd_hiatus") ; } ; - - if (vio->signal == CMD_SUCCESS) - break ; - } ; + } + while (vio->signal != CMD_SUCCESS); if (ret == CMD_WAITING) { @@ -1418,8 +1419,10 @@ vty_cmd_hiatus(vty vty, cmd_ret_t ret) * pselect() system has moved things forward to). */ static cmd_ret_t -uty_cmd_hiatus(vty_io vio, cmd_ret_t ret) +uty_cmd_hiatus(vty_io vio) { + cmd_ret_t ret ; + /* (1) Do we need to close one or more vin and/or vout, or are we waiting for * one to close ? * |