Subject: Re: [PATCH v9 00/30] Builtin FSMonitor Part 2

From: Ævar Arnfjörð Bjarmason <[email-masked]>
Date: Sat, 26 Mar 2022 01:48:10 +0100

On Fri, Mar 25 2022, Jeff Hostetler wrote:

> On 3/25/22 3:02 PM, [email-masked] wrote:
>> On March 25, 2022 2:03 PM, Jeff Hostetler wrote:
> [...]
>> So that we can plan for next time, would you mind giving some
>> thought to what would be required for Linux and whether it makes
>> sense to extend this. No urgency, but I would not mind participating
>> - assuming my $DAYJOB lets me. I have a backlog for git that I need
>> to get done first anyway.
>> Kind Regards,
>> Randall
>> 
>
> A Linux backend would need to:
>
> (1) stub in compat/fsmonitor/fsm-listen-linux.c (see commits
>     8/30 and 9/30 in this series).  That gives you enough for
>     the builtin/fsmonitor--daemon.c to link with your new
>     backend.
>
> (2) populate those 4 routines.
>
> (2a) __ctor() and __dtor() will be called from the main thread
>      before and after the listener thread is created.  You can
>      do anything you need there to register/deregister a watch
>      on the FS.
>
>      See inotify() and/or fanotify().  I haven't looked at those
>      routines for a while, so all I can say is google it.
>
> (2b) __stop_async() will be called by "some" thread to request
>      that the listener thread stop listening.  This is an async
>      request, so just notify the listener thread and return.
>      (There is an example of this for Unix in
>       compat/simple-ipc/ipc-unix-sockets.c)
>
> (2c) __loop() will be called (once) by the "listener" thread-proc
>      to process/service events from the FS until a shutdown event
>      is received.  This runs in the body of the "listener" thread.
>      It should probably use poll()/select()/whatever on fd's from
>      inotify()/fsnotify() *and* whatever you set up in (2b) to
>      wait for a shutdown event.
>
>      (There are examples of this wait-loop in the Windows and Mac
>      backends, but they have *very* different FS event and wait
>      models, so they might not be very helpful here.)
>
>      When you get a "batch" of one or more paths from the FS,
>      use the fsmonitor_classify_*() routines to classify or
>      discard them and then use fsmonitor_publish() to publish
>      newly changed paths to the other threads.
>
>      The core code will handle path de-dup and all locking so
>      you don't have to.
>
> It is important that you figure out how to get recursive data
> from the FS.  We want to watch the complete worktree.  Windows
> and Mac let you register the root directory of the watch and
> automatically give me events for anything under it.  IIRC,
> inotify() only gave you a single directory and you had to
> readdir() and recurse to get fd's to the subdirs.  I haven't
> looked to see if fanotify() solves that or not.  So there may
> be some fd juggling and tree walking required.  That could/should
> all be hidden inside the __ctor() and/or __loop() routines.
>
> (3) stub in compat/fsmonitor/fsm-settings-linux.c (see the
>     peers.  This is needed to link.
>
> (4) fill in any platform-specific reasons why you might want
>     to reject a worktree.  for example, when they are remote
>     (NFS/SMB might support it, but do you trust it....)
>
> (5) stub in compat/fsmonitor/fsm-health-linux.c (see
>     fsm-health-*.c in part 3).  That will give you enough
>     to link the health thread.
>
> (6) this part is probably optional (at least for now).  we
>     can use this if we want to add platform-specific things
>     like auto-shutdown after idle.  The mac version is currently
>     empty, but the Windows version needs to watch the worktree
>     root separately (because the FS watch is limited to what
>     is *within* watched directory root).
>
> That should help get you get started.
> Let me know if you have questions.

Wouldn't it be much simpler POC in this case to write "watchman
backend"?  Then we'd both get a Linux backend, and an alternate backend
for the other platforms to validate their implementation.

Some past references to that:
https://lore.kernel.org/git/[email-masked]/ &
https://lore.kernel.org/git/[email-masked]/