Beispiel #1
0
        private static void AcquireGVFSLockForProcess(string fullCommand, int pid, Process parentProcess, NamedPipeClient pipeClient)
        {
            NamedPipeMessages.LockRequest request =
                new NamedPipeMessages.LockRequest(pid, fullCommand);

            NamedPipeMessages.Message requestMessage = request.CreateMessage(NamedPipeMessages.AcquireLock.AcquireRequest);
            pipeClient.SendRequest(requestMessage);

            NamedPipeMessages.AcquireLock.Response response = new NamedPipeMessages.AcquireLock.Response(pipeClient.ReadResponse());

            if (response.Result == NamedPipeMessages.AcquireLock.AcceptResult)
            {
                return;
            }
            else if (response.Result == NamedPipeMessages.AcquireLock.MountNotReadyResult)
            {
                ExitWithError("GVFS has not finished initializing, please wait a few seconds and try again.");
            }
            else
            {
                string message = string.Empty;
                switch (response.Result)
                {
                case NamedPipeMessages.AcquireLock.AcceptResult:
                    break;

                case NamedPipeMessages.AcquireLock.DenyGVFSResult:
                    message = "Waiting for GVFS to release the lock";
                    break;

                case NamedPipeMessages.AcquireLock.DenyGitResult:
                    message = string.Format("Waiting for '{0}' to release the lock", response.ResponseData.ParsedCommand);
                    break;

                default:
                    ExitWithError("Error when acquiring the lock. Unrecognized response: " + response.CreateMessage());
                    break;
                }

                ConsoleHelper.ShowStatusWhileRunning(
                    () =>
                {
                    while (response.Result != NamedPipeMessages.AcquireLock.AcceptResult)
                    {
                        Thread.Sleep(250);
                        pipeClient.SendRequest(requestMessage);
                        response = new NamedPipeMessages.AcquireLock.Response(pipeClient.ReadResponse());
                    }

                    return(true);
                },
                    message,
                    output: Console.Out,
                    showSpinner: !ConsoleHelper.IsConsoleOutputRedirectedToFile());
            }
        }
Beispiel #2
0
        private static void ReleaseGVFSLock(string fullCommand, int pid, Process parentProcess, NamedPipeClient pipeClient)
        {
            NamedPipeMessages.LockRequest request =
                new NamedPipeMessages.LockRequest(pid, fullCommand);

            NamedPipeMessages.Message requestMessage = request.CreateMessage(NamedPipeMessages.ReleaseLock.Request);

            pipeClient.SendRequest(requestMessage);

            NamedPipeMessages.ReleaseLock.Response response = null;
            ConsoleHelper.ShowStatusWhileRunning(
                () =>
            {
                response = new NamedPipeMessages.ReleaseLock.Response(pipeClient.ReadResponse());

                if (response.ResponseData == null)
                {
                    return(ConsoleHelper.ActionResult.Failure);
                }

                return(response.ResponseData.HasFailures ? ConsoleHelper.ActionResult.CompletedWithErrors : ConsoleHelper.ActionResult.Success);
            },
                "Waiting for GVFS to parse index and update placeholder files",
                output: Console.Out,
                showSpinner: !ConsoleHelper.IsConsoleOutputRedirectedToFile(),
                suppressGvfsLogMessage: false,
                initialDelayMs: PostCommandSpinnerDelayMs);

            if (response == null || response.ResponseData == null)
            {
                Console.WriteLine("\nError communicating with GVFS: Run 'git status' to check the status of your repo");
            }
            else if (response.ResponseData.HasFailures)
            {
                if (response.ResponseData.FailureCountExceedsMaxFileNames)
                {
                    Console.WriteLine(
                        "\nGVFS failed to update {0} files, run 'git status' to check the status of files in the repo",
                        response.ResponseData.FailedToDeleteCount + response.ResponseData.FailedToUpdateCount);
                }
                else
                {
                    string deleteFailuresMessage = BuildUpdatePlaceholderFailureMessage(response.ResponseData.FailedToDeleteFileList, "delete", "git clean -f ");
                    if (deleteFailuresMessage.Length > 0)
                    {
                        Console.WriteLine(deleteFailuresMessage);
                    }

                    string updateFailuresMessage = BuildUpdatePlaceholderFailureMessage(response.ResponseData.FailedToUpdateFileList, "update", "git checkout -- ");
                    if (updateFailuresMessage.Length > 0)
                    {
                        Console.WriteLine(updateFailuresMessage);
                    }
                }
            }
        }
