Jump to content
Калькуляторы

Linux Snmpd много (2-3К) интерфейсов

так и не нашел ответа как бороть "пожирание памяти" на ВПН-серверах...

Раньше было не нужно, но сейчас пытаюсь "прикинуться циской" и сделать поддержку сбоса с линии по SNMP соответвенно, проблема встала во всей красе... ((

Кто решил, ткните где почитать, хочется что б snmpd забыл про все кроме моего скрипта на нужный OID

Share this post


Link to post
Share on other sites

Тоже хотелось бы услышать про решение данной проблемы. Сейчас по крону банальная проверка на прожорливость и рестарт в случае чрезвычайной наглости :) :

#!/bin/bash

PID=`/bin/pidof snmpd`
RSS=`/bin/ps h -o rss -p $PID`

if [ $RSS -gt 50000 ]
then
    /usr/sbin/invoke-rc.d snmpd restart
    /usr/bin/logger -t SNMPD-RESTART "RSS=$RSS kBytes"
fi

 

Share this post


Link to post
Share on other sites

DemYaN

Cпасибо, капитан Очевиднось!

 

А если серьезно (только не обижайтесь!) то это очевидный костыль а быть "мастером костылей" уже надоело, хочется сделать по нормальному...

Я не смог нануглить ниченго по этой проблеме.

Кстати, это только с линуксом или с mpd то же самое?

Share this post


Link to post
Share on other sites

во фре по дефаулту bsnmpd.

root 6025 0.0 0.6 6804 5836 ?? Ss Sun04AM 3:35.41 /usr/sbin/bsnmpd

 

P.S.

ifconfig |grep ng|wc -l

1108

 

Edited by Giga-Byte

Share this post


Link to post
Share on other sites
Тоже хотелось бы услышать про решение данной проблемы. Сейчас по крону банальная проверка на прожорливость и рестарт в случае чрезвычайной наглости :) :

#!/bin/bash

PID=`/bin/pidof snmpd`
RSS=`/bin/ps h -o rss -p $PID`

if [ $RSS -gt 50000 ]
then
    /usr/sbin/invoke-rc.d snmpd restart
    /usr/bin/logger -t SNMPD-RESTART "RSS=$RSS kBytes"
fi

юмора про очевидность не понял, про то что это костыль и хотелось бы найти другое решение выше в своем посте написал...а костыль - может кто-то и без него живет, так будет на заметку

Share this post


Link to post
Share on other sites

да, надо установить ucd-net

потом по манам в /etc/snmpd.conf

...
begemotSnmpdModulePath."ucd" = "/usr/local/lib/snmp_ucd.so"
%ucd

extNames.1 = "connections"
extCommand.1 = "/usr/bin/netstat -rnl | /usr/bin/egrep -e 'ng[0-9]+' | /usr/bin/wc -l | /usr/bin/sed 's/ //g'"
extNames.2 = "cpu_temperature"
extCommand.2 = "/usr/local/sbin/get_cpu_temp.sh"
extNames.3 = "cpu_idle"
extCommand.3 = "/usr/local/sbin/get_cpu_idle.sh"
extNames.4 = "dummynet_load"
extCommand.4 = "/usr/local/sbin/get_dummynet_load.sh"
extNames.5 = "swinet_load"
extCommand.5 = "/usr/local/sbin/get_swinet_load.sh"
extNames.6 = "ngem_load"
extCommand.6 = "/usr/local/sbin/get_ngem_load.sh"

 

Share this post


Link to post
Share on other sites

DemYaN

Во-первых, спасибо за ответ, в любом случае, хоть мне они не помог.

Если Вас обидел мой ответ - извиняюсь. Просто, мне кажется, скрипт на перезапуск - это очевидно и нет смысла спрашивать о таком...

 

Просто перезапуск демона - это личение симтомов. А хочется вылечить причину - понять почему отжирается память. И исправиь это.

 

Share this post


Link to post
Share on other sites
А хочется вылечить причину - понять почему отжирается память. И исправиь это.
цитирую одного участника форума
Скорее с valgrind баловаться, и искать где утекает... помогать разработчикам :-)

только у меня ни руки ни другие части тела не дошли до этой софтины (с поиском утечек в vlc)

 

