Library layering

From Net-SNMP Wiki
Jump to: navigation, search

Problem

The three libraries libnetsnmpmibs, libnetsnmphelpers and libnetsnmpagent have circular dependencies instead of what should be a clean mibs -> helpers -> agent -> main library dependency chain:

  • libnetsnmpmibs depends on libnetsnmphelpers
  • both of these depend on libnetsnmpagent
  • all 3 of these depend on libnetsnmp

There are only a few problematic calls/functions that violate this dependency chain:

Critical dependency Symbol/function implementation in ... (under agent/) caller(s) (under agent/) Comment
agent -> mibs make_tempfile mibgroup/util_funcs.c mibgroup/utilities/execute.c:run_shell_command() fixed in 5.4+ by introducing netsnmp_mktemp
agent -> helpers netsnmp_init_helpers helpers/all_helpers.c snmp_vars.c:init_agent() fix by e.g. merging agent and helpers libs (see below)
agent -> helpers netsnmp_register_null helpers/null.c agent_registry.c:setup_tree() ditto
agent -> helpers netsnmp_register_null_context helpers/null.c agent_registry.c:netsnmp_subtree_load() ditto
agent -> helpers netsnmp_register_old_api helpers/old_api.c agent_registry.c:register_mib_context() ditto
agent -> helpers netsnmp_bulk_to_next_fix_requests helpers/bulk_to_next.c mibgroup/agentx/master.c:agentx_got_response() ditto
agent -> helpers netsnmp_get_bulk_to_next_handler helpers/bulk_to_next.c agent_handler.c:netsnmp_register_handler() ditto
other strange dependencies
libnetsnmptrapd -> snmptrapd extern int dropauth apps/snmptrapd.c apps/snmptrapd_handlers.c:print_handler() Move 'dropauth' from snmptrapd.c to snmptrapd_handlers.c. Done for MAIN.
libnetsnmptrapd -> snmptrapd extern int SyslogTrap apps/snmptrapd.c apps/snmptrapd_handlers.c:syslog_handler() Move 'SyslogTrap' from snmptrapd.c to snmptrapd_handlers.c. Done for MAIN.
libnetsnmptrapd -> snmptrapd event_input apps/snmptrapd.c apps/snmptrapd_handlers.c:event_handler() Drop "-e"/printEventNumbers support altogether. Done for MAIN.

Discussion

Most library layering issues have been solved without any drastic changes (see below for details). There's just one issue left: the circular dependency between the agent and helpers lib.

As of May 2010, we seem to have three choices:

  • Merge agent and helpers libraries into one libagent library again. Pro: maintain backward-compatibility. Con: agent lib will have increased footprint (+50%). Need to keep empty helpers lib around which is odd.
  • Remove the netsnmp_init_helpers() call from init_agent() and require agent developers to add an explicit call to netsnmp_init_helpers() after every call to init_agent(). Pro: keep libraries separate. Small change for developers. Con: backwards-incompatible change.
  • Clever compiler constructs to check if helpers lib has been loaded before agent lib. Con: non-portable (gcc-ism)!! Pro: maintain backward-compatibility, keep libraries separate.

The choice under discussion is basically between the first and second approach, unless somebody can come up with a portable third approach.

Status

what? who? status?
rework Makefiles to build libnetsnmp, libnetsnmpagent, libnetsnmphelpers and libnetsnmpmibs in that order tanders done for 5.4+
duplicate libnetsnmpmibs' make_tempfile as netsnmp_mktemp in libnetsnmp tanders done for 5.4+
resolve circular dependency between agent and helpers libs (e.g. by merging them) tbd TODO (trunk only)
fix libnetsnmptrapd->snmptrapd dependencies by moving integer variables to the library and dropping the event_input code dts12, tanders done for MAIN
rework Makefiles/configure to fullfil internal and external library dependencies correctly (see below) tanders done (5.4+)
link libperl to libnetsnmpagent instead of snmpd/snmptrapd. How to check at configure time whether linking of libperl to a shared library works? tanders forced for 5.5 (w/o additional configure check, r16529); protected by --enable-as-needed in 5.4 (r16569)

Library linking

Here are the details of what library linking dependencies need to be cleaned up.

shared object/library/binary currently linked against dependencies to be added/removed Comment
libnetsnmp.so -lcrypto ditto ok
libnetsnmpagent.so - -lnetsnmp -lperl

Linking a shared library against libperl turns out to be tricky since existing PERLLDOPTS reference the static DynaLoader.a which isn't always portable.

r16529 (5.5) + r16569 (5.4.1.c1)
libnetsnmphelpers.so - -lnetsnmpagent -lnetsnmp r16419 (5.4+)
libnetsnmpmibs.so - -lnetsnmphelpers -lnetsnmpagent -lnetsnmp r16419 (5.4+)
-ldl -lrpm -lrpmio -lpopt -lz ... r16399 (5.4+)
libnetsnmptrapd.so - -lnetsnmpmibs -lnetsnmp -lperl r16419 (5.4+), r16529 (Perl, 5.5)
Perl SNMP/SNMP.so -lnetsnmp -lcrypto (net-snmp-config --libs) remove "-crypto" in "net-snmp-config --libs" r16419 (5.4+)
Perl NetSNMP/ASN/ASN.so see SNMP.so see SNMP.so r16419 (5.4+)
Perl NetSNMP/OID/OID.so see SNMP.so see SNMP.so r16419 (5.4+)
Perl NetSNMP/agent/default_store/default_store.so see SNMP.so see SNMP.so r16419 (5.4+)
Perl NetSNMP/default_store/default_store.so see SNMP.so see SNMP.so r16419 (5.4+)
Perl NetSNMP/TrapReceiver/TrapReceiver.so - -lnetsnmptrapd -lnetsnmpagent -lnetsnmp r16419 (5.4+)
Perl NetSNMP/agent/agent.so almost everything remove: most external references (dependencies are in libnetsnmpmibs instead) fixed for 5.4.1.pre3/5.5
Python netsnmp/client_intf.so see SNMP.so see SNMP.so r16419 (5.4+)
agent/snmpd almost everything remove: most external references (incl. Perl; dependencies are in libnetsnmpmibs/libnetsnmpagent instead) fixed for 5.4.1.pre3/5.5
apps/snmptrapd almost everything remove: most external references (incl. Perl; dependencies are in libnetsnmpmibs/libnetsnmpagent instead) fixed for 5.4.1.pre3/5.5
apps/snmp{get,set,walk,...} almost everything remove: most external references (not needed at all) fixed for 5.4.1.pre2/5.5

References