Esempio n. 1
0
        protected override void Execute(GVFSEnlistment enlistment, ITracer tracer = null)
        {
            this.CheckAntiVirusExclusion(enlistment);

            this.Output.WriteLine("Attempting to connect to GVFS at {0}...", enlistment.EnlistmentRoot);
            using (NamedPipeClient pipeClient = new NamedPipeClient(enlistment.NamedPipeName))
            {
                if (!pipeClient.Connect())
                {
                    this.ReportErrorAndExit("Unable to connect to GVFS.  Try running 'gvfs mount'");
                }

                this.Output.WriteLine("Connected");
                this.Output.WriteLine();

                try
                {
                    pipeClient.SendRequest(NamedPipeMessages.GetStatus.Request);
                    NamedPipeMessages.GetStatus.Response getStatusResponse =
                        NamedPipeMessages.GetStatus.Response.FromJson(pipeClient.ReadRawResponse());

                    this.Output.WriteLine("Mount status: " + getStatusResponse.MountStatus);
                    this.Output.WriteLine("GVFS Lock: " + getStatusResponse.LockStatus);
                    this.Output.WriteLine("Enlistment root: " + getStatusResponse.EnlistmentRoot);
                    this.Output.WriteLine("Repo URL: " + getStatusResponse.RepoUrl);
                    this.Output.WriteLine("Objects URL: " + getStatusResponse.ObjectsUrl);
                    this.Output.WriteLine("Background operations: " + getStatusResponse.BackgroundOperationCount);
                    this.Output.WriteLine("Disk layout version: " + getStatusResponse.DiskLayoutVersion);
                }
                catch (BrokenPipeException e)
                {
                    this.ReportErrorAndExit("Unable to communicate with GVFS: " + e.ToString());
                }
            }
        }
Esempio n. 2
0
        protected override void Execute(GSDEnlistment enlistment)
        {
            using (NamedPipeClient pipeClient = new NamedPipeClient(enlistment.NamedPipeName))
            {
                if (!pipeClient.Connect())
                {
                    this.ReportErrorAndExit("Unable to connect to GSD.  Try running 'gvfs mount'");
                }

                try
                {
                    pipeClient.SendRequest(NamedPipeMessages.GetStatus.Request);
                    NamedPipeMessages.GetStatus.Response getStatusResponse =
                        NamedPipeMessages.GetStatus.Response.FromJson(pipeClient.ReadRawResponse());

                    this.Output.WriteLine("Enlistment root: " + getStatusResponse.EnlistmentRoot);
                    this.Output.WriteLine("Repo URL: " + getStatusResponse.RepoUrl);
                    this.Output.WriteLine("Cache Server: " + getStatusResponse.CacheServer);
                    this.Output.WriteLine("Local Cache: " + getStatusResponse.LocalCacheRoot);
                    this.Output.WriteLine("Mount status: " + getStatusResponse.MountStatus);
                    this.Output.WriteLine("GSD Lock: " + getStatusResponse.LockStatus);
                    this.Output.WriteLine("Background operations: " + getStatusResponse.BackgroundOperationCount);
                    this.Output.WriteLine("Disk layout version: " + getStatusResponse.DiskLayoutVersion);
                }
                catch (BrokenPipeException e)
                {
                    this.ReportErrorAndExit("Unable to communicate with GSD: " + e.ToString());
                }
            }
        }
