On Sat, Dec 19, 2009 at 10:03 AM, Bart Van Assche
<[email protected]> wrote:
> As known libnetsnmp supports time-based alarms via the functions
> snmp_alarm_register(), run_alarms() and other functions. Two different ways
> to trigger the function run_alarms() are supported inside libnetsnmp:
> 1. By making sure that the timeout argument of select() is small enough such
> that select() returns before the next alarm must be handled (when the
> variable NETSNMP_DS_LIB_ALARM_DONT_USE_SIG is set to one, which is the
> default).
> 2. By making sure that the kernel fires SIGALRM at the time when
> run_alarms() should be called (when the variable
> NETSNMP_DS_LIB_ALARM_DONT_USE_SIG is set to zero, which has to be configured
> explicitly).
>
> The following issues are associated with the second approach:
> 1. Alarm functions are used inside Net-SNMP to e.g. refresh cached table
> contents. As far as I can see there is nothing in the Net-SNMP source code
> that prevents the following from happening: a table refresh triggered via
> SIGALRM while a row is being removed from a cached table. This can result in
> dangling pointer dereferences and even a crash.
> 2. POSIX restricts signal handlers to calling functions that are either
> reentrant or non-interruptible
> (http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html#tag_02_04).
> Standard I/O functions like printf() and fprintf() are neither reentrant nor
> non-interruptible. run_alarms() is called from inside a signal handler,
> which means that this restriction applies to the function run_alarms()
> itself and all functions called by it (which includes the alarm callback
> functions). Or: e.g. snmp_log() and its callers must not be called from
> inside run_alarms() when this function is invoked from inside a signal
> handler. This is a severe restriction, and one that is hard to work with.
> 3. Not all software developers know how to make sure that signal delivery
> works correctly in a multithreaded context. POSIX does not guarantee to
> which thread a signal like SIGALRM will be delivered, unless that signal has
> been blocked before thread creation and is unblocked after thread creation
> (see also
> http://www.opengroup.org/onlinepubs/009695399/functions/pthread_sigmask.html).
> This is relevant for the Net-SNMP project not only because a worker thread
> is created inside agent/mibgroup/if-mib/data_access/interface_linux.c but
> also because libnetsnmp is often used inside multithreaded software.
> Currently no attempt is made to make sure that SIGALRM is processed by the
> Net-SNMP event processing loop thread. If SIGALRM is processed by another
> thread, this will result in one or more data races.
>
> Because all the difficulties associated with processing alarms from inside a
> signal handler function, and because fixing these would require more effort
> than it is worth, I propose to remove this feature from the Net-SNMP code
> base and to always use approach (1), whether or not
> NETSNMP_DS_LIB_ALARM_DONT_USE_SIG has been set.
If I do not receive any feedback, I will apply the patch below whithin
a few days. This patch does not modify the behavior of the Net-SNMP
agent itself (snmpd). It only modifies the behavior of applications
linked with libnetsnmp and that set NETSNMP_DS_LIB_ALARM_DONT_USE_SIG
to zero -- for these applications alarm handlers will be called from
inside agent_check_and_process() instead of from the context of
SIGALRM. Applications that set NETSNMP_DS_LIB_ALARM_DONT_USE_SIG to
zero and that did not call run_alarms() (either directly or indirectly
via agent_check_and_process()) will have to be updated -- an explicit
call to run_alarms() will have to be inserted in the socket processing
loop. Enabling SIGALRM based alarm handling by directly calling
set_an_alarm() remains possible.
Index: snmplib/snmp_api.c
===================================================================
--- snmplib/snmp_api.c (revision 17919)
+++ snmplib/snmp_api.c (working copy)
@@ -6244,11 +6244,9 @@ snmp_sess_select_info2(void *sessp,
}
DEBUGMSG(("sess_select", "\n"));
- if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID,
NETSNMP_DS_LIB_ALARM_DONT_USE_SIG)) {
- next_alarm = get_next_alarm_delay_time(&delta);
- DEBUGMSGT(("sess_select","next alarm %d.%06d sec\n",
- (int)delta.tv_sec, (int)delta.tv_usec));
- }
+ next_alarm = get_next_alarm_delay_time(&delta);
+ DEBUGMSGT(("sess_select","next alarm %d.%06d sec\n",
+ (int)delta.tv_sec, (int)delta.tv_usec));
if (next_alarm == 0 && requests == 0) {
/*
* If none are active, skip arithmetic.
Index: snmplib/snmp_alarm.c
===================================================================
--- snmplib/snmp_alarm.c (revision 17919)
+++ snmplib/snmp_alarm.c (working copy)
@@ -65,22 +65,18 @@
#include <net-snmp/library/snmp_alarm.h>
static struct snmp_alarm *thealarms = NULL;
-static int start_alarms = 0;
static unsigned int regnum = 1;
int
init_alarm_post_config(int majorid, int minorid, void *serverarg,
void *clientarg)
{
- start_alarms = 1;
- set_an_alarm();
return SNMPERR_SUCCESS;
}
void
init_snmp_alarm(void)
{
- start_alarms = 0;
snmp_register_callback(SNMP_CALLBACK_LIBRARY,
SNMP_CALLBACK_POST_READ_CONFIG,
init_alarm_post_config, NULL);
@@ -422,8 +418,6 @@ snmp_alarm_register(unsigned int when, u
(*sa_pptr)->clientreg, (*sa_pptr)->t.tv_sec,
((*sa_pptr)->t.tv_usec / 1000), (*sa_pptr)->flags));
- if (start_alarms)
- set_an_alarm();
return (*sa_pptr)->clientreg;
}
@@ -492,10 +486,6 @@ snmp_alarm_register_hr(struct timeval t,
(*s)->clientreg, (*s)->t.tv_sec, ((*s)->t.tv_usec / 1000),
(*s)->flags));
- if (start_alarms) {
- set_an_alarm();
- }
-
return (*s)->clientreg;
}
/** @} */
------------------------------------------------------------------------------
This SF.Net email is sponsored by the Verizon Developer Community
Take advantage of Verizon's best-in-class app development support
A streamlined, 14 day to market process makes app distribution fast and easy
Join now and get one step closer to millions of Verizon customers
http://p.sf.net/sfu/verizon-dev2dev
_______________________________________________
Net-snmp-coders mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/net-snmp-coders