X Tutup
The Wayback Machine - https://web.archive.org/web/20221017170543/https://github.com/git/git/pull/1352
Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fsmonitor: Implement fsmonitor for Linux #1352

Open
wants to merge 12 commits into
base: master
Choose a base branch
from

Conversation

edecosta-mw
Copy link
Contributor

@edecosta-mw edecosta-mw commented Sep 29, 2022

Goal is to deliver fsmonitor for Linux that is on par with fsmonitor for Windows and Mac OS.

This patch set builds upon previous work for done for Windows and Mac OS (first 6 patches) to implement a fsmonitor back-end for Linux based on the Linux inotify API. inotify differs significantly from the equivalent Windows and Mac OS APIs in that a watch must be registered for every directory of interest (rather than a singular watch at the root of the directory tree) and special care must be taken to handle directory renames correctly.

More information about inotify: https://man7.org/linux/man-pages/man7/inotify.7.html

v1 differs from v0:

  • Code review feedback
  • Update how and which code can be shared between Mac OS and Linux
  • Increase polling frequency to every 1ms (matches Mac OS)
  • Updates to t7527 to improve test stability

cc: Eric Sunshine sunshine@sunshineco.com
cc: Ævar Arnfjörð Bjarmason avarab@gmail.com

@gitgitgadget-git
Copy link

gitgitgadget-git bot commented Sep 29, 2022

There are issues in commit 39f88e5:
fsmonitor: determine if filesystem is local or remote
Lines in the body of the commit messages should be wrapped between 60 and 76 characters.
Indented lines, and lines without whitespace, are exempt

@edecosta-mw edecosta-mw force-pushed the fsmonitor_linux branch 10 times, most recently from 8622a77 to 20f3e77 Compare Oct 6, 2022
@gitgitgadget-git
Copy link

gitgitgadget-git bot commented Oct 6, 2022

There are issues in commit c74ffa4:
fsmonitor: test updates
Lines in the body of the commit messages should be wrapped between 60 and 76 characters.
Indented lines, and lines without whitespace, are exempt

@edecosta-mw edecosta-mw force-pushed the fsmonitor_linux branch 6 times, most recently from 73d2435 to 77ed35b Compare Oct 7, 2022
@edecosta-mw
Copy link
Contributor Author

edecosta-mw commented Oct 9, 2022

/submit

@gitgitgadget-git
Copy link

gitgitgadget-git bot commented Oct 9, 2022

Submitted as pull.1352.git.git.1665326258.gitgitgadget@gmail.com

To fetch this version into FETCH_HEAD:

git fetch https://github.com/gitgitgadget/git/ pr-git-1352/edecosta-mw/fsmonitor_linux-v1

To fetch this version to local tag pr-git-1352/edecosta-mw/fsmonitor_linux-v1:

git fetch --no-tags https://github.com/gitgitgadget/git/ tag pr-git-1352/edecosta-mw/fsmonitor_linux-v1

@gitgitgadget-git
Copy link

gitgitgadget-git bot commented Oct 9, 2022

This branch is now known as ed/fsmonitor-inotify.

@gitgitgadget-git
Copy link

gitgitgadget-git bot commented Oct 9, 2022

This patch series was integrated into seen via 529e7ca.

@gitgitgadget-git gitgitgadget-git bot added the seen label Oct 9, 2022
@gitgitgadget-git
Copy link

gitgitgadget-git bot commented Oct 9, 2022

On the Git mailing list, Junio C Hamano wrote (reply to this):

"Eric DeCosta via GitGitGadget" <gitgitgadget@gmail.com> writes:

> Goal is to deliver fsmonitor for Linux that is on par with fsmonitor for
> Windows and Mac OS.
>
> This patch set builds upon previous work for done for Windows and Mac OS
> (first 6 patches) ...

For those who are watching from sidelines...

The Windows part is already in Git 2.38; the changes needed for
macOS are already in 'next' and the first 6 patches in this 12-patch
series are identical to them.  The patches 7-12 are new.

> to implement a fsmonitor back-end for Linux based on the
> Linux inotify API. inotify differs significantly from the equivalent Windows
> and Mac OS APIs in that a watch must be registered for every directory of
> interest (rather than a singular watch at the root of the directory tree)
> and special care must be taken to handle directory renames correctly.

@gitgitgadget-git
Copy link