Esempio n. 3
0
        private bool WaitForGVFSStatus()
        {
            using (NamedPipeClient pipeClient = new NamedPipeClient(NamedPipeClient.GetPipeNameFromPath(this.enlistmentRoot)))
            {
                if (!pipeClient.Connect(BackgroundProcessConnectTimeoutMS))
                {
                    this.tracer.RelatedError("Unable to mount because the GVFS.Mount process is not responding.");
                    return(false);
                }

                while (true)
                {
                    string response = string.Empty;
                    try
                    {
                        pipeClient.SendRequest(NamedPipeMessages.GetStatus.Request);
                        response = pipeClient.ReadRawResponse();
                        NamedPipeMessages.GetStatus.Response getStatusResponse =
                            NamedPipeMessages.GetStatus.Response.FromJson(response);

                        // TODO: 872426 Improve responsiveness of GVFS.Service waiting for GVFS.Mount to return status while mounting.
                        if (getStatusResponse.MountStatus == NamedPipeMessages.GetStatus.Ready)
                        {
                            this.tracer.RelatedInfo("Successfully mounted at {0}", this.enlistmentRoot);
                            return(true);
                        }
                        else if (getStatusResponse.MountStatus == NamedPipeMessages.GetStatus.MountFailed)
                        {
                            this.tracer.RelatedInfo("Failed to mount at {0}", this.enlistmentRoot);
                            return(false);
                        }
                        else
                        {
                            Thread.Sleep(500);
                        }
                    }
                    catch (BrokenPipeException e)
                    {
                        this.tracer.RelatedInfo("Could not connect to GVFS.Mount: {0}", e.ToString());
                        return(false);
                    }
                    catch (JsonReaderException e)
                    {
                        EventMetadata metadata = new EventMetadata();
                        metadata.Add("Area", "GVFSService");
                        metadata.Add("Exception", e.ToString());
                        metadata.Add("ErrorMessage", "Mount: failed to parse response from GVFS.Mount");
                        metadata.Add("Response", response);
                        this.tracer.RelatedError(metadata);
                        return(false);
                    }
                }
            }
        }
Esempio n. 4
0
        public static bool WaitUntilMounted(string enlistmentRoot, bool unattended, out string errorMessage)
        {
            errorMessage = null;
            using (NamedPipeClient pipeClient = new NamedPipeClient(NamedPipeClient.GetPipeNameFromPath(enlistmentRoot)))
            {
                int timeout = unattended ? 300000 : 60000;
                if (!pipeClient.Connect(timeout))
                {
                    errorMessage = "Unable to mount because the GVFS.Mount process is not responding.";
                    return(false);
                }

                while (true)
                {
                    string response = string.Empty;
                    try
                    {
                        pipeClient.SendRequest(NamedPipeMessages.GetStatus.Request);
                        response = pipeClient.ReadRawResponse();
                        NamedPipeMessages.GetStatus.Response getStatusResponse =
                            NamedPipeMessages.GetStatus.Response.FromJson(response);

                        if (getStatusResponse.MountStatus == NamedPipeMessages.GetStatus.Ready)
                        {
                            return(true);
                        }
                        else if (getStatusResponse.MountStatus == NamedPipeMessages.GetStatus.MountFailed)
                        {
                            errorMessage = string.Format("Failed to mount at {0}", enlistmentRoot);
                            return(false);
                        }
                        else
                        {
                            Thread.Sleep(500);
                        }
                    }
                    catch (BrokenPipeException e)
                    {
                        errorMessage = string.Format("Could not connect to GVFS.Mount: {0}", e);
                        return(false);
                    }
                    catch (JsonReaderException e)
                    {
                        errorMessage = string.Format("Failed to parse response from GVFS.Mount.\n {0}", e);
                        return(false);
                    }
                }
            }
        }
Esempio n. 5
0
        protected override void Execute(GVFSEnlistment enlistment)
        {
            bool   isExcluded;
            string errorMessage;

            if (AntiVirusExclusions.TryGetIsPathExcluded(enlistment.EnlistmentRoot, out isExcluded, out errorMessage))
            {
                if (!isExcluded)
                {
                    this.Output.WriteLine(
                        "This repo is not excluded from antivirus.",
                        enlistment.EnlistmentRoot);
                }
            }
            else
            {
                this.Output.WriteLine(
                    "Could not check if '{0}' is excluded from anti-virus. Please check to ensure that '{0}' is excluded. Error: {1}",
                    enlistment.EnlistmentRoot,
                    errorMessage);
            }

            using (NamedPipeClient pipeClient = new NamedPipeClient(enlistment.NamedPipeName))
            {
                if (!pipeClient.Connect())
                {
                    this.ReportErrorAndExit("Unable to connect to GVFS.  Try running 'gvfs mount'");
                }

                try
                {
                    pipeClient.SendRequest(NamedPipeMessages.GetStatus.Request);
                    NamedPipeMessages.GetStatus.Response getStatusResponse =
                        NamedPipeMessages.GetStatus.Response.FromJson(pipeClient.ReadRawResponse());

                    this.Output.WriteLine("Enlistment root: " + getStatusResponse.EnlistmentRoot);
                    this.Output.WriteLine("Repo URL: " + getStatusResponse.RepoUrl);
                    this.Output.WriteLine("Objects URL: " + getStatusResponse.ObjectsUrl);
                    this.Output.WriteLine("Mount status: " + getStatusResponse.MountStatus);
                    this.Output.WriteLine("GVFS Lock: " + getStatusResponse.LockStatus);
                    this.Output.WriteLine("Background operations: " + getStatusResponse.BackgroundOperationCount);
                    this.Output.WriteLine("Disk layout version: " + getStatusResponse.DiskLayoutVersion);
                }
                catch (BrokenPipeException e)
                {
                    this.ReportErrorAndExit("Unable to communicate with GVFS: " + e.ToString());
                }
            }
        }
