libev issue due to inotify bug

Marc Lehmann schmorp at schmorp.de
Wed Oct 15 15:59:08 CEST 2008


Yoann brought the following issue to my attention, which affects libev
ev_stat watchers when a file gets deleted which is still open.

----- Forwarded message from Yoann Vandoorselaere <yoann at prelude-ids.org> -----

Subject: libev issue due to inotify bug
From: Yoann Vandoorselaere <yoann at prelude-ids.org>
Date: Mon, 13 Oct 2008 17:25:51 +0200
To: schmorp at schmorp.de
X-Mailer: Evolution 2.22.3.1 

Hello Marc,

We are currently porting Prelude-LML (a log analyzer) to use libev
ev_stat notification in place of GAMIN/basic polling, and wanted to let
you know about an inotify bug that impact vanilla Linux kernel < 2.6.25.

Before 2.6.25, inotify did not notify the user in case a file st_nlink
reached 0 (IN_ATTRIB event). This is problematic for application that
wish to be notified of file deletion although they still have an open
file descriptor on the deleted file (they never get any notification
about the deletion). 

More information about the kernel issue is available here:
http://www.ussg.indiana.edu/hypermail/linux/kernel/0711.3/1208.html


It would be great to add some test case to libev.m4 so that it check
whether the current inotify version is buggy or not (some Linux
distribution use kernel < 2.6.25 but included a patch for this issue).

You can test the problem using the following code:


static void libev_check_cb(struct ev_loop *loop, ev_stat *st, int revents)
{
        int *inotify_work = st->data;
        *inotify_work = TRUE;
}


static void libev_check_timer_cb(struct ev_loop *loop, ev_stat *st, int revents)
{
        ev_unloop(EV_A_ EVUNLOOP_ALL);
}


static void inotify_ok(void)
{
        int fd;
        char fname[1024];
        struct ev_stat event;
        struct ev_timer evt;
        int inotify_ok = FALSE;

        snprintf(fname, sizeof(fname), "%s/test-inotify.XXXXXX", P_tmpdir);

        fd = mkstemp(fname);
        if ( fd < 0 ) {
                fprintf(stderr, "error creating unique temporary filename: %s.\n", strerror(errno));
                return;
        }

        ev_timer_init(&evt, libev_check_timer_cb, 1, 1);
        evt.data = &inotify_ok;
        ev_timer_start(ev_default_loop(0), &evt);

        ev_stat_init(&event, libev_check_cb, fname, 1);
        event.data = &inotify_ok;
        ev_stat_start(ev_default_loop(0), &event);

        unlink(fname);
        ev_loop(ev_default_loop(0), 0);

        if ( ! inotify_ok ) {
                fprintf(stderr, "WARNING: buggy delete detection.\n");
        }

        close(fd);
}

Hope this help,
Regards,

-- 
Yoann Vandoorselaere <yoann at prelude-ids.org>


----- End forwarded message -----

-- 
                The choice of a       Deliantra, the free code+content MORPG
      -----==-     _GNU_              http://www.deliantra.net
      ----==-- _       generation
      ---==---(_)__  __ ____  __      Marc Lehmann
      --==---/ / _ \/ // /\ \/ /      pcg at goof.com
      -=====/_/_//_/\_,_/ /_/\_\



More information about the libev mailing list