http://xtalk.msk.su/~ott/ru/linux/valgrind/Valgrind.html

 

может, у вас что-либо полезное получится

Share this post


Link to post
Share on other sites

"Утекает" по одной простой причине - помнятся ifTable и ifXTable счетчики для каждого существовавшего интерфейса. И это как бы фича такая... ядро не переиспользует индексы интерфейсов (/sbin/ip link show покажет), а старые в net-snmp удалять вроде и не за чем, получается...

 

По идее не сложно в net-snmp/agent/mibgroup/if-mib/data_access/interface_*.c отфильтровать все ppp интерфейсы или, если не хочется туда лезть, через LD_PRELOAD отловить fopen() и fgets() для /proc/net/dev.

Share this post


Link to post
Share on other sites
По идее не сложно в net-snmp/agent/mibgroup/if-mib/data_access/interface_*.c отфильтровать все ppp интерфейсы
патч
--- net-snmp-5.4.2.1/agent/mibgroup/if-mib/data_access/interface_linux.c.orig   2008-05-14 13:35:40.000000000 +0000
+++ net-snmp-5.4.2.1/agent/mibgroup/if-mib/data_access/interface_linux.c        2009-11-22 12:49:00.000000000 +0000
@@ -545,6 +545,7 @@
          */
         *stats++ = 0; /* null terminate name */

+       if(strncmp(ifstart,"ppp",3)==0)continue;
         if_index = netsnmp_arch_interface_index_find(ifstart);

         /*

На 5k ifb повёл себя ожидаемо - snmpd перестал есть CPU.

Edited by voron

Share this post


Link to post
Share on other sites

И второй вариант, для тех, кто не хочет net-snmp пересобирать :)

/*
* Compile with:
* gcc -shared -Wl,-soname,noprocnetdevppp.so -ldl -o noprocnetdevppp.so noprocnetdevppp.c  -fPIC -Wall
*
* To check if the library works see instructions at the end of this file.
*
* Usage: LD_PRELOAD=noprocnetdevppp.so /usr/sbin/snmpd
* 
* License: GPLv3
* Credits: based on libeatmydata, http://www.flamingspork.com/projects/libeatmydata/
*/

#define _GNU_SOURCE

#include <dlfcn.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>

#define IF_FILTEROUT_PREFIX "ppp"
#define NAME_PROC_NET_NEV "/proc/net/dev"

static FILE *fprocnetdev = NULL;

static FILE* (*libc_fopen)(const char *path, const char *mode);
static FILE* (*libc_fopen64)(const char *path, const char *mode);
static char* (*libc_fgets)(char *s, int size, FILE *stream);
static int (*libc_fclose)(FILE *fp);

void __attribute__ ((constructor)) self_init(void)
{
	libc_fopen = dlsym(RTLD_NEXT, "fopen");
	if (!libc_fopen || dlerror())
			_exit(1);
	libc_fopen64 = dlsym(RTLD_NEXT, "fopen64");
	if (!libc_fopen64 || dlerror())
			_exit(1);
	libc_fgets = dlsym(RTLD_NEXT, "fgets");
	if (!libc_fgets || dlerror())
			_exit(1);
	libc_fclose = dlsym(RTLD_NEXT, "fclose");
	if (!libc_fclose || dlerror())
			_exit(1);
}

FILE *fopen(const char *path, const char *mode)
{
FILE *fp = libc_fopen(path, mode);
if (fp != NULL){
	if (strcmp(NAME_PROC_NET_NEV, path) == 0){
		fprocnetdev = fp;
	}
}
return fp;
}

FILE *fopen64(const char *path, const char *mode)
{
FILE *fp = libc_fopen64(path, mode);
if (fp != NULL){
	if (strcmp(NAME_PROC_NET_NEV, path) == 0){
		fprocnetdev = fp;
	}
}
return fp;
}

char *fgets(char *s, int size, FILE *stream)
{
char *res;
char *ifname;

res = libc_fgets(s, size, stream);

while ((fprocnetdev != NULL) && (stream == fprocnetdev) && res){
	ifname = res;
	while (*ifname && *ifname==' ')
		ifname++;

	if (strncmp(ifname, IF_FILTEROUT_PREFIX, strlen(IF_FILTEROUT_PREFIX)) != 0){
		break;
	}
	res = libc_fgets(s, size, stream);
}

return res;
}

