Re: [PATCH v5 4/4] fsmonitor: deal with synthetic firmlinks on macOS
- From
Eric Sunshine <sunshine@sunshineco.com>
- Date
- Sep 11, 2022, 01:01 UTC
- Message-ID
- <CAPig+cT0mKAX86cKPaJ44tH1StH+GnOEHuJEu=G4w2fOKkEgpQ@mail.gmail.com>
- In-Reply-To
- <b7d6cf44695c7b6285573f454ebfd3866fe49f38.1662840031.git.gitgitgadget@gmail.com>
On Sat, Sep 10, 2022 at 4:00 PM Eric DeCosta via GitGitGadget <gitgitgadget@gmail.com> wrote:
Show 10 quoted lines
> 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 invloves > a synthetic firmlink, the path is reported from the point of the > synthetic firmlink and not the real path. For example:
s/invloves/involves/
Show 43 quoted lines
> 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> > --- > diff --git a/compat/fsmonitor/fsm-path-utils-darwin.c b/compat/fsmonitor/fsm-path-utils-darwin.c > @@ -38,3 +41,91 @@ int fsmonitor__is_fs_remote(const char *path) > +/* > + * Scan the root directory for synthetic firmlinks that when resolved > + * are a prefix of the path, stopping at the first one found. > + * > + * Some information about firmlinks and synthetic firmlinks: > + * https://eclecticlight.co/2020/01/23/catalina-boot-volumes/ > + * > + * macOS no longer allows symlinks in the root directory; any link found > + * there is therefore a synthetic firmlink. > + * > + * If this function gets called often, will want to cache all the firmlink > + * information, but for now there is only one caller of this function. > + * > + * If there is more than one alias for the path, that is another > + * matter altogteher. > + */
s/altogteher/altogether/
Show 15 quoted lines
> diff --git a/fsmonitor-path-utils.h b/fsmonitor-path-utils.h
> @@ -1,6 +1,14 @@
> +struct alias_info
> +{
> + struct strbuf alias;
> + struct strbuf points_to;
> +};
> +/*
> + * Get the alias in given path, if any.
> + *
> + * Sets alias to the first alias that matches any part of the path.
> + *
> + * Returns -1 on error, 0 otherwise.
> + */
> +int fsmonitor__get_alias(const char *path, struct alias_info *info);I suppose it's somewhat clear here that the caller is responsible for releasing the strbufs in alias_info (though it's not clear why they need to be strbufs in the first place)...
Show 7 quoted lines
> +/* > + * Resolve the path against the given alias. > + * > + * Returns the resolved path if there is one, NULL otherwise. > + */ > +char *fsmonitor__resolve_alias(const char *path, > + const struct alias_info *info);
But what about the return value from this function? It's `char*` which suggests a possible ownership transfer(?). Is the caller responsible for freeing it? If so, perhaps the documentation could state that.