Beispiel #1
0
        /// <exception cref="System.IO.IOException"/>
        public virtual void TestChangeVolumeWithRunningCheckDirs()
        {
            RoundRobinVolumeChoosingPolicy <FsVolumeImpl> blockChooser = new RoundRobinVolumeChoosingPolicy
                                                                         <FsVolumeImpl>();

            conf.SetLong(DFSConfigKeys.DfsDatanodeScanPeriodHoursKey, -1);
            BlockScanner blockScanner = new BlockScanner(datanode, conf);
            FsVolumeList volumeList   = new FsVolumeList(Sharpen.Collections.EmptyList <VolumeFailureInfo
                                                                                        >(), blockScanner, blockChooser);
            IList <FsVolumeImpl> oldVolumes = new AList <FsVolumeImpl>();
            // Initialize FsVolumeList with 5 mock volumes.
            int NumVolumes = 5;

            for (int i = 0; i < NumVolumes; i++)
            {
                FsVolumeImpl volume = Org.Mockito.Mockito.Mock <FsVolumeImpl>();
                oldVolumes.AddItem(volume);
                Org.Mockito.Mockito.When(volume.GetBasePath()).ThenReturn("data" + i);
                FsVolumeReference @ref = Org.Mockito.Mockito.Mock <FsVolumeReference>();
                Org.Mockito.Mockito.When(@ref.GetVolume()).ThenReturn(volume);
                volumeList.AddVolume(@ref);
            }
            // When call checkDirs() on the 2nd volume, anther "thread" removes the 5th
            // volume and add another volume. It does not affect checkDirs() running.
            FsVolumeImpl      newVolume = Org.Mockito.Mockito.Mock <FsVolumeImpl>();
            FsVolumeReference newRef    = Org.Mockito.Mockito.Mock <FsVolumeReference>();

            Org.Mockito.Mockito.When(newRef.GetVolume()).ThenReturn(newVolume);
            Org.Mockito.Mockito.When(newVolume.GetBasePath()).ThenReturn("data4");
            FsVolumeImpl blockedVolume = volumeList.GetVolumes()[1];

            Org.Mockito.Mockito.DoAnswer(new _Answer_295(volumeList, newRef)).When(blockedVolume
                                                                                   ).CheckDirs();
            FsVolumeImpl brokenVolume = volumeList.GetVolumes()[2];

            Org.Mockito.Mockito.DoThrow(new DiskChecker.DiskErrorException("broken")).When(brokenVolume
                                                                                           ).CheckDirs();
            volumeList.CheckDirs();
            // Since FsVolumeImpl#checkDirs() get a snapshot of the list of volumes
            // before running removeVolume(), it is supposed to run checkDirs() on all
            // the old volumes.
            foreach (FsVolumeImpl volume_1 in oldVolumes)
            {
                Org.Mockito.Mockito.Verify(volume_1).CheckDirs();
            }
            // New volume is not visible to checkDirs() process.
            Org.Mockito.Mockito.Verify(newVolume, Org.Mockito.Mockito.Never()).CheckDirs();
            NUnit.Framework.Assert.IsTrue(volumeList.GetVolumes().Contains(newVolume));
            NUnit.Framework.Assert.IsFalse(volumeList.GetVolumes().Contains(brokenVolume));
            NUnit.Framework.Assert.AreEqual(NumVolumes - 1, volumeList.GetVolumes().Count);
        }
Beispiel #2
0
 /// <summary>
 /// Calls
 /// <see cref="FsVolumeImpl.CheckDirs()"/>
 /// on each volume.
 /// Use checkDirsMutext to allow only one instance of checkDirs() call
 /// </summary>
 /// <returns>list of all the failed volumes.</returns>
 internal virtual ICollection <FilePath> CheckDirs()
 {
     lock (checkDirsMutex)
     {
         ICollection <FilePath> failedVols = null;
         // Make a copy of volumes for performing modification
         IList <FsVolumeImpl> volumeList = GetVolumes();
         for (IEnumerator <FsVolumeImpl> i = volumeList.GetEnumerator(); i.HasNext();)
         {
             FsVolumeImpl fsv = i.Next();
             try
             {
                 using (FsVolumeReference @ref = fsv.ObtainReference())
                 {
                     fsv.CheckDirs();
                 }
             }
             catch (DiskChecker.DiskErrorException e)
             {
                 FsDatasetImpl.Log.Warn("Removing failed volume " + fsv + ": ", e);
                 if (failedVols == null)
                 {
                     failedVols = new HashSet <FilePath>(1);
                 }
                 failedVols.AddItem(new FilePath(fsv.GetBasePath()).GetAbsoluteFile());
                 AddVolumeFailureInfo(fsv);
                 RemoveVolume(fsv);
             }
             catch (ClosedChannelException e)
             {
                 FsDatasetImpl.Log.Debug("Caught exception when obtaining " + "reference count on closed volume"
                                         , e);
             }
             catch (IOException e)
             {
                 FsDatasetImpl.Log.Error("Unexpected IOException", e);
             }
         }
         if (failedVols != null && failedVols.Count > 0)
         {
             FsDatasetImpl.Log.Warn("Completed checkDirs. Found " + failedVols.Count + " failure volumes."
                                    );
         }
         return(failedVols);
     }
 }
Beispiel #3
0
        /// <summary>Dynamically remove volume in the list.</summary>
        /// <param name="volume">the volume to be removed.</param>
        /// <param name="clearFailure">set true to remove failure info for this volume.</param>
        internal virtual void RemoveVolume(FilePath volume, bool clearFailure)
        {
            // Make a copy of volumes to remove one volume.
            FsVolumeImpl[]       curVolumes = volumes.Get();
            IList <FsVolumeImpl> volumeList = Lists.NewArrayList(curVolumes);

            for (IEnumerator <FsVolumeImpl> it = volumeList.GetEnumerator(); it.HasNext();)
            {
                FsVolumeImpl fsVolume = it.Next();
                string       basePath;
                string       targetPath;
                basePath   = new FilePath(fsVolume.GetBasePath()).GetAbsolutePath();
                targetPath = volume.GetAbsolutePath();
                if (basePath.Equals(targetPath))
                {
                    // Make sure the removed volume is the one in the curVolumes.
                    RemoveVolume(fsVolume);
                }
            }
            if (clearFailure)
            {
                RemoveVolumeFailureInfo(volume);
            }
        }
Beispiel #4
0
 private void AddVolumeFailureInfo(FsVolumeImpl vol)
 {
     AddVolumeFailureInfo(new VolumeFailureInfo(new FilePath(vol.GetBasePath()).GetAbsolutePath
                                                    (), Time.Now(), vol.GetCapacity()));
 }