Subject: kern/33752: Bug in kqueue VNODE handling
To: None <kern-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: None <mahendra.m@gmail.com>
List: netbsd-bugs
Date: 06/16/2006 14:30:00
>Number:         33752
>Category:       kern
>Synopsis:       Bug in kqueue VNODE handling
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri Jun 16 14:30:00 +0000 2006
>Originator:     Mahendra M
>Release:        2.0
>Organization:
Infosys Technologies Ltd.
>Environment:
# uname -a
NetBSD  2.0 NetBSD 2.0 (GENERIC) #0: Wed Dec  1 10:58:25 UTC 2004  builds@build:/big/builds/ab/netbsd-2-0-RELEASE/i386/200411300000Z-obj/big/builds/ab/netbsd-2-0-RELEASE/src/sys/arch/i386/compile/GENERIC i386
#

>Description:
Hi,

I was playing around with kqueues (NetBSD 2.0) when I noticed the following behaviour for EVFILT_VNODE with NOTE_ATTRIB filter flag. ( for monitoring attribute changes in the file ).

EV_SET(&event, fileno, EVFILT_VNODE, EV_ADD, NOTE_ATTRIB, 0, 0);

Two issues are seen.
1. Now, if you use kevent on the above ( in a loop ), it blocks till the first change in the file attribute. After that the event keeps happening again. Ideally ( as per documentation ), it should have blocked till the next time the file attribute changes.

2. Now, if you specify EV_ONESHOT, as per documentation, after the first occurance of the event, the event should be deleted from kqueue. This does not happen. After the first occurance of the event, the event is still resident on the kqueue and waits till the file attributes change again. ( Ideally this behaviour should have been observed in the previous case ).

Regards,
Mahendra

>How-To-Repeat:
Some sample code to reproduce the problem. ( Add EV_ONESHOT ) to replicate the seconds issue. ( do "touch /tmp/foo" to change the file attributes.

   kq = kqueue();

   f = open("/tmp/foo", O_RDONLY);

   EV_SET(&change, f, EVFILT_VNODE, EV_ADD, NOTE_ATTRIB, 0, 0);

   for (;;) {
       nev = kevent(kq, &change, 1, &event, 1, NULL);
       if (nev == -1)
           perror("kevent");
       else if (nev > 0) {
           if (event.fflags & NOTE_ATTRIB)
               printf("File attributes modified\n");
       }
   }


>Fix:
EV_ONESHOT fixes issue 1. :-)

Looking into the fix. Will update the PR, if I find any.