Esempio n. 6
0
        private bool WaitForMountToComplete(GVFSEnlistment enlistment, out string errorMessage)
        {
            using (NamedPipeClient pipeClient = new NamedPipeClient(enlistment.NamedPipeName))
            {
                if (!pipeClient.Connect(BackgroundProcessConnectTimeoutMS))
                {
                    errorMessage = "Unable to mount because the background process is not responding.";
                    return(false);
                }

                bool isMounted = false;
                while (!isMounted)
                {
                    try
                    {
                        pipeClient.SendRequest(NamedPipeMessages.GetStatus.Request);
                        NamedPipeMessages.GetStatus.Response getStatusResponse =
                            NamedPipeMessages.GetStatus.Response.FromJson(pipeClient.ReadRawResponse());

                        if (getStatusResponse.MountStatus == NamedPipeMessages.GetStatus.Ready)
                        {
                            isMounted = true;
                        }
                        else if (getStatusResponse.MountStatus == NamedPipeMessages.GetStatus.MountFailed)
                        {
                            errorMessage = "Failed to mount";
                            return(false);
                        }
                        else
                        {
                            Thread.Sleep(100);
                        }
                    }
                    catch (BrokenPipeException)
                    {
                        errorMessage = "Failed to mount";
                        return(false);
                    }
                }

                errorMessage = null;
                return(isMounted);
            }
        }
Esempio n. 7
0
        private void HandleGetStatusRequest(NamedPipeServer.Connection connection)
        {
            NamedPipeMessages.GetStatus.Response response = new NamedPipeMessages.GetStatus.Response();
            response.EnlistmentRoot = this.enlistment.EnlistmentRoot;
            response.LocalCacheRoot = !string.IsNullOrWhiteSpace(this.enlistment.LocalCacheRoot) ? this.enlistment.LocalCacheRoot : this.enlistment.GitObjectsRoot;
            response.RepoUrl        = this.enlistment.RepoUrl;
            response.CacheServer    = this.cacheServer.ToString();
            response.LockStatus     = this.context?.Repository.GVFSLock != null?this.context.Repository.GVFSLock.GetStatus() : "Unavailable";

            response.DiskLayoutVersion = $"{GVFSPlatform.Instance.DiskLayoutUpgrade.Version.CurrentMajorVersion}.{GVFSPlatform.Instance.DiskLayoutUpgrade.Version.CurrentMinorVersion}";

            switch (this.currentState)
            {
            case MountState.Mounting:
                response.MountStatus = NamedPipeMessages.GetStatus.Mounting;
                break;

            case MountState.Ready:
                response.MountStatus = NamedPipeMessages.GetStatus.Ready;
                response.BackgroundOperationCount = this.fileSystemCallbacks.BackgroundOperationCount;
                break;

            case MountState.Unmounting:
                response.MountStatus = NamedPipeMessages.GetStatus.Unmounting;
                break;

            case MountState.MountFailed:
                response.MountStatus = NamedPipeMessages.GetStatus.MountFailed;
                break;

            default:
                response.MountStatus = NamedPipeMessages.UnknownGVFSState;
                break;
            }

            connection.TrySendResponse(response.ToJson());
        }
