Mailinglist archives

[list-arpalert] Re: arpalert.c invald argument on FreeBSD

From: Fumiyuki Shimizu <fumifumi_at_abacustech.jp>
Date: Wed, 21 Oct 2009 18:51:11 +0900 (JST)

Hi,

Thanks to the developers of this useful tool.

I met the same situation on FreeBSD 7.1, two or three times a day, and
then I traced it. It is caused by timeval.tv_usec, which contains 1 or
more seconds(tv_usec>=1,000,000). I put some additional confirmation
at the bottom of this e-mail. The attached patch may fix the case. It
also includes codes to avoid FD_SET(-1, ..), its behavior is
undefined, for safe. After patching, I have got normal detection
messages, and nothing about EINVAL of select().

The reason arpalert-debug.tgz have not shown much is that the
condition is negated and the order is revered. The intention might be
-----------------
if (selret == -1) {
  if (errno == EINVAL) {
    /* verbose logging, and continue */
    continue;
  }
  if (errno != EINTR) {
    /* original logging */
  }
}
-----------------
or someting.

There is another workaround for unexpected exit, by setting a line
like below into cron for FreeBSD without daemon managers.
-----------------
*/5 * * * * root /usr/bin/pgrep -f -F /var/run/arpalert.pid /usr/local/sbin/arpalert>/dev/null || /usr/local/sbin/arpalert _args_
-----------------

I hope some part of this e-mail help you if this is still a problem.

Thank you,

---
fumifumi_at_abacustech.jp
Fumiyuki Shimizu
-----------------------------------------------------------
End-points of select() returning EINVAL. These are very interesting.
FreeBSD
  No calcutaion for large tv_usec.
<URL:http://fxr.googlebit.com/source/sys/kern/kern_time.c?v=7-STABLE#L703>
  EINVAL: nfds < 0, OK: nfds == 0
<URL:http://fxr.googlebit.com/source/sys/kern/sys_generic.c?v=7-STABLE#L684>
NetBSD -> same as FreeBSD as usual.
<URL:http://fxr.googlebit.com/source/sys/kern/subr_time.c?v=NETBSD-CURRENT#L155>
<URL:http://fxr.googlebit.com/source/sys/kern/sys_select.c?v=NETBSD-CURRENT#L229>
Linux
  check only minus values, and add them appropliately.
<URL:http://fxr.googlebit.com/source/fs/select.c?v=linux-2.6.22.4#L394>
  EINVAL: nfds < 0, OK: nfds == 0 (ret is overwritten below)
<URL:http://fxr.googlebit.com/source/fs/select.c?v=linux-2.6.22.4#L319>
-----------------------------------------------------------
I got these lines on FreeBSD as expected,
-----
d: Invalid argument
e: Invalid argument
f: Invalid argument
g: Invalid argument
-----
by runnuing
> cat | cc -x c - && ./a.out
#include <sys/select.h>
#include <stdio.h>
#include <errno.h>
int main (int argc, char **argv){
  fd_set read_filed_set;
  struct timeval timeout;
  FD_ZERO (&read_filed_set);
  timeout.tv_sec = 0;
  timeout.tv_usec = 0;
  if (-1 == select(0, &read_filed_set, NULL, NULL, &timeout))
    printf ("a: %s\n", strerror (errno));
  timeout.tv_sec = 0;
  timeout.tv_usec = 1;
  if (-1 == select(0, &read_filed_set, NULL, NULL, &timeout))
    printf ("b: %s\n", strerror (errno));
  timeout.tv_sec = 0;
  timeout.tv_usec = 999999;
  if (-1 == select(0, &read_filed_set, NULL, NULL, &timeout))
    printf ("c: %s\n", strerror (errno));
  timeout.tv_sec = 0;
  timeout.tv_usec = 1000000;
  if (-1 == select(0, &read_filed_set, NULL, NULL, &timeout))
    printf ("d: %s\n", strerror (errno));
  timeout.tv_sec = 1;
  timeout.tv_usec = -1;
  if (-1 == select(0, &read_filed_set, NULL, NULL, &timeout))
    printf ("e: %s\n", strerror (errno));
  timeout.tv_sec = -1;
  timeout.tv_usec = 1;
  if (-1 == select(0, &read_filed_set, NULL, NULL, &timeout))
    printf ("f: %s\n", strerror (errno));
  timeout.tv_sec = -1;
  timeout.tv_usec = 2000000;
  if (-1 == select(0, &read_filed_set, NULL, NULL, &timeout))
    printf ("g: %s\n", strerror (errno));
}
/* EOF */

-- 
To unsubscribe send a mail to list+unsubscribe_at_arpalert.org
Received on Wed Oct 21 2009 - 11:51:48 CEST