From patchwork Mon Sep 19 19:37:52 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric DeCosta X-Patchwork-Id: 12980993 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8B6F1C6FA82 for ; Mon, 19 Sep 2022 19:38:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229726AbiISTiF (ORCPT ); Mon, 19 Sep 2022 15:38:05 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35096 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229473AbiISTiD (ORCPT ); Mon, 19 Sep 2022 15:38:03 -0400 Received: from mail-wr1-x435.google.com (mail-wr1-x435.google.com [IPv6:2a00:1450:4864:20::435]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A6589175A5 for ; Mon, 19 Sep 2022 12:38:01 -0700 (PDT) Received: by mail-wr1-x435.google.com with SMTP id e16so744160wrx.7 for ; Mon, 19 Sep 2022 12:38:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:from:to:cc:subject:date; bh=tSI4wjNeIflA/knXfDoCVkgZBGpukIFoGspd8/vXmZ8=; b=Mehp6wON1TC3ENZJAAL8iJJE7J+ZCjnFLmEI5F3citkzI2uvtT22X3iI3xpwagPBqw Arb9uC20pm4li+y15QPm9+sFw4amphl1a/xljMiqaz5q/2IgdL73itkYoW99euBidRWq MDdFXUEPmLySIYiIMTMxZRehHj0WTuMhgQsDXXDXVn25uO1SeEk/f+6EZf7p8KxE9/Y/ g5+c19xtZM+rzfSLdJG40p5+IjU/whJ6SncZRKu8VQFxf9hGzsCJt7RxcsGX8ugYgEsk mXOug+/1A7qoGIcIaYrdPfKlKfC7bVOz9919d8CwBd27oN8kWZ0S5UBpD5DTgrip466h eoIg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:x-gm-message-state:from:to:cc :subject:date; bh=tSI4wjNeIflA/knXfDoCVkgZBGpukIFoGspd8/vXmZ8=; b=ctCscm8jKf93URgtqlu4St/NsW2sJrZkDJ2pebzhQIAKNPMt7qHPuXN6evKweCWL6I H4eiZxYNVvjkypP24EOVt3hEvHTJMOVOfO/cBeJetDMcQecMs12lIdZYoOM2wy9wUvJb vENVwiJVAnAROeBXukL7PLubTAdfECBCHLGtKjtX5CuRxz4t1gXgcQrGNLR+TYusZSMb CRUyETRj6F/y8R3JcoEjuvxKGj3UORUFpuYPU4oBFlxmORIjYvsSn3P880XT2p7n6eIc 2d7ry6/MXb872j7gLX2aRFAu5D3yoQW7HOsjL6B8Cz16ekbdmIV5I8AlRCAROsxkmQWB 7GCw== X-Gm-Message-State: ACrzQf3SvWfxJQnfNnNwUdw0PHZQX+i66bKuESoBEi6VIWaEJz1phjJU vS55/f9poK1f7/1UwduVttWogW1lRnw= X-Google-Smtp-Source: AMsMyM6uEC6UHhx7LnHu2NxQT9J+v8vDoWFpva/hz907FU6a8tRUzLWekVZHUNJx5r5ffDfCfkzZMQ== X-Received: by 2002:adf:f385:0:b0:228:dbf1:d731 with SMTP id m5-20020adff385000000b00228dbf1d731mr11544414wro.364.1663616279611; Mon, 19 Sep 2022 12:37:59 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id q17-20020adff951000000b00228dff8d975sm14668663wrr.109.2022.09.19.12.37.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Sep 2022 12:37:59 -0700 (PDT) Message-Id: <155a689080658e1953fc4434016f746f371ba08a.1663616277.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Mon, 19 Sep 2022 19:37:52 +0000 Subject: [PATCH v9 1/6] fsmonitor: refactor filesystem checks to common interface Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Jeff Hostetler , Eric Sunshine , Torsten =?utf-8?q?B=C3=B6gershause?= =?utf-8?q?n?= , =?utf-8?b?w4Z2YXIgQXJuZmrDtnLDsA==?= Bjarmason , Ramsay Jones , Johannes Schindelin , Eric DeCosta , Eric DeCosta Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Eric DeCosta From: Eric DeCosta 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 --- Makefile | 1 + compat/fsmonitor/fsm-path-utils-darwin.c | 40 ++++++ compat/fsmonitor/fsm-path-utils-win32.c | 128 +++++++++++++++++ compat/fsmonitor/fsm-settings-darwin.c | 62 +++----- compat/fsmonitor/fsm-settings-win32.c | 172 +---------------------- contrib/buildsystems/CMakeLists.txt | 2 + fsmonitor-path-utils.h | 23 +++ fsmonitor-settings.c | 50 +++++++ 8 files changed, 263 insertions(+), 215 deletions(-) create mode 100644 compat/fsmonitor/fsm-path-utils-darwin.c create mode 100644 compat/fsmonitor/fsm-path-utils-win32.c create mode 100644 fsmonitor-path-utils.h diff --git a/Makefile b/Makefile index d9247ead45b..6e492a67547 100644 --- a/Makefile +++ b/Makefile @@ -2039,6 +2039,7 @@ endif ifdef FSMONITOR_OS_SETTINGS COMPAT_CFLAGS += -DHAVE_FSMONITOR_OS_SETTINGS COMPAT_OBJS += compat/fsmonitor/fsm-settings-$(FSMONITOR_OS_SETTINGS).o + COMPAT_OBJS += compat/fsmonitor/fsm-path-utils-$(FSMONITOR_OS_SETTINGS).o endif ifeq ($(TCLTK_PATH),) diff --git a/compat/fsmonitor/fsm-path-utils-darwin.c b/compat/fsmonitor/fsm-path-utils-darwin.c new file mode 100644 index 00000000000..067cbe6990a --- /dev/null +++ b/compat/fsmonitor/fsm-path-utils-darwin.c @@ -0,0 +1,40 @@ +#include "fsmonitor.h" +#include "fsmonitor-path-utils.h" +#include +#include + +int fsmonitor__get_fs_info(const char *path, struct fs_info *fs_info) +{ + struct statfs fs; + if (statfs(path, &fs) == -1) { + int saved_errno = errno; + trace_printf_key(&trace_fsmonitor, "statfs('%s') failed: %s", + path, strerror(saved_errno)); + errno = saved_errno; + return -1; + } + + trace_printf_key(&trace_fsmonitor, + "statfs('%s') [type 0x%08x][flags 0x%08x] '%s'", + path, fs.f_type, fs.f_flags, fs.f_fstypename); + + if (!(fs.f_flags & MNT_LOCAL)) + fs_info->is_remote = 1; + else + fs_info->is_remote = 0; + + fs_info->typename = fs.f_fstypename; + + trace_printf_key(&trace_fsmonitor, + "'%s' is_remote: %d", + path, fs_info->is_remote); + return 0; +} + +int fsmonitor__is_fs_remote(const char *path) +{ + struct fs_info fs; + if (fsmonitor__get_fs_info(path, &fs)) + return -1; + return fs.is_remote; +} diff --git a/compat/fsmonitor/fsm-path-utils-win32.c b/compat/fsmonitor/fsm-path-utils-win32.c new file mode 100644 index 00000000000..a90b8f7925b --- /dev/null +++ b/compat/fsmonitor/fsm-path-utils-win32.c @@ -0,0 +1,128 @@ +#include "cache.h" +#include "fsmonitor.h" +#include "fsmonitor-path-utils.h" + +/* + * Check remote working directory protocol. + * + * Return -1 if client machine cannot get remote protocol information. + */ +static int check_remote_protocol(wchar_t *wpath) +{ + HANDLE h; + FILE_REMOTE_PROTOCOL_INFO proto_info; + + h = CreateFileW(wpath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS, NULL); + + if (h == INVALID_HANDLE_VALUE) { + error(_("[GLE %ld] unable to open for read '%ls'"), + GetLastError(), wpath); + return -1; + } + + if (!GetFileInformationByHandleEx(h, FileRemoteProtocolInfo, + &proto_info, sizeof(proto_info))) { + error(_("[GLE %ld] unable to get protocol information for '%ls'"), + GetLastError(), wpath); + CloseHandle(h); + return -1; + } + + CloseHandle(h); + + trace_printf_key(&trace_fsmonitor, + "check_remote_protocol('%ls') remote protocol %#8.8lx", + wpath, proto_info.Protocol); + + return 0; +} + +/* + * Notes for testing: + * + * (a) Windows allows a network share to be mapped to a drive letter. + * (This is the normal method to access it.) + * + * $ NET USE Z: \\server\share + * $ git -C Z:/repo status + * + * (b) Windows allows a network share to be referenced WITHOUT mapping + * it to drive letter. + * + * $ NET USE \\server\share\dir + * $ git -C //server/share/repo status + * + * (c) Windows allows "SUBST" to create a fake drive mapping to an + * arbitrary path (which may be remote) + * + * $ SUBST Q: Z:\repo + * $ git -C Q:/ status + * + * (d) Windows allows a directory symlink to be created on a local + * file system that points to a remote repo. + * + * $ mklink /d ./link //server/share/repo + * $ git -C ./link status + */ +int fsmonitor__get_fs_info(const char *path, struct fs_info *fs_info) +{ + wchar_t wpath[MAX_PATH]; + wchar_t wfullpath[MAX_PATH]; + size_t wlen; + UINT driveType; + + /* + * Do everything in wide chars because the drive letter might be + * a multi-byte sequence. See win32_has_dos_drive_prefix(). + */ + if (xutftowcs_path(wpath, path) < 0) { + return -1; + } + + /* + * GetDriveTypeW() requires a final slash. We assume that the + * worktree pathname points to an actual directory. + */ + wlen = wcslen(wpath); + if (wpath[wlen - 1] != L'\\' && wpath[wlen - 1] != L'/') { + wpath[wlen++] = L'\\'; + wpath[wlen] = 0; + } + + /* + * Normalize the path. If nothing else, this converts forward + * slashes to backslashes. This is essential to get GetDriveTypeW() + * correctly handle some UNC "\\server\share\..." paths. + */ + if (!GetFullPathNameW(wpath, MAX_PATH, wfullpath, NULL)) { + return -1; + } + + driveType = GetDriveTypeW(wfullpath); + trace_printf_key(&trace_fsmonitor, + "DriveType '%s' L'%ls' (%u)", + path, wfullpath, driveType); + + if (driveType == DRIVE_REMOTE) { + fs_info->is_remote = 1; + if (check_remote_protocol(wfullpath) < 0) + return -1; + } else { + fs_info->is_remote = 0; + } + + trace_printf_key(&trace_fsmonitor, + "'%s' is_remote: %d", + path, fs_info->is_remote); + + return 0; +} + +int fsmonitor__is_fs_remote(const char *path) +{ + struct fs_info fs; + if (fsmonitor__get_fs_info(path, &fs)) + return -1; + return fs.is_remote; +} diff --git a/compat/fsmonitor/fsm-settings-darwin.c b/compat/fsmonitor/fsm-settings-darwin.c index efc732c0f31..dba3ced6bb7 100644 --- a/compat/fsmonitor/fsm-settings-darwin.c +++ b/compat/fsmonitor/fsm-settings-darwin.c @@ -1,32 +1,10 @@ -#include "cache.h" #include "config.h" -#include "repository.h" -#include "fsmonitor-settings.h" #include "fsmonitor.h" -#include -#include +#include "fsmonitor-ipc.h" +#include "fsmonitor-settings.h" +#include "fsmonitor-path-utils.h" -/* - * [1] Remote working directories are problematic for FSMonitor. - * - * The underlying file system on the server machine and/or the remote - * mount type (NFS, SAMBA, etc.) dictates whether notification events - * are available at all to remote client machines. - * - * Kernel differences between the server and client machines also - * dictate the how (buffering, frequency, de-dup) the events are - * delivered to client machine processes. - * - * A client machine (such as a laptop) may choose to suspend/resume - * and it is unclear (without lots of testing) whether the watcher can - * resync after a resume. We might be able to treat this as a normal - * "events were dropped by the kernel" event and do our normal "flush - * and resync" --or-- we might need to close the existing (zombie?) - * notification fd and create a new one. - * - * In theory, the above issues need to be addressed whether we are - * using the Hook or IPC API. - * + /* * For the builtin FSMonitor, we create the Unix domain socket for the * IPC in the .git directory. If the working directory is remote, * then the socket will be created on the remote file system. This @@ -38,40 +16,34 @@ * be taken to ensure that $HOME is actually local and not a managed * file share.) * - * So (for now at least), mark remote working directories as - * incompatible. - * - * - * [2] FAT32 and NTFS working directories are problematic too. + * FAT32 and NTFS working directories are problematic too. * * The builtin FSMonitor uses a Unix domain socket in the .git * directory for IPC. These Windows drive formats do not support * Unix domain sockets, so mark them as incompatible for the daemon. * */ -static enum fsmonitor_reason check_volume(struct repository *r) +static enum fsmonitor_reason check_uds_volume(struct repository *r) { - struct statfs fs; + struct fs_info fs; + const char *ipc_path = fsmonitor_ipc__get_path(); + struct strbuf path = STRBUF_INIT; + strbuf_add(&path, ipc_path, strlen(ipc_path)); - if (statfs(r->worktree, &fs) == -1) { - int saved_errno = errno; - trace_printf_key(&trace_fsmonitor, "statfs('%s') failed: %s", - r->worktree, strerror(saved_errno)); - errno = saved_errno; + if (fsmonitor__get_fs_info(dirname(path.buf), &fs) == -1) { + strbuf_release(&path); return FSMONITOR_REASON_ERROR; } - trace_printf_key(&trace_fsmonitor, - "statfs('%s') [type 0x%08x][flags 0x%08x] '%s'", - r->worktree, fs.f_type, fs.f_flags, fs.f_fstypename); + strbuf_release(&path); - if (!(fs.f_flags & MNT_LOCAL)) + if (fs.is_remote) return FSMONITOR_REASON_REMOTE; - if (!strcmp(fs.f_fstypename, "msdos")) /* aka FAT32 */ + if (!strcmp(fs.typename, "msdos")) /* aka FAT32 */ return FSMONITOR_REASON_NOSOCKETS; - if (!strcmp(fs.f_fstypename, "ntfs")) + if (!strcmp(fs.typename, "ntfs")) return FSMONITOR_REASON_NOSOCKETS; return FSMONITOR_REASON_OK; @@ -81,7 +53,7 @@ enum fsmonitor_reason fsm_os__incompatible(struct repository *r) { enum fsmonitor_reason reason; - reason = check_volume(r); + reason = check_uds_volume(r); if (reason != FSMONITOR_REASON_OK) return reason; diff --git a/compat/fsmonitor/fsm-settings-win32.c b/compat/fsmonitor/fsm-settings-win32.c index e5ec5b0a9f7..d88b06ae610 100644 --- a/compat/fsmonitor/fsm-settings-win32.c +++ b/compat/fsmonitor/fsm-settings-win32.c @@ -1,8 +1,9 @@ #include "cache.h" #include "config.h" #include "repository.h" -#include "fsmonitor-settings.h" #include "fsmonitor.h" +#include "fsmonitor-settings.h" +#include "fsmonitor-path-utils.h" /* * VFS for Git is incompatible with FSMonitor. @@ -24,171 +25,6 @@ static enum fsmonitor_reason check_vfs4git(struct repository *r) return FSMONITOR_REASON_OK; } -/* - * Check if monitoring remote working directories is allowed. - * - * By default, monitoring remote working directories is - * disabled. Users may override this behavior in enviroments where - * they have proper support. - */ -static int check_config_allowremote(struct repository *r) -{ - int allow; - - if (!repo_config_get_bool(r, "fsmonitor.allowremote", &allow)) - return allow; - - return -1; /* fsmonitor.allowremote not set */ -} - -/* - * Check remote working directory protocol. - * - * Error if client machine cannot get remote protocol information. - */ -static int check_remote_protocol(wchar_t *wpath) -{ - HANDLE h; - FILE_REMOTE_PROTOCOL_INFO proto_info; - - h = CreateFileW(wpath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS, NULL); - - if (h == INVALID_HANDLE_VALUE) { - error(_("[GLE %ld] unable to open for read '%ls'"), - GetLastError(), wpath); - return -1; - } - - if (!GetFileInformationByHandleEx(h, FileRemoteProtocolInfo, - &proto_info, sizeof(proto_info))) { - error(_("[GLE %ld] unable to get protocol information for '%ls'"), - GetLastError(), wpath); - CloseHandle(h); - return -1; - } - - CloseHandle(h); - - trace_printf_key(&trace_fsmonitor, - "check_remote_protocol('%ls') remote protocol %#8.8lx", - wpath, proto_info.Protocol); - - return 0; -} - -/* - * Remote working directories are problematic for FSMonitor. - * - * The underlying file system on the server machine and/or the remote - * mount type dictates whether notification events are available at - * all to remote client machines. - * - * Kernel differences between the server and client machines also - * dictate the how (buffering, frequency, de-dup) the events are - * delivered to client machine processes. - * - * A client machine (such as a laptop) may choose to suspend/resume - * and it is unclear (without lots of testing) whether the watcher can - * resync after a resume. We might be able to treat this as a normal - * "events were dropped by the kernel" event and do our normal "flush - * and resync" --or-- we might need to close the existing (zombie?) - * notification fd and create a new one. - * - * In theory, the above issues need to be addressed whether we are - * using the Hook or IPC API. - * - * So (for now at least), mark remote working directories as - * incompatible. - * - * Notes for testing: - * - * (a) Windows allows a network share to be mapped to a drive letter. - * (This is the normal method to access it.) - * - * $ NET USE Z: \\server\share - * $ git -C Z:/repo status - * - * (b) Windows allows a network share to be referenced WITHOUT mapping - * it to drive letter. - * - * $ NET USE \\server\share\dir - * $ git -C //server/share/repo status - * - * (c) Windows allows "SUBST" to create a fake drive mapping to an - * arbitrary path (which may be remote) - * - * $ SUBST Q: Z:\repo - * $ git -C Q:/ status - * - * (d) Windows allows a directory symlink to be created on a local - * file system that points to a remote repo. - * - * $ mklink /d ./link //server/share/repo - * $ git -C ./link status - */ -static enum fsmonitor_reason check_remote(struct repository *r) -{ - int ret; - wchar_t wpath[MAX_PATH]; - wchar_t wfullpath[MAX_PATH]; - size_t wlen; - UINT driveType; - - /* - * Do everything in wide chars because the drive letter might be - * a multi-byte sequence. See win32_has_dos_drive_prefix(). - */ - if (xutftowcs_path(wpath, r->worktree) < 0) - return FSMONITOR_REASON_ERROR; - - /* - * GetDriveTypeW() requires a final slash. We assume that the - * worktree pathname points to an actual directory. - */ - wlen = wcslen(wpath); - if (wpath[wlen - 1] != L'\\' && wpath[wlen - 1] != L'/') { - wpath[wlen++] = L'\\'; - wpath[wlen] = 0; - } - - /* - * Normalize the path. If nothing else, this converts forward - * slashes to backslashes. This is essential to get GetDriveTypeW() - * correctly handle some UNC "\\server\share\..." paths. - */ - if (!GetFullPathNameW(wpath, MAX_PATH, wfullpath, NULL)) - return FSMONITOR_REASON_ERROR; - - driveType = GetDriveTypeW(wfullpath); - trace_printf_key(&trace_fsmonitor, - "DriveType '%s' L'%ls' (%u)", - r->worktree, wfullpath, driveType); - - if (driveType == DRIVE_REMOTE) { - trace_printf_key(&trace_fsmonitor, - "check_remote('%s') true", - r->worktree); - - ret = check_remote_protocol(wfullpath); - if (ret < 0) - return FSMONITOR_REASON_ERROR; - - switch (check_config_allowremote(r)) { - case 0: /* config overrides and disables */ - return FSMONITOR_REASON_REMOTE; - case 1: /* config overrides and enables */ - return FSMONITOR_REASON_OK; - default: - break; /* config has no opinion */ - } - - return FSMONITOR_REASON_REMOTE; - } - - return FSMONITOR_REASON_OK; -} - enum fsmonitor_reason fsm_os__incompatible(struct repository *r) { enum fsmonitor_reason reason; @@ -197,9 +33,5 @@ enum fsmonitor_reason fsm_os__incompatible(struct repository *r) if (reason != FSMONITOR_REASON_OK) return reason; - reason = check_remote(r); - if (reason != FSMONITOR_REASON_OK) - return reason; - return FSMONITOR_REASON_OK; } diff --git a/contrib/buildsystems/CMakeLists.txt b/contrib/buildsystems/CMakeLists.txt index 2237109b57f..b88494bf59b 100644 --- a/contrib/buildsystems/CMakeLists.txt +++ b/contrib/buildsystems/CMakeLists.txt @@ -308,6 +308,7 @@ if(SUPPORTS_SIMPLE_IPC) add_compile_definitions(HAVE_FSMONITOR_DAEMON_BACKEND) list(APPEND compat_SOURCES compat/fsmonitor/fsm-listen-win32.c) list(APPEND compat_SOURCES compat/fsmonitor/fsm-health-win32.c) + list(APPEND compat_SOURCES compat/fsmonitor/fsm-path-utils-win32.c) add_compile_definitions(HAVE_FSMONITOR_OS_SETTINGS) list(APPEND compat_SOURCES compat/fsmonitor/fsm-settings-win32.c) @@ -315,6 +316,7 @@ if(SUPPORTS_SIMPLE_IPC) add_compile_definitions(HAVE_FSMONITOR_DAEMON_BACKEND) list(APPEND compat_SOURCES compat/fsmonitor/fsm-listen-darwin.c) list(APPEND compat_SOURCES compat/fsmonitor/fsm-health-darwin.c) + list(APPEND compat_SOURCES compat/fsmonitor/fsm-path-utils-darwin.c) add_compile_definitions(HAVE_FSMONITOR_OS_SETTINGS) list(APPEND compat_SOURCES compat/fsmonitor/fsm-settings-darwin.c) diff --git a/fsmonitor-path-utils.h b/fsmonitor-path-utils.h new file mode 100644 index 00000000000..e48592887e7 --- /dev/null +++ b/fsmonitor-path-utils.h @@ -0,0 +1,23 @@ +#ifndef FSM_PATH_UTILS_H +#define FSM_PATH_UTILS_H + +struct fs_info { + int is_remote; + char *typename; +}; + +/* + * Get some basic filesystem informtion for the given path + * + * Returns -1 on error, zero otherwise. + */ +int fsmonitor__get_fs_info(const char *path, struct fs_info *fs_info); + +/* + * Determines if the filesystem that path resides on is remote. + * + * Returns -1 on error, 0 if not remote, 1 if remote. + */ +int fsmonitor__is_fs_remote(const char *path); + +#endif diff --git a/fsmonitor-settings.c b/fsmonitor-settings.c index 464424a1e92..d288cbad479 100644 --- a/fsmonitor-settings.c +++ b/fsmonitor-settings.c @@ -2,6 +2,7 @@ #include "config.h" #include "repository.h" #include "fsmonitor-settings.h" +#include "fsmonitor-path-utils.h" /* * We keep this structure defintion private and have getters @@ -13,6 +14,52 @@ struct fsmonitor_settings { char *hook_path; }; +/* + * Remote working directories are problematic for FSMonitor. + * + * The underlying file system on the server machine and/or the remote + * mount type dictates whether notification events are available at + * all to remote client machines. + * + * Kernel differences between the server and client machines also + * dictate the how (buffering, frequency, de-dup) the events are + * delivered to client machine processes. + * + * A client machine (such as a laptop) may choose to suspend/resume + * and it is unclear (without lots of testing) whether the watcher can + * resync after a resume. We might be able to treat this as a normal + * "events were dropped by the kernel" event and do our normal "flush + * and resync" --or-- we might need to close the existing (zombie?) + * notification fd and create a new one. + * + * In theory, the above issues need to be addressed whether we are + * using the Hook or IPC API. + * + * So (for now at least), mark remote working directories as + * incompatible unless 'fsmonitor.allowRemote' is true. + * + */ +#ifdef HAVE_FSMONITOR_OS_SETTINGS +static enum fsmonitor_reason check_remote(struct repository *r) +{ + int allow_remote = -1; /* -1 unset, 0 not allowed, 1 allowed */ + int is_remote = fsmonitor__is_fs_remote(r->worktree); + + switch (is_remote) { + case 0: + return FSMONITOR_REASON_OK; + case 1: + repo_config_get_bool(r, "fsmonitor.allowremote", &allow_remote); + if (allow_remote < 1) + return FSMONITOR_REASON_REMOTE; + else + return FSMONITOR_REASON_OK; + default: + return FSMONITOR_REASON_ERROR; + } +} +#endif + static enum fsmonitor_reason check_for_incompatible(struct repository *r) { if (!r->worktree) { @@ -27,6 +74,9 @@ static enum fsmonitor_reason check_for_incompatible(struct repository *r) { enum fsmonitor_reason reason; + reason = check_remote(r); + if (reason != FSMONITOR_REASON_OK) + return reason; reason = fsm_os__incompatible(r); if (reason != FSMONITOR_REASON_OK) return reason; From patchwork Mon Sep 19 19:37:53 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric DeCosta X-Patchwork-Id: 12980994 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8B60FECAAA1 for ; Mon, 19 Sep 2022 19:38:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229743AbiISTiH (ORCPT ); Mon, 19 Sep 2022 15:38:07 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35098 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229724AbiISTiE (ORCPT ); Mon, 19 Sep 2022 15:38:04 -0400 Received: from mail-wr1-x42f.google.com (mail-wr1-x42f.google.com [IPv6:2a00:1450:4864:20::42f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5848A175BB for ; Mon, 19 Sep 2022 12:38:02 -0700 (PDT) Received: by mail-wr1-x42f.google.com with SMTP id z6so802333wrq.1 for ; Mon, 19 Sep 2022 12:38:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:from:to:cc:subject:date; bh=NBvhNBZ7DRCHK9Lpr9kfdIMe7wvAPVlWQpq6adf3Uxk=; b=j8t2layLPk5hV7vYUOayEkxiMlXjKglRasczRFy34eHN7zzMyHDeDIJSkkE78ByNLd ZO8RrrSEP6ZEMaNPd4OiZLV3/HBpLynQerFdY4nLO7ZbWS1HM8pEiEZsYGJQAbpPg4aD mJLy8MKGKqribmJfsHql3j2DCBzvJrEQbCxivYRdJUnGhU3N6avOx0Mh8F6ug9dRT5bR XD3+msvhlL8Te4JfuAzmGmXdfOd/SzCRd3R11P4NFxRxSRxhik7uAPHVmCm5rTQAn3iG QvvtBRzBO6luSaAgkH837B0gtg5fCZfELDtByEB/VKmD9LWoudacTXaWgIDdcYkvWEXy wdmg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:x-gm-message-state:from:to:cc :subject:date; bh=NBvhNBZ7DRCHK9Lpr9kfdIMe7wvAPVlWQpq6adf3Uxk=; b=lLpqY+X0AgD0YNg4mNpJ+cSWmo3qu62sgpgKPIzsTDMsd+m75pGo/jsPAIgI//NQw5 rkowdOjoMmOMMyrJlalNNQZTLk4DfSh02eCGTFX4Rh5THunzC50SCkg/ujPicJg29MKa 6ix5UmaCS2roIz2GZ0m59zVw3u09EM/uAV5rWK5sWO2G4CkKYSxDPnbxL+Tcjww4UNiI 8ZxQ+R3eESDekvwnqTRiPuqK+T/O67PUgbozAtyrDO/ud5Z95Zqj5ZVmPIh1vLhH9tYY aIlOaLZO140Y0Q95g6NMC6lMnZKU1cZ2E35iPXTtZf9SQ4zHxNCfPyHQwO6XVVBquNss kiBA== X-Gm-Message-State: ACrzQf2tziHioUmATEDCoi9z1AShlT7OwOkPOCHJyDEUqsBMdc5Y80AA sNuLGWLyi9+jtYZ6WOJGCU7T7xZ1hGI= X-Google-Smtp-Source: AMsMyM457vikaULT3RGDCzqN/+bRW6r7+Ag6LcKWTF7Wr4gXIA6OXJrs+tAiGjjxz6hEoILft5iINQ== X-Received: by 2002:a5d:64c2:0:b0:228:cb2b:f38d with SMTP id f2-20020a5d64c2000000b00228cb2bf38dmr11662912wri.491.1663616280579; Mon, 19 Sep 2022 12:38:00 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id az24-20020adfe198000000b00228d7078c4esm15029790wrb.4.2022.09.19.12.37.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Sep 2022 12:38:00 -0700 (PDT) Message-Id: <68709d788d531805d9328e16f53381fcd8d7bd5e.1663616277.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Mon, 19 Sep 2022 19:37:53 +0000 Subject: [PATCH v9 2/6] fsmonitor: relocate socket file if .git directory is remote Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Jeff Hostetler , Eric Sunshine , Torsten =?utf-8?q?B=C3=B6gershause?= =?utf-8?q?n?= , =?utf-8?b?w4Z2YXIgQXJuZmrDtnLDsA==?= Bjarmason , Ramsay Jones , Johannes Schindelin , Eric DeCosta , Eric DeCosta Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Eric DeCosta From: Eric DeCosta If the .git directory is on a remote file system, create the socket file in 'fsmonitor.socketDir' if it is defined, else create it in $HOME. Signed-off-by: Eric DeCosta --- Makefile | 1 + builtin/fsmonitor--daemon.c | 3 +- compat/fsmonitor/fsm-ipc-darwin.c | 48 ++++++++++++++++++++++++++ compat/fsmonitor/fsm-ipc-win32.c | 9 +++++ compat/fsmonitor/fsm-settings-darwin.c | 2 +- contrib/buildsystems/CMakeLists.txt | 2 ++ fsmonitor-ipc.c | 18 +++++----- fsmonitor-ipc.h | 4 ++- 8 files changed, 74 insertions(+), 13 deletions(-) create mode 100644 compat/fsmonitor/fsm-ipc-darwin.c create mode 100644 compat/fsmonitor/fsm-ipc-win32.c diff --git a/Makefile b/Makefile index 6e492a67547..58bb9248471 100644 --- a/Makefile +++ b/Makefile @@ -2034,6 +2034,7 @@ ifdef FSMONITOR_DAEMON_BACKEND COMPAT_CFLAGS += -DHAVE_FSMONITOR_DAEMON_BACKEND COMPAT_OBJS += compat/fsmonitor/fsm-listen-$(FSMONITOR_DAEMON_BACKEND).o COMPAT_OBJS += compat/fsmonitor/fsm-health-$(FSMONITOR_DAEMON_BACKEND).o + COMPAT_OBJS += compat/fsmonitor/fsm-ipc-$(FSMONITOR_DAEMON_BACKEND).o endif ifdef FSMONITOR_OS_SETTINGS diff --git a/builtin/fsmonitor--daemon.c b/builtin/fsmonitor--daemon.c index 2c109cf8b37..0123fc33ed2 100644 --- a/builtin/fsmonitor--daemon.c +++ b/builtin/fsmonitor--daemon.c @@ -1343,7 +1343,8 @@ static int fsmonitor_run_daemon(void) * directory.) */ strbuf_init(&state.path_ipc, 0); - strbuf_addstr(&state.path_ipc, absolute_path(fsmonitor_ipc__get_path())); + strbuf_addstr(&state.path_ipc, + absolute_path(fsmonitor_ipc__get_path(the_repository))); /* * Confirm that we can create platform-specific resources for the diff --git a/compat/fsmonitor/fsm-ipc-darwin.c b/compat/fsmonitor/fsm-ipc-darwin.c new file mode 100644 index 00000000000..d48d67690ee --- /dev/null +++ b/compat/fsmonitor/fsm-ipc-darwin.c @@ -0,0 +1,48 @@ +#include "cache.h" +#include "config.h" +#include "strbuf.h" +#include "fsmonitor.h" +#include "fsmonitor-ipc.h" +#include "fsmonitor-path-utils.h" + +static GIT_PATH_FUNC(fsmonitor_ipc__get_default_path, "fsmonitor--daemon.ipc") + +const char *fsmonitor_ipc__get_path(struct repository *r) +{ + static const char *ipc_path; + SHA_CTX sha1ctx; + char *sock_dir; + struct strbuf ipc_file = STRBUF_INIT; + unsigned char hash[SHA_DIGEST_LENGTH]; + + if (ipc_path) + return ipc_path; + + ipc_path = fsmonitor_ipc__get_default_path(); + + /* By default the socket file is created in the .git directory */ + if (fsmonitor__is_fs_remote(ipc_path) < 1) + return ipc_path; + + SHA1_Init(&sha1ctx); + SHA1_Update(&sha1ctx, r->worktree, strlen(r->worktree)); + SHA1_Final(hash, &sha1ctx); + + repo_config_get_string(r, "fsmonitor.socketdir", &sock_dir); + + /* Create the socket file in either socketDir or $HOME */ + if (sock_dir && *sock_dir) { + strbuf_addf(&ipc_file, "%s/.git-fsmonitor-%s", + sock_dir, hash_to_hex(hash)); + free(sock_dir); + } else { + strbuf_addf(&ipc_file, "~/.git-fsmonitor-%s", hash_to_hex(hash)); + } + + ipc_path = interpolate_path(ipc_file.buf, 1); + if (!ipc_path) + die(_("Invalid path: %s"), ipc_file.buf); + + strbuf_release(&ipc_file); + return ipc_path; +} diff --git a/compat/fsmonitor/fsm-ipc-win32.c b/compat/fsmonitor/fsm-ipc-win32.c new file mode 100644 index 00000000000..3a3a46db209 --- /dev/null +++ b/compat/fsmonitor/fsm-ipc-win32.c @@ -0,0 +1,9 @@ +#include "config.h" +#include "fsmonitor-ipc.h" + +const char *fsmonitor_ipc__get_path(struct repository *r) { + static char *ret; + if (!ret) + ret = git_pathdup("fsmonitor--daemon.ipc"); + return ret; +} \ No newline at end of file diff --git a/compat/fsmonitor/fsm-settings-darwin.c b/compat/fsmonitor/fsm-settings-darwin.c index dba3ced6bb7..681d8bf963e 100644 --- a/compat/fsmonitor/fsm-settings-darwin.c +++ b/compat/fsmonitor/fsm-settings-darwin.c @@ -26,7 +26,7 @@ static enum fsmonitor_reason check_uds_volume(struct repository *r) { struct fs_info fs; - const char *ipc_path = fsmonitor_ipc__get_path(); + const char *ipc_path = fsmonitor_ipc__get_path(r); struct strbuf path = STRBUF_INIT; strbuf_add(&path, ipc_path, strlen(ipc_path)); diff --git a/contrib/buildsystems/CMakeLists.txt b/contrib/buildsystems/CMakeLists.txt index b88494bf59b..7e7b6b9a362 100644 --- a/contrib/buildsystems/CMakeLists.txt +++ b/contrib/buildsystems/CMakeLists.txt @@ -308,6 +308,7 @@ if(SUPPORTS_SIMPLE_IPC) add_compile_definitions(HAVE_FSMONITOR_DAEMON_BACKEND) list(APPEND compat_SOURCES compat/fsmonitor/fsm-listen-win32.c) list(APPEND compat_SOURCES compat/fsmonitor/fsm-health-win32.c) + list(APPEND compat_SOURCES compat/fsmonitor/fsm-ipc-win32.c) list(APPEND compat_SOURCES compat/fsmonitor/fsm-path-utils-win32.c) add_compile_definitions(HAVE_FSMONITOR_OS_SETTINGS) @@ -316,6 +317,7 @@ if(SUPPORTS_SIMPLE_IPC) add_compile_definitions(HAVE_FSMONITOR_DAEMON_BACKEND) list(APPEND compat_SOURCES compat/fsmonitor/fsm-listen-darwin.c) list(APPEND compat_SOURCES compat/fsmonitor/fsm-health-darwin.c) + list(APPEND compat_SOURCES compat/fsmonitor/fsm-ipc-darwin.c) list(APPEND compat_SOURCES compat/fsmonitor/fsm-path-utils-darwin.c) add_compile_definitions(HAVE_FSMONITOR_OS_SETTINGS) diff --git a/fsmonitor-ipc.c b/fsmonitor-ipc.c index 789e7397baa..c0f42301c84 100644 --- a/fsmonitor-ipc.c +++ b/fsmonitor-ipc.c @@ -18,7 +18,7 @@ int fsmonitor_ipc__is_supported(void) return 0; } -const char *fsmonitor_ipc__get_path(void) +const char *fsmonitor_ipc__get_path(struct repository *r) { return NULL; } @@ -47,11 +47,9 @@ int fsmonitor_ipc__is_supported(void) return 1; } -GIT_PATH_FUNC(fsmonitor_ipc__get_path, "fsmonitor--daemon.ipc") - enum ipc_active_state fsmonitor_ipc__get_state(void) { - return ipc_get_active_state(fsmonitor_ipc__get_path()); + return ipc_get_active_state(fsmonitor_ipc__get_path(the_repository)); } static int spawn_daemon(void) @@ -81,8 +79,8 @@ int fsmonitor_ipc__send_query(const char *since_token, trace2_data_string("fsm_client", NULL, "query/command", tok); try_again: - state = ipc_client_try_connect(fsmonitor_ipc__get_path(), &options, - &connection); + state = ipc_client_try_connect(fsmonitor_ipc__get_path(the_repository), + &options, &connection); switch (state) { case IPC_STATE__LISTENING: @@ -117,13 +115,13 @@ try_again: case IPC_STATE__INVALID_PATH: ret = error(_("fsmonitor_ipc__send_query: invalid path '%s'"), - fsmonitor_ipc__get_path()); + fsmonitor_ipc__get_path(the_repository)); goto done; case IPC_STATE__OTHER_ERROR: default: ret = error(_("fsmonitor_ipc__send_query: unspecified error on '%s'"), - fsmonitor_ipc__get_path()); + fsmonitor_ipc__get_path(the_repository)); goto done; } @@ -149,8 +147,8 @@ int fsmonitor_ipc__send_command(const char *command, options.wait_if_busy = 1; options.wait_if_not_found = 0; - state = ipc_client_try_connect(fsmonitor_ipc__get_path(), &options, - &connection); + state = ipc_client_try_connect(fsmonitor_ipc__get_path(the_repository), + &options, &connection); if (state != IPC_STATE__LISTENING) { die(_("fsmonitor--daemon is not running")); return -1; diff --git a/fsmonitor-ipc.h b/fsmonitor-ipc.h index b6a7067c3af..8b489da762b 100644 --- a/fsmonitor-ipc.h +++ b/fsmonitor-ipc.h @@ -3,6 +3,8 @@ #include "simple-ipc.h" +struct repository; + /* * Returns true if built-in file system monitor daemon is defined * for this platform. @@ -16,7 +18,7 @@ int fsmonitor_ipc__is_supported(void); * * Returns NULL if the daemon is not supported on this platform. */ -const char *fsmonitor_ipc__get_path(void); +const char *fsmonitor_ipc__get_path(struct repository *r); /* * Try to determine whether there is a `git-fsmonitor--daemon` process From patchwork Mon Sep 19 19:37:54 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric DeCosta X-Patchwork-Id: 12980995 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D6918ECAAD3 for ; Mon, 19 Sep 2022 19:38:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229749AbiISTiJ (ORCPT ); Mon, 19 Sep 2022 15:38:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35100 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229723AbiISTiE (ORCPT ); Mon, 19 Sep 2022 15:38:04 -0400 Received: from mail-wr1-x42e.google.com (mail-wr1-x42e.google.com [IPv6:2a00:1450:4864:20::42e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 311B515A1A for ; Mon, 19 Sep 2022 12:38:03 -0700 (PDT) Received: by mail-wr1-x42e.google.com with SMTP id r7so793867wrm.2 for ; Mon, 19 Sep 2022 12:38:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:from:to:cc:subject:date; bh=Sn7vsF8saTSOV85OIZnrqZlKAyOg5t4JuZwq78TkGgc=; b=mKYz/+Mc6RSXeMQfmDrlxY77Wd46woczq2pCinVhqK/OFjoB78XDFwNYXKOSbJ/Yma Z++sAZUus210D8KlLV0XPgutQv/ztveAJ/djUxQN/ki73Kgyh9Ir4jfQMQ1rTA5uQAAU +OjTNYruWms98hXxrvEEaUq8eQIJX2YAe+E8B7AiS2g1spOksAy3WVbnxzD+J/yt5vWN aFlFFKFmcwEywIXnfFYtq18yqR0JhmNbWkCugYy+Sq4OUGTQb3zM1fis0FqMCyWfIQre IlarmQpiuauUuaJQ42GbMv33Sswa/ccnrVxdlmk1G5afFD6M/IdbmZdDWjOYO95AAI27 0lLA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:x-gm-message-state:from:to:cc :subject:date; bh=Sn7vsF8saTSOV85OIZnrqZlKAyOg5t4JuZwq78TkGgc=; b=dKbHJwKxCfEd1MFxAw2rVa8ViNj8tFgi/NbeZuiFG1YWGR9zI0jhxEigflW2OS/ofN F1t4fGQZaY7q7lC7AiRedktJmiLFXULcsrs3MRzlGlnafJ9KQsn/xxCDsWsGiZeNT9Yr viV2zSB1eoEmJt8SBgatbpVrAB79Op/ABAsOP9H5FfxUd+jThWWXxUNAPu1A4Rb+YmNY Ly7qGUo3+6yFqa08OopmCASgUC+UfxoZJ01YPSD/iO4A0rwxC24jjnQ1kuZaibC5cfoj abkkroK0wCcnxtAePVJ9fkTmoEmzZiMO2fRgSHcUm0B3wQ40o8jteistbRfjRceLmK+2 1GZw== X-Gm-Message-State: ACrzQf0cq1gIZWPqz33JgIF0iZ2tyCBjyTgvH2cDLNrFINtjAvrIt2Rq ljRHJ8lM/3m1n5stSRXrDhmAGJK92Xc= X-Google-Smtp-Source: AMsMyM4il3cwNNSLSzXJlHvESIx42jMC/UAvSnVTtoOpLh44RbQozbNO1amymrj+qhK5bHeMJ/8PZw== X-Received: by 2002:a05:6000:1548:b0:22a:c113:c9d0 with SMTP id 8-20020a056000154800b0022ac113c9d0mr12201728wry.653.1663616281457; Mon, 19 Sep 2022 12:38:01 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id s2-20020a5d4242000000b00224f7c1328dsm14621162wrr.67.2022.09.19.12.38.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Sep 2022 12:38:00 -0700 (PDT) Message-Id: <6ddd922917a144f2339af47b9f5c17c122c1ebbd.1663616277.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Mon, 19 Sep 2022 19:37:54 +0000 Subject: [PATCH v9 3/6] fsmonitor: avoid socket location check if using hook Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Jeff Hostetler , Eric Sunshine , Torsten =?utf-8?q?B=C3=B6gershause?= =?utf-8?q?n?= , =?utf-8?b?w4Z2YXIgQXJuZmrDtnLDsA==?= Bjarmason , Ramsay Jones , Johannes Schindelin , Eric DeCosta , Eric DeCosta Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Eric DeCosta From: Eric DeCosta 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 --- compat/fsmonitor/fsm-settings-darwin.c | 10 ++++++---- compat/fsmonitor/fsm-settings-win32.c | 2 +- fsmonitor-settings.c | 8 ++++---- fsmonitor-settings.h | 2 +- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/compat/fsmonitor/fsm-settings-darwin.c b/compat/fsmonitor/fsm-settings-darwin.c index 681d8bf963e..40da2d3b533 100644 --- a/compat/fsmonitor/fsm-settings-darwin.c +++ b/compat/fsmonitor/fsm-settings-darwin.c @@ -49,13 +49,15 @@ static enum fsmonitor_reason check_uds_volume(struct repository *r) return FSMONITOR_REASON_OK; } -enum fsmonitor_reason fsm_os__incompatible(struct repository *r) +enum fsmonitor_reason fsm_os__incompatible(struct repository *r, int ipc) { enum fsmonitor_reason reason; - reason = check_uds_volume(r); - if (reason != FSMONITOR_REASON_OK) - return reason; + if (ipc) { + reason = check_uds_volume(r); + if (reason != FSMONITOR_REASON_OK) + return reason; + } return FSMONITOR_REASON_OK; } diff --git a/compat/fsmonitor/fsm-settings-win32.c b/compat/fsmonitor/fsm-settings-win32.c index d88b06ae610..a8af31b71de 100644 --- a/compat/fsmonitor/fsm-settings-win32.c +++ b/compat/fsmonitor/fsm-settings-win32.c @@ -25,7 +25,7 @@ static enum fsmonitor_reason check_vfs4git(struct repository *r) return FSMONITOR_REASON_OK; } -enum fsmonitor_reason fsm_os__incompatible(struct repository *r) +enum fsmonitor_reason fsm_os__incompatible(struct repository *r, int ipc) { enum fsmonitor_reason reason; diff --git a/fsmonitor-settings.c b/fsmonitor-settings.c index d288cbad479..531a1b6f956 100644 --- a/fsmonitor-settings.c +++ b/fsmonitor-settings.c @@ -60,7 +60,7 @@ static enum fsmonitor_reason check_remote(struct repository *r) } #endif -static enum fsmonitor_reason check_for_incompatible(struct repository *r) +static enum fsmonitor_reason check_for_incompatible(struct repository *r, int ipc) { if (!r->worktree) { /* @@ -77,7 +77,7 @@ static enum fsmonitor_reason check_for_incompatible(struct repository *r) reason = check_remote(r); if (reason != FSMONITOR_REASON_OK) return reason; - reason = fsm_os__incompatible(r); + reason = fsm_os__incompatible(r, ipc); if (reason != FSMONITOR_REASON_OK) return reason; } @@ -162,7 +162,7 @@ const char *fsm_settings__get_hook_path(struct repository *r) void fsm_settings__set_ipc(struct repository *r) { - enum fsmonitor_reason reason = check_for_incompatible(r); + enum fsmonitor_reason reason = check_for_incompatible(r, 1); if (reason != FSMONITOR_REASON_OK) { fsm_settings__set_incompatible(r, reason); @@ -185,7 +185,7 @@ void fsm_settings__set_ipc(struct repository *r) void fsm_settings__set_hook(struct repository *r, const char *path) { - enum fsmonitor_reason reason = check_for_incompatible(r); + enum fsmonitor_reason reason = check_for_incompatible(r, 0); if (reason != FSMONITOR_REASON_OK) { fsm_settings__set_incompatible(r, reason); diff --git a/fsmonitor-settings.h b/fsmonitor-settings.h index d9c2605197f..0721617b95a 100644 --- a/fsmonitor-settings.h +++ b/fsmonitor-settings.h @@ -48,7 +48,7 @@ struct fsmonitor_settings; * fsm_os__* routines should considered private to fsm_settings__ * routines. */ -enum fsmonitor_reason fsm_os__incompatible(struct repository *r); +enum fsmonitor_reason fsm_os__incompatible(struct repository *r, int ipc); #endif /* HAVE_FSMONITOR_OS_SETTINGS */ #endif /* FSMONITOR_SETTINGS_H */ From patchwork Mon Sep 19 19:37:55 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric DeCosta X-Patchwork-Id: 12980997 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9955FECAAD3 for ; Mon, 19 Sep 2022 19:38:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229783AbiISTiX (ORCPT ); Mon, 19 Sep 2022 15:38:23 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35158 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229732AbiISTiG (ORCPT ); Mon, 19 Sep 2022 15:38:06 -0400 Received: from mail-wr1-x431.google.com (mail-wr1-x431.google.com [IPv6:2a00:1450:4864:20::431]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0996D1759A for ; Mon, 19 Sep 2022 12:38:04 -0700 (PDT) Received: by mail-wr1-x431.google.com with SMTP id y5so783010wrh.3 for ; Mon, 19 Sep 2022 12:38:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:from:to:cc:subject:date; bh=RieE0QInLL2f3TtewJjo66wdOAFxsTbnPd6eR1ZyKCY=; b=GjJWdUDDLVxddEG3K9Bwo1q5ZS/36D3+VpssPvea1piEedZgXsXjSR90NzPQQJs6kr IZGH73z1/oRkTnpsKAAMUGKdKysHJoZQStaUKxm1gE7Otb0spcBzViLULW6T7tctmeCT KjF9bJ1DOGrNgDjUEMIaFMhPbUsVeK+zXKJ3wykx6fnv7yNuknQizkt2MQviYe/jFPXr xEZ6Uxwof3ri6aD2vM4kNRixyAujFyU5cUB1zl1d60rwBYVF8etgSpVlNSSznjQ9ZjrX YYIt0bqXlRHlYvilUzHHhIsqLaoy/FHrBhmDTrZ9P0AIbJeUaVnG61lNLwqJDMyZCb+e 5DyQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:x-gm-message-state:from:to:cc :subject:date; bh=RieE0QInLL2f3TtewJjo66wdOAFxsTbnPd6eR1ZyKCY=; b=O+H2HF9LKd3K01lzBxdie4/NPGK7JwSPUu1RzMUmsUFIa6DEdhPekwtdNoq+i0R7CD I80lmW73pYwufXjLOO5KdlsEV6YU1C6SCPwlNHPtzQDydAq6wTWv/oMpakv4iMk3D2rx 4mhMXfpMrY4VpzEhR59Y2oT4mZukGAh8bNTJw8KkRTp0WkOkug3W9Amh8SJHLdL0FUkJ e3EJBxx+KUheNimVSLba2FP5lPpoyMkFx3wFwRejzSuYz8Z0rtsMET3KMp8cU65Cfs1X XzRZjDDR8uuYC1UblP7x26fJo5aAn4xwAjA8H9x2SilQ6IUXc9ViXotXnIsTxjSqCA+r KjjA== X-Gm-Message-State: ACrzQf03XTuQrr9EyqC6wQ4WOdVMEMnTM1oRGXa7B33RfVowe9kOU9f/ WsIJShsM+zIO94ZCHnWus8Ibafdxmzc= X-Google-Smtp-Source: AMsMyM6IGE6Fab0XnlAADs+vTGm/Ff/obh9efDyXDPY2CCYhT6xdDzGO3LhyxjzHDPN9kN2mqILeGg== X-Received: by 2002:a5d:6a07:0:b0:228:dba4:2138 with SMTP id m7-20020a5d6a07000000b00228dba42138mr11465121wru.346.1663616282273; Mon, 19 Sep 2022 12:38:02 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id t12-20020a05600c128c00b003b4931eb435sm14265446wmd.26.2022.09.19.12.38.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Sep 2022 12:38:01 -0700 (PDT) Message-Id: <73afd9f31229a50a7c23271a66e842647378628a.1663616277.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Mon, 19 Sep 2022 19:37:55 +0000 Subject: [PATCH v9 4/6] fsmonitor: deal with synthetic firmlinks on macOS Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Jeff Hostetler , Eric Sunshine , Torsten =?utf-8?q?B=C3=B6gershause?= =?utf-8?q?n?= , =?utf-8?b?w4Z2YXIgQXJuZmrDtnLDsA==?= Bjarmason , Ramsay Jones , Johannes Schindelin , Eric DeCosta , Eric DeCosta Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Eric DeCosta From: Eric DeCosta 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 --- builtin/fsmonitor--daemon.c | 8 +++ compat/fsmonitor/fsm-listen-darwin.c | 6 +- compat/fsmonitor/fsm-path-utils-darwin.c | 92 ++++++++++++++++++++++++ compat/fsmonitor/fsm-path-utils-win32.c | 17 +++++ fsmonitor--daemon.h | 3 + fsmonitor-path-utils.h | 36 ++++++++++ 6 files changed, 161 insertions(+), 1 deletion(-) diff --git a/builtin/fsmonitor--daemon.c b/builtin/fsmonitor--daemon.c index 0123fc33ed2..56fcd1c2baa 100644 --- a/builtin/fsmonitor--daemon.c +++ b/builtin/fsmonitor--daemon.c @@ -3,6 +3,7 @@ #include "parse-options.h" #include "fsmonitor.h" #include "fsmonitor-ipc.h" +#include "fsmonitor-path-utils.h" #include "compat/fsmonitor/fsm-health.h" #include "compat/fsmonitor/fsm-listen.h" #include "fsmonitor--daemon.h" @@ -1282,6 +1283,13 @@ static int fsmonitor_run_daemon(void) strbuf_addstr(&state.path_worktree_watch, absolute_path(get_git_work_tree())); state.nr_paths_watching = 1; + state.alias.alias = NULL; + state.alias.points_to = NULL; + if (fsmonitor__get_alias(state.path_worktree_watch.buf, &state.alias)) { + err = error(_("could not get worktree alias")); + goto done; + } + /* * We create and delete cookie files somewhere inside the .git * directory to help us keep sync with the file system. If diff --git a/compat/fsmonitor/fsm-listen-darwin.c b/compat/fsmonitor/fsm-listen-darwin.c index 8e208e8289e..179886bc15b 100644 --- a/compat/fsmonitor/fsm-listen-darwin.c +++ b/compat/fsmonitor/fsm-listen-darwin.c @@ -26,6 +26,7 @@ #include "fsmonitor.h" #include "fsm-listen.h" #include "fsmonitor--daemon.h" +#include "fsmonitor-path-utils.h" struct fsm_listen_data { @@ -209,7 +210,9 @@ static void fsevent_callback(ConstFSEventStreamRef streamRef, /* * On Mac, we receive an array of absolute paths. */ - path_k = paths[k]; + path_k = fsmonitor__resolve_alias(paths[k], &state->alias); + if (!path_k) + path_k = paths[k]; /* * If you want to debug FSEvents, log them to GIT_TRACE_FSMONITOR. @@ -238,6 +241,7 @@ static void fsevent_callback(ConstFSEventStreamRef streamRef, fsmonitor_force_resync(state); fsmonitor_batch__free_list(batch); string_list_clear(&cookie_list, 0); + batch = NULL; /* * We assume that any events that we received diff --git a/compat/fsmonitor/fsm-path-utils-darwin.c b/compat/fsmonitor/fsm-path-utils-darwin.c index 067cbe6990a..13807f58e95 100644 --- a/compat/fsmonitor/fsm-path-utils-darwin.c +++ b/compat/fsmonitor/fsm-path-utils-darwin.c @@ -1,5 +1,8 @@ #include "fsmonitor.h" #include "fsmonitor-path-utils.h" +#include +#include +#include #include #include @@ -38,3 +41,92 @@ int fsmonitor__is_fs_remote(const char *path) return -1; return fs.is_remote; } + +/* + * 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 altogether. + */ +int fsmonitor__get_alias(const char *path, struct alias_info *info) +{ + DIR * dir; + int read; + int retval; + struct dirent *de; + struct strbuf alias; + struct strbuf points_to; + + retval = 0; + dir = opendir("/"); + if (!dir) + return -1; + + strbuf_init(&alias, 256); + strbuf_init(&points_to, MAXPATHLEN); + + while ((de = readdir(dir)) != NULL) { + strbuf_reset(&alias); + strbuf_addch(&alias, '/'); + strbuf_add(&alias, de->d_name, strlen(de->d_name)); + + read = readlink(alias.buf, points_to.buf, MAXPATHLEN); + if (read > 0) { + strbuf_setlen(&points_to, read); + if ((strncmp(points_to.buf, path, points_to.len) == 0) + && path[points_to.len] == '/') { + info->alias = strbuf_detach(&alias, NULL); + info->points_to = strbuf_detach(&points_to, NULL); + trace_printf_key(&trace_fsmonitor, + "Found alias for '%s' : '%s' -> '%s'", + path, info->alias, info->points_to); + retval = 0; + goto done; + } + } else if (errno != EINVAL) { /* Something other than not a link */ + trace_printf_key(&trace_fsmonitor, "Error %s", strerror(errno)); + retval = -1; + goto done; + } + } + + done: + closedir(dir); + strbuf_release(&alias); + strbuf_release(&points_to); + return retval; +} + +char *fsmonitor__resolve_alias(const char *path, + const struct alias_info *info) +{ + int len = info->alias ? strlen(info->alias) : 0; + + if (!len) + return NULL; + + if ((strncmp(info->alias, path, len) == 0) + && path[len] == '/') { + struct strbuf tmp; + const char *remainder = path + len; + int ptr_len = strlen(info->points_to); + int rem_len = strlen(remainder); + + strbuf_init(&tmp, ptr_len + rem_len); + strbuf_add(&tmp, info->points_to, ptr_len); + strbuf_add(&tmp, remainder, rem_len); + return strbuf_detach(&tmp, NULL); + } + + return NULL; +} diff --git a/compat/fsmonitor/fsm-path-utils-win32.c b/compat/fsmonitor/fsm-path-utils-win32.c index a90b8f7925b..0d95bbb416f 100644 --- a/compat/fsmonitor/fsm-path-utils-win32.c +++ b/compat/fsmonitor/fsm-path-utils-win32.c @@ -126,3 +126,20 @@ int fsmonitor__is_fs_remote(const char *path) return -1; return fs.is_remote; } + +/* + * No-op for now. + */ +int fsmonitor__get_alias(const char *path, struct alias_info *info) +{ + return 0; +} + +/* + * No-op for now. + */ +char *fsmonitor__resolve_alias(const char *path, + const struct alias_info *info) +{ + return NULL; +} diff --git a/fsmonitor--daemon.h b/fsmonitor--daemon.h index 2102a5c9ff5..e24838f9a86 100644 --- a/fsmonitor--daemon.h +++ b/fsmonitor--daemon.h @@ -8,6 +8,7 @@ #include "run-command.h" #include "simple-ipc.h" #include "thread-utils.h" +#include "fsmonitor-path-utils.h" struct fsmonitor_batch; struct fsmonitor_token_data; @@ -43,6 +44,7 @@ struct fsmonitor_daemon_state { struct strbuf path_worktree_watch; struct strbuf path_gitdir_watch; + struct alias_info alias; int nr_paths_watching; struct fsmonitor_token_data *current_token_data; @@ -59,6 +61,7 @@ struct fsmonitor_daemon_state { struct ipc_server_data *ipc_server_data; struct strbuf path_ipc; + }; /* diff --git a/fsmonitor-path-utils.h b/fsmonitor-path-utils.h index e48592887e7..50ef37e57bb 100644 --- a/fsmonitor-path-utils.h +++ b/fsmonitor-path-utils.h @@ -1,6 +1,14 @@ #ifndef FSM_PATH_UTILS_H #define FSM_PATH_UTILS_H +#include "strbuf.h" + +struct alias_info +{ + char *alias; + char *points_to; +}; + struct fs_info { int is_remote; char *typename; @@ -20,4 +28,32 @@ int fsmonitor__get_fs_info(const char *path, struct fs_info *fs_info); */ int fsmonitor__is_fs_remote(const char *path); +/* + * Get the alias in given path, if any. + * + * Sets alias to the first alias that matches any part of the path. + * + * If an alias is found, info.alias and info.points_to are set to the + * found mapping. + * + * Returns -1 on error, 0 otherwise. + * + * The caller owns the storage that is occupied by set info.alias and + * info.points_to and is responsible for releasing it with `free(3)` + * when done. + */ +int fsmonitor__get_alias(const char *path, struct alias_info *info); + +/* + * Resolve the path against the given alias. + * + * Returns the resolved path if there is one, NULL otherwise. + * + * The caller owns the storage that the returned string occupies and + * is responsible for releasing it with `free(3)` when done. + */ +char *fsmonitor__resolve_alias(const char *path, + const struct alias_info *info); + + #endif From patchwork Mon Sep 19 19:37:56 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric DeCosta X-Patchwork-Id: 12980996 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id EE303C6FA86 for ; Mon, 19 Sep 2022 19:38:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229774AbiISTiZ (ORCPT ); Mon, 19 Sep 2022 15:38:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35168 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229473AbiISTiG (ORCPT ); Mon, 19 Sep 2022 15:38:06 -0400 Received: from mail-wr1-x42b.google.com (mail-wr1-x42b.google.com [IPv6:2a00:1450:4864:20::42b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A3F56192B2 for ; Mon, 19 Sep 2022 12:38:04 -0700 (PDT) Received: by mail-wr1-x42b.google.com with SMTP id c11so701081wrp.11 for ; Mon, 19 Sep 2022 12:38:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:from:to:cc:subject:date; bh=bebhsgLSR/dvglUaatrpWC4eZSs07ICzF3roFpByZIo=; b=DnuOE3N2tiLKwAueww4JKphec8OmRb0Y6eOrcn2Sqa15WugebIYpAIJfGO24ETtc4i jtOGrgC+/q2IAlzb3YycWSxlGJHs4YZ2fLBusjNDLco5TUnroEv2ZJsnfU1svRIeQ33D rU04zoNGNmVefKuUYQpObrUWY4sNzmTEg+R+XtfTiM+mi3a2h5XLjcMGrOahApBaikGv HBMWWMXGLb+iv2vXS6MjlbjemD5nMIO9MkgvEj5yUIZ3RkESY9L/+W8RH0Ww+3TV5dWz 0K3L50njrCdEf3MdtBdhWplO/WTf3f40XSC3WX6nDOBS2v9ND91ZH2tt5dR4kLBheNSp eOmg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:x-gm-message-state:from:to:cc :subject:date; bh=bebhsgLSR/dvglUaatrpWC4eZSs07ICzF3roFpByZIo=; b=xwfCuZMKC/g9EWVbRz9Wb6BqxeDHnfTCI3p2bp56+oVeHEtvHOJBB4gHTpz3dr9px4 FkV7cdaBH4KAkP9aU4lFJ8WktCK/Z1X1S7A2jhlHxqL3MhfbI+3AoATT5Ay6hZyyRGXu le3kelV+95FGSS15mBf7N9Jtyd7W690aKS764Dvy2KVAlSXHoj23gHJlIXmqutnkf6k7 E0DGNsyz1ozhGrh/1zXjvQAMajIgBjGs6q5nNzihyKLQk7lUBgXB6BJ4+ZYLNrlATtYc MiqkeJ/g+tvT2CSOndlmEGs8y4RvboYO6hucRCo5S6oOwhL6Z4IZJ1k5IP2OGlCH0KK7 /nDQ== X-Gm-Message-State: ACrzQf3HXvDUe3COALZrB/ELmuCNzYXnEVDGn0pCdT9QVylRqzPkUE5/ oCVARak1oOt6a+BcgKp3laJN3nn0ZX4= X-Google-Smtp-Source: AMsMyM7C4KUWYgXF3H8Tz97cP5jK3jF4hkbq5jL6eH2Kc02AXAsoM6YUhnbwozoTDOwfIAfiRFb0uQ== X-Received: by 2002:a5d:47c5:0:b0:22a:6d4c:f21e with SMTP id o5-20020a5d47c5000000b0022a6d4cf21emr11795624wrc.417.1663616283093; Mon, 19 Sep 2022 12:38:03 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id az24-20020adfe198000000b00228d7078c4esm15029886wrb.4.2022.09.19.12.38.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Sep 2022 12:38:02 -0700 (PDT) Message-Id: <02afeaa01bef0a033c17a2ab37cc37e5e7818eb9.1663616277.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Mon, 19 Sep 2022 19:37:56 +0000 Subject: [PATCH v9 5/6] fsmonitor: check for compatability before communicating with fsmonitor Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Jeff Hostetler , Eric Sunshine , Torsten =?utf-8?q?B=C3=B6gershause?= =?utf-8?q?n?= , =?utf-8?b?w4Z2YXIgQXJuZmrDtnLDsA==?= Bjarmason , Ramsay Jones , Johannes Schindelin , Eric DeCosta , Eric DeCosta Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Eric DeCosta From: Eric DeCosta If fsmonitor is not in a compatible state, die with an appropriate error messge. Signed-off-by: Eric DeCosta --- fsmonitor-settings.c | 2 ++ fsmonitor.c | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/fsmonitor-settings.c b/fsmonitor-settings.c index 531a1b6f956..aaa204e0352 100644 --- a/fsmonitor-settings.c +++ b/fsmonitor-settings.c @@ -247,6 +247,8 @@ char *fsm_settings__get_incompatible_msg(const struct repository *r, { struct strbuf msg = STRBUF_INIT; + strbuf_add(&msg, "fsmonitor: ", strlen("fsmonitor: ")); + switch (reason) { case FSMONITOR_REASON_UNTESTED: case FSMONITOR_REASON_OK: diff --git a/fsmonitor.c b/fsmonitor.c index 57d6a483bee..43d580132fb 100644 --- a/fsmonitor.c +++ b/fsmonitor.c @@ -305,6 +305,10 @@ void refresh_fsmonitor(struct index_state *istate) int is_trivial = 0; struct repository *r = istate->repo ? istate->repo : the_repository; enum fsmonitor_mode fsm_mode = fsm_settings__get_mode(r); + enum fsmonitor_reason reason = fsm_settings__get_reason(r); + + if (reason > FSMONITOR_REASON_OK) + die("%s", fsm_settings__get_incompatible_msg(r, reason)); if (fsm_mode <= FSMONITOR_MODE_DISABLED || istate->fsmonitor_has_run_once) From patchwork Mon Sep 19 19:37:57 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric DeCosta X-Patchwork-Id: 12980998 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 625F6ECAAD3 for ; Mon, 19 Sep 2022 19:38:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229528AbiISTi1 (ORCPT ); Mon, 19 Sep 2022 15:38:27 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35538 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229580AbiISTiV (ORCPT ); Mon, 19 Sep 2022 15:38:21 -0400 Received: from mail-wr1-x436.google.com (mail-wr1-x436.google.com [IPv6:2a00:1450:4864:20::436]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A44914056B for ; Mon, 19 Sep 2022 12:38:05 -0700 (PDT) Received: by mail-wr1-x436.google.com with SMTP id y5so783134wrh.3 for ; Mon, 19 Sep 2022 12:38:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:from:to:cc:subject:date; bh=LRAZFpHOU5+ay4ne+GDRmL5kg+GCUi05Q3xa/zAhpco=; b=nKIE8Qb3Zpl2IFEWcsmUq45lOEcTVZJsqnCTWkmmotQsbFZEAN5AedTbF0YUjDVYNP xouFcrPAzFYW8EcA6ydO1rKyecu2R+aI/9esoACZf8KJ9G2yNPd+zc2mrjGNSdAQRj6k U/oyUkC0bxCTMZQxsvRrDT0EiXaxqusroOUTvkZY+Y8JfSShFvx8c8HbrhYBeltXrFYX UdUFzQ3Lw4/3pm/VrTRWqbt4rv3s2535yn9VBjM09//PAg1i8lvp89wTddOBKdatR0me 7u2Tut0V3ZyLXsGYyn/nlhKk/pjhq+DV8vlEwrmfFvYMG5Gsn2WiJHuYfTV/ZZnqwo0R V4pw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:x-gm-message-state:from:to:cc :subject:date; bh=LRAZFpHOU5+ay4ne+GDRmL5kg+GCUi05Q3xa/zAhpco=; b=dLVYUnAAQ51OAK9Gr7leQbBw0avJDJv/5BPHTTIG0/NmJw5AWuuiP8FK38pH7DSUah PQgK+masaslfXiI/eRJxvDJTrNTCVk2t/MkEDFHDlQ6Ow7555pYpbM5QJwwTxCK58NX6 JagfFGru5ry+dl6AKiUOABtk4VrYOJFVShnwCXvjbjtAgIWDR8i7lToEMDb5XledoxS9 b12r8PA4z1sXatnRhX+QkzO/3Ox37dmJH05qnG8fPj56g6m429yL48Pc0WyLur4w/Yor yg5W0j+dx8uNDEovVnUvFirsMksClQmeM5WY8MR1pzT4jW3crOGWM0YnPiGoHPZ+iA18 I4rg== X-Gm-Message-State: ACrzQf2bXK+DNR0w3DtCeKlZ74gLTJf4xZUQLpT5qC/Xl/T9N/bR1mTq 48et5ilXD6ooBVD5Xav30fsAXu5KqLQ= X-Google-Smtp-Source: AMsMyM7KcniARPhNxvSM85HBXp24WTq1bdoNM1PJ7WWYf6yOGPFFxbKU6/jjTM7mtvyqGkFxckF5TA== X-Received: by 2002:a5d:5b18:0:b0:22a:fb91:3d6b with SMTP id bx24-20020a5d5b18000000b0022afb913d6bmr5128047wrb.56.1663616283855; Mon, 19 Sep 2022 12:38:03 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id t9-20020a05600c198900b003b47b80cec3sm15913484wmq.42.2022.09.19.12.38.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Sep 2022 12:38:03 -0700 (PDT) Message-Id: <0e8ea28acc12850f2a6b347c6bce509beb756d81.1663616277.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Mon, 19 Sep 2022 19:37:57 +0000 Subject: [PATCH v9 6/6] fsmonitor: add documentation for allowRemote and socketDir options Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Jeff Hostetler , Eric Sunshine , Torsten =?utf-8?q?B=C3=B6gershause?= =?utf-8?q?n?= , =?utf-8?b?w4Z2YXIgQXJuZmrDtnLDsA==?= Bjarmason , Ramsay Jones , Johannes Schindelin , Eric DeCosta , Eric DeCosta Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Eric DeCosta From: Eric DeCosta Add documentation for 'fsmonitor.allowRemote' and 'fsmonitor.socketDir'. Call-out experimental nature of 'fsmonitor.allowRemote' and limited file system support for 'fsmonitor.socketDir'. Signed-off-by: Eric DeCosta --- Documentation/git-fsmonitor--daemon.txt | 48 +++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/Documentation/git-fsmonitor--daemon.txt b/Documentation/git-fsmonitor--daemon.txt index cc142fb8612..6ad3e518ae0 100644 --- a/Documentation/git-fsmonitor--daemon.txt +++ b/Documentation/git-fsmonitor--daemon.txt @@ -3,7 +3,7 @@ git-fsmonitor{litdd}daemon(1) NAME ---- -git-fsmonitor--daemon - A Built-in File System Monitor +git-fsmonitor--daemon - A Built-in Filesystem Monitor SYNOPSIS -------- @@ -17,7 +17,7 @@ DESCRIPTION ----------- A daemon to watch the working directory for file and directory -changes using platform-specific file system notification facilities. +changes using platform-specific filesystem notification facilities. This daemon communicates directly with commands like `git status` using the link:technical/api-simple-ipc.html[simple IPC] interface @@ -63,13 +63,55 @@ CAVEATS ------- The fsmonitor daemon does not currently know about submodules and does -not know to filter out file system events that happen within a +not know to filter out filesystem events that happen within a submodule. If fsmonitor daemon is watching a super repo and a file is modified within the working directory of a submodule, it will report the change (as happening against the super repo). However, the client will properly ignore these extra events, so performance may be affected but it will not cause an incorrect result. +By default, the fsmonitor daemon refuses to work against network-mounted +repositories; this may be overridden by setting `fsmonitor.allowRemote` to +`true`. Note, however, that the fsmonitor daemon is not guaranteed to work +correctly with all network-mounted repositories and such use is considered +experimental. + +On Mac OS, the inter-process communication (IPC) between various Git +commands and the fsmonitor daemon is done via a Unix domain socket (UDS) -- a +special type of file -- which is supported by native Mac OS filesystems, +but not on network-mounted filesystems, NTFS, or FAT32. Other filesystems +may or may not have the needed support; the fsmonitor daemon is not guaranteed +to work with these filesystems and such use is considered experimental. + +By default, the socket is created in the `.git` directory, however, if the +`.git` directory is on a network-mounted filesystem, it will be instead be +created at `$HOME/.git-fsmonitor-*` unless `$HOME` itself is on a +network-mounted filesystem in which case you must set the configuration +variable `fsmonitor.socketDir` to the path of a directory on a Mac OS native +filesystem in which to create the socket file. + +If none of the above directories (`.git`, `$HOME`, or `fsmonitor.socketDir`) +is on a native Mac OS file filesystem the fsmonitor daemon will report an +error that will cause the daemon and the currently running command to exit. + +CONFIGURATION +------------- + +When `core.fsmonitor` is set to `true` (see linkgit:git-config[1]) +the fsmonitor daemon will pay attention to the following configuration +variables: + +`fsmonitor.allowRemote`:: + By default, the daemon refuses to work against network-mounted + repositories. Setting `fsmonitor.allowRemote` to `true` overrides + this behavior. + +`fsmonitor.socketDir`:: + This Mac OS-specific option, if set, specifies the directory in + which to create the Unix domain socket used for communication + between fsmonitor and various Git commands. The directory must + reside on a native Mac OS filesystem as discussed above. + GIT --- Part of the linkgit:git[1] suite