Перейти к содержимому
Калькуляторы

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

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

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

#!/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

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

DemYaN

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

 

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

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

во фре по дефаулту 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

 

Изменено пользователем Giga-Byte

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Giga-Byte

Внешние скрипты поддерживаются?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

#!/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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

да, надо установить 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"

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

DemYaN

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

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

 

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

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

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

 

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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

"Утекает" по одной простой причине - помнятся 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.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

По идее не сложно в 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.

Изменено пользователем voron

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

И второй вариант, для тех, кто не хочет 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 ---------------------

*/

Изменено пользователем vitalyb

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

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» нам помогло

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

И второй вариант, для тех, кто не хочет 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>

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

А разработчики что говорят?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Гость
Ответить в тему...

×   Вставлено в виде отформатированного текста.   Вставить в виде обычного текста

  Разрешено не более 75 смайлов.

×   Ваша ссылка была автоматически встроена.   Отобразить как ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставить изображения напрямую. Загрузите или вставьте изображения по ссылке.