Esempio n. 8
0
        private void HandleGetStatusRequest(NamedPipeServer.Connection connection)
        {
            NamedPipeMessages.GetStatus.Response response = new NamedPipeMessages.GetStatus.Response();
            response.EnlistmentRoot = this.enlistment.EnlistmentRoot;
            response.RepoUrl        = this.enlistment.RepoUrl;
            response.ObjectsUrl     = this.enlistment.ObjectsEndpointUrl;
            response.LockStatus     = this.gvfsLock != null?this.gvfsLock.GetStatus() : "Unavailable";

            response.DiskLayoutVersion = RepoMetadata.GetCurrentDiskLayoutVersion();

            switch (this.currentState)
            {
            case MountState.Mounting:
                response.MountStatus = NamedPipeMessages.GetStatus.Mounting;
                break;

            case MountState.Ready:
                response.MountStatus = NamedPipeMessages.GetStatus.Ready;
                response.BackgroundOperationCount = this.gvfltCallbacks.GetBackgroundOperationCount();
                break;

            case MountState.Unmounting:
                response.MountStatus = NamedPipeMessages.GetStatus.Unmounting;
                break;

            case MountState.MountFailed:
                response.MountStatus = NamedPipeMessages.GetStatus.MountFailed;
                break;

            default:
                response.MountStatus = NamedPipeMessages.UnknownGVFSState;
                break;
            }

            connection.TrySendResponse(response.ToJson());
        }