int fclose(FILE *fp)
{
if (fp == fprocnetdev)
	fprocnetdev = NULL;
return libc_fclose(fp);
}

/********************************************************************************/
/*

Use this to test if the library works as expected. PPP interfaces from /proc/net/dev
should not be shown, only from "anotherfile".

$ cat > anotherfile <<EOF
Inter-|   Receive
face |bytes	packets errs drop fifo frame compressed multicast|
lo:   98156	 831	0	0	0	 0
 eth2:	   0	   0	0	0	0	 0
 eth0:	   0	   0	0	0	0	 0
ppp13:	6610	 100	0	0	0	 0
ppp101:1745084476 42609137	0	0
 eth1:3665847358 2103417164  688	0
ppp225:611310162  500428	0	0	0
ppp239:3708296793 53542565	0	0
dummy0:	   0	   0	0	0	0	 0
EOF

--------------------- CUT ---------------------
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>

int main()
{
char line[1024];
FILE *f;

f = fopen("/proc/net/dev", "r");

printf("Reading /proc/net/dev:\n");

while (fgets(line, sizeof(line), f))
	printf(line);

fclose(f);

f = fopen("anotherfile", "r");

if (f){
	printf("Reading anotherfile:\n");

	while (fgets(line, sizeof(line), f))
		printf(line);

	fclose(f);
}

return 0;
}
--------------------- CUT ---------------------

*/

Edited by vitalyb

Share this post


Link to post
Share on other sites

И ещё вариантик:

man snmpd
...
       -I [-]INITLIST
               Specifies which modules should (or should not) be initialized when the agent starts  up.   If
               the  comma-separated  INITLIST  is preceded with a '-', it is the list of modules that should
               not be started.  Otherwise this is the list of the only modules that should be started.

               To get a list of compiled modules, run the agent with the arguments -Dmib_init  -H  (assuming
               debugging support has been compiled in).
...

«-I-ipAddressTable» нам помогло

Share this post


Link to post
Share on other sites

Есть у кого-нибудь успешный опыт эксплуатации snmpd на BRASах? У меня коллега говорил, что snmpd спустя какое-то время начинает сильно процессор жрать... и он в итоге от него отказался.

Share this post


Link to post
Share on other sites

А кто нибудь 5.5 ставил? А то пишут что там пофиксили утечку.

Share this post


Link to post
Share on other sites

И второй вариант, для тех, кто не хочет net-snmp пересобирать :)

<div class='codetop'>CODE</div><div class='codemain' style='height:200px;white-space:pre;overflow:auto'>/*

* Compile with:

* gcc -shared -Wl,-soname,noprocnetdevppp.so -ldl -o noprocnetdevppp.so noprocnetdevppp.c -fPIC -Wall

*

* To check if the library works see instructions at the end of this file.

*

* Usage: LD_PRELOAD=noprocnetdevppp.so /usr/sbin/snmpd

*

* License: GPLv3

* Credits: based on libeatmydata, <a href="http://www.flamingspork.com/projects/libeatmydata/" target="_blank">http://www.flamingspork.com/projects/libeatmydata/</a>

*/

 

#define _GNU_SOURCE

 

#include <dlfcn.h>

#include <unistd.h>

#include <errno.h>

#include <stdio.h>

#include <string.h>

 

#define IF_FILTEROUT_PREFIX "ppp"

#define NAME_PROC_NET_NEV "/proc/net/dev"

 

static FILE *fprocnetdev = NULL;

 

static FILE* (*libc_fopen)(const char *path, const char *mode);

static FILE* (*libc_fopen64)(const char *path, const char *mode);

static char* (*libc_fgets)(char *s, int size, FILE *stream);

static int (*libc_fclose)(FILE *fp);

 

void __attribute__ ((constructor)) self_init(void)

{

libc_fopen = dlsym(RTLD_NEXT, "fopen");

if (!libc_fopen || dlerror())

_exit(1);

libc_fopen64 = dlsym(RTLD_NEXT, "fopen64");

if (!libc_fopen64 || dlerror())

_exit(1);

libc_fgets = dlsym(RTLD_NEXT, "fgets");

if (!libc_fgets || dlerror())

_exit(1);

libc_fclose = dlsym(RTLD_NEXT, "fclose");

if (!libc_fclose || dlerror())

_exit(1);

}

 