Beispiel #3
0
        private static void ReleaseGVFSLock(string fullCommand, int pid, Process parentProcess, NamedPipeClient pipeClient)
        {
            NamedPipeMessages.LockRequest request =
                new NamedPipeMessages.LockRequest(pid, fullCommand);

            NamedPipeMessages.Message requestMessage = request.CreateMessage(NamedPipeMessages.ReleaseLock.Request);

            pipeClient.SendRequest(requestMessage);
            pipeClient.ReadRawResponse(); // Response doesn't really matter
        }
Beispiel #4
0
        private void HandleLockRequest(string messageBody, NamedPipeServer.Connection connection)
        {
            NamedPipeMessages.AcquireLock.Response response;

            NamedPipeMessages.LockRequest request   = new NamedPipeMessages.LockRequest(messageBody);
            NamedPipeMessages.LockData    requester = request.RequestData;
            if (this.currentState == MountState.Unmounting)
            {
                response = new NamedPipeMessages.AcquireLock.Response(NamedPipeMessages.AcquireLock.UnmountInProgressResult);

                EventMetadata metadata = new EventMetadata();
                metadata.Add("LockRequest", requester.ToString());
                metadata.Add(TracingConstants.MessageKey.InfoMessage, "Request denied, unmount in progress");
                this.tracer.RelatedEvent(EventLevel.Informational, "HandleLockRequest_UnmountInProgress", metadata);
            }
            else if (this.currentState != MountState.Ready)
            {
                response = new NamedPipeMessages.AcquireLock.Response(NamedPipeMessages.AcquireLock.MountNotReadyResult);
            }
            else
            {
                bool lockAcquired = false;

                NamedPipeMessages.LockData existingExternalHolder = null;
                string denyGVFSMessage = null;

                bool lockAvailable = this.context.Repository.GVFSLock.IsLockAvailableForExternalRequestor(out existingExternalHolder);
                bool isReadyForExternalLockRequests = this.fileSystemCallbacks.IsReadyForExternalAcquireLockRequests(requester, out denyGVFSMessage);

                if (!requester.CheckAvailabilityOnly && isReadyForExternalLockRequests)
                {
                    lockAcquired = this.context.Repository.GVFSLock.TryAcquireLockForExternalRequestor(requester, out existingExternalHolder);
                }

                if (requester.CheckAvailabilityOnly && lockAvailable && isReadyForExternalLockRequests)
                {
                    response = new NamedPipeMessages.AcquireLock.Response(NamedPipeMessages.AcquireLock.AvailableResult);
                }
                else if (lockAcquired)
                {
                    response = new NamedPipeMessages.AcquireLock.Response(NamedPipeMessages.AcquireLock.AcceptResult);
                    this.tracer.SetGitCommandSessionId(requester.GitCommandSessionId);
                }
                else if (existingExternalHolder == null)
                {
                    response = new NamedPipeMessages.AcquireLock.Response(NamedPipeMessages.AcquireLock.DenyGVFSResult, responseData: null, denyGVFSMessage: denyGVFSMessage);
                }
                else
                {
                    response = new NamedPipeMessages.AcquireLock.Response(NamedPipeMessages.AcquireLock.DenyGitResult, existingExternalHolder);
                }
            }

            connection.TrySendResponse(response.CreateMessage());
        }