Esempio n. 9
0
        private bool Unmount(string enlistmentRoot, out string errorMessage)
        {
            errorMessage = string.Empty;

            string pipeName             = GVFSPlatform.Instance.GetNamedPipeName(enlistmentRoot);
            string rawGetStatusResponse = string.Empty;

            try
            {
                using (NamedPipeClient pipeClient = new NamedPipeClient(pipeName))
                {
                    if (!pipeClient.Connect())
                    {
                        errorMessage = "Unable to connect to GVFS.Mount";
                        return(false);
                    }

                    pipeClient.SendRequest(NamedPipeMessages.GetStatus.Request);
                    rawGetStatusResponse = pipeClient.ReadRawResponse();
                    NamedPipeMessages.GetStatus.Response getStatusResponse =
                        NamedPipeMessages.GetStatus.Response.FromJson(rawGetStatusResponse);

                    switch (getStatusResponse.MountStatus)
                    {
                    case NamedPipeMessages.GetStatus.Mounting:
                        errorMessage = "Still mounting, please try again later";
                        return(false);

                    case NamedPipeMessages.GetStatus.Unmounting:
                        errorMessage = "Already unmounting, please wait";
                        return(false);

                    case NamedPipeMessages.GetStatus.Ready:
                        break;

                    case NamedPipeMessages.GetStatus.MountFailed:
                        break;

                    default:
                        errorMessage = "Unrecognized response to GetStatus: " + rawGetStatusResponse;
                        return(false);
                    }

                    pipeClient.SendRequest(NamedPipeMessages.Unmount.Request);
                    string unmountResponse = pipeClient.ReadRawResponse();

                    switch (unmountResponse)
                    {
                    case NamedPipeMessages.Unmount.Acknowledged:
                        string finalResponse = pipeClient.ReadRawResponse();
                        if (finalResponse == NamedPipeMessages.Unmount.Completed)
                        {
                            errorMessage = string.Empty;
                            return(true);
                        }
                        else
                        {
                            errorMessage = "Unrecognized final response to unmount: " + finalResponse;
                            return(false);
                        }

                    case NamedPipeMessages.Unmount.NotMounted:
                        errorMessage = "Unable to unmount, repo was not mounted";
                        return(false);

                    case NamedPipeMessages.Unmount.MountFailed:
                        errorMessage = "Unable to unmount, previous mount attempt failed";
                        return(false);

                    default:
                        errorMessage = "Unrecognized response to unmount: " + unmountResponse;
                        return(false);
                    }
                }
            }
            catch (BrokenPipeException e)
            {
                errorMessage = "Unable to communicate with GVFS: " + e.ToString();
                return(false);
            }
        }
        public static bool WaitUntilMounted(ITracer tracer, string enlistmentRoot, bool unattended, out string errorMessage)
        {
            string pipeName = GVFSPlatform.Instance.GetNamedPipeName(enlistmentRoot);
            tracer.RelatedInfo($"{nameof(WaitUntilMounted)}: Creating NamedPipeClient for pipe '{pipeName}'");

            errorMessage = null;
            using (NamedPipeClient pipeClient = new NamedPipeClient(pipeName))
            {
                tracer.RelatedInfo($"{nameof(WaitUntilMounted)}: Connecting to '{pipeName}'");

                int timeout = unattended ? 300000 : 60000;
                if (!pipeClient.Connect(timeout))
                {
                    tracer.RelatedError($"{nameof(WaitUntilMounted)}: Failed to connect to '{pipeName}' after {timeout} ms");
                    errorMessage = "Unable to mount because the GVFS.Mount process is not responding.";
                    return false;
                }

                tracer.RelatedInfo($"{nameof(WaitUntilMounted)}: Connected to '{pipeName}'");

                while (true)
                {
                    string response = string.Empty;
                    try
                    {
                        pipeClient.SendRequest(NamedPipeMessages.GetStatus.Request);
                        response = pipeClient.ReadRawResponse();
                        NamedPipeMessages.GetStatus.Response getStatusResponse =
                            NamedPipeMessages.GetStatus.Response.FromJson(response);

                        if (getStatusResponse.MountStatus == NamedPipeMessages.GetStatus.Ready)
                        {
                            tracer.RelatedInfo($"{nameof(WaitUntilMounted)}: Mount process ready");
                            return true;
                        }
                        else if (getStatusResponse.MountStatus == NamedPipeMessages.GetStatus.MountFailed)
                        {
                            errorMessage = string.Format("Failed to mount at {0}", enlistmentRoot);
                            tracer.RelatedError($"{nameof(WaitUntilMounted)}: Mount failed: {errorMessage}");
                            return false;
                        }
                        else
                        {
                            tracer.RelatedInfo($"{nameof(WaitUntilMounted)}: Waiting 500ms for mount process to be ready");
                            Thread.Sleep(500);
                        }
                    }
                    catch (BrokenPipeException e)
                    {
                        errorMessage = string.Format("Could not connect to GVFS.Mount: {0}", e);
                        tracer.RelatedError($"{nameof(WaitUntilMounted)}: {errorMessage}");
                        return false;
                    }
                    catch (JsonReaderException e)
                    {
                        errorMessage = string.Format("Failed to parse response from GVFS.Mount.\n {0}", e);
                        tracer.RelatedError($"{nameof(WaitUntilMounted)}: {errorMessage}");
                        return false;
                    }
                }
            }
        }
