我有一个C程序,它试图轮询网络中的设备,如果设备可用,它会尝试从它们读取值。但是,当没有设备时,应用程序的运行会在内核日志中创建以下消息。此外,日志中没有其他警告/警报消息,只有下面的消息。(即使在禁用了使用net.core.message_cost=0的比率消除之后)
net_ratelimit: xx callbacks supressed同时,另一个通过网络广播消息的应用程序在发送系统调用中开始失败,返回EINVAL。一旦我停止轮询TCP客户机,UDP Broadcast应用程序就能正常运行。
我运行它的系统是一个基于RAMFS的系统,运行3.14系列内核和RT_PREEMPT 修补程序应用。我编写了一个示例应用程序,当我在后台启动5个进程时,它模拟了与我的原始应用程序相同的行为。(请注意,触发它的进程超过4个)。下面是示例客户端代码。
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define CHK_NULL(x) if ((x)==NULL) exit (1)
#define CHK_ERR(err,s) if ((err)==-1) { perror(s); exit(1); }
#define CHK_SSL(err) if ((err)==-1) { ERR_print_errors_fp(stderr); exit(2); }
int sfd;
void openProtocol(const char *hostname) {
int sfd = socket(PF_INET, SOCK_STREAM, 0);
CHK_ERR(sfd, "socket");
struct sockaddr_in address;
memset(&address, 0, sizeof(address));
address.sin_family = PF_INET;
address.sin_addr.s_addr = inet_addr(hostname);
address.sin_port = htons(502);
int opt = 1;
int result = ioctl(sfd, FIONBIO, &opt);
if (result == -1) {
close(sfd);
CHK_ERR(result, "ioctl");
}
result = connect(sfd, (struct sockaddr*)&address, sizeof(address));
if (result == -1 && errno != EINPROGRESS) {
close(sfd);
CHK_ERR(result, "connect");
}
fd_set fdlist;
FD_ZERO(&fdlist);
struct timeval tm;
tm.tv_sec = 1;
tm.tv_usec = 0;
result = select(sfd + 1, NULL, &fdlist, NULL, &tm);
if (result == 0) {
printf ("TCP/IP connection error!\n");
close(sfd);
}
if (result == -1) {
close(sfd);
CHK_ERR(result, "select");
}
}
int main(int argc, char *argv[])
{
char *base_addr = "192.168.1.";
unsigned short startAddr = 21;
if ( argc < 3) {
fprintf (stderr, "Please provide number of IP and wait period\n");
exit(EXIT_FAILURE);
}
unsigned int no_of_ip;
if (sscanf (argv[1], "%u", (unsigned int*)&no_of_ip) != 1 ) {
fprintf (stderr, "Scan of number of device failed\n");
exit(EXIT_FAILURE);
}
unsigned int wait_period;
if (sscanf (argv[2], "%u", (unsigned int*)&wait_period) != 1) {
fprintf (stderr, "Scan of wait period failed\n");
exit(EXIT_FAILURE);
}
char full_addr[100];
char last_part[10];
while (1) {
for (int i = startAddr; i < (startAddr + no_of_ip); i++) {
memset(&full_addr[0], 0, sizeof(full_addr));
memset(&last_part[0], 0, sizeof(last_part));
strncat (full_addr, base_addr, sizeof(full_addr));
snprintf (last_part, sizeof(last_part), "%u", i);
strncat (full_addr, last_part, sizeof(full_addr));
openProtocol(full_addr);
usleep(wait_period * 1000);
}
}
return 0;
}应用程序将输入作为设备数量和等待时间。我通过一个shell脚本运行上述应用程序的5个实例,其中128 为设备号,5为等待时间(5 ms)。
现在是我的问题。
5 实例)的net_ratelimit消息。我试图通过将net_ratelimit设置为0来禁用net_ratelimit,但是除了net_ratelimit消息之外,在内核日志中找不到任何东西。UDP broadcast客户端)在试图发送广播时得到EINVAL。而且,只有当我的轮询应用程序运行时,才会发生这种情况。终止轮询应用程序广播客户端返回正常。PS:我无法得到更好的标题线,如果有更好的标题线,请建议/编辑;-)。
发布于 2017-04-25 04:18:06
在将内核升级到4.1系列之后,我可以看到消息的原因。实际的根本原因是以下消息
neighbour: arp_cache: neighbour table overflow然后,我注意到我正在将条目添加到ARP缓存中,这超过了1024,这是默认限制。在解决这个问题后,回调抑制消息的问题停止了。我想这是3.14系列中的一个错误,它没有提供call back supressed消息的实际原因。
https://stackoverflow.com/questions/38826490
复制相似问题