Beispiel #5
0
        private void HandleLockRequest(string messageBody, NamedPipeServer.Connection connection)
        {
            NamedPipeMessages.AcquireLock.Response response;
            NamedPipeMessages.LockData             externalHolder;

            NamedPipeMessages.LockRequest request   = new NamedPipeMessages.LockRequest(messageBody);
            NamedPipeMessages.LockData    requester = request.RequestData;
            if (request == null)
            {
                response = new NamedPipeMessages.AcquireLock.Response(NamedPipeMessages.UnknownRequest, requester);
            }
            else if (this.currentState == MountState.Unmounting)
            {
                response = new NamedPipeMessages.AcquireLock.Response(NamedPipeMessages.AcquireLock.UnmountInProgressResult);

                EventMetadata metadata = new EventMetadata();
                metadata.Add("LockRequest", requester.ToString());
                metadata.Add(TracingConstants.MessageKey.InfoMessage, "Request denied, unmount in progress");
                this.tracer.RelatedEvent(EventLevel.Informational, "HandleLockRequest_UnmountInProgress", metadata);
            }
            else if (this.currentState != MountState.Ready)
            {
                response = new NamedPipeMessages.AcquireLock.Response(NamedPipeMessages.AcquireLock.MountNotReadyResult);
            }
            else
            {
                bool   lockAcquired = false;
                string denyMessage;
                if (this.gvfltCallbacks.IsReadyForExternalAcquireLockRequests(requester, out denyMessage))
                {
                    lockAcquired = this.context.Repository.GVFSLock.TryAcquireLock(requester, out externalHolder);
                }
                else
                {
                    // There might be an external lock holder, and it should be reported to the user
                    externalHolder = this.context.Repository.GVFSLock.GetExternalLockHolder();
                }

                if (lockAcquired)
                {
                    response = new NamedPipeMessages.AcquireLock.Response(NamedPipeMessages.AcquireLock.AcceptResult);
                }
                else if (externalHolder == null)
                {
                    response = new NamedPipeMessages.AcquireLock.Response(NamedPipeMessages.AcquireLock.DenyGVFSResult, responseData: null, denyGVFSMessage: denyMessage);
                }
                else
                {
                    response = new NamedPipeMessages.AcquireLock.Response(NamedPipeMessages.AcquireLock.DenyGitResult, externalHolder);
                }
            }

            connection.TrySendResponse(response.CreateMessage());
        }
Beispiel #6
0
        private void HandleReleaseLockRequest(string messageBody, NamedPipeServer.Connection connection)
        {
            NamedPipeMessages.LockRequest request = new NamedPipeMessages.LockRequest(messageBody);

            if (this.gvfltCallbacks.TryReleaseExternalLock(request.RequestData.PID))
            {
                connection.TrySendResponse(NamedPipeMessages.ReleaseLock.SuccessResult);
            }
            else
            {
                connection.TrySendResponse(NamedPipeMessages.ReleaseLock.FailureResult);
            }
        }
Beispiel #7
0
        private void HandleReleaseLockRequest(string messageBody, NamedPipeServer.Connection connection)
        {
            NamedPipeMessages.LockRequest request = new NamedPipeMessages.LockRequest(messageBody);

            if (request.RequestData == null)
            {
                this.tracer.RelatedError($"{nameof(this.HandleReleaseLockRequest)} received invalid lock request with body '{messageBody}'");
                this.UnmountAndStopWorkingDirectoryCallbacks();
                Environment.Exit((int)ReturnCode.NullRequestData);
            }

            NamedPipeMessages.ReleaseLock.Response response = this.fileSystemCallbacks.TryReleaseExternalLock(request.RequestData.PID);
            connection.TrySendResponse(response.CreateMessage());
        }
Beispiel #8
0
        private static void ReleaseLock(string enlistmentPipename, string enlistmentRoot)
        {
            using (NamedPipeClient pipeClient = new NamedPipeClient(enlistmentPipename))
            {
                if (!pipeClient.Connect())
                {
                    throw new Exception("The repo does not appear to be mounted. Use 'gvfs status' to check.");
                }

                int pid = Process.GetCurrentProcess().Id;

                NamedPipeMessages.LockRequest request        = new NamedPipeMessages.LockRequest(pid: pid, isElevated: false, checkAvailabilityOnly: false, parsedCommand: AcquireGVFSLockVerb.fullCommand, gitCommandSessionId: string.Empty);
                NamedPipeMessages.Message     requestMessage = request.CreateMessage(NamedPipeMessages.ReleaseLock.Request);

                pipeClient.SendRequest(requestMessage);
                NamedPipeMessages.ReleaseLock.Response response = response = new NamedPipeMessages.ReleaseLock.Response(pipeClient.ReadResponse());
            }
        }
