private void HandleUnmountRequest(NamedPipeServer.Connection connection) { switch (this.currentState) { case MountState.Mounting: connection.TrySendResponse(NamedPipeMessages.Unmount.NotMounted); break; // Even if the previous mount failed, attempt to unmount anyway. Otherwise the user has no // recourse but to kill the process. case MountState.MountFailed: goto case MountState.Ready; case MountState.Ready: this.currentState = MountState.Unmounting; connection.TrySendResponse(NamedPipeMessages.Unmount.Acknowledged); this.UnmountAndStopWorkingDirectoryCallbacks(); connection.TrySendResponse(NamedPipeMessages.Unmount.Completed); this.unmountEvent.Set(); Environment.Exit((int)ReturnCode.Success); break; case MountState.Unmounting: connection.TrySendResponse(NamedPipeMessages.Unmount.AlreadyUnmounting); break; default: connection.TrySendResponse(NamedPipeMessages.UnknownGVFSState); break; } }
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); } }
private void HandleRequest(ITracer tracer, string request, NamedPipeServer.Connection connection) { NamedPipeMessages.Message message = NamedPipeMessages.Message.FromString(request); switch (message.Header) { case NamedPipeMessages.GetStatus.Request: this.HandleGetStatusRequest(connection); break; case NamedPipeMessages.Unmount.Request: this.HandleUnmountRequest(connection); break; case NamedPipeMessages.DownloadObject.DownloadRequest: this.HandleDownloadObjectRequest(message, connection); break; case NamedPipeMessages.RunPostFetchJob.PostFetchJob: this.HandlePostFetchJobRequest(message, connection); break; default: EventMetadata metadata = new EventMetadata(); metadata.Add("Area", "Mount"); metadata.Add("Header", message.Header); this.tracer.RelatedError(metadata, "HandleRequest: Unknown request"); connection.TrySendResponse(NamedPipeMessages.UnknownRequest); break; } }
private void HandleRequest(string request, NamedPipeServer.Connection connection) { NamedPipeMessages.Message message = NamedPipeMessages.Message.FromString(request); switch (message.Header) { case NamedPipeMessages.GetStatus.Request: this.HandleGetStatusRequest(connection); break; case NamedPipeMessages.Unmount.Request: this.HandleUnmountRequest(connection); break; case NamedPipeMessages.AcquireLock.AcquireRequest: this.HandleLockRequest(message.Body, connection); break; case NamedPipeMessages.ReleaseLock.Request: this.HandleReleaseLockRequest(message.Body, connection); break; case NamedPipeMessages.DownloadObject.DownloadRequest: this.HandleDownloadObjectRequest(message, connection); break; default: connection.TrySendResponse(NamedPipeMessages.UnknownRequest); break; } }
private void HandleLockRequest(NamedPipeServer.Connection connection, NamedPipeMessages.Message message) { NamedPipeMessages.AcquireLock.Response response; NamedPipeMessages.AcquireLock.Data externalHolder; NamedPipeMessages.AcquireLock.Request request = new NamedPipeMessages.AcquireLock.Request(message); NamedPipeMessages.AcquireLock.Data 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 = this.gvfsLock.TryAcquireLock(requester, out externalHolder); 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()); }
private void HandleDehydrateFolders(NamedPipeMessages.Message message, NamedPipeServer.Connection connection) { NamedPipeMessages.DehydrateFolders.Request request = new NamedPipeMessages.DehydrateFolders.Request(message); this.tracer.RelatedInfo($"Received dehydrate folders request with body {message.Body}"); NamedPipeMessages.DehydrateFolders.Response response; if (this.currentState == MountState.Ready) { response = new NamedPipeMessages.DehydrateFolders.Response(NamedPipeMessages.DehydrateFolders.DehydratedResult); string[] folders = request.Folders.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries); foreach (string folder in folders) { if (this.fileSystemCallbacks.TryDehydrateFolder(folder, out string errorMessage)) { response.SuccessfulFolders.Add(folder); } else { response.FailedFolders.Add($"{folder}\0{errorMessage}"); } } // Since placeholders and modified paths could have changed with the dehydrate, the index needs to be rebuilt GitProcess gitProcess = new GitProcess(this.enlistment); gitProcess.ForceCheckout(GVFSConstants.DotGit.HeadName); } else { response = new NamedPipeMessages.DehydrateFolders.Response(NamedPipeMessages.DehydrateFolders.MountNotReadyResult); } connection.TrySendResponse(response.CreateMessage()); }
protected void WriteToClient(NamedPipeMessages.Message message, NamedPipeServer.Connection connection, ITracer tracer) { if (!connection.TrySendResponse(message)) { tracer.RelatedError("Failed to send line to client: {0}", message); } }
private void HandlePostIndexChangedRequest(NamedPipeMessages.Message message, NamedPipeServer.Connection connection) { NamedPipeMessages.PostIndexChanged.Response response; NamedPipeMessages.PostIndexChanged.Request request = new NamedPipeMessages.PostIndexChanged.Request(message); if (request == null) { response = new NamedPipeMessages.PostIndexChanged.Response(NamedPipeMessages.UnknownRequest); } else if (this.currentState != MountState.Ready) { response = new NamedPipeMessages.PostIndexChanged.Response(NamedPipeMessages.MountNotReadyResult); } else { if (this.resetForDehydrateInProgress) { // To avoid having to parse the index twice when dehydrating folders, repurpose the PostIndexChangedRequest // for git reset to rebuild the projection. Additionally, if we were to call ForceIndexProjectionUpdate // directly in HandleDehydrateFolders we'd have a race condition where the OnIndexWriteRequiringModifiedPathsValidation // background task would be trying to parse the index at the same time as HandleDehydrateFolders this.fileSystemCallbacks.ForceIndexProjectionUpdate(invalidateProjection: true, invalidateModifiedPaths: false); } else { this.fileSystemCallbacks.ForceIndexProjectionUpdate(request.UpdatedWorkingDirectory, request.UpdatedSkipWorktreeBits); } response = new NamedPipeMessages.PostIndexChanged.Response(NamedPipeMessages.PostIndexChanged.SuccessResult); } connection.TrySendResponse(response.CreateMessage()); }
private void HandleModifiedPathsListRequest(NamedPipeMessages.Message message, NamedPipeServer.Connection connection) { NamedPipeMessages.ModifiedPaths.Response response; NamedPipeMessages.ModifiedPaths.Request request = new NamedPipeMessages.ModifiedPaths.Request(message); if (request == null) { response = new NamedPipeMessages.ModifiedPaths.Response(NamedPipeMessages.UnknownRequest); } else if (this.currentState != MountState.Ready) { response = new NamedPipeMessages.ModifiedPaths.Response(NamedPipeMessages.MountNotReadyResult); } else { if (request.Version != ModifiedPathsVersion) { response = new NamedPipeMessages.ModifiedPaths.Response(NamedPipeMessages.ModifiedPaths.InvalidVersion); } else { string data = string.Join("\0", this.fileSystemCallbacks.GetAllModifiedPaths()) + "\0"; response = new NamedPipeMessages.ModifiedPaths.Response(NamedPipeMessages.ModifiedPaths.SuccessResult, data); } } connection.TrySendResponse(response.CreateMessage()); }
private void TrySendResponse( ITracer tracer, string message, NamedPipeServer.Connection connection) { if (!connection.TrySendResponse(message)) { tracer.RelatedError($"{nameof(this.TrySendResponse)}: Could not send response to client. Reply Info: {message}"); } }
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()); }
private static void HandleRequest(string request, NamedPipeServer.Connection connection) { NamedPipeMessages.Message message = NamedPipeMessages.Message.FromString(request); switch (message.Header) { case NamedPipeMessages.AcquireLock.AcquireRequest: NamedPipeMessages.AcquireLock.Response response = new NamedPipeMessages.AcquireLock.Response(NamedPipeMessages.AcquireLock.AcceptResult); connection.TrySendResponse(response.CreateMessage()); break; case NamedPipeMessages.ReleaseLock.Request: connection.TrySendResponse(NamedPipeMessages.ReleaseLock.SuccessResult); break; default: connection.TrySendResponse(NamedPipeMessages.UnknownRequest); break; } }
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()); }
private void HandleRequest(ITracer tracer, string request, NamedPipeServer.Connection connection) { NamedPipeMessages.Message message = NamedPipeMessages.Message.FromString(request); switch (message.Header) { case NamedPipeMessages.GetStatus.Request: this.HandleGetStatusRequest(connection); break; case NamedPipeMessages.Unmount.Request: this.HandleUnmountRequest(connection); break; case NamedPipeMessages.AcquireLock.AcquireRequest: this.HandleLockRequest(message.Body, connection); break; case NamedPipeMessages.ReleaseLock.Request: this.HandleReleaseLockRequest(message.Body, connection); break; case NamedPipeMessages.DownloadObject.DownloadRequest: this.HandleDownloadObjectRequest(message, connection); break; case NamedPipeMessages.ModifiedPaths.ListRequest: this.HandleModifiedPathsListRequest(message, connection); break; case NamedPipeMessages.PostIndexChanged.NotificationRequest: this.HandlePostIndexChangedRequest(message, connection); break; case NamedPipeMessages.RunPostFetchJob.PostFetchJob: this.HandlePostFetchJobRequest(message, connection); break; case NamedPipeMessages.DehydrateFolders.Dehydrate: this.HandleDehydrateFolders(message, connection); break; default: EventMetadata metadata = new EventMetadata(); metadata.Add("Area", "Mount"); metadata.Add("Header", message.Header); this.tracer.RelatedError(metadata, "HandleRequest: Unknown request"); connection.TrySendResponse(NamedPipeMessages.UnknownRequest); break; } }
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()); }
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()); }
private void HandlePostIndexChangedRequest(NamedPipeMessages.Message message, NamedPipeServer.Connection connection) { NamedPipeMessages.PostIndexChanged.Response response; NamedPipeMessages.PostIndexChanged.Request request = new NamedPipeMessages.PostIndexChanged.Request(message); if (request == null) { response = new NamedPipeMessages.PostIndexChanged.Response(NamedPipeMessages.UnknownRequest); } else if (this.currentState != MountState.Ready) { response = new NamedPipeMessages.PostIndexChanged.Response(NamedPipeMessages.MountNotReadyResult); } else { this.fileSystemCallbacks.ForceIndexProjectionUpdate(request.UpdatedWorkingDirectory, request.UpdatedSkipWorktreeBits); response = new NamedPipeMessages.PostIndexChanged.Response(NamedPipeMessages.PostIndexChanged.SuccessResult); } connection.TrySendResponse(response.CreateMessage()); }
private void HandleDownloadObjectRequest(NamedPipeMessages.Message message, NamedPipeServer.Connection connection) { NamedPipeMessages.DownloadObject.Response response; NamedPipeMessages.DownloadObject.Request request = new NamedPipeMessages.DownloadObject.Request(message); string objectSha = request.RequestSha; if (request == null) { response = new NamedPipeMessages.DownloadObject.Response(NamedPipeMessages.UnknownRequest); } else if (this.currentState != MountState.Ready) { response = new NamedPipeMessages.DownloadObject.Response(NamedPipeMessages.DownloadObject.MountNotReadyResult); } else { if (!SHA1Util.IsValidShaFormat(objectSha)) { response = new NamedPipeMessages.DownloadObject.Response(NamedPipeMessages.DownloadObject.InvalidSHAResult); } else { Stopwatch downloadTime = Stopwatch.StartNew(); if (this.gitObjects.TryDownloadAndSaveObject(objectSha, GVFSGitObjects.RequestSource.NamedPipeMessage) == GitObjects.DownloadAndSaveObjectResult.Success) { response = new NamedPipeMessages.DownloadObject.Response(NamedPipeMessages.DownloadObject.SuccessResult); } else { response = new NamedPipeMessages.DownloadObject.Response(NamedPipeMessages.DownloadObject.DownloadFailed); } bool isBlob; this.context.Repository.TryGetIsBlob(objectSha, out isBlob); this.context.Repository.GVFSLock.RecordObjectDownload(isBlob, downloadTime.ElapsedMilliseconds); } } connection.TrySendResponse(response.CreateMessage()); }
private void HandlePostFetchJobRequest(NamedPipeMessages.Message message, NamedPipeServer.Connection connection) { NamedPipeMessages.RunPostFetchJob.Request request = new NamedPipeMessages.RunPostFetchJob.Request(message); this.tracer.RelatedInfo("Received post-fetch job request with body {0}", message.Body); NamedPipeMessages.RunPostFetchJob.Response response; if (this.currentState == MountState.Ready) { List <string> packIndexes = JsonConvert.DeserializeObject <List <string> >(message.Body); this.fileSystemCallbacks.LaunchPostFetchJob(packIndexes); response = new NamedPipeMessages.RunPostFetchJob.Response(NamedPipeMessages.RunPostFetchJob.QueuedResult); } else { response = new NamedPipeMessages.RunPostFetchJob.Response(NamedPipeMessages.RunPostFetchJob.MountNotReadyResult); } connection.TrySendResponse(response.CreateMessage()); }
private void HandlePostFetchJobRequest(NamedPipeMessages.Message message, NamedPipeServer.Connection connection) { NamedPipeMessages.RunPostFetchJob.Request request = new NamedPipeMessages.RunPostFetchJob.Request(message); this.tracer.RelatedInfo("Received post-fetch job request with body {0}", message.Body); NamedPipeMessages.RunPostFetchJob.Response response; if (this.currentState == MountState.Ready) { List <string> packIndexes = JsonConvert.DeserializeObject <List <string> >(message.Body); this.maintenanceScheduler.EnqueueOneTimeStep(new PostFetchStep(this.context, packIndexes)); response = new NamedPipeMessages.RunPostFetchJob.Response(NamedPipeMessages.RunPostFetchJob.QueuedResult); } else { response = new NamedPipeMessages.RunPostFetchJob.Response(NamedPipeMessages.RunPostFetchJob.MountNotReadyResult); } connection.TrySendResponse(response.CreateMessage()); }
private void HandleConnection(NamedPipeServer.Connection connection) { while (connection.IsConnected) { string request = connection.ReadRequest(); if (request == null || !connection.IsConnected) { break; } NamedPipeMessages.Message message = NamedPipeMessages.Message.FromString(request); switch (message.Header) { case NamedPipeMessages.GetStatus.Request: this.HandleGetStatusRequest(connection); break; case NamedPipeMessages.Unmount.Request: this.HandleUnmountRequest(connection); break; case NamedPipeMessages.AcquireLock.AcquireRequest: this.HandleLockRequest(connection, message); break; case NamedPipeMessages.DownloadObject.DownloadRequest: this.HandleDownloadObjectRequest(connection, message); break; default: connection.TrySendResponse(NamedPipeMessages.UnknownRequest); break; } } }
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 void HandleDownloadObjectRequest(NamedPipeMessages.Message message, NamedPipeServer.Connection connection) { NamedPipeMessages.DownloadObject.Response response; NamedPipeMessages.DownloadObject.Request request = new NamedPipeMessages.DownloadObject.Request(message); string objectSha = request.RequestSha; if (request == null) { response = new NamedPipeMessages.DownloadObject.Response(NamedPipeMessages.UnknownRequest); } else if (this.currentState != MountState.Ready) { response = new NamedPipeMessages.DownloadObject.Response(NamedPipeMessages.DownloadObject.MountNotReadyResult); } else { if (!GitHelper.IsValidFullSHA(objectSha)) { response = new NamedPipeMessages.DownloadObject.Response(NamedPipeMessages.DownloadObject.InvalidSHAResult); } else { if (this.gitObjects.TryDownloadAndSaveObject(objectSha.Substring(0, 2), objectSha.Substring(2))) { response = new NamedPipeMessages.DownloadObject.Response(NamedPipeMessages.DownloadObject.SuccessResult); } else { response = new NamedPipeMessages.DownloadObject.Response(NamedPipeMessages.DownloadObject.DownloadFailed); } } } connection.TrySendResponse(response.CreateMessage()); }
private void HandleDehydrateFolders(NamedPipeMessages.Message message, NamedPipeServer.Connection connection) { NamedPipeMessages.DehydrateFolders.Request request = new NamedPipeMessages.DehydrateFolders.Request(message); EventMetadata metadata = new EventMetadata(); metadata.Add(nameof(request.Folders), request.Folders); metadata.Add(TracingConstants.MessageKey.InfoMessage, "Received dehydrate folders request"); this.tracer.RelatedEvent(EventLevel.Informational, nameof(this.HandleDehydrateFolders), metadata); NamedPipeMessages.DehydrateFolders.Response response; if (this.currentState == MountState.Ready) { response = new NamedPipeMessages.DehydrateFolders.Response(NamedPipeMessages.DehydrateFolders.DehydratedResult); string[] folders = request.Folders.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries); StringBuilder resetFolderPaths = new StringBuilder(); foreach (string folder in folders) { if (this.fileSystemCallbacks.TryDehydrateFolder(folder, out string errorMessage)) { response.SuccessfulFolders.Add(folder); } else { response.FailedFolders.Add($"{folder}\0{errorMessage}"); } resetFolderPaths.Append($"\"{folder.Replace(Path.DirectorySeparatorChar, GVFSConstants.GitPathSeparator)}\" "); } // Since modified paths could have changed with the dehydrate, the paths that were dehydrated need to be reset in the index string resetPaths = resetFolderPaths.ToString(); GitProcess gitProcess = new GitProcess(this.enlistment); EventMetadata resetIndexMetadata = new EventMetadata(); resetIndexMetadata.Add(nameof(resetPaths), resetPaths); GitProcess.Result refreshIndexResult; this.resetForDehydrateInProgress = true; try { // Because we've set resetForDehydrateInProgress to true, this call to 'git reset' will also force // the projection to be updated (required because 'git reset' will adjust the skip worktree bits in // the index). refreshIndexResult = gitProcess.Reset(GVFSConstants.DotGit.HeadName, resetPaths); } finally { this.resetForDehydrateInProgress = false; } resetIndexMetadata.Add(nameof(refreshIndexResult.ExitCode), refreshIndexResult.ExitCode); resetIndexMetadata.Add(nameof(refreshIndexResult.Output), refreshIndexResult.Output); resetIndexMetadata.Add(nameof(refreshIndexResult.Errors), refreshIndexResult.Errors); resetIndexMetadata.Add(TracingConstants.MessageKey.InfoMessage, $"{nameof(this.HandleDehydrateFolders)}: Reset git index"); this.tracer.RelatedEvent(EventLevel.Informational, $"{nameof(this.HandleDehydrateFolders)}_ResetIndex", resetIndexMetadata); } else { response = new NamedPipeMessages.DehydrateFolders.Response(NamedPipeMessages.DehydrateFolders.MountNotReadyResult); } connection.TrySendResponse(response.CreateMessage()); }
private void HandleRequest(ITracer tracer, string request, NamedPipeServer.Connection connection) { NamedPipeMessages.Message message = NamedPipeMessages.Message.FromString(request); if (string.IsNullOrWhiteSpace(message.Header)) { return; } using (ITracer activity = this.tracer.StartActivity(message.Header, EventLevel.Informational, new EventMetadata { { "request", request } })) { switch (message.Header) { case NamedPipeMessages.MountRepoRequest.Header: try { NamedPipeMessages.MountRepoRequest mountRequest = NamedPipeMessages.MountRepoRequest.FromMessage(message); MountHandler mountHandler = new MountHandler(activity, this.repoRegistry, connection, mountRequest); mountHandler.Run(); } catch (SerializationException ex) { activity.RelatedError("Could not deserialize mount request: {0}", ex.Message); } break; case NamedPipeMessages.UnmountRepoRequest.Header: try { NamedPipeMessages.UnmountRepoRequest unmountRequest = NamedPipeMessages.UnmountRepoRequest.FromMessage(message); UnmountHandler unmountHandler = new UnmountHandler(activity, this.repoRegistry, connection, unmountRequest); unmountHandler.Run(); } catch (SerializationException ex) { activity.RelatedError("Could not deserialize unmount request: {0}", ex.Message); } break; case NamedPipeMessages.Notification.Request.Header: try { NamedPipeMessages.Notification.Request notificationRequest = NamedPipeMessages.Notification.Request.FromMessage(message); NotificationHandler.Instance.SendNotification(activity, notificationRequest); } catch (SerializationException ex) { activity.RelatedError("Could not deserialize notification request: {0}", ex.Message); } break; default: EventMetadata metadata = new EventMetadata(); metadata.Add("Area", EtwArea); metadata.Add("Header", message.Header); metadata.Add("ErrorMessage", "HandleNewConnection: Unknown request"); this.tracer.RelatedError(metadata); connection.TrySendResponse(NamedPipeMessages.UnknownRequest); break; } } }
private void HandleRequest(ITracer tracer, string request, NamedPipeServer.Connection connection) { NamedPipeMessages.Message message = NamedPipeMessages.Message.FromString(request); if (string.IsNullOrWhiteSpace(message.Header)) { return; } using (ITracer activity = this.tracer.StartActivity(message.Header, EventLevel.Informational, new EventMetadata { { "request", request } })) { switch (message.Header) { case NamedPipeMessages.RegisterRepoRequest.Header: try { NamedPipeMessages.RegisterRepoRequest mountRequest = NamedPipeMessages.RegisterRepoRequest.FromMessage(message); RegisterRepoHandler mountHandler = new RegisterRepoHandler(activity, this.repoRegistry, connection, mountRequest); mountHandler.Run(); } catch (SerializationException ex) { activity.RelatedError("Could not deserialize mount request: {0}", ex.Message); } break; case NamedPipeMessages.UnregisterRepoRequest.Header: try { NamedPipeMessages.UnregisterRepoRequest unmountRequest = NamedPipeMessages.UnregisterRepoRequest.FromMessage(message); UnregisterRepoHandler unmountHandler = new UnregisterRepoHandler(activity, this.repoRegistry, connection, unmountRequest); unmountHandler.Run(); } catch (SerializationException ex) { activity.RelatedError("Could not deserialize unmount request: {0}", ex.Message); } break; case NamedPipeMessages.EnableAndAttachProjFSRequest.Header: try { NamedPipeMessages.EnableAndAttachProjFSRequest attachRequest = NamedPipeMessages.EnableAndAttachProjFSRequest.FromMessage(message); EnableAndAttachProjFSHandler attachHandler = new EnableAndAttachProjFSHandler(activity, connection, attachRequest); attachHandler.Run(); } catch (SerializationException ex) { activity.RelatedError("Could not deserialize attach volume request: {0}", ex.Message); } break; case NamedPipeMessages.GetActiveRepoListRequest.Header: try { NamedPipeMessages.GetActiveRepoListRequest repoListRequest = NamedPipeMessages.GetActiveRepoListRequest.FromMessage(message); GetActiveRepoListHandler excludeHandler = new GetActiveRepoListHandler(activity, this.repoRegistry, connection, repoListRequest); excludeHandler.Run(); } catch (SerializationException ex) { activity.RelatedError("Could not deserialize repo list request: {0}", ex.Message); } break; default: EventMetadata metadata = new EventMetadata(); metadata.Add("Area", EtwArea); metadata.Add("Header", message.Header); this.tracer.RelatedWarning(metadata, "HandleNewConnection: Unknown request", Keywords.Telemetry); connection.TrySendResponse(NamedPipeMessages.UnknownRequest); break; } } }
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()); }