diff options
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) ; |