Beispiel #9
0
        private void HandleLockRequest(string messageBody, NamedPipeServer.Connection connection)
        {
            NamedPipeMessages.AcquireLock.Response response;
            NamedPipeMessages.LockData             externalHolder;

            NamedPipeMessages.LockRequest request   = new NamedPipeMessages.LockRequest(messageBody);
            NamedPipeMessages.LockData    requester = request.RequestData;
            if (request == null)
            {
                response = new NamedPipeMessages.AcquireLock.Response(NamedPipeMessages.UnknownRequest, requester);
            }
            else if (this.currentState != MountState.Ready)
            {
                response = new NamedPipeMessages.AcquireLock.Response(NamedPipeMessages.AcquireLock.MountNotReadyResult);
            }
            else
            {
                bool lockAcquired = false;
                if (this.gvfltCallbacks.IsReadyForExternalAcquireLockRequests())
                {
                    lockAcquired = this.gvfsLock.TryAcquireLock(requester, out externalHolder);
                }
                else
                {
                    // There might be an external lock holder, and it should be reported to the user
                    externalHolder = this.gvfsLock.GetExternalLockHolder();
                }

                if (lockAcquired)
                {
                    response = new NamedPipeMessages.AcquireLock.Response(NamedPipeMessages.AcquireLock.AcceptResult);
                }
                else if (externalHolder == null)
                {
                    response = new NamedPipeMessages.AcquireLock.Response(NamedPipeMessages.AcquireLock.DenyGVFSResult);
                }
                else
                {
                    response = new NamedPipeMessages.AcquireLock.Response(NamedPipeMessages.AcquireLock.DenyGitResult, externalHolder);
                }
            }

            connection.TrySendResponse(response.CreateMessage());
        }
Beispiel #10
0
        public static void ReleaseGVFSLock(
            bool unattended,
            NamedPipeClient pipeClient,
            string fullCommand,
            int pid,
            bool isElevated,
            bool isConsoleOutputRedirectedToFile,
            Action <NamedPipeMessages.ReleaseLock.Response> responseHandler,
            string gvfsEnlistmentRoot,
            string waitingMessage = "",
            int spinnerDelay      = 0)
        {
            NamedPipeMessages.LockRequest request = new NamedPipeMessages.LockRequest(pid, isElevated, checkAvailabilityOnly: false, parsedCommand: fullCommand);

            NamedPipeMessages.Message requestMessage = request.CreateMessage(NamedPipeMessages.ReleaseLock.Request);

            pipeClient.SendRequest(requestMessage);
            NamedPipeMessages.ReleaseLock.Response response = null;

            Func <ConsoleHelper.ActionResult> releaseLock =
                () =>
            {
                response = new NamedPipeMessages.ReleaseLock.Response(pipeClient.ReadResponse());
                responseHandler(response);
                return(ConsoleHelper.ActionResult.Success);
            };

            if (unattended || isConsoleOutputRedirectedToFile)
            {
                releaseLock();
            }
            else
            {
                ConsoleHelper.ShowStatusWhileRunning(
                    releaseLock,
                    waitingMessage,
                    output: Console.Out,
                    showSpinner: true,
                    gvfsLogEnlistmentRoot: gvfsEnlistmentRoot,
                    initialDelayMs: spinnerDelay);
            }
        }
Beispiel #11
0
        public static void ReleaseGVFSLock(
            NamedPipeClient pipeClient,
            string fullCommand,
            int pid,
            Process parentProcess,
            Action <NamedPipeMessages.ReleaseLock.Response> responseHandler,
            string gvfsEnlistmentRoot,
            string waitingMessage = "",
            int spinnerDelay      = 0)
        {
            NamedPipeMessages.LockRequest request =
                new NamedPipeMessages.LockRequest(pid, fullCommand);

            NamedPipeMessages.Message requestMessage = request.CreateMessage(NamedPipeMessages.ReleaseLock.Request);

            pipeClient.SendRequest(requestMessage);
            NamedPipeMessages.ReleaseLock.Response response = null;

            if (ConsoleHelper.IsConsoleOutputRedirectedToFile())
            {
                // If output is redirected then don't show waiting message or it might be interpreted as error
                response = new NamedPipeMessages.ReleaseLock.Response(pipeClient.ReadResponse());
                responseHandler(response);
            }
            else
            {
                ConsoleHelper.ShowStatusWhileRunning(
                    () =>
                {
                    response = new NamedPipeMessages.ReleaseLock.Response(pipeClient.ReadResponse());
                    responseHandler(response);
                    return(ConsoleHelper.ActionResult.Success);
                },
                    waitingMessage,
                    output: Console.Out,
                    showSpinner: true,
                    gvfsLogEnlistmentRoot: gvfsEnlistmentRoot,
                    initialDelayMs: spinnerDelay);
            }
        }