gitgitgadget-git bot commented Oct 10, 2022

On the Git mailing list, Eric Sunshine wrote (reply to this):

On Sun, Oct 9, 2022 at 7:55 PM Junio C Hamano <gitster@pobox.com> wrote:
> "Eric DeCosta via GitGitGadget" <gitgitgadget@gmail.com> writes:
> > Goal is to deliver fsmonitor for Linux that is on par with fsmonitor for
> > Windows and Mac OS.
> >
> > This patch set builds upon previous work for done for Windows and Mac OS
> > (first 6 patches) ...
>
> For those who are watching from sidelines...
>
> The Windows part is already in Git 2.38; the changes needed for
> macOS are already in 'next' and the first 6 patches in this 12-patch
> series are identical to them.  The patches 7-12 are new.

Thanks for clarifying. I found it confusing that there were a number
of patches in this series which I had already seen despite the cover
letter's claim that this series builds upon "previous work". Thus, it
wasn't clear whether this series was a reroll (refining some
already-seen patches) with additional patches for Linux, or if it was
purely new work with the original patches included by accident[1].

[1]: In the few times I've used GitGitGadget, I've had to jump through
hoops to make it send just the "new" patches when I've built a series
atop some other series only in 'next' or 'seen', so I can understand
the inclusion of the first six patches being accidental. (Regarding
the hoop-jumping, it may be that I just don't understand how to "work"
GitGitGadget or GitHub pull-requests.)

@gitgitgadget-git
Copy link

gitgitgadget-git bot commented Oct 10, 2022

User Eric Sunshine <sunshine@sunshineco.com> has been added to the cc: list.

@@ -0,0 +1,163 @@
#include "fsmonitor.h"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the Git mailing list, Ævar Arnfjörð Bjarmason wrote (reply to this):

On Sun, Oct 09 2022, Eric DeCosta via GitGitGadget wrote:

> From: Eric DeCosta <edecosta@mathworks.com>
>
> Compare the given path to the mounted filesystems. Find the mount that is
> the longest prefix of the path (if any) and determine if that mount is on a
> local or remote filesystem.
>
> Signed-off-by: Eric DeCosta <edecosta@mathworks.com>
> ---
>  compat/fsmonitor/fsm-path-utils-linux.c | 163 ++++++++++++++++++++++++
>  1 file changed, 163 insertions(+)
>  create mode 100644 compat/fsmonitor/fsm-path-utils-linux.c
>
> diff --git a/compat/fsmonitor/fsm-path-utils-linux.c b/compat/fsmonitor/fsm-path-utils-linux.c
> new file mode 100644
> index 00000000000..369692a788f
> --- /dev/null
> +++ b/compat/fsmonitor/fsm-path-utils-linux.c
> @@ -0,0 +1,163 @@
> +#include "fsmonitor.h"
> +#include "fsmonitor-path-utils.h"
> +#include <errno.h>
> +#include <mntent.h>
> +#include <sys/mount.h>
> +#include <sys/statvfs.h>
> +
> +/*
> + * https://github.com/coreutils/gnulib/blob/master/lib/mountlist.c
> + */
> +#ifndef ME_REMOTE
> +/* A file system is "remote" if its Fs_name contains a ':'
> +   or if (it is of type (smbfs or cifs) and its Fs_name starts with '//')
> +   or if it is of any other of the listed types
> +   or Fs_name is equal to "-hosts" (used by autofs to mount remote fs).
> +   "VM" file systems like prl_fs or vboxsf are not considered remote here. */
> +# define ME_REMOTE(Fs_name, Fs_type)            \
> +	(strchr (Fs_name, ':') != NULL              \
> +	 || ((Fs_name)[0] == '/'                    \
> +		 && (Fs_name)[1] == '/'                 \
> +		 && (strcmp (Fs_type, "smbfs") == 0     \
> +			 || strcmp (Fs_type, "smb3") == 0   \
> +			 || strcmp (Fs_type, "cifs") == 0)) \
> +	 || strcmp (Fs_type, "acfs") == 0           \
> +	 || strcmp (Fs_type, "afs") == 0            \
> +	 || strcmp (Fs_type, "coda") == 0           \
> +	 || strcmp (Fs_type, "auristorfs") == 0     \
> +	 || strcmp (Fs_type, "fhgfs") == 0          \
> +	 || strcmp (Fs_type, "gpfs") == 0           \
> +	 || strcmp (Fs_type, "ibrix") == 0          \
> +	 || strcmp (Fs_type, "ocfs2") == 0          \
> +	 || strcmp (Fs_type, "vxfs") == 0           \
> +	 || strcmp ("-hosts", Fs_name) == 0)
> +#endif

