예제 #1
0
        public Response MountVolume(VolumeMountRequest request)
        {
            if (!this.VolumeExists(request.Name))
            {
                return(new Response("volume not found"));
            }

            this.rwLock.EnterWriteLock();
            try
            {
                if (!knownVolumeMappings.ContainsKey(request.Name))
                {
                    return(new Response("volume not found"));
                }

                if (string.IsNullOrEmpty(this.knownVolumeMappings[request.Name].Mountpoint))
                {
                    // TODO: Holding the lock during network call - improve.
                    var item = this.knownVolumeMappings[request.Name];
                    if (!this.DoMount(request.Name, ref item))
                    {
                        return(new Response("mount failed"));
                    }
                }

                string mountMetadataFilename = Path.Combine(mountMetadataPath, request.Name, request.ID);
                // Using just File.Create will leave the file open, dispose immediately
                System.IO.File.Create(mountMetadataFilename).Dispose();

                this.knownVolumeMappings[request.Name].MountIDs.Add(request.ID);

                return(new VolumeMountResponse(this.knownVolumeMappings[request.Name].Mountpoint));
            }
            catch (Exception e)
            {
                TraceWriter.WriteErrorWithId(
                    TraceType,
                    this.serviceContext.TraceId,
                    $"Mount volume {request.Name}:{request.ID} failed with exception {e}.");

                return(new Response($"Mount volume {request.Name}:{request.ID} failed with exception {e}."));
            }
            finally
            {
                this.rwLock.ExitWriteLock();
            }
        }
예제 #2
0
        public Response MountVolume(VolumeMountRequest request, string traceId)
        {
            if (!this.VolumeExists(request.Name))
            {
                string errorMessage = String.Format("Attempt to mount volume {0} that does not exist.", request.Name);
                TraceWriter.WriteErrorWithId(Constants.TraceSource, traceId, errorMessage);
                return(new Response(errorMessage));
            }

            this.volumeRWLock.EnterWriteLock();
            try
            {
                if (!volumeMappings.ContainsKey(request.Name))
                {
                    string errorMessage = String.Format("Mapping for volume {0} was not found.", request.Name);
                    TraceWriter.WriteErrorWithId(Constants.TraceSource, traceId, errorMessage);
                    return(new Response(errorMessage));
                }

                VolumeEntry volumeEntry = this.volumeMappings[request.Name];

                string volumeDetails = String.Format("Volume:{0}, servicePartitionId:{1}, LUID:{2}, sizeDisk:{3}, fileSystem:{4}", request.Name, volumeEntry.ServicePartitionID, volumeEntry.LUID, volumeEntry.SizeDisk, volumeEntry.FileSystem);

                TraceWriter.WriteInfoWithId(Constants.TraceSource, traceId, String.Format("Processing mount request: {0}", volumeDetails));

                bool fVolumeProvisioned = false;
                if (!System.IO.Directory.Exists(volumeEntry.Mountpoint))
                {
                    // The folder created here is which volume will be mounted
                    System.IO.Directory.CreateDirectory(volumeEntry.Mountpoint);

                    // Give built-in users access to the folder
                    if (SetMountpointRWAccessForUsers(volumeEntry.Mountpoint, traceId))
                    {
                        // Provision the volume
                        TraceWriter.WriteInfoWithId(Constants.TraceSource, traceId, String.Format("Provisioning volume: {0}", volumeDetails));
                        fVolumeProvisioned = this.ProvisionLU(request.Name, volumeEntry, traceId);
                    }

                    // If volume provisioning fails, delete the mountpoint folder
                    if (!fVolumeProvisioned)
                    {
                        System.IO.Directory.Delete(volumeEntry.Mountpoint);
                    }
                }
                else
                {
#if DotNetCoreClrLinux
                    TraceWriter.WriteInfoWithId(Constants.TraceSource, traceId, "Attempting Umount before provisioning volume.");
                    var returnValue = umount(volumeEntry.Mountpoint);
                    TraceWriter.WriteInfoWithId(Constants.TraceSource, traceId, "Umount returned " + returnValue);
#endif
                    // Connect to BlockStore Native Service and send ProvisionLU cmd
                    TraceWriter.WriteInfoWithId(Constants.TraceSource, traceId, String.Format("Provisioning existing mountpoint for volume: {0}", volumeDetails));
                    fVolumeProvisioned = this.ProvisionLU(request.Name, volumeEntry, traceId);
                }

                if (!fVolumeProvisioned)
                {
                    string errorMessage = String.Format("Unable to provision volume: {0}", volumeDetails);
                    TraceWriter.WriteErrorWithId(Constants.TraceSource, traceId, errorMessage);
                    return(new Response(errorMessage));
                }
                else
                {
                    TraceWriter.WriteInfoWithId(Constants.TraceSource, traceId, String.Format("Successfully provisioned volume: {0}", volumeDetails));
                }

                volumeEntry.MountIDs.Add(request.ID);
                ++volumeEntry.NumberOfMounts;
#if DotNetCoreClrLinux
                Interlocked.Increment(ref BSDockerVolumePlugin.SynchronizedKestrelCommunicationListener.TotalMountedVolumesOnNode);
#endif

                return(new VolumeMountResponse(volumeEntry.Mountpoint));
            }
            catch (Exception ex)
            {
                string errorMesg = String.Format("Unable to mount volume {0} due to exception: {1}", request.Name, ex.Message);
                TraceWriter.WriteErrorWithId(Constants.TraceSource, traceId, errorMesg);

                return(new Response(errorMesg));
            }
            finally
            {
                this.volumeRWLock.ExitWriteLock();
            }
        }