Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 1 | Fix ping mode failure |
| 2 | |
| 3 | Upstream-Status: Pending |
| 4 | |
| 5 | When watchdog works on ping mode, the system will be rebooted since |
| 6 | watchdog can not receive the expected ECOREPLY on a setting interval. |
| 7 | |
| 8 | Ping mode uses a raw socket to send a ECO packet, then uses select() |
| 9 | to wait and recvfrom() to receive the ECOREPLY packet, if select() |
| 10 | shows the data is ready, and the data is not the expected ECOREPLY, |
| 11 | and waiting time is not overdue, it will continue use select() and |
| 12 | recvfrom(). |
| 13 | |
| 14 | Problem is that the raw socket can receive any icmp packets, if we do |
| 15 | not set filters, and there are many icmp packets on socket, this |
| 16 | program will not find its interested ECOREPLY packet in a special |
| 17 | interval, which makes the ping mode fail. |
| 18 | |
| 19 | |
| 20 | Other program is that watchdog sometime can not reach the call of |
| 21 | recvfrom to try to receive packets since tv_sec of struct timeval |
| 22 | of select parameter is 0. |
| 23 | |
| 24 | The timeout of select() is the result of ping interval minusing the |
| 25 | time of calling gettimeofday spending, when ping interval is 1 second, |
| 26 | and the call of gettimeofday() spends several useconds, the tv_sec of |
| 27 | struct timeval of select parameter must be 0, at that condition, we |
| 28 | should it is valid of tv_sec of struct timeval of select parameter be 0 |
| 29 | |
| 30 | Signed-off-by: Roy.Li <rongqing.li@windriver.com> |
| 31 | --- |
| 32 | src/net.c | 2 +- |
| 33 | src/watchdog.c | 5 ++++- |
| 34 | 2 files changed, 5 insertions(+), 2 deletions(-) |
| 35 | |
| 36 | Index: watchdog-5.14/src/watchdog.c |
| 37 | =================================================================== |
| 38 | --- watchdog-5.14.orig/src/watchdog.c |
| 39 | +++ watchdog-5.14/src/watchdog.c |
| 40 | @@ -24,6 +24,7 @@ |
| 41 | #include <sys/types.h> |
| 42 | #include <sys/ioctl.h> |
| 43 | #include <linux/oom.h> |
| 44 | +#include <linux/icmp.h> |
| 45 | #include <linux/watchdog.h> |
| 46 | #include <string.h> |
| 47 | |
| 48 | Index: watchdog-5.14/src/net.c |
| 49 | =================================================================== |
| 50 | --- watchdog-5.14.orig/src/net.c |
| 51 | +++ watchdog-5.14/src/net.c |
| 52 | @@ -11,7 +11,8 @@ |
| 53 | #include <errno.h> |
| 54 | #include <sys/time.h> |
| 55 | #include <netinet/ip.h> |
| 56 | -#include <netinet/ip_icmp.h> |
| 57 | +#include <linux/icmp.h> |
| 58 | +//#include <netinet/ip_icmp.h> |
| 59 | #include <fcntl.h> |
| 60 | #include <string.h> |
| 61 | #include <unistd.h> /* for gethostname() etc */ |
| 62 | @@ -179,6 +180,9 @@ int open_netcheck(struct list *tlist) |
| 63 | { |
| 64 | struct list *act; |
| 65 | int hold = 0; |
| 66 | + struct icmp_filter filt; |
| 67 | + filt.data = ~(1<<ICMP_ECHOREPLY); |
| 68 | + |
| 69 | |
| 70 | if (tlist != NULL) { |
| 71 | for (act = tlist; act != NULL; act = act->next) { |
| 72 | @@ -202,6 +206,7 @@ int open_netcheck(struct list *tlist) |
| 73 | fatal_error(EX_SYSERR, "error opening socket (%s)", strerror(errno)); |
| 74 | } |
| 75 | |
| 76 | + setsockopt(net->sock_fp, SOL_RAW, ICMP_FILTER, (char*)&filt, sizeof(filt)); |
| 77 | /* this is necessary for broadcast pings to work */ |
| 78 | (void)setsockopt(net->sock_fp, SOL_SOCKET, SO_BROADCAST, (char *)&hold, sizeof(hold)); |
| 79 | |