From patchwork Tue Sep 27 20:57:28 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric DeCosta X-Patchwork-Id: 12991398 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 240BCC54EE9 for ; Tue, 27 Sep 2022 20:57:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232322AbiI0U5q (ORCPT ); Tue, 27 Sep 2022 16:57:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58072 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232144AbiI0U5k (ORCPT ); Tue, 27 Sep 2022 16:57:40 -0400 Received: from mail-wr1-x430.google.com (mail-wr1-x430.google.com [IPv6:2a00:1450:4864:20::430]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6F76A18B4B0 for ; Tue, 27 Sep 2022 13:57:38 -0700 (PDT) Received: by mail-wr1-x430.google.com with SMTP id t14so16777715wrx.8 for ; Tue, 27 Sep 2022 13:57:38 -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=jyQe/NQP3hTHVE49v/cZfXEl/Zy3w2uVEPriXZZMtPI=; b=qhnLc1OwNdqmsL2W4xZmHczc7yA2HdJ+ZxlMW65o8Gn9C9pSV/qBKTVmeNa9VcP5JZ BhEMNt7xd+g7fcLRG+GdjK2IwC1I1J0qWOf6radNH3gGkaoyJ6LgP6LZdkmQNyGIgiKR b51UwoRPp+QeCDAGvIMBxMgFqwK5WGj7iin+0kQI08aHV1gDiht1rKLcZJB/a/4aJXH5 EZt7/mCwtS6gDj1WYrfxYtNwHVaOSAc98/rRdlULEBP2MxZ5rBau2cKxVbjGNq9r4M7I KNmHHGOfXKETcFCqTl6BHR8+cyegMJxN32NNXy/f70SmejQ2F2TQnQ5DGfskI6nFQx9X VG9A== 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=jyQe/NQP3hTHVE49v/cZfXEl/Zy3w2uVEPriXZZMtPI=; b=tBxj8ImeDx11LY7Mp1wP1qnZZoOF8QWpuwc2z960T1g5Dol6XfcyVGBIer8sUTZek8 trW0DP8MlimGo9Qsc92qjkFlAloI/9YMSJoCq0Gzf23WpPtNf7yIkkOHn/LziYS45KcT 8ulOIinRsOuizRB4Jt4jHxlqKv/mh5/SyM/3kVBEEAjCoN80CMp7MOJ602/6nNKNfKYt Fi2aKcJLEk44U2lR412Aq3IPoMoH9TTErbBTOAyoIXsqr1evd7ALlbDqQgDCIanudIMP xxsgZ9KWCGy8Wb4qBk6YwWvgO87+CGN6Yn3415cCGF1qonWyuWI9GvtsYp/TXSZdnOfM WBwQ== X-Gm-Message-State: ACrzQf2KoKFfRiNoLQUGsc6SY8hEVgojgVVTrSuhjwCJGRklSdm6oNQZ mYil3mT4idR8jsA9X0iyUcCI2Hr126k= X-Google-Smtp-Source: AMsMyM6d52GTpgUTICi4RtXU7QXrI62ctlpye9toc+6Uy75RvXrZZ8u/FQ3LKWbgU0o8JGcbEv05tg== X-Received: by 2002:a5d:4d4c:0:b0:22c:c2fc:12a3 with SMTP id a12-20020a5d4d4c000000b0022cc2fc12a3mr2348225wru.90.1664312256475; Tue, 27 Sep 2022 13:57:36 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id t126-20020a1c4684000000b003b505d26776sm14661781wma.5.2022.09.27.13.57.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 27 Sep 2022 13:57:36 -0700 (PDT) Message-Id: <0b9b64428c5e096ada1f274639be9604e8c2f9ed.1664312254.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Tue, 27 Sep 2022 20:57:28 +0000 Subject: [PATCH v13 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 cac3452edb9..ffab427ea5b 100644 --- a/Makefile +++ b/Makefile @@ -2044,6 +2044,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 ea2a531be87..5482a04b3ce 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 Tue Sep 27 20:57:29 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric DeCosta X-Patchwork-Id: 12991399 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 C1479C07E9D for ; Tue, 27 Sep 2022 20:57:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232465AbiI0U5r (ORCPT ); Tue, 27 Sep 2022 16:57:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58070 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232125AbiI0U5k (ORCPT ); Tue, 27 Sep 2022 16:57:40 -0400 Received: from mail-wm1-x332.google.com (mail-wm1-x332.google.com [IPv6:2a00:1450:4864:20::332]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3DA041B527C for ; Tue, 27 Sep 2022 13:57:39 -0700 (PDT) Received: by mail-wm1-x332.google.com with SMTP id r10-20020a1c440a000000b003b494ffc00bso2049394wma.0 for ; Tue, 27 Sep 2022 13:57:39 -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=iH31q5XFlDjFmjSCRRAV8EdGb54MBB7nD+8fkLm82u4=; b=QNVttz3RoMqqnKFmGUOnMbgkMiPJyv0pfzL2OOReDmGvN88lx/pF9HKwogb0HvQc7b kBVm3PpOWT6SaX98lMQjdCWXPIRJr2CPX8zwcW/MFcU4Uu0vnMGJWgyaZfPtu2g5M40e J6qktbyMTgw6fJVfkF1AWxsr9ijg4bPz6Tkf9MFKsPX0rpgYphecEnqsVC8Wv3y95Kcq TL5fG/VsxywjOo48Gb701qi8X7oRn0AFJvnGFUMQNVOGBDROQ+/VX07lX2Jw/8s6o0qq DYfJEalSDq79Som6fCTIXwbDOVPVSZn8O372a+8bla5O03bLua8q3Zg8AzdiUDEFqM9n VuMA== 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=iH31q5XFlDjFmjSCRRAV8EdGb54MBB7nD+8fkLm82u4=; b=GVycm3K+s3hQ+xkZjKV1EzZQL3ArYWtAPFLmNEl/k3XYoAmks83V4c8I+szmq6z1oQ 2TiQgyswdzr03cOu/8ekyT8jQy9oFv6O0eucUvYqICL8GsJt2g3hN3gqBnlzR9Trp1ea u1PXuIYZh4pVR3A4guNhjk2gmde6XhE5KZ4t8DUJXwFV2i9JiHZ0jjkNPBpSQ/VI8rWq W6fwulkQzA2Ahh0BeD7CFAyhsiKn7F2JCGyXpsMhdZNGtt+VIM5pq8mb/4tnfgXj+ajF BvGFYSyAOE9eRR98Hl3X/VIGJGW1TFvFeChKfDsctcIV3UI/Q/rAhTEFbEqpfNCvN6xD +L3A== X-Gm-Message-State: ACrzQf04GhWXynxuuln/PKOj12gYT0LMwwlwzK5537OpYjvcOAoIPo58 k7OeFcqE9wjfoQflqRd+H1OWRO4qSEg= X-Google-Smtp-Source: AMsMyM5saSQhqTG2fhssXTd319iX8RQiYdAycgaHor/X/tsPe8wYwamRmNFqhFbslPnrQ83VWlxEdw== X-Received: by 2002:a05:600c:b47:b0:3b4:8604:410c with SMTP id k7-20020a05600c0b4700b003b48604410cmr4200076wmr.51.1664312257523; Tue, 27 Sep 2022 13:57:37 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id d37-20020a05600c4c2500b003b332a7b898sm2437086wmp.45.2022.09.27.13.57.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 27 Sep 2022 13:57:36 -0700 (PDT) Message-Id: <680d4c83f99dacb1cac90f96bc2f02d9614b880c.1664312254.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Tue, 27 Sep 2022 20:57:29 +0000 Subject: [PATCH v13 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 filesystem, 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 | 52 ++++++++++++++++++++++++++ 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, 78 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 ffab427ea5b..feb675a6959 100644 --- a/Makefile +++ b/Makefile @@ -2039,6 +2039,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..ce843d63348 --- /dev/null +++ b/compat/fsmonitor/fsm-ipc-darwin.c @@ -0,0 +1,52 @@ +#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 = NULL; + SHA_CTX sha1ctx; + char *sock_dir = NULL; + struct strbuf ipc_file = STRBUF_INIT; + unsigned char hash[SHA_DIGEST_LENGTH]; + + if (!r) + BUG("No repository passed into fsmonitor_ipc__get_path"); + + if (ipc_path) + return ipc_path; + + + /* By default the socket file is created in the .git directory */ + if (fsmonitor__is_fs_remote(r->gitdir) < 1) { + ipc_path = fsmonitor_ipc__get_default_path(); + 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)); + } else { + strbuf_addf(&ipc_file, "~/.git-fsmonitor-%s", hash_to_hex(hash)); + } + free(sock_dir); + + 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..e08c505c148 --- /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; +} 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 5482a04b3ce..787738e6fa3 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 Tue Sep 27 20:57:30 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric DeCosta X-Patchwork-Id: 12991400 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 51B90C07E9D for ; Tue, 27 Sep 2022 20:57:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232540AbiI0U5u (ORCPT ); Tue, 27 Sep 2022 16:57:50 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58078 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229966AbiI0U5l (ORCPT ); Tue, 27 Sep 2022 16:57:41 -0400 Received: from mail-wm1-x336.google.com (mail-wm1-x336.google.com [IPv6:2a00:1450:4864:20::336]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 602111B34B6 for ; Tue, 27 Sep 2022 13:57:40 -0700 (PDT) Received: by mail-wm1-x336.google.com with SMTP id i203-20020a1c3bd4000000b003b3df9a5ecbso10189565wma.1 for ; Tue, 27 Sep 2022 13:57:40 -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=MhCHcKKG6FXt86rhAKICt50HbWAYArkoQlUvmTeezWRVUCEtehjHWtd0XGxuBDS2AO fWSjnHMPlfiJj2FZ1aWhJW0MgZxJ75Gqh0zX+TRD8TzzTyxT6uzlj0Ueg/jGivHFetmK Lhi5PF3BNfsPmy+InlTBHxCOx05nR60lQ0W6WBn53OI0uKav9cTCOuDbuuE03u2D0B2u BbigPviyfWBp3ipZFu9mV97XrkDIJhV59khijKi+ikG/fDw3Xett7WW30pUoM6SsfyUc EXKLgwVJYFikvUhX4MuU3xz6XXffslXR2nIjXLhahOEU/0ZVyj5u6dzyhFXXEyPvWv0h V9nQ== 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=lOo526d4jQZvS0WS877HlKylX7U109KYX7YPweyXAAhpdu5TTtpsDJVROllYOR54aS +DouNZdKMCByAxuHIHixgKdoUeNMjv8lrGlZGyP0XyDOV5oes18Ekj/VfCVtKBMkulL7 PinwOZ6QLO5KRuaT35askM/BZYrQYhCvnqJgORmFnDqRNmQ8sPl3OQwd3cg53D/7SzMd uHhOAQWtoF0P0fFiiTzLQ56NR+U6f+PAGopj5OqmCpxkgquoBnTvseUELyW2JREpNPu1 svVUZWsJDPvBKYp62MOKlO/7xJZrsG+oD0V8Ff/NhiMWkMYmXtAryZPPQN/XgkcLMxjd tjzQ== X-Gm-Message-State: ACrzQf0cx0gCTQ1lem2eSymT5HrODcD301N+HP3qrh5VZmyNVROAETSF qDQw68olZfMjtNOJtLbF5q3cHzJsbs8= X-Google-Smtp-Source: AMsMyM4ku7w/rAPL9ntJnmrmmGK1vP/uhAfHLQcwNAyo9qtIbR2wxZT06vUZ8/DlgHhei4rc2uiZ7A== X-Received: by 2002:a1c:7213:0:b0:3b3:4065:66cc with SMTP id n19-20020a1c7213000000b003b3406566ccmr4179291wmc.184.1664312258724; Tue, 27 Sep 2022 13:57:38 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id h4-20020a05600c498400b003b4935f04a4sm3140429wmp.5.2022.09.27.13.57.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 27 Sep 2022 13:57:38 -0700 (PDT) Message-Id: <7987d0c1f33da7cdd62f2ffbaccd1cda281a7305.1664312254.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Tue, 27 Sep 2022 20:57:30 +0000 Subject: [PATCH v13 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 Tue Sep 27 20:57:31 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric DeCosta X-Patchwork-Id: 12991401 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 0CCE6C07E9D for ; Tue, 27 Sep 2022 20:57:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232557AbiI0U5w (ORCPT ); Tue, 27 Sep 2022 16:57:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58072 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232160AbiI0U5n (ORCPT ); Tue, 27 Sep 2022 16:57:43 -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 51D56149D2F for ; Tue, 27 Sep 2022 13:57:41 -0700 (PDT) Received: by mail-wr1-x435.google.com with SMTP id x18so16799314wrm.7 for ; Tue, 27 Sep 2022 13:57:41 -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=yzfz98q2dztrByC52f9hrlPrszlAs4lsv0IDlH5j8u8=; b=imeBIeGR3HapbmDlzJt62qnxIIuUlruyY1IPMse+G6T3BtdVx73RRHfzY4vavoxt2R GQ1HDfo4tGpM5JXtFvQ6xEhCB68jcrWvAUJq90fqanMwpr5dLj5SMoLAL5mkaP/IZadq qz2mcOmSNAQTPG5S/K2+X0P6lt2rmwJaNLJ8cmKacCBVZeOkukySfyGx64LlDHHxS+x3 VuLxtUVOebAo6T+RZ5Nn+1k+4SdvBbfvQPPU8z+6DTVH0b5599Q7j5w/ZUXQF06duCTy Zpz9ngvXi5pgqnXTsL+rp7XpKmH7bSz6RtqNU/gSWBIXLXV2KHSq18PZ6NxdX0AJUprP AOdw== 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=yzfz98q2dztrByC52f9hrlPrszlAs4lsv0IDlH5j8u8=; b=NDe3JAZwcA09/IEUiRHwBJ9etJFK3NZpNcFUR96d/9AGr5XJi5V/4bZuhy9GDFqMWG qDxFBeVUQDQ2xL0a5ywR6lfvuOkqdYZz0NdMj4iYCjZXp5Tue/EERWdzrUPV44fcjNvC 44z0M/1LGQqEFZCpxSlqBe5UwYV+ekE8lHr4+v4K5GazPJSJ5JHhiHFGz1a6afeebUQT uHoiAuyqTX5+R3+BscNUsNJsdPVIizMig4VHw+guE2zAqnPmGeL6a8mvfQUZ16vTFEqH 4kFus8onEFi44f6G7ASR1U+ZhzfEugA9wSzokVsVRsIOTAoyoDyRNWUc/wPzhyz7rjC/ NvSw== X-Gm-Message-State: ACrzQf3GOuSH510/hdA5VVpBB4EYkFwQ7/gG4fJ3HpevcH1OhlU3aube cWCRGmH0zalRidis39LwTfY/bWdUzQg= X-Google-Smtp-Source: AMsMyM4oE01UwMmqXh/HKGdCEY4HtKrpcSO0TvCBpoKt0N8lExhR1SGApM3TBl3/B+aPrRC3pqN6Jg== X-Received: by 2002:adf:9dd0:0:b0:22c:3fe0:42ef with SMTP id q16-20020adf9dd0000000b0022c3fe042efmr14693224wre.348.1664312259609; Tue, 27 Sep 2022 13:57:39 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id i1-20020adfa501000000b0022a2f4fa042sm2628316wrb.103.2022.09.27.13.57.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 27 Sep 2022 13:57:39 -0700 (PDT) Message-Id: <324eb5acd856f6a8122a5239f9fa1a9a8ecc9ee3.1664312254.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Tue, 27 Sep 2022 20:57:31 +0000 Subject: [PATCH v13 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 | 10 +++ compat/fsmonitor/fsm-listen-darwin.c | 14 +++- compat/fsmonitor/fsm-path-utils-darwin.c | 93 ++++++++++++++++++++++++ compat/fsmonitor/fsm-path-utils-win32.c | 17 +++++ fsmonitor--daemon.h | 3 + fsmonitor-path-utils.h | 36 ++++++++- 6 files changed, 170 insertions(+), 3 deletions(-) diff --git a/builtin/fsmonitor--daemon.c b/builtin/fsmonitor--daemon.c index 0123fc33ed2..d5056a97a06 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; + strbuf_init(&state.alias.alias, 0); + strbuf_init(&state.alias.points_to, 0); + 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 @@ -1391,6 +1399,8 @@ done: strbuf_release(&state.path_gitdir_watch); strbuf_release(&state.path_cookie_prefix); strbuf_release(&state.path_ipc); + strbuf_release(&state.alias.alias); + strbuf_release(&state.alias.points_to); return err; } diff --git a/compat/fsmonitor/fsm-listen-darwin.c b/compat/fsmonitor/fsm-listen-darwin.c index 8e208e8289e..daeee4e465c 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 { @@ -198,8 +199,9 @@ static void fsevent_callback(ConstFSEventStreamRef streamRef, struct string_list cookie_list = STRING_LIST_INIT_DUP; const char *path_k; const char *slash; - int k; + char *resolved = NULL; struct strbuf tmp = STRBUF_INIT; + int k; /* * Build a list of all filesystem changes into a private/local @@ -209,7 +211,12 @@ static void fsevent_callback(ConstFSEventStreamRef streamRef, /* * On Mac, we receive an array of absolute paths. */ - path_k = paths[k]; + free(resolved); + resolved = fsmonitor__resolve_alias(paths[k], &state->alias); + if (resolved) + path_k = resolved; + else + path_k = paths[k]; /* * If you want to debug FSEvents, log them to GIT_TRACE_FSMONITOR. @@ -238,6 +245,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 @@ -360,12 +368,14 @@ static void fsevent_callback(ConstFSEventStreamRef streamRef, } } + free(resolved); fsmonitor_publish(state, batch, &cookie_list); string_list_clear(&cookie_list, 0); strbuf_release(&tmp); return; force_shutdown: + free(resolved); fsmonitor_batch__free_list(batch); string_list_clear(&cookie_list, 0); diff --git a/compat/fsmonitor/fsm-path-utils-darwin.c b/compat/fsmonitor/fsm-path-utils-darwin.c index 067cbe6990a..931c9318572 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,93 @@ 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 = -1; + struct dirent *de; + struct strbuf alias; + struct strbuf points_to; + + dir = opendir("/"); + if (!dir) { + error_errno("opendir('/') failed"); + return -1; + } + + strbuf_init(&alias, 256); + + /* no way of knowing what the link will resolve to, so MAXPATHLEN */ + 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)) + && path[points_to.len] == '/') { + strbuf_addbuf(&info->alias, &alias); + strbuf_addbuf(&info->points_to, &points_to); + trace_printf_key(&trace_fsmonitor, + "Found alias for '%s' : '%s' -> '%s'", + path, info->alias.buf, info->points_to.buf); + retval = 0; + goto done; + } + } else if (!read) { + BUG("readlink returned 0"); + } else if (errno != EINVAL) { /* Something other than not a link */ + error_errno("readlink('%s') failed", alias.buf); + goto done; + } + } + retval = 0; /* no alias */ + +done: + if (closedir(dir) < 0) + warning_errno("closedir('/') failed"); + strbuf_release(&alias); + strbuf_release(&points_to); + return retval; +} + +char *fsmonitor__resolve_alias(const char *path, + const struct alias_info *info) +{ + if (!info->alias.len) + return NULL; + + if ((!strncmp(info->alias.buf, path, info->alias.len)) + && path[info->alias.len] == '/') { + struct strbuf tmp = STRBUF_INIT; + const char *remainder = path + info->alias.len; + + strbuf_addbuf(&tmp, &info->points_to); + strbuf_add(&tmp, remainder, strlen(remainder)); + 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..2624798d2c7 100644 --- a/fsmonitor-path-utils.h +++ b/fsmonitor-path-utils.h @@ -1,13 +1,21 @@ #ifndef FSM_PATH_UTILS_H #define FSM_PATH_UTILS_H +#include "strbuf.h" + +struct alias_info +{ + struct strbuf alias; + struct strbuf points_to; +}; + struct fs_info { int is_remote; char *typename; }; /* - * Get some basic filesystem informtion for the given path + * Get some basic filesystem information for the given path * * Returns -1 on error, zero otherwise. */ @@ -20,4 +28,30 @@ 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 info.alias and + * info.points_to and is responsible for releasing it. + */ +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. + */ +char *fsmonitor__resolve_alias(const char *path, + const struct alias_info *info); + #endif From patchwork Tue Sep 27 20:57:32 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric DeCosta X-Patchwork-Id: 12991402 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 E9B45C6FA82 for ; Tue, 27 Sep 2022 20:57:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232586AbiI0U54 (ORCPT ); Tue, 27 Sep 2022 16:57:56 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58092 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232201AbiI0U5n (ORCPT ); Tue, 27 Sep 2022 16:57:43 -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 5396E1B85E3 for ; Tue, 27 Sep 2022 13:57:42 -0700 (PDT) Received: by mail-wr1-x435.google.com with SMTP id z6so16835365wrq.1 for ; Tue, 27 Sep 2022 13:57:42 -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=dGPBcKUgeUZ0B0/7zoDbOtB89jBJhmHgJI4xQ6b+zEk=; b=eTiR4D03dv342Lbt/xBJCYOpDiTbPdGXglUYjvNKxJyejR5FL7rnUeTsLGZb+Eysyn kxnySZNdTz+29o7QXiy1HnRM9Pu/GdF74tJKWrAJS6NOhx3a3/8nsCt9WSy3EQ+/6kfC C4igv6J3k0hEUSZQS/ACWGoI04RF9nkXNbIf88KvhiT6+XdSrC5kjzQF6mlGwEf8hkzG ZcMX2xovYHNMlundwl2fcIGM8cAe9zX6AVdN0pJ339xA14l7PZ5Qv6rACbjLiv7dp5SC g1Ok4kAF/eqCVNEcqdtMcZ+Ynu3Uf6BXD4qEinNbSHSO9PKaWzZOio308yCbcphlpb2W m+cA== 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=dGPBcKUgeUZ0B0/7zoDbOtB89jBJhmHgJI4xQ6b+zEk=; b=xIpUgAA7j2e/3pE7RYzGZb2PIq30JMi4zCESXMS13sffF24LaPEDlFnEIiKryAOmW2 hazvK5CRu+0LFS6hlpEzOONwDwEIqX8obGYOrifosNzIlOqeR4/VTsyfMCkGWi+CQLGW BP1+HAZq2/rgDCUwAC5dWDfLf0f+gsGjoeoK5NAGYlnLUzH9kceopEA2JMZ90BobqJQI 08FpM1kC/+4F39QHnm5O+KWN3LoKQuWF5Ge589xcmFCyEoYSYa0RQV2DqOGa7U7bzccc q09n8IVqPtbVpqp67t8BP5fJkDgsPKT5AhmSrKzC8yVy2ms8QI7s2S704mEJGuAcHYsO m6hw== X-Gm-Message-State: ACrzQf0sLjclfemzNtt01JoCIyZTe543J3eC4j02kNfCK/FTtDdewS9s px8iJ7IauWq+1Zxwo48PfbN5kBzFiCc= X-Google-Smtp-Source: AMsMyM6CBgJ36yHADVeemzg5HQCcCxcbx1UwOFhAKWjZhdWExO7VgRw3/yB4rbkdj7TC+x95FFtLrg== X-Received: by 2002:adf:d1e3:0:b0:22a:b9e2:8841 with SMTP id g3-20020adfd1e3000000b0022ab9e28841mr17939806wrd.184.1664312260698; Tue, 27 Sep 2022 13:57:40 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id n43-20020a05600c502b00b003b486027c8asm15239129wmr.20.2022.09.27.13.57.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 27 Sep 2022 13:57:40 -0700 (PDT) Message-Id: In-Reply-To: References: Date: Tue, 27 Sep 2022 20:57:32 +0000 Subject: [PATCH v13 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, warn with an appropriate message. Signed-off-by: Eric DeCosta --- compat/fsmonitor/fsm-settings-darwin.c | 2 +- fsmonitor-settings.c | 10 +++++++--- fsmonitor-settings.h | 2 +- fsmonitor.c | 7 +++++++ 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/compat/fsmonitor/fsm-settings-darwin.c b/compat/fsmonitor/fsm-settings-darwin.c index 40da2d3b533..44233125df8 100644 --- a/compat/fsmonitor/fsm-settings-darwin.c +++ b/compat/fsmonitor/fsm-settings-darwin.c @@ -38,7 +38,7 @@ static enum fsmonitor_reason check_uds_volume(struct repository *r) strbuf_release(&path); if (fs.is_remote) - return FSMONITOR_REASON_REMOTE; + return FSMONITOR_REASON_NOSOCKETS; if (!strcmp(fs.typename, "msdos")) /* aka FAT32 */ return FSMONITOR_REASON_NOSOCKETS; diff --git a/fsmonitor-settings.c b/fsmonitor-settings.c index 531a1b6f956..ee63a97dc51 100644 --- a/fsmonitor-settings.c +++ b/fsmonitor-settings.c @@ -1,6 +1,7 @@ #include "cache.h" #include "config.h" #include "repository.h" +#include "fsmonitor-ipc.h" #include "fsmonitor-settings.h" #include "fsmonitor-path-utils.h" @@ -242,10 +243,11 @@ enum fsmonitor_reason fsm_settings__get_reason(struct repository *r) return r->settings.fsmonitor->reason; } -char *fsm_settings__get_incompatible_msg(const struct repository *r, +char *fsm_settings__get_incompatible_msg(struct repository *r, enum fsmonitor_reason reason) { struct strbuf msg = STRBUF_INIT; + const char *socket_dir; switch (reason) { case FSMONITOR_REASON_UNTESTED: @@ -281,9 +283,11 @@ char *fsm_settings__get_incompatible_msg(const struct repository *r, goto done; case FSMONITOR_REASON_NOSOCKETS: + socket_dir = dirname((char *)fsmonitor_ipc__get_path(r)); strbuf_addf(&msg, - _("repository '%s' is incompatible with fsmonitor due to lack of Unix sockets"), - r->worktree); + _("socket directory '%s' is incompatible with fsmonitor due" + " to lack of Unix sockets support"), + socket_dir); goto done; } diff --git a/fsmonitor-settings.h b/fsmonitor-settings.h index 0721617b95a..ab02e3995ee 100644 --- a/fsmonitor-settings.h +++ b/fsmonitor-settings.h @@ -33,7 +33,7 @@ enum fsmonitor_mode fsm_settings__get_mode(struct repository *r); const char *fsm_settings__get_hook_path(struct repository *r); enum fsmonitor_reason fsm_settings__get_reason(struct repository *r); -char *fsm_settings__get_incompatible_msg(const struct repository *r, +char *fsm_settings__get_incompatible_msg(struct repository *r, enum fsmonitor_reason reason); struct fsmonitor_settings; diff --git a/fsmonitor.c b/fsmonitor.c index 57d6a483bee..540736b39fd 100644 --- a/fsmonitor.c +++ b/fsmonitor.c @@ -295,6 +295,7 @@ static int fsmonitor_force_update_threshold = 100; void refresh_fsmonitor(struct index_state *istate) { + static int warn_once = 0; struct strbuf query_result = STRBUF_INIT; int query_success = 0, hook_version = -1; size_t bol = 0; /* beginning of line */ @@ -305,6 +306,12 @@ 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 (!warn_once && reason > FSMONITOR_REASON_OK) { + warn_once = 1; + warning("%s", fsm_settings__get_incompatible_msg(r, reason)); + } if (fsm_mode <= FSMONITOR_MODE_DISABLED || istate->fsmonitor_has_run_once) From patchwork Tue Sep 27 20:57:33 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric DeCosta X-Patchwork-Id: 12991403 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 331E3C07E9D for ; Tue, 27 Sep 2022 20:58:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232599AbiI0U56 (ORCPT ); Tue, 27 Sep 2022 16:57:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58102 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232261AbiI0U5o (ORCPT ); Tue, 27 Sep 2022 16:57:44 -0400 Received: from mail-wr1-x432.google.com (mail-wr1-x432.google.com [IPv6:2a00:1450:4864:20::432]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 42A2D18B4B0 for ; Tue, 27 Sep 2022 13:57:43 -0700 (PDT) Received: by mail-wr1-x432.google.com with SMTP id c11so16763240wrp.11 for ; Tue, 27 Sep 2022 13:57:43 -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=NZZ/jRI252DzMeVq+3yot+76+uTRZX0nJIDrWhlOFuE=; b=AgCveodU+cNT+B6qUY0SVU5aLApIYhWBe93HOdSznALLlEDQEMZbsX/hkgjz7RTDof gfLyVN6W1ESBYCAFjXh9cE2hKZWK6IBwYwP330oQT6p1rWDO+O5jtaB6FMcoUmzomf1p FZLbfSLmr7bO5mTMHXEa9HH6UjGCDlFjs+Jn26x5ikqBfF3sYAKOnF795usa49iNLybf SJh1ZhhGCVF5el+l+QXR9DnkdnOCKGHeBEOpLoRFZUU1FJ/sR7sux8N1e02V4ndHKKm9 3jpNL3SeAXE+5nRBvXTVN16opLkWRQv0DM0zb3vkjYyBY0+fvQEgd72Ns6kUFwkUbP3L nkcA== 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=NZZ/jRI252DzMeVq+3yot+76+uTRZX0nJIDrWhlOFuE=; b=vDvoRO8bJrQfpL4xeBdLWFb+rHOmY3deCVjpgh0qaxeVP+u/K49QQrrQb9FKZo32Qt 4QVtqNGakmEXG0hx3qMRL+BBcfzz4U3lmPOUX6k+IQcqXSLZaPW/pucZcy5/btis8BuL nUOk59PFKeJDyYISKR+g9e7sWvAW79Tq8ZTGT+eqoRUmK49Rjtuc6NOsQEta+MNvDfFD IdNh6QnLAASZpm7a6thz1aQNcFBvTVCm09h9EmyN+jCY+sm6giYFDwYL5hghNO5FLnvp 0qMdUi58DR5icUS7Pa0Z3EdZuYjD2o1m5NZsn9QkDo6uLgGieZfjqAYJRzW9/nbQhP7o WzJA== X-Gm-Message-State: ACrzQf0m+8ynwHqEVayc/LAVClNa97gcYfANWZlYcCtRK74JAVrn6qT4 ni11DEt2YTkG6UNwUc23luIryKsYgrk= X-Google-Smtp-Source: AMsMyM6BTnkzq3BogVUGt4OxAom5s92mrmF4nNrrf9hq5oV29cGjZmG1COeNnUu/RgRTVf8EKpBvlg== X-Received: by 2002:a5d:59c3:0:b0:22a:4463:5a3a with SMTP id v3-20020a5d59c3000000b0022a44635a3amr17501891wry.123.1664312261603; Tue, 27 Sep 2022 13:57:41 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id e12-20020adffc4c000000b0022ad393ba3csm2488486wrs.107.2022.09.27.13.57.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 27 Sep 2022 13:57:41 -0700 (PDT) Message-Id: <04f607b1f21ede3ef35af05846995e4f80906301.1664312254.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Tue, 27 Sep 2022 20:57:33 +0000 Subject: [PATCH v13 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 filesystem support for 'fsmonitor.socketDir'. Signed-off-by: Eric DeCosta --- Documentation/config.txt | 2 ++ Documentation/config/fsmonitor--daemon.txt | 11 +++++++ Documentation/git-fsmonitor--daemon.txt | 37 ++++++++++++++++++++-- 3 files changed, 47 insertions(+), 3 deletions(-) create mode 100644 Documentation/config/fsmonitor--daemon.txt diff --git a/Documentation/config.txt b/Documentation/config.txt index 5b5b9765699..1e205831656 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -423,6 +423,8 @@ include::config/filter.txt[] include::config/fsck.txt[] +include::config/fsmonitor--daemon.txt[] + include::config/gc.txt[] include::config/gitcvs.txt[] diff --git a/Documentation/config/fsmonitor--daemon.txt b/Documentation/config/fsmonitor--daemon.txt new file mode 100644 index 00000000000..c225c6c9e74 --- /dev/null +++ b/Documentation/config/fsmonitor--daemon.txt @@ -0,0 +1,11 @@ +fsmonitor.allowRemote:: + By default, the fsmonitor daemon refuses to work against network-mounted + repositories. Setting `fsmonitor.allowRemote` to `true` overrides this + behavior. Only respected when `core.fsmonitor` is set to `true`. + +fsmonitor.socketDir:: + This Mac OS-specific option, if set, specifies the directory in + which to create the Unix domain socket used for communication + between the fsmonitor daemon and various Git commands. The directory must + reside on a native Mac OS filesystem. Only respected when `core.fsmonitor` + is set to `true`. diff --git a/Documentation/git-fsmonitor--daemon.txt b/Documentation/git-fsmonitor--daemon.txt index cc142fb8612..8238eadb0e1 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,44 @@ 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 +------------- + +include::includes/cmd-config-section-all.txt[] + +include::config/fsmonitor--daemon.txt[] + GIT --- Part of the linkgit:git[1] suite