diff options
author | Chris Hall <chris.hall@highwayman.com> | 2011-07-21 19:53:02 +0100 |
---|---|---|
committer | Chris Hall <chris.hall@highwayman.com> | 2011-07-21 19:53:02 +0100 |
commit | 56da2a1c9b6361e302b7a39fe2740561a9012d88 (patch) | |
tree | 6b6543532133a0c618d0f4ec70a87cf3f96caf30 /lib/vty_log.c | |
parent | e535bc959729262480a9702e71334002edee3f8c (diff) | |
download | quagga-56da2a1c9b6361e302b7a39fe2740561a9012d88.tar.bz2 quagga-56da2a1c9b6361e302b7a39fe2740561a9012d88.tar.xz |
Update pipework and improve memory reporting.
Improve error handling for all new pipework inputs and outputs.
Change behaviour of ^C from VTY Terminal, so that will interrupt
output and terminate all running pipes -- including running
shell commands.
In pipe commands, recognise "~/..." and "~user/..." home directory
forms.
Changed "~/" to mean the usual home for the current user. "~~/"
now means the configuration file directory.
Introduced "shdir DIR" command to show what is (currently) what.
Changed "<|" so that if the command has a path, it is expanded
using Quagga's rules (including "~~/" and "~./") and the
"here" directory is set to that path.
Fixed collection of stderr output from all pipes so that is
separate from stdout output, and is always sent to the base
output (eg VTY Terminal).
Increase amount of information about the heap that "show mem"
shows -- particularly if the "memory_tracker" is enabled.
Tested and applied resulting fixes.
Diffstat (limited to 'lib/vty_log.c')
-rw-r--r-- | lib/vty_log.c | 93 |
1 files changed, 79 insertions, 14 deletions
diff --git a/lib/vty_log.c b/lib/vty_log.c index 080f86a3..1f485e89 100644 --- a/lib/vty_log.c +++ b/lib/vty_log.c @@ -35,6 +35,8 @@ * This supports the "vty monitor" facility -- which reflects logging * information to one or more VTY_TERMINAL vty. * + * NB: this *only* only to the base_vout of a VTY_TERMINAL. + * * There are a number of issues: * * a) output of logging information should not be held up any longer than @@ -46,14 +48,16 @@ * c) zlog() et al, hold the LOG_LOCK(), which is at a lower level than the * VTY_LOCK(). * + * MUST NOT require the VTY_LOCK() in order to complete a zlog() operation, + * hence the buffering and other mechanisms. + * * d) may have one or more monitor vty, possibly at different levels of * message. * - * e) must avoid logging error messages for given vty on that vty ! - * - * - * + * e) must avoid logging I/O error log messages for given vty on that vty ! * + * The I/O error handling turns off log monitoring for the vty if the + * vin_base or the vout_base is the locus of the error. */ static vio_fifo monitor_buffer = NULL ; static uint monitor_count = 0 ; @@ -62,6 +66,7 @@ static bool mon_kicked = false ; static mqueue_block mon_mqb = NULL ; static void vty_mon_action(mqueue_block mqb, mqb_flag_t flag) ; +static void uty_monitor_update(void) ; /*------------------------------------------------------------------------------ * Initialise the vty monitor facility. @@ -91,12 +96,12 @@ extern void uty_set_monitor(vty_io vio, bool on) { int level ; - int count ; + int delta ; VTY_ASSERT_LOCKED() ; level = 0 ; - count = 0 ; + delta = 0 ; LOG_LOCK() ; @@ -106,7 +111,7 @@ uty_set_monitor(vty_io vio, bool on) { vio->monitor = true ; - vio->maxlvl = INT_MAX ; /* pro tem TODO */ + vio->maxlvl = uzlog_get_monitor_lvl(NULL) ; vio->mon_kick = false ; if (vio->mbuf == NULL) @@ -114,29 +119,85 @@ uty_set_monitor(vty_io vio, bool on) sdl_push(vio_monitor_list, vio, mon_list) ; - count = +1 ; + delta = +1 ; } ; } else if (!on && vio->monitor) { vio->monitor = false ; - vio->maxlvl = INT_MAX ; /* pro tem TODO */ + vio->maxlvl = ZLOG_DISABLED ; vio->mon_kick = false ; sdl_del(vio_monitor_list, vio, mon_list) ; - count = -1 ; + delta = -1 ; } - if (count != 0) - uzlog_add_monitor(NULL, count) ; + monitor_count += delta ; - monitor_count += count ; + if (delta != 0) + uty_monitor_update() ; /* tell logging if number of monitors changes */ LOG_UNLOCK() ; } ; /*------------------------------------------------------------------------------ + * If the current VTY is a log monitor, set a new level + */ +extern void +vty_set_monitor_level(vty vty, int level) +{ + VTY_LOCK() ; + + if (vty->vio->monitor) + { + LOG_LOCK() ; + + vty->vio->maxlvl = level ; + uty_monitor_update() ; + + LOG_UNLOCK() ; + } ; + + VTY_UNLOCK() ; +} ; + +/*------------------------------------------------------------------------------ + * Establish the maximum level of all monitors and tell the logging levels. + * + * This is used when a monitor is enabled or disabled, and when a VTY's monitor + * level is changed. + */ +static void +uty_monitor_update(void) +{ + int level ; + uint count ; + vty_io vio ; + + VTY_ASSERT_LOCKED() ; + LOG_ASSERT_LOCKED() ; + + vio = vio_monitor_list ; + count = 0 ; + level = ZLOG_DISABLED ; + while (vio != NULL) + { + ++count ; + qassert(vio->vout_base->vout_type == VOUT_TERM) ; + + if (level <= vio->maxlvl) + level = vio->maxlvl ; + + vio = sdl_next(vio, mon_list) ; + } ; + + qassert(monitor_count == count) ; + + uzlog_set_monitor(NULL, level) ; +} ; + +/*------------------------------------------------------------------------------ * Put logging message to all suitable monitors. * * All we can do here is to shovel stuff into buffers and then kick the VTY @@ -158,6 +219,8 @@ vty_log(int priority, const char* line, uint len) kick = false ; while (vio != NULL) { + qassert(vio->vout_base->vout_type == VOUT_TERM) ; + if (priority <= vio->maxlvl) { vio_fifo_put_bytes(vio->mbuf, line, len) ; @@ -209,7 +272,7 @@ vty_mon_action(mqueue_block mqb, mqb_flag_t flag) vio = vio_monitor_list ; while (vio != NULL) { - assert(vio->vout_base->vout_type == VOUT_TERM) ; + qassert(vio->vout_base->vout_type == VOUT_TERM) ; if (vio->mon_kick) { @@ -244,6 +307,8 @@ vty_log_fixed (const char *buf, uint len) vio = sdl_head(vio_monitor_list) ; while (vio != NULL) { + qassert(vio->vout_base->vout_type == VOUT_TERM) ; + write(vio_vfd_fd(vio->vout_base->vfd), buf, len) ; write(vio_vfd_fd(vio->vout_base->vfd), "\r\n", 2) ; |