So, this is just copy/pasted GPLv3 code into our GPLv2-only codebase?:
https://github.com/coreutils/gnulib/blob/cd1fdabe8b66c102124b6a5b0c97dded20246b46/lib/mountlist.c#L230-L247

> +static struct mntent *find_mount(const char *path, const struct statvfs *fs)
> +{
> +	const char *const mounts = "/proc/mounts";
> +	const char *rp = real_pathdup(path, 1);
> +	struct mntent *ment = NULL;
> +	struct mntent *found = NULL;
> +	struct statvfs mntfs;
> +	FILE *fp;
> +	int dlen, plen, flen = 0;
> +
> +	fp = setmntent(mounts, "r");
> +	if (!fp) {
> +		error_errno(_("setmntent('%s') failed"), mounts);
> +		return NULL;

This code would probably be nicer if you returned int, and passed a
pointer to a struct to populate as a paremeter. Then you could just
"return error..." for this and the below cases.

> +	}
> +
> +	plen = strlen(rp);
> +
> +	/* read all the mount information and compare to path */
> +	while ((ment = getmntent(fp)) != NULL) {
> +		if (statvfs(ment->mnt_dir, &mntfs)) {
> +			switch (errno) {
> +			case EPERM:
> +			case ESRCH:
> +			case EACCES:
> +				continue;
> +			default:
> +				error_errno(_("statvfs('%s') failed"), ment->mnt_dir);
> +				endmntent(fp);is 
> +				return NULL;
> +			}
> +		}
> +
> +		/* is mount on the same filesystem and is a prefix of the path */
> +		if ((fs->f_fsid == mntfs.f_fsid) &&
> +			!strncmp(ment->mnt_dir, rp, strlen(ment->mnt_dir))) {
> +			dlen = strlen(ment->mnt_dir);
> +			if (dlen > plen)
> +				continue;
> +			/*
> +			 * root is always a potential match; otherwise look for
> +			 * directory prefix
> +			 */
> +			if ((dlen == 1 && ment->mnt_dir[0] == '/') ||
> +				(dlen > flen && (!rp[dlen] || rp[dlen] == '/'))) {
> +				flen = dlen;
> +				/*
> +				 * https://man7.org/linux/man-pages/man3/getmntent.3.html
> +				 *
> +				 * The pointer points to a static area of memory which is
> +				 * overwritten by subsequent calls to getmntent().
> +				 */
> +				if (!found)
> +					CALLOC_ARRAY(found, 1);

It seems we never populate >1 of these, so don't you just want
xmalloc(). Or actually...

> +				free(found->mnt_dir);
> +				free(found->mnt_type);
> +				free(found->mnt_fsname);
> +				found->mnt_dir = xmemdupz(ment->mnt_dir, strlen(ment->mnt_dir));
> +				found->mnt_type = xmemdupz(ment->mnt_type, strlen(ment->mnt_type));
> +				found->mnt_fsname = xmemdupz(ment->mnt_fsname, strlen(ment->mnt_fsname));

Don't mix mem*() and str*(). In this case we need the string to be '\0'
delimited, so use xstrndup().

And once we do that, we might wonder why we're explicitly finding the
'\0', just to pass it to the xstrn*() function, when we can just do:

	found->mnt_dir = xstrdup(ment->mnt_dir);
	...

Which would AFAICT be equivalent to what you're doing here.

> +			}
> +		}
> +	}
> +	endmntent(fp);
> +
> +	return found;
> +}
> +
> +int fsmonitor__get_fs_info(const char *path, struct fs_info *fs_info)
> +{
> +	struct mntent *ment;

...make this (or above) a "struct mntent ment", then pass &ment down, so
we can fill that struct? Dunno...

> +	struct statvfs fs;
> +
> +	if (statvfs(path, &fs))
> +		return error_errno(_("statvfs('%s') failed"), path);
> +
> +	ment = find_mount(path, &fs);
> +	if (!ment)
> +		return -1;
> +
> +	trace_printf_key(&trace_fsmonitor,
> +			 "statvfs('%s') [flags 0x%08lx] '%s' '%s'",
> +			 path, fs.f_flag, ment->mnt_type, ment->mnt_fsname);
> +
> +	if (ME_REMOTE(ment->mnt_fsname, ment->mnt_type))
> +		fs_info->is_remote = 1;
> +	else
> +		fs_info->is_remote = 0;

Shorter:

	fs_info->is_remote = ME_REMOTE(ment->mnt_fsname, ment->mnt_type);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the Git mailing list, Eric DeCosta wrote (reply to this):

> -----Original Message-----
> From: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> Sent: Monday, October 10, 2022 6:04 AM
> To: Eric DeCosta via GitGitGadget <gitgitgadget@gmail.com>
> Cc: git@vger.kernel.org; Eric DeCosta <edecosta@mathworks.com>
> Subject: Re: [PATCH 08/12] fsmonitor: determine if filesystem is local or
> remote
> 
> 
> On Sun, Oct 09 2022, Eric DeCosta via GitGitGadget wrote:
> 
> > From: Eric DeCosta <edecosta@mathworks.com>
> >
> > Compare the given path to the mounted filesystems. Find the mount that
> > is the longest prefix of the path (if any) and determine if that mount
> > is on a local or remote filesystem.
> >
> > Signed-off-by: Eric DeCosta <edecosta@mathworks.com>
> > ---
> > compat/fsmonitor/fsm-path-utils-linux.c | 163
> ++++++++++++++++++++++++
> > 1 file changed, 163 insertions(+)
> > create mode 100644 compat/fsmonitor/fsm-path-utils-linux.c
> >
> > diff --git a/compat/fsmonitor/fsm-path-utils-linux.c
> > b/compat/fsmonitor/fsm-path-utils-linux.c
> > new file mode 100644
> > index 00000000000..369692a788f
> > --- /dev/null
> > +++ b/compat/fsmonitor/fsm-path-utils-linux.c
> > @@ -0,0 +1,163 @@
> > +#include "fsmonitor.h"
> > +#include "fsmonitor-path-utils.h"
> > +#include <errno.h>
> > +#include <mntent.h>
> > +#include <sys/mount.h>
> > +#include <sys/statvfs.h>
> > +
> > +/*
> > + * https://github.com/coreutils/gnulib/blob/master/lib/mountlist.c
> > +<https://protect-
> us.mimecast.com/s/wKJsC9rj7lc3WKmYUOq9E9?domain=gith
> > +ub.com>
> > + */
> > +#ifndef ME_REMOTE
> > +/* A file system is "remote" if its Fs_name contains a ':'
> > + or if (it is of type (smbfs or cifs) and its Fs_name starts with
> > +'//')  or if it is of any other of the listed types  or Fs_name is
> > +equal to "-hosts" (used by autofs to mount remote fs).
> > + "VM" file systems like prl_fs or vboxsf are not considered remote
> > +here. */ # define ME_REMOTE(Fs_name, Fs_type) \  (strchr (Fs_name,
> > +':') != NULL \
> > + || ((Fs_name)[0] == '/' \
> > + && (Fs_name)[1] == '/' \
> > + && (strcmp (Fs_type, "smbfs") == 0 \
> > + || strcmp (Fs_type, "smb3") == 0 \
> > + || strcmp (Fs_type, "cifs") == 0)) \ strcmp (Fs_type, "acfs") == 0 \
> > + || strcmp (Fs_type, "afs") == 0 \ strcmp (Fs_type, "coda") == 0 \
> > + || strcmp (Fs_type, "auristorfs") == 0 \ strcmp (Fs_type, "fhgfs")
> > + || == 0 \ strcmp (Fs_type, "gpfs") == 0 \ strcmp (Fs_type, "ibrix")
> > + || == 0 \ strcmp (Fs_type, "ocfs2") == 0 \ strcmp (Fs_type, "vxfs")
> > + || == 0 \ strcmp ("-hosts", Fs_name) == 0)
> > +#endif
> 
> So, this is just copy/pasted GPLv3 code into our GPLv2-only codebase?:
> https://github.com/coreutils/gnulib/blob/cd1fdabe8b66c102124b6a5b0c97d
> ded20246b46/lib/mountlist.c#L230-L247 <https://protect-
> us.mimecast.com/s/zxPbC0RMy1hoXW2rCOSXJD?domain=github.com>
> 
Yes. I was hoping for some guidance as to what to do with ME_REMOTE.

