Library layering
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 merging agent and helpers libs |
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
There doesn't seem to be a way around merging the agent and helpers libraries into one libagent library again, so this is what we're going to do for 5.5 and beyond.
We haven't found any clever way would be to sensibly restructure both libraries to get rid of circular interdependencies while maintaining backward-compatibility and not causing too much overhead for agent developers.
All other library layering issues will likely be solved properly without such drastic changes.
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+ |
merge agent and helpers libs! | 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 trunk (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
- 2006-10-19 #net-snmp IRC log (starting at 07:12:29)
- Bug #1565496: library layering violation
- Bug #1619827: building with --as-needed is broken
- perl5-porters thread "how to best link libperl to a shared library?"