mheily / libkqueue

kqueue(2) compatibility library
Other
237 stars 77 forks source link

Support for eventfd file descriptors? #97

Closed timwoj closed 3 years ago

timwoj commented 4 years ago

The Zeek project had a user report that libkqueue returns an error when used with a load-balanced pf-ring zero-copy interface. The pf_ring-zc system uses eventfd for load balanced interfaces. A call to kevent() returns a "Bad Address" error when adding the interface.

Does libkqueue support eventfd descriptors? I haven't tried to reduce it down to a simple example where I just open an eventfd manually, but opening the load-balanced interface via libpcap and then trying to pass that FD into libkqueue definitely fails. I have a pf_ring interface all set up here for testing so I can definitely provide any information you need. For starters, here's a debug log:

KQ [16851]: libkqueue_init(): library initialization complete
KQ [16851]: filter_register_all(): complete
KQ [16852]: monitoring_thread_loop(): tid=16852 - monitoring thread started
KQ [16851]: linux_kqueue_init(): active_kqueues=1
KQ [16851]: linux_kqueue_init(): kq=0xb232e0 - monitoring fd=4 for closure
KQ [16851]: kqueue(): kq=0xb232e0 - alloced with fd=5
KQ [16851]: map_insert(): idx=5 - inserted ptr=0xb232e0 into map
Using fd 10
KQ [16851]: kevent(): --- kevent 1 --- (nchanges = 1 nevents = 0)
KQ [16851]: kevent(): waiting for &(kq)->kq_mtx
KQ [16851]: kevent(): locked &(kq)->kq_mtx
KQ [16851]: kevent_copyin(): nchanges=1 nevents=0
KQ [16851]: kevent_copyin_one(): src={ ident=10, filter=-1 (EVFILT_READ), flags=0x0001 (EV_ADD), fflags=0x0000 (), data=0, udata=(nil) }
KQ [16851]: linux_get_descriptor_type(): unknown fd type: Bad file descriptor (errno=9)
KQ [16851]: kevent_copyin_one(): kn_create failed
KQ [16851]: knote_release(): kn=0xb28ab0 - freeing
KQ [16851]: kevent_copyin(): errno=Bad address
KQ [16851]: kevent(): unlocked &(kq)->kq_mtx
KQ [16851]: kevent(): (1) kevent_copyin rv=-1
KQ [16851]: kevent(): --- END kevent 1 ret -1 ---

We do know that libpcap supports these interfaces correctly. Earlier versions of our software worked with them, prior to our change over to use libkqueue.

timwoj commented 3 years ago

Any thoughts on this? Or maybe pointers on where I can start looking into it myself? Zeek has a new release coming in the next few months and I'd love to get this fixed before then so I can make sure it works over there.

arr2036 commented 3 years ago

There's no reason it shouldn't work. linux_get_descriptor_type is a Linux specific function use to determine what type of file descriptor was passed in by the caller (file, socket, other exotic resource type...). We need to know this so we can use resource specific eventing facilities for retrieving events.

The issue is that the FD returned by eventfd() doesn't have an st_mode type flag we recognise.

Could you try with 6095fad38ed43383f7499b6a079598d7e7cf3c33 and let me know the st_mode value that gets printed in the debug output.

timwoj commented 3 years ago

Here's that output:

KQ [13932]: linux_get_descriptor_type(): fd=10 unknown fd type, st_mode=0x0: Bad file descriptor (errno=9)

timwoj commented 3 years ago

Great, thank you!