I also found it, verbatim,  here in midnight commander:
https://github.com/MidnightCommander/mc/blob/e48cd98ac13a9b4366bd88287f632413766b967f/src/filemanager/mountlist.c#L258-L281

But that's just another GPLv3 code base.

> > +static struct mntent *find_mount(const char *path, const struct
> > +statvfs *fs) {  const char *const mounts = "/proc/mounts";  const
> > +char *rp = real_pathdup(path, 1);  struct mntent *ment = NULL;
> > +struct mntent *found = NULL;  struct statvfs mntfs;  FILE *fp;  int
> > +dlen, plen, flen = 0;
> > +
> > + fp = setmntent(mounts, "r");
> > + if (!fp) {
> > + error_errno(_("setmntent('%s') failed"), mounts); return NULL;
> 
> This code would probably be nicer if you returned int, and passed a pointer
> to a struct to populate as a paremeter. Then you could just "return error..."
> for this and the below cases.
> 
> > + }
> > +
> > + plen = strlen(rp);
> > +
> > + /* read all the mount information and compare to path */ while
> > + ((ment = getmntent(fp)) != NULL) { if (statvfs(ment->mnt_dir,
> > + &mntfs)) { switch (errno) { case EPERM:
> > + case ESRCH:
> > + case EACCES:
> > + continue;
> > + default:
> > + error_errno(_("statvfs('%s') failed"), ment->mnt_dir);
> > + endmntent(fp);is return NULL; } }
> > +
> > + /* is mount on the same filesystem and is a prefix of the path */ if
> > + ((fs->f_fsid == mntfs.f_fsid) && !strncmp(ment->mnt_dir, rp,
> > + strlen(ment->mnt_dir))) { dlen = strlen(ment->mnt_dir); if (dlen >
> > + plen) continue;
> > + /*
> > + * root is always a potential match; otherwise look for
> > + * directory prefix
> > + */
> > + if ((dlen == 1 && ment->mnt_dir[0] == '/') || (dlen > flen &&
> > + (!rp[dlen] || rp[dlen] == '/'))) { flen = dlen;
> > + /*
> > + * https://man7.org/linux/man-pages/man3/getmntent.3.html
> > + <https://protect-
> us.mimecast.com/s/aOmSCgJyVrT01WlYc76tSR?domain=man
> > + 7.org>
> > + *
> > + * The pointer points to a static area of memory which is
> > + * overwritten by subsequent calls to getmntent().
> > + */
> > + if (!found)
> > + CALLOC_ARRAY(found, 1);
> 
> It seems we never populate >1 of these, so don't you just want xmalloc(). Or
> actually...
> 
> > + free(found->mnt_dir);
> > + free(found->mnt_type);
> > + free(found->mnt_fsname);
> > + found->mnt_dir = xmemdupz(ment->mnt_dir, strlen(ment->mnt_dir));
> > + found->mnt_type = xmemdupz(ment->mnt_type, strlen(ment-
> >mnt_type));
> > + found->mnt_fsname = xmemdupz(ment->mnt_fsname,
> > + found->strlen(ment->mnt_fsname));
> 
> Don't mix mem*() and str*(). In this case we need the string to be '\0'
> delimited, so use xstrndup().
> 
> And once we do that, we might wonder why we're explicitly finding the '\0',
> just to pass it to the xstrn*() function, when we can just do:
> 
> found->mnt_dir = xstrdup(ment->mnt_dir);
> ...
> 
> Which would AFAICT be equivalent to what you're doing here.
> 
> > + }
> > + }
> > + }
> > + endmntent(fp);
> > +
> > + return found;
> > +}
> > +
> > +int fsmonitor__get_fs_info(const char *path, struct fs_info *fs_info)
> > +{  struct mntent *ment;
> 
> ...make this (or above) a "struct mntent ment", then pass &ment down, so
> we can fill that struct? Dunno...
> 
> > + struct statvfs fs;
> > +
> > + if (statvfs(path, &fs))
> > + return error_errno(_("statvfs('%s') failed"), path);
> > +
> > + ment = find_mount(path, &fs);
> > + if (!ment)
> > + return -1;
> > +
> > + trace_printf_key(&trace_fsmonitor,
> > + "statvfs('%s') [flags 0x%08lx] '%s' '%s'", path, fs.f_flag,
> > + ment->mnt_type, ment->mnt_fsname);
> > +
> > + if (ME_REMOTE(ment->mnt_fsname, ment->mnt_type)) fs_info-
> >is_remote
> > + = 1; else fs_info->is_remote = 0;
> 
> Shorter:
> 
> fs_info->is_remote = ME_REMOTE(ment->mnt_fsname, ment->mnt_type);

@gitgitgadget-git
Copy link

gitgitgadget-git bot commented Oct 10, 2022

User Ævar Arnfjörð Bjarmason <avarab@gmail.com> has been added to the cc: list.

@gitgitgadget-git
Copy link

gitgitgadget-git bot commented Oct 10, 2022

On the Git mailing list, Junio C Hamano wrote (reply to this):

"Eric DeCosta via GitGitGadget" <gitgitgadget@gmail.com> writes:

> Goal is to deliver fsmonitor for Linux that is on par with fsmonitor for
> Windows and Mac OS.
>
> This patch set builds upon previous work for done for Windows and Mac OS
> (first 6 patches) to implement a fsmonitor back-end for Linux based on the
> Linux inotify API. inotify differs significantly from the equivalent Windows
> and Mac OS APIs in that a watch must be registered for every directory of
> interest (rather than a singular watch at the root of the directory tree)
> and special care must be taken to handle directory renames correctly.

I am seeing occasional breakages of t7527.16 that does not seem to
reproduce reliably.

@gitgitgadget-git
Copy link

gitgitgadget-git bot commented Oct 10, 2022

There was a status update in the "New Topics" section about the branch ed/fsmonitor-inotify on the Git mailing list:

Bundled fsmonitor for Linux using inotify API.

Needs review.
source: <pull.1326.v15.git.1664904751.gitgitgadget@gmail.com>
source: <pull.1352.git.git.1665326258.gitgitgadget@gmail.com>

edecosta-mw added 6 commits Oct 12, 2022
Provide a common interface for getting basic filesystem information
including filesystem type and whether the filesystem is remote.

Refactor existing code for getting basic filesystem info and detecting
remote file systems to the new interface.

Refactor filesystem checks to leverage new interface. For macOS,
error-out if the Unix Domain socket (UDS) file is on a remote
filesystem.

Signed-off-by: Eric DeCosta <edecosta@mathworks.com>
If the .git directory is on a remote filesystem, create the socket
file in 'fsmonitor.socketDir' if it is defined, else create it in $HOME.

Signed-off-by: Eric DeCosta <edecosta@mathworks.com>
If monitoring is done via fsmonitor hook rather than IPC there is no
need to check if the location of the Unix Domain socket (UDS) file is
on a remote filesystem.

Signed-off-by: Eric DeCosta <edecosta@mathworks.com>
Starting with macOS 10.15 (Catalina), Apple introduced a new feature
called 'firmlinks' in order to separate the boot volume into two
volumes, one read-only and one writable but still present them to the
user as a single volume. Along with this change, Apple removed the
ability to create symlinks in the root directory and replaced them with
'synthetic firmlinks'. See 'man synthetic.conf'

When FSEevents reports the path of changed files, if the path involves
a synthetic firmlink, the path is reported from the point of the
synthetic firmlink and not the real path. For example:

Real path:
/System/Volumes/Data/network/working/directory/foo.txt

Synthetic firmlink:
/network -> /System/Volumes/Data/network

FSEvents path:
/network/working/directory/foo.txt

This causes the FSEvents path to not match against the worktree
directory.

There are several ways in which synthetic firmlinks can be created:
they can be defined in /etc/synthetic.conf, the automounter can create
them, and there may be other means. Simply reading /etc/synthetic.conf
is insufficient. No matter what process creates synthetic firmlinks,
they all get created in the root directory.

Therefore, in order to deal with synthetic firmlinks, the root directory
is scanned and the first possible synthetic firmink that, when resolved,
is a prefix of the worktree is used to map FSEvents paths to worktree
paths.

Signed-off-by: Eric DeCosta <edecosta@mathworks.com>
If fsmonitor is not in a compatible state, warn with an appropriate message.

Signed-off-by: Eric DeCosta <edecosta@mathworks.com>
Add documentation for 'fsmonitor.allowRemote' and 'fsmonitor.socketDir'.
Call-out experimental nature of 'fsmonitor.allowRemote' and limited
filesystem support for 'fsmonitor.socketDir'.

Signed-off-by: Eric DeCosta <edecosta@mathworks.com>
@gitgitgadget-git
Copy link

gitgitgadget-git bot commented Oct 12, 2022

There was a status update in the "Cooking" section about the branch ed/fsmonitor-inotify on the Git mailing list:

Bundled fsmonitor for Linux using inotify API.

Needs review.
source: <pull.1352.git.git.1665326258.gitgitgadget@gmail.com>

@edecosta-mw edecosta-mw force-pushed the fsmonitor_linux branch 3 times, most recently from 704e978 to bc207fe Compare Oct 14, 2022
edecosta-mw added 6 commits Oct 14, 2022
Linux and Mac OS can share some of the code originally developed for Mac OS.

Minor update to compat/fsmonitor/fsm-ipc-unix.c to make it cross-platform.
Mac OS and Linux can share fsm-ipc-unix.c

Both platforms can also share compat/fsmonitor/fsm-settings-unix.c but we
will leave room for future, platform-specific checks by having the platform-
specific implementations call into fsm-settings-unix.

Signed-off-by: Eric DeCosta <edecosta@mathworks.com>
Compare the given path to the mounted filesystems. Find the mount that is
the longest prefix of the path (if any) and determine if that mount is on a
local or remote filesystem.

Signed-off-by: Eric DeCosta <edecosta@mathworks.com>
Implement a filesystem change listener for Linux based on the inotify API:
https://man7.org/linux/man-pages/man7/inotify.7.html

inotify requires registering a watch on every directory in the worktree and
special handling of moves/renames.

Signed-off-by: Eric DeCosta <edecosta@mathworks.com>
Update build to enable fsmonitor for Linux.

Signed-off-by: Eric DeCosta <edecosta@mathworks.com>
t7527-builtin-fsmonitor was leaking fsmonitor--daemon processes in some
cases.

Accomodate slight difference in the number of events generated on Linux.

On lower-powered systems, spin a little to give the daemon time
to respond to and log filesystem events.

Signed-off-by: Eric DeCosta <edecosta@mathworks.com>
Update the documentation for Linux.

Signed-off-by: Eric DeCosta <edecosta@mathworks.com>
@edecosta-mw
Copy link
Contributor Author

edecosta-mw commented Oct 14, 2022

/submit

@gitgitgadget-git
Copy link

gitgitgadget-git bot commented Oct 14, 2022

Submitted as pull.1352.v2.git.git.1665783944.gitgitgadget@gmail.com

To fetch this version into FETCH_HEAD:

git fetch https://github.com/gitgitgadget/git/ pr-git-1352/edecosta-mw/fsmonitor_linux-v2

To fetch this version to local tag pr-git-1352/edecosta-mw/fsmonitor_linux-v2:

git fetch --no-tags https://github.com/gitgitgadget/git/ tag pr-git-1352/edecosta-mw/fsmonitor_linux-v2

@gitgitgadget-git
Copy link

gitgitgadget-git bot commented Oct 14, 2022

On the Git mailing list, Junio C Hamano wrote (reply to this):

"Eric DeCosta via GitGitGadget" <gitgitgadget@gmail.com> writes:

> Goal is to deliver fsmonitor for Linux that is on par with fsmonitor for
> Windows and Mac OS.
>
> This patch set builds upon previous work for done for Windows and Mac OS
> (first 6 patches) to implement a fsmonitor back-end for Linux based on the
> Linux inotify API.

Again, the first six patches are a part of what is queued as
ed/fsmonitor-on-networked-macos that is now in 'next' but lacks a
fix-up commit from Jeff King.

I understand that it might not be easy/possible (e.g. perhaps it is
a limitation of GGG?), but I really prefer not to see them re-posted
as part of this series, as I have to apply them and make sure there
are no changes from the last one before discarding them.

Anyway, thanks for an update.  Will requeue.

@gitgitgadget-git
Copy link

gitgitgadget-git bot commented Oct 14, 2022

This patch series was integrated into seen via c7e67d6.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
1 participant
X Tutup