Re: [RFC] 0/11 fanotify: fscking all notifiction and file accesssystem (intended for antivirus scanning and file indexers)

From: Eric Paris
Date: Thu Oct 02 2008 - 15:26:18 EST


On Fri, 2008-09-26 at 22:34 +0100, Alan Cox wrote:

> The two discussions are fortunately orthogonal. Is there any reason you
> can't use the socket based notification model - that gives you a much
> more natural way to express the thing
>
>
> socket
> bind(AF_FAN, group=foo+flags etc, PF_FAN);
>
> fd = accept(old_fd, &addr[returned info])
>
> close(fd);
>
> as well as fairly natural and importantly standards defined semantics for
> poll including polling for a new file handles, for reconfiguration of
> stuff via get/setsockopt (which do pass stuff like object sizes unlike
> ioctls) and for reading/writing data.

An hour, a whiteboard, 3 other hackers and I think I have a handle on
something you might like a little more.

groups will be 'created' when you call bind(). the struct sockaddr will
include a priority and an event mask. Group names will be eliminated
since priorities must be unique. Two processes will be allowed to
bind() to the same priority if the mask is the same. Those will be
considered to be in the same 'group.'

groups will be destroy when ALL fd's associated with that group are
closed.

calling accept() on the socket from bind will return a new fd. This fd
will be created in the kernel using dentry_open() (just like i do it
today) only I will then try to overload and bastardize the new file to
add additional support so that this it will allow sendmsg() with flags =
MSG_OOB or setsockopt(). I'll also present an alternative below.

the struct sockaddr from the accept() will be filled with a something
like

struct fan_sockaddr {
int version;
unsigned int mask;
pid_t pid;
pid_t tgid;
int f_flags;
}

so this will be a binary interface for metadata. Sending the metadata
about the open fd up the sockaddrs is very slick, but not easily
extended that I can see. Guess we need to get the metadata right the
first time.

One way to do responses from the listeners (like access decisions and
fastpath entries) would be by sending a message back down the new fd
using sendmsg(MSG_OOB). The PF_FAN 'stuff' should be able to get this
message and do its magic. I don't have a format for this message
thought up. Maybe __u32 len, __u32 version, do whatever. Maybe people
would prefer I bastardize on setsockopts() for this new fd send to the
listener? Alternative still to come...

Some operations a listener program might want to do may not be
associated with an event. This might include flushing all fastpaths on
a definitions update or preemptively adding a fastpath entry for an fd.
I suggest calling connect() on the bound fd to connect to the kernel
PF_FAN system. This new fd from connect can then take commands using
either sendmsg() or setsockopt() or really anything since it doesn't
have a 'real file' on the backend.

Is this reasonable? I don't even know the technical hurdles I'm going
to get trying to take a regular file that would pass S_ISREG and adding
on sendmesg() or setsockopt().

So the alternative would be that I could make ALL listener->kernel
communication go over the fd that came from connect(). Setting a
fastpath would be something like

setsockopt(connect_fd, FAN_LEVEL, fastpath_val, fastpath_struct, len);

with fastpath_struct something like

struct fastpath {
int fd;
unsigned int mask
}

Where fd was a currently open fd in the listener process that the
fastpath was intended to be applied to. If I'm using a fd from connect
I can really use any method I want but setsockopt() seems nice since it
includes types and lens. Is is it bad to have a fd whose only
implemented function is setsockopt?

-Eric

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/