|
|
34d7f3 |
Bug 1252048 - net-snmp snmpd fork() overhead [fix available]
|
|
|
34d7f3 |
|
|
|
34d7f3 |
Backported from:
|
|
|
34d7f3 |
|
|
|
34d7f3 |
commit f0e87f4918ffc41e03f707e9670ea422cd154a9b
|
|
|
34d7f3 |
Author: Bart Van Assche <bvanassche@acm.org>
|
|
|
34d7f3 |
Date: Sat Jan 31 12:05:24 2015 +0100
|
|
|
34d7f3 |
|
|
|
34d7f3 |
CHANGES: snmpd: BUG: 2596: Reduce fork() overhead
|
|
|
34d7f3 |
|
|
|
34d7f3 |
Avoid that the close() loop that is executed after a fork() delays
|
|
|
34d7f3 |
the pass/extend API on systems with a large maximum number of files
|
|
|
34d7f3 |
by reducing the number of iterations of this loop on Linux systems.
|
|
|
34d7f3 |
|
|
|
34d7f3 |
See also http://sourceforge.net/p/net-snmp/bugs/2596.
|
|
|
34d7f3 |
|
|
|
34d7f3 |
Reported-by: andymf <andymf@users.sf.net>
|
|
|
34d7f3 |
|
|
|
34d7f3 |
|
|
|
34d7f3 |
diff -up net-snmp-5.7.2/agent/mibgroup/util_funcs.c.test net-snmp-5.7.2/agent/mibgroup/util_funcs.c
|
|
|
34d7f3 |
--- net-snmp-5.7.2/agent/mibgroup/util_funcs.c.test 2012-10-10 00:28:58.000000000 +0200
|
|
|
34d7f3 |
+++ net-snmp-5.7.2/agent/mibgroup/util_funcs.c 2015-08-18 10:15:18.888767023 +0200
|
|
|
34d7f3 |
@@ -480,8 +480,7 @@ get_exec_pipes(char *cmd, int *fdIn, int
|
|
|
34d7f3 |
/*
|
|
|
34d7f3 |
* close all non-standard open file descriptors
|
|
|
34d7f3 |
*/
|
|
|
34d7f3 |
- for (cnt = getdtablesize() - 1; cnt >= 2; --cnt)
|
|
|
34d7f3 |
- (void) close(cnt);
|
|
|
34d7f3 |
+ netsnmp_close_fds(1);
|
|
|
34d7f3 |
(void) dup(1); /* stderr */
|
|
|
34d7f3 |
|
|
|
34d7f3 |
for (cnt = 1, cptr1 = cmd, cptr2 = argvs; *cptr1 != 0;
|
|
|
34d7f3 |
diff -up net-snmp-5.7.2/agent/mibgroup/utilities/execute.c.test net-snmp-5.7.2/agent/mibgroup/utilities/execute.c
|
|
|
34d7f3 |
--- net-snmp-5.7.2/agent/mibgroup/utilities/execute.c.test 2012-10-10 00:28:58.000000000 +0200
|
|
|
34d7f3 |
+++ net-snmp-5.7.2/agent/mibgroup/utilities/execute.c 2015-08-18 10:15:18.889767028 +0200
|
|
|
34d7f3 |
@@ -22,6 +22,9 @@
|
|
|
34d7f3 |
#if HAVE_FCNTL_H
|
|
|
34d7f3 |
#include <fcntl.h>
|
|
|
34d7f3 |
#endif
|
|
|
34d7f3 |
+#if HAVE_DIRENT_H
|
|
|
34d7f3 |
+#include <dirent.h>
|
|
|
34d7f3 |
+#endif
|
|
|
34d7f3 |
#if HAVE_SYS_WAIT_H
|
|
|
34d7f3 |
#include <sys/wait.h>
|
|
|
34d7f3 |
#endif
|
|
|
34d7f3 |
@@ -207,8 +210,8 @@ run_exec_command( char *command, char *i
|
|
|
34d7f3 |
close(opipe[0]);
|
|
|
34d7f3 |
close(2);
|
|
|
34d7f3 |
dup(1);
|
|
|
34d7f3 |
- for (i = getdtablesize()-1; i>2; i--)
|
|
|
34d7f3 |
- close(i);
|
|
|
34d7f3 |
+
|
|
|
34d7f3 |
+ netsnmp_close_fds(2);
|
|
|
34d7f3 |
|
|
|
34d7f3 |
/*
|
|
|
34d7f3 |
* Set up the argv array and execute it
|
|
|
34d7f3 |
@@ -406,3 +409,30 @@ run_exec_command( char *command, char *i
|
|
|
34d7f3 |
return run_shell_command( command, input, output, out_len );
|
|
|
34d7f3 |
#endif
|
|
|
34d7f3 |
}
|
|
|
34d7f3 |
+
|
|
|
34d7f3 |
+/**
|
|
|
34d7f3 |
+ * Close all file descriptors larger than @fd.
|
|
|
34d7f3 |
+ */
|
|
|
34d7f3 |
+void netsnmp_close_fds(int fd)
|
|
|
34d7f3 |
+{
|
|
|
34d7f3 |
+#if defined(HAVE_FORK)
|
|
|
34d7f3 |
+ DIR *dir;
|
|
|
34d7f3 |
+ struct dirent *ent;
|
|
|
34d7f3 |
+ int i, largest_fd = -1;
|
|
|
34d7f3 |
+
|
|
|
34d7f3 |
+ if ((dir = opendir("/proc/self/fd"))) {
|
|
|
34d7f3 |
+ while ((ent = readdir(dir))) {
|
|
|
34d7f3 |
+ if (sscanf(ent->d_name, "%d", &i) == 1) {
|
|
|
34d7f3 |
+ if (i > largest_fd)
|
|
|
34d7f3 |
+ largest_fd = i;
|
|
|
34d7f3 |
+ }
|
|
|
34d7f3 |
+ }
|
|
|
34d7f3 |
+ closedir(dir);
|
|
|
34d7f3 |
+ } else {
|
|
|
34d7f3 |
+ largest_fd = getdtablesize() - 1;
|
|
|
34d7f3 |
+ }
|
|
|
34d7f3 |
+
|
|
|
34d7f3 |
+ for (i = largest_fd; i > fd && i > 0; i--)
|
|
|
34d7f3 |
+ close(i);
|
|
|
34d7f3 |
+#endif
|
|
|
34d7f3 |
+}
|
|
|
34d7f3 |
diff -up net-snmp-5.7.2/agent/mibgroup/utilities/execute.h.test net-snmp-5.7.2/agent/mibgroup/utilities/execute.h
|
|
|
34d7f3 |
--- net-snmp-5.7.2/agent/mibgroup/utilities/execute.h.test 2012-10-10 00:28:58.000000000 +0200
|
|
|
34d7f3 |
+++ net-snmp-5.7.2/agent/mibgroup/utilities/execute.h 2015-08-18 10:15:18.889767028 +0200
|
|
|
34d7f3 |
@@ -3,6 +3,7 @@
|
|
|
34d7f3 |
|
|
|
34d7f3 |
config_belongs_in(agent_module)
|
|
|
34d7f3 |
|
|
|
34d7f3 |
+void netsnmp_close_fds(int fd);
|
|
|
34d7f3 |
int run_shell_command(char *command, char *input,
|
|
|
34d7f3 |
char *output, int *out_len);
|
|
|
34d7f3 |
int run_exec_command( char *command, char *input,
|
|
|
34d7f3 |
diff -up net-snmp-5.7.2/agent/snmpd.c.test net-snmp-5.7.2/agent/snmpd.c
|
|
|
34d7f3 |
--- net-snmp-5.7.2/agent/snmpd.c.test 2015-08-18 10:15:08.450714809 +0200
|
|
|
34d7f3 |
+++ net-snmp-5.7.2/agent/snmpd.c 2015-08-18 10:17:31.579430763 +0200
|
|
|
34d7f3 |
@@ -143,6 +143,7 @@ typedef long fd_mask;
|
|
|
34d7f3 |
#include <net-snmp/agent/agent_module_config.h>
|
|
|
34d7f3 |
#include <net-snmp/agent/mib_module_config.h>
|
|
|
34d7f3 |
|
|
|
34d7f3 |
+#include "utilities/execute.h" /* netsnmp_close_fds() */
|
|
|
34d7f3 |
#include "snmpd.h"
|
|
|
34d7f3 |
|
|
|
34d7f3 |
#include <net-snmp/agent/mib_modules.h>
|
|
|
34d7f3 |
@@ -451,7 +452,6 @@ main(int argc, char *argv[])
|
|
|
34d7f3 |
FILE *PID;
|
|
|
34d7f3 |
#endif
|
|
|
34d7f3 |
|
|
|
34d7f3 |
-#ifndef WIN32
|
|
|
34d7f3 |
#ifndef NETSNMP_NO_SYSYSTEMD
|
|
|
34d7f3 |
/* check if systemd has sockets for us and don't close them */
|
|
|
34d7f3 |
prepared_sockets = netsnmp_sd_listen_fds(0);
|
|
|
34d7f3 |
@@ -462,11 +462,8 @@ main(int argc, char *argv[])
|
|
|
34d7f3 |
* inherited from the shell.
|
|
|
34d7f3 |
*/
|
|
|
34d7f3 |
if (!prepared_sockets) {
|
|
|
34d7f3 |
- for (i = getdtablesize() - 1; i > 2; --i) {
|
|
|
34d7f3 |
- (void) close(i);
|
|
|
34d7f3 |
- }
|
|
|
34d7f3 |
+ netsnmp_close_fds(2);
|
|
|
34d7f3 |
}
|
|
|
34d7f3 |
-#endif /* #WIN32 */
|
|
|
34d7f3 |
|
|
|
34d7f3 |
/*
|
|
|
34d7f3 |
* register signals ASAP to prevent default action (usually core)
|
|
|
34d7f3 |
diff -up net-snmp-5.7.2/apps/snmptrapd.c.test net-snmp-5.7.2/apps/snmptrapd.c
|
|
|
34d7f3 |
--- net-snmp-5.7.2/apps/snmptrapd.c.test 2015-08-18 10:15:08.450714809 +0200
|
|
|
34d7f3 |
+++ net-snmp-5.7.2/apps/snmptrapd.c 2015-08-18 10:18:15.454650235 +0200
|
|
|
34d7f3 |
@@ -97,6 +97,7 @@ SOFTWARE.
|
|
|
34d7f3 |
#include <net-snmp/net-snmp-includes.h>
|
|
|
34d7f3 |
#include <net-snmp/agent/net-snmp-agent-includes.h>
|
|
|
34d7f3 |
#include <net-snmp/library/fd_event_manager.h>
|
|
|
34d7f3 |
+#include "utilities/execute.h" /* netsnmp_close_fds() */
|
|
|
34d7f3 |
#include "snmptrapd_handlers.h"
|
|
|
34d7f3 |
#include "snmptrapd_log.h"
|
|
|
34d7f3 |
#include "snmptrapd_auth.h"
|
|
|
34d7f3 |
@@ -662,7 +663,6 @@ main(int argc, char *argv[])
|
|
|
34d7f3 |
int prepared_sockets = 0;
|
|
|
34d7f3 |
|
|
|
34d7f3 |
|
|
|
34d7f3 |
-#ifndef WIN32
|
|
|
34d7f3 |
#ifndef NETSNMP_NO_SYSTEMD
|
|
|
34d7f3 |
/* check if systemd has sockets for us and don't close them */
|
|
|
34d7f3 |
prepared_sockets = netsnmp_sd_listen_fds(0);
|
|
|
34d7f3 |
@@ -672,11 +672,8 @@ main(int argc, char *argv[])
|
|
|
34d7f3 |
* inherited from the shell.
|
|
|
34d7f3 |
*/
|
|
|
34d7f3 |
if (!prepared_sockets) {
|
|
|
34d7f3 |
- for (i = getdtablesize() - 1; i > 2; --i) {
|
|
|
34d7f3 |
- (void) close(i);
|
|
|
34d7f3 |
- }
|
|
|
34d7f3 |
+ netsnmp_close_fds(2);
|
|
|
34d7f3 |
}
|
|
|
34d7f3 |
-#endif /* #WIN32 */
|
|
|
34d7f3 |
|
|
|
34d7f3 |
#ifdef SIGTERM
|
|
|
34d7f3 |
signal(SIGTERM, term_handler);
|
|
|
34d7f3 |
@@ -1382,18 +1379,6 @@ trapd_update_config(void)
|
|
|
34d7f3 |
read_configs();
|
|
|
34d7f3 |
}
|
|
|
34d7f3 |
|
|
|
34d7f3 |
-
|
|
|
34d7f3 |
-#if !defined(HAVE_GETDTABLESIZE) && !defined(WIN32)
|
|
|
34d7f3 |
-#include <sys/resource.h>
|
|
|
34d7f3 |
-int
|
|
|
34d7f3 |
-getdtablesize(void)
|
|
|
34d7f3 |
-{
|
|
|
34d7f3 |
- struct rlimit rl;
|
|
|
34d7f3 |
- getrlimit(RLIMIT_NOFILE, &rl);
|
|
|
34d7f3 |
- return (rl.rlim_cur);
|
|
|
34d7f3 |
-}
|
|
|
34d7f3 |
-#endif
|
|
|
34d7f3 |
-
|
|
|
34d7f3 |
/*
|
|
|
34d7f3 |
* Windows Service Related functions
|
|
|
34d7f3 |
*/
|