FILE *fopen(const char *path, const char *mode)

{

FILE *fp = libc_fopen(path, mode);

if (fp != NULL){

if (strcmp(NAME_PROC_NET_NEV, path) == 0){

fprocnetdev = fp;

}

}

return fp;

}

 

FILE *fopen64(const char *path, const char *mode)

{

FILE *fp = libc_fopen64(path, mode);

if (fp != NULL){

if (strcmp(NAME_PROC_NET_NEV, path) == 0){

fprocnetdev = fp;

}

}

return fp;

}

 

char *fgets(char *s, int size, FILE *stream)

{

char *res;

char *ifname;

 

res = libc_fgets(s, size, stream);

 

while ((fprocnetdev != NULL) && (stream == fprocnetdev) && res){

ifname = res;

while (*ifname && *ifname==' ')

ifname++;

 

if (strncmp(ifname, IF_FILTEROUT_PREFIX, strlen(IF_FILTEROUT_PREFIX)) != 0){

break;

}

res = libc_fgets(s, size, stream);

}

 

return res;

}

 

int fclose(FILE *fp)

{

if (fp == fprocnetdev)

fprocnetdev = NULL;

return libc_fclose(fp);

}

 

/********************************************************************************/

/*

 

Use this to test if the library works as expected. PPP interfaces from /proc/net/dev

should not be shown, only from "anotherfile".

 

$ cat > anotherfile <<EOF

Inter-| Receive

face |bytes packets errs drop fifo frame compressed multicast|

lo: 98156 831 0 0 0 0

eth2: 0 0 0 0 0 0

eth0: 0 0 0 0 0 0

ppp13: 6610 100 0 0 0 0

ppp101:1745084476 42609137 0 0

eth1:3665847358 2103417164 688 0

ppp225:611310162 500428 0 0 0

ppp239:3708296793 53542565 0 0

dummy0: 0 0 0 0 0 0

EOF

 

--------------------- CUT ---------------------

#include <unistd.h>

#include <errno.h>

#include <stdio.h>

#include <string.h>

 

int main()

{

char line[1024];

FILE *f;

 

f = fopen("/proc/net/dev", "r");

 

printf("Reading /proc/net/dev:\n");

 

while (fgets(line, sizeof(line), f))

printf(line);

 

fclose(f);

 

f = fopen("anotherfile", "r");

 

if (f){

printf("Reading anotherfile:\n");

 

while (fgets(line, sizeof(line), f))

printf(line);

 

fclose(f);

}

 

return 0;

}

--------------------- CUT ---------------------

 

*/</div>

А это чо такое?)

Share this post


Link to post
Share on other sites

Подниму некротемку))

Что-то изменилось на сегодняшний день?

Что-то способы описанные тут не подходят ни для версии 5.7.3 ни для 5.7.2.1

Share this post


Link to post
Share on other sites

Пока не обращался. Думал, может есть у народа решение.

Сегодня перепробовал все варианты - не помогает. В системе куча ppp интерфейсов. Грузит процессор ужасно.

Пока ищу решение.

Share this post


Link to post
Share on other sites

Судя по тому, что делают патчи - они просто перехатывают обращения функций изнутри snmpd к файлу /proc/net/dev и скрывают от snmpd наличие ppp интерфейсов в системе. Вполне неплохое решение с LD_PRELOAD. Попробуйте, должно помочь :) Но лучше достать авторов, чтобы они сделали возможность исключения интерфейсов.

Share this post


Link to post
Share on other sites

В линухе же есть всякие механизмы безопасности, вот взять и запретить юзеру от которого работает демон открывать /proc/net/dev.

Либо селинух либо тупо ручками как то chmod сделать, я хз вообщем.

Share this post


Link to post
Share on other sites

Тогда он не будет видеть все интерфейсы. А нужно показать обычные ethX и bondX, а вот ppp убрать за ненадобностью.

Share this post


Link to post
Share on other sites

костыль в ip-up исправит эту проблему, имхо. Но костыльненько выходит...

Share this post


Link to post
Share on other sites

Мы так и поступили, nagios-nrpe агенты стоят вместо snmpd.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this