Beispiel #12
0
 private void HandleReleaseLockRequest(string messageBody, NamedPipeServer.Connection connection)
 {
     NamedPipeMessages.LockRequest          request  = new NamedPipeMessages.LockRequest(messageBody);
     NamedPipeMessages.ReleaseLock.Response response = this.gvfltCallbacks.TryReleaseExternalLock(request.RequestData.PID);
     connection.TrySendResponse(response.CreateMessage());
 }
Beispiel #13
0
        public static bool TryAcquireGVFSLockForProcess(
            bool unattended,
            NamedPipeClient pipeClient,
            string fullCommand,
            int pid,
            bool isElevated,
            bool checkAvailabilityOnly,
            string gvfsEnlistmentRoot,
            out string result)
        {
            NamedPipeMessages.LockRequest request = new NamedPipeMessages.LockRequest(pid, isElevated, checkAvailabilityOnly, fullCommand);

            NamedPipeMessages.Message requestMessage = request.CreateMessage(NamedPipeMessages.AcquireLock.AcquireRequest);
            pipeClient.SendRequest(requestMessage);

            NamedPipeMessages.AcquireLock.Response response = new NamedPipeMessages.AcquireLock.Response(pipeClient.ReadResponse());

            string message = string.Empty;

            switch (response.Result)
            {
            case NamedPipeMessages.AcquireLock.AcceptResult:
                return(CheckAcceptResponse(response, checkAvailabilityOnly, out result));

            case NamedPipeMessages.AcquireLock.AvailableResult:
                return(CheckAcceptResponse(response, checkAvailabilityOnly, out result));

            case NamedPipeMessages.AcquireLock.MountNotReadyResult:
                result = "GVFS has not finished initializing, please wait a few seconds and try again.";
                return(false);

            case NamedPipeMessages.AcquireLock.UnmountInProgressResult:
                result = "GVFS is unmounting.";
                return(false);

            case NamedPipeMessages.AcquireLock.DenyGVFSResult:
                message = response.DenyGVFSMessage;
                break;

            case NamedPipeMessages.AcquireLock.DenyGitResult:
                message = string.Format("Waiting for '{0}' to release the lock", response.ResponseData.ParsedCommand);
                break;

            default:
                result = "Error when acquiring the lock. Unrecognized response: " + response.CreateMessage();
                return(false);
            }

            Func <bool> waitForLock =
                () =>
            {
                while (true)
                {
                    Thread.Sleep(250);
                    pipeClient.SendRequest(requestMessage);
                    response = new NamedPipeMessages.AcquireLock.Response(pipeClient.ReadResponse());
                    switch (response.Result)
                    {
                    case NamedPipeMessages.AcquireLock.AcceptResult:
                        return(CheckAcceptResponse(response, checkAvailabilityOnly, out _));

                    case NamedPipeMessages.AcquireLock.AvailableResult:
                        return(CheckAcceptResponse(response, checkAvailabilityOnly, out _));

                    case NamedPipeMessages.AcquireLock.UnmountInProgressResult:
                        return(false);

                    default:
                        break;
                    }
                }
            };

            if (unattended)
            {
                waitForLock();
            }
            else
            {
                ConsoleHelper.ShowStatusWhileRunning(
                    waitForLock,
                    message,
                    output: Console.Out,
                    showSpinner: !ConsoleHelper.IsConsoleOutputRedirectedToFile(),
                    gvfsLogEnlistmentRoot: gvfsEnlistmentRoot);
            }

            result = null;
            return(true);
        }