Esempio n. 11
0
        protected override void Execute(GVFSEnlistment enlistment, ITracer tracer = null)
        {
            try
            {
                using (NamedPipeClient pipeClient = new NamedPipeClient(enlistment.NamedPipeName))
                {
                    if (!pipeClient.Connect())
                    {
                        this.ReportErrorAndExit("Unable to connect to GVFS");
                    }

                    pipeClient.SendRequest(NamedPipeMessages.GetStatus.Request);
                    string rawGetStatusResponse = pipeClient.ReadRawResponse();
                    NamedPipeMessages.GetStatus.Response getStatusResponse =
                        NamedPipeMessages.GetStatus.Response.FromJson(rawGetStatusResponse);

                    switch (getStatusResponse.MountStatus)
                    {
                    case NamedPipeMessages.GetStatus.Mounting:
                        this.ReportErrorAndExit("Still mounting, please try again later");
                        break;

                    case NamedPipeMessages.GetStatus.Unmounting:
                        this.ReportErrorAndExit("Already unmounting, please wait");
                        break;

                    case NamedPipeMessages.GetStatus.Ready:
                        this.Output.WriteLine("Repo is mounted.  Starting to unmount...");
                        break;

                    case NamedPipeMessages.GetStatus.MountFailed:
                        this.Output.WriteLine("Previous mount attempt failed, run 'gvfs log' for details.");
                        this.Output.WriteLine("Attempting to unmount anyway...");
                        break;

                    default:
                        this.ReportErrorAndExit("Unrecognized response to GetStatus: {0}", rawGetStatusResponse);
                        break;
                    }

                    pipeClient.SendRequest(NamedPipeMessages.Unmount.Request);
                    string unmountResponse = pipeClient.ReadRawResponse();

                    switch (unmountResponse)
                    {
                    case NamedPipeMessages.Unmount.Acknowledged:
                        this.Output.WriteLine("Unmount was acknowledged.  Waiting for complete unmount...");
                        string finalResponse = pipeClient.ReadRawResponse();
                        if (finalResponse == NamedPipeMessages.Unmount.Completed)
                        {
                            this.Output.WriteLine("Unmount completed");
                        }
                        else
                        {
                            this.ReportErrorAndExit("Unrecognized final response to unmount: " + finalResponse);
                        }

                        break;

                    case NamedPipeMessages.Unmount.NotMounted:
                        this.ReportErrorAndExit("Unable to unmount, repo was not mounted");
                        break;

                    case NamedPipeMessages.Unmount.MountFailed:
                        this.ReportErrorAndExit("Unable to unmount, previous mount attempt failed");
                        break;

                    default:
                        this.ReportErrorAndExit("Unrecognized response to Unmount: " + unmountResponse);
                        break;
                    }
                }
            }
            catch (BrokenPipeException e)
            {
                this.ReportErrorAndExit("Unable to communicate with GVFS: " + e.ToString());
            }
        }
Esempio n. 12
0
        protected override void Execute(GVFSEnlistment enlistment, ITracer tracer = null)
        {
            this.CheckGitVersion(enlistment);
            this.CheckAntiVirusExclusion(enlistment);

            string mountExeLocation = Path.Combine(ProcessHelper.GetCurrentProcessLocation(), MountExeName);

            if (!File.Exists(mountExeLocation))
            {
                this.ReportErrorAndExit("Could not find GVFS.Mount.exe. You may need to reinstall GVFS.");
            }

            // This tracer is only needed for the HttpGitObjects so we can check the GVFS version.
            // If we keep it around longer, it will collide with the background process tracer.
            using (ITracer mountTracer = tracer ?? new JsonEtwTracer(GVFSConstants.GVFSEtwProviderName, "Mount"))
            {
                HttpGitObjects gitObjects = new HttpGitObjects(mountTracer, enlistment, maxConnections: 1);
                this.ValidateGVFSVersion(enlistment, gitObjects, mountTracer);
            }

            // We have to parse these parameters here to make sure they are valid before
            // handing them to the background process which cannot tell the user when they are bad
            EventLevel verbosity;
            Keywords   keywords;

            this.ParseEnumArgs(out verbosity, out keywords);

            GitProcess git = new GitProcess(enlistment);

            if (!git.IsValidRepo())
            {
                this.ReportErrorAndExit("The physical git repo is missing or invalid");
            }

            this.SetGitConfigSettings(git);

            const string ParamPrefix = "--";

            ProcessHelper.StartBackgroundProcess(
                mountExeLocation,
                string.Join(
                    " ",
                    enlistment.EnlistmentRoot,
                    ParamPrefix + MountParameters.Verbosity,
                    this.Verbosity,
                    ParamPrefix + MountParameters.Keywords,
                    this.KeywordsCsv,
                    this.ShowDebugWindow ? ParamPrefix + MountParameters.DebugWindow : string.Empty),
                createWindow: this.ShowDebugWindow);

            this.Output.WriteLine("Waiting for GVFS to mount");

            using (NamedPipeClient pipeClient = new NamedPipeClient(enlistment.NamedPipeName))
            {
                if (!pipeClient.Connect(BackgroundProcessConnectTimeoutMS))
                {
                    this.ReportErrorAndExit("Unable to mount because the background process is not responding.");
                }

                bool isMounted = false;
                int  tryCount  = 0;
                while (!isMounted)
                {
                    try
                    {
                        pipeClient.SendRequest(NamedPipeMessages.GetStatus.Request);
                        NamedPipeMessages.GetStatus.Response getStatusResponse =
                            NamedPipeMessages.GetStatus.Response.FromJson(pipeClient.ReadRawResponse());

                        if (getStatusResponse.MountStatus == NamedPipeMessages.GetStatus.Ready)
                        {
                            this.Output.WriteLine("Virtual repo is ready.");
                            isMounted = true;
                        }
                        else if (getStatusResponse.MountStatus == NamedPipeMessages.GetStatus.MountFailed)
                        {
                            this.ReportErrorAndExit("Failed to mount, run 'gvfs log' for details");
                        }
                        else
                        {
                            if (tryCount % 10 == 0)
                            {
                                this.Output.WriteLine(getStatusResponse.MountStatus + "...");
                            }

                            Thread.Sleep(500);
                            tryCount++;
                        }
                    }
                    catch (BrokenPipeException)
                    {
                        this.ReportErrorAndExit("Failed to mount, run 'gvfs log' for details");
                    }
                }
            }
        }
