From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: AS3215 2.6.0.0/16 X-Spam-Status: No, score=-3.5 required=3.0 tests=AWL,BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE shortcircuit=no autolearn=ham autolearn_force=no version=3.4.2 Received: from out1.vger.email (out1.vger.email [IPv6:2620:137:e000::1:20]) by dcvr.yhbt.net (Postfix) with ESMTP id 5CEB91F670 for ; Tue, 8 Mar 2022 22:16:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1350392AbiCHWRF (ORCPT ); Tue, 8 Mar 2022 17:17:05 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52080 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1350668AbiCHWQ5 (ORCPT ); Tue, 8 Mar 2022 17:16:57 -0500 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 753A6574A6 for ; Tue, 8 Mar 2022 14:15:44 -0800 (PST) Received: by mail-wr1-x432.google.com with SMTP id j26so282366wrb.1 for ; Tue, 08 Mar 2022 14:15:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=EcFYnwkzP4+zTTHaSF78Zw6De5rCM8prxq8TifZp5Yg=; b=bIH90xI2eKB+1JhsHVV6y8Fm9Uzqnr6mfHJV/ao1/istAwsj7LW9YmNKNK2V/GjGeb R4KbZwjcmkTr2YpWhnx3/vleGi8JEyl4tIIJJ9LJaCPhgrhTgrtSmIilqR1ihDyQBeYG bo7+fB4LTA4UDTJBIiqq3cE/iGTQZ/CI1OvyItx5UtowHZmG3CVXI0LTFV3bFPN2GzKJ blQmuG+qU61smvT9cmB6MJ0ods3/ii6jIun9Dcy9YBp9cPjL3Xn2o1KlOOHUp/Nrx3ST BBxtbIe9hAYbIN+RlVKYcSI3lb+1TKNPRIoyCHh5sTGh4K9skMKRG+nyfgR29l+K5KFb 9xFw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=EcFYnwkzP4+zTTHaSF78Zw6De5rCM8prxq8TifZp5Yg=; b=6W3yCNnwtwzA1EAP3aFv4QvzPiW4ScHuleN+7kuN8nMCPrutA2GvkZrPnx9hcifVK/ /nKgAH5zHQ93hYiiKd08ByyCDxxIQTRwefCd7+A9W5JMQGhKOpBQCuvqQkM5teRYecyS +OH7+/KXtzx5jqcZSVVWTEuottVR0kooWiLOSxz69EVHuyLz8Q0jFOX/zPOyYLTr9/gb Bgtqvq01i5ORX+b4+KRu1Ib6Ws0PmlfGKBCHagYx6sFfcJE1uMt8H3eNuqUkgEyjQlem z4Uaq4aQHQTn2quIdvIxqIvUCGLTgyO+q1ywooAqSG5k7yUbV/jl2aVTz3kGTfdnsE3/ cpeA== X-Gm-Message-State: AOAM532JYrvZHXJx5ZufWl15wflPFXMUiJiwv01sbitq7MJlKSOTeyr2 8uV0xvbDpTV4gcGPm6BGXX+86bKoJR0= X-Google-Smtp-Source: ABdhPJzf0rgpnU7rRvkxtJ7em7+3kce7frboh2WhqS0WcYd5RHD6xJAQY6d4Y1k0wb0Df0zgp51eFg== X-Received: by 2002:adf:f348:0:b0:1f0:6849:2b7d with SMTP id e8-20020adff348000000b001f068492b7dmr13606163wrp.14.1646777742836; Tue, 08 Mar 2022 14:15:42 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id r1-20020a5d4941000000b001ed89dcacbbsm104006wrs.23.2022.03.08.14.15.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 08 Mar 2022 14:15:42 -0800 (PST) Message-Id: In-Reply-To: References: From: "Jeff Hostetler via GitGitGadget" Date: Tue, 08 Mar 2022 22:15:12 +0000 Subject: [PATCH v2 12/27] fsmonitor--daemon: cd out of worktree root Fcc: Sent Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MIME-Version: 1.0 To: git@vger.kernel.org Cc: Jeff Hostetler , Derrick Stolee , =?UTF-8?Q?=C3=86var_Arnfj=C3=B6r=C3=B0?= Bjarmason , Torsten =?unknown-8bit?Q?B=C3=B6gershausen?= , Jeff Hostetler , Jeff Hostetler Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Jeff Hostetler Teach the fsmonitor--daemon to CD outside of the worktree before starting up. The common Git startup mechanism causes the CWD of the daemon process to be in the root of the worktree. On Windows, this causes the daemon process to hold a locked handle on the CWD and prevents other processes from moving or deleting the worktree while the daemon is running. CD to HOME before entering main event loops. Signed-off-by: Jeff Hostetler --- builtin/fsmonitor--daemon.c | 32 +++++++++++++++++++++++++++-- compat/fsmonitor/fsm-listen-win32.c | 22 ++++++++++++++------ fsmonitor--daemon.h | 1 + 3 files changed, 47 insertions(+), 8 deletions(-) diff --git a/builtin/fsmonitor--daemon.c b/builtin/fsmonitor--daemon.c index 00eaffbb945..dbd37a2b3b8 100644 --- a/builtin/fsmonitor--daemon.c +++ b/builtin/fsmonitor--daemon.c @@ -1175,11 +1175,11 @@ static int fsmonitor_run_daemon_1(struct fsmonitor_daemon_state *state) * before we need it. */ if (ipc_server_run_async(&state->ipc_server_data, - fsmonitor_ipc__get_path(), &ipc_opts, + state->path_ipc.buf, &ipc_opts, handle_client, state)) return error_errno( _("could not start IPC thread pool on '%s'"), - fsmonitor_ipc__get_path()); + state->path_ipc.buf); /* * Start the fsmonitor listener thread to collect filesystem @@ -1214,6 +1214,7 @@ static int fsmonitor_run_daemon_1(struct fsmonitor_daemon_state *state) static int fsmonitor_run_daemon(void) { struct fsmonitor_daemon_state state; + const char *home; int err; memset(&state, 0, sizeof(state)); @@ -1283,6 +1284,15 @@ static int fsmonitor_run_daemon(void) strbuf_addch(&state.path_cookie_prefix, '/'); + /* + * We create a named-pipe or unix domain socket inside of the + * ".git" directory. (Well, on Windows, we base our named + * pipe in the NPFS on the absolute path of the git + * directory.) + */ + strbuf_init(&state.path_ipc, 0); + strbuf_addstr(&state.path_ipc, absolute_path(fsmonitor_ipc__get_path())); + /* * Confirm that we can create platform-specific resources for the * filesystem listener before we bother starting all the threads. @@ -1292,6 +1302,23 @@ static int fsmonitor_run_daemon(void) goto done; } + /* + * CD out of the worktree root directory. + * + * The common Git startup mechanism causes our CWD to be the + * root of the worktree. On Windows, this causes our process + * to hold a locked handle on the CWD. This prevents the + * worktree from being moved or deleted while the daemon is + * running. + * + * We assume that our FS and IPC listener threads have either + * opened all of the handles that they need or will do + * everything using absolute paths. + */ + home = getenv("HOME"); + if (home && *home && chdir(home)) + die_errno("could not cd home '%s'", home); + err = fsmonitor_run_daemon_1(&state); done: @@ -1304,6 +1331,7 @@ done: strbuf_release(&state.path_worktree_watch); strbuf_release(&state.path_gitdir_watch); strbuf_release(&state.path_cookie_prefix); + strbuf_release(&state.path_ipc); return err; } diff --git a/compat/fsmonitor/fsm-listen-win32.c b/compat/fsmonitor/fsm-listen-win32.c index f4673d7d8b1..948f0e63915 100644 --- a/compat/fsmonitor/fsm-listen-win32.c +++ b/compat/fsmonitor/fsm-listen-win32.c @@ -402,12 +402,22 @@ static int recv_rdcw_watch(struct one_watch *watch) } /* - * NEEDSWORK: If an external is deleted, the above - * returns an error. I'm not sure that there's anything that - * we can do here other than failing -- the /.git - * link file would be broken anyway. We might try to check - * for that and return a better error message, but I'm not - * sure it is worth it. + * GetOverlappedResult() fails if the watched directory is + * deleted while we were waiting for an overlapped IO to + * complete. The documentation did not list specific errors, + * but I observed ERROR_ACCESS_DENIED (0x05) errors during + * testing. + * + * Note that we only get notificaiton events for events + * *within* the directory, not *on* the directory itself. + * (These might be properies of the parent directory, for + * example). + * + * NEEDSWORK: We might try to check for the deleted directory + * case and return a better error message, but I'm not sure it + * is worth it. + * + * Shutdown if we get any error. */ error("GetOverlappedResult failed on '%s' [GLE %ld]", diff --git a/fsmonitor--daemon.h b/fsmonitor--daemon.h index bd09fffc176..223c2131b58 100644 --- a/fsmonitor--daemon.h +++ b/fsmonitor--daemon.h @@ -54,6 +54,7 @@ struct fsmonitor_daemon_state { struct fsmonitor_daemon_backend_data *backend_data; struct ipc_server_data *ipc_server_data; + struct strbuf path_ipc; }; /* -- gitgitgadget