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()); } } }
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()); } } }
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); } } } }
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); } } } }
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()); } } }
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); } }
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()); }
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()); }
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; } } } }
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()); } }
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"); } } } }
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); } }