Esempio n. 13
0
        private bool Unmount(out string errorMessage)
        {
            errorMessage = string.Empty;

            string pipeName             = NamedPipeClient.GetPipeNameFromPath(this.request.EnlistmentRoot);
            string rawGetStatusResponse = string.Empty;

            try
            {
                using (NamedPipeClient pipeClient = new NamedPipeClient(pipeName))
                {
                    if (!pipeClient.Connect())
                    {
                        errorMessage = "Unable to connect to GVFS.Mount";
                        return(false);
                    }

                    pipeClient.SendRequest(NamedPipeMessages.GetStatus.Request);
                    rawGetStatusResponse = pipeClient.ReadRawResponse();
                    NamedPipeMessages.GetStatus.Response getStatusResponse =
                        NamedPipeMessages.GetStatus.Response.FromJson(rawGetStatusResponse);

                    switch (getStatusResponse.MountStatus)
                    {
                    case NamedPipeMessages.GetStatus.Mounting:
                        errorMessage = "Still mounting, please try again later";
                        return(false);

                    case NamedPipeMessages.GetStatus.Unmounting:
                        errorMessage = "Already unmounting, please wait";
                        return(false);

                    case NamedPipeMessages.GetStatus.Ready:
                        break;

                    case NamedPipeMessages.GetStatus.MountFailed:
                        break;

                    default:
                        errorMessage = "Unrecognized response to GetStatus: " + rawGetStatusResponse;
                        return(false);
                    }

                    pipeClient.SendRequest(NamedPipeMessages.Unmount.Request);
                    string unmountResponse = pipeClient.ReadRawResponse();

                    switch (unmountResponse)
                    {
                    case NamedPipeMessages.Unmount.Acknowledged:
                        string finalResponse = pipeClient.ReadRawResponse();
                        if (finalResponse == NamedPipeMessages.Unmount.Completed)
                        {
                            this.registry.TryDeactivateRepo(this.request.EnlistmentRoot);

                            errorMessage = string.Empty;
                            return(true);
                        }
                        else
                        {
                            errorMessage = "Unrecognized final response to unmount: " + finalResponse;
                            return(false);
                        }

                    case NamedPipeMessages.Unmount.NotMounted:
                        errorMessage = "Unable to unmount, repo was not mounted";
                        return(false);

                    case NamedPipeMessages.Unmount.MountFailed:
                        errorMessage = "Unable to unmount, previous mount attempt failed";
                        return(false);

                    default:
                        errorMessage = "Unrecognized response to unmount: " + unmountResponse;
                        return(false);
                    }
                }
            }
            catch (BrokenPipeException e)
            {
                errorMessage = "Unable to communicate with GVFS: " + e.ToString();
                return(false);
            }
            catch (JsonReaderException e)
            {
                EventMetadata metadata = new EventMetadata();
                metadata.Add("Area", "GVFSService");
                metadata.Add("Exception", e.ToString());
                metadata.Add("ErrorMessage", "Unmount: failed to parse response from GVFS.Mount");
                metadata.Add("rawGetStatusResponse", rawGetStatusResponse);
                this.tracer.RelatedError(metadata);
                return(false);
            }
        }