@@ -39,6 +39,7 @@
#include <linux/netlink.h>
#include <pthread.h>
#include <sys/mman.h>
+#include <sys/time.h>
#include <libudev.h>
#include <errno.h>
@@ -51,6 +52,10 @@
#include "config.h"
#include "blacklist.h"
+#define MAX_ACCUMULATION_COUNT 2048
+#define MAX_ACCUMULATION_TIME 30*1000
+#define MIN_BURST_SPEED 10
+
typedef int (uev_trigger)(struct uevent *, void * trigger_data);
LIST_HEAD(uevq);
@@ -490,11 +495,43 @@ struct uevent *uevent_from_udev_device(struct udev_device *dev)
return uev;
}
+bool uevent_burst(struct timeval *start_time, int events)
+{
+ struct timeval diff_time, end_time;
+ unsigned long speed;
+ unsigned long eclipse_ms;
+
+ if(events > MAX_ACCUMULATION_COUNT) {
+ condlog(2, "burst got %u uevents, too much uevents, stopped", events);
+ return false;
+ }
+
+ gettimeofday(&end_time, NULL);
+ timersub(&end_time, start_time, &diff_time);
+
+ eclipse_ms = diff_time.tv_sec * 1000 + diff_time.tv_usec / 1000;
+
+ if (eclipse_ms == 0)
+ return true;
+
+ if (eclipse_ms > MAX_ACCUMULATION_TIME) {
+ condlog(2, "burst continued %lu ms, too long time, stopped", eclipse_ms);
+ return false;
+ }
+
+ speed = (events * 1000) / eclipse_ms;
+ if (speed > MIN_BURST_SPEED)
+ return true;
+
+ return false;
+}
+
int uevent_listen(struct udev *udev)
{
int err = 2;
struct udev_monitor *monitor = NULL;
int fd, socket_flags, events;
+ struct timeval start_time;
int need_failback = 1;
int timeout = 30;
LIST_HEAD(uevlisten_tmp);
@@ -548,6 +585,7 @@ int uevent_listen(struct udev *udev)
}
events = 0;
+ gettimeofday(&start_time, NULL);
while (1) {
struct uevent *uev;
struct udev_device *dev;
@@ -562,7 +600,8 @@ int uevent_listen(struct udev *udev)
errno = 0;
fdcount = poll(&ev_poll, 1, poll_timeout);
if (fdcount && ev_poll.revents & POLLIN) {
- timeout = 0;
+ timeout = uevent_burst(&start_time, events + 1) ? 1 : 0;
+
dev = udev_monitor_receive_device(monitor);
if (!dev) {
condlog(0, "failed getting udev device");
@@ -600,6 +639,7 @@ int uevent_listen(struct udev *udev)
pthread_mutex_unlock(uevq_lockp);
events = 0;
}
+ gettimeofday(&start_time, NULL);
timeout = 30;
}
need_failback = 0;