66 lines
2.3 KiB
Diff
66 lines
2.3 KiB
Diff
Fix ping mode failure
|
|
|
|
Upstream-Status: Pending
|
|
|
|
When watchdog works on ping mode, the system will be rebooted since
|
|
watchdog can not receive the expected ECOREPLY on a setting interval.
|
|
|
|
Ping mode uses a raw socket to send a ECO packet, then uses select()
|
|
to wait and recvfrom() to receive the ECOREPLY packet, if select()
|
|
shows the data is ready, and the data is not the expected ECOREPLY,
|
|
and waiting time is not overdue, it will continue use select() and
|
|
recvfrom().
|
|
|
|
Problem is that the raw socket can receive any icmp packets, if we do
|
|
not set filters, and there are many icmp packets on socket, this
|
|
program will not find its interested ECOREPLY packet in a special
|
|
interval, which makes the ping mode fail.
|
|
|
|
|
|
Other program is that watchdog sometime can not reach the call of
|
|
recvfrom to try to receive packets since tv_sec of struct timeval
|
|
of select parameter is 0.
|
|
|
|
The timeout of select() is the result of ping interval minusing the
|
|
time of calling gettimeofday spending, when ping interval is 1 second,
|
|
and the call of gettimeofday() spends several useconds, the tv_sec of
|
|
struct timeval of select parameter must be 0, at that condition, we
|
|
should it is valid of tv_sec of struct timeval of select parameter be 0
|
|
|
|
Signed-off-by: Roy.Li <rongqing.li@windriver.com>
|
|
---
|
|
src/net.c | 2 +-
|
|
src/watchdog.c | 5 ++++-
|
|
2 files changed, 5 insertions(+), 2 deletions(-)
|
|
|
|
Index: watchdog-5.13/src/watchdog.c
|
|
===================================================================
|
|
--- watchdog-5.13.orig/src/watchdog.c 2013-02-01 03:15:44.000000000 -0800
|
|
+++ watchdog-5.13/src/watchdog.c 2013-03-11 22:27:48.741657881 -0700
|
|
@@ -28,6 +28,7 @@
|
|
#include <sys/types.h>
|
|
#include <sys/ioctl.h>
|
|
#include <linux/oom.h>
|
|
+#include <linux/icmp.h>
|
|
#include <linux/watchdog.h>
|
|
#include <string.h>
|
|
|
|
@@ -567,6 +568,8 @@
|
|
pid_t child_pid;
|
|
int oom_adjusted = 0;
|
|
struct stat s;
|
|
+ struct icmp_filter filt;
|
|
+ filt.data = ~(1<<ICMP_ECHOREPLY);
|
|
|
|
#if USE_SYSLOG
|
|
char *opts = "d:i:n:Ffsvbql:p:t:c:r:m:a:";
|
|
@@ -703,7 +706,7 @@
|
|
perror(progname);
|
|
exit(1);
|
|
}
|
|
-
|
|
+ setsockopt(net->sock_fp, SOL_RAW, ICMP_FILTER, (char*)&filt, sizeof(filt));
|
|
/* this is necessary for broadcast pings to work */
|
|
(void) setsockopt(net->sock_fp, SOL_SOCKET, SO_BROADCAST, (char *)&hold, sizeof(hold));
|
|
|