Hello everybody

The context: 
perfused attemps to implement Linux's FUSE kernel API on NetBSD. Linux
has a /dev/fuse character device, perfused presents a /dev/fuse local 
socket. By including <perfuse.h> in files where /dev/fuse is open, and 
linking with -lperfuse, we have open() and mount() intercepted so that
a FUSE filesystem can talk to perfused over the /dev/fuse socket.

The bug to fix:
The problem is that a socket and a device do not have exactly the 
same semantics. I experience packet losses on some occasions. The 
problem is that FUSE filesystems expect the kernel to sleep on 
resource exhaustion. Therefore they do not bother to check if 
write(2) returns ENOBUFS or EAGAIN. They just write, and the
write system call will return whenever possible, but without ENOBUFS
or EAGAIN.

That breaks with my implementation, as local SOCK_DGRAM sockets will return 
ENOBUFS when kernel is out of buffer memory. As I understand, there is
no way to sleeep instead. 

I thought this was specific to SOCK_DGRAM, since SOCK_DGRAM is not supposed 
to be reliable. I therefore added support for SOCK_SEQPACKET (SOCK_STREAM
is not relevant, I need atomicity) in the kernel, but I face the very same
problem, except that SOCK_SEQPACKET local sockets will return EMSGSIZE
when kernel is out of buffer memory.

The questions:
- did I miss a way to sleep on write when kernel is out of buffer memory?
- if this is impossible, what about adding a socket option for that?
- would it make sense to have such an option be the default for 
SOCK_STREAM and SOCK_SEQPACKET? 

-- 
Emmanuel Dreyfus
m...@netbsd.org

Reply via email to