Пример #1
0
 /// <summary>Disallow the scanner from scanning the given block pool.</summary>
 /// <param name="bpid">The block pool id.</param>
 public virtual void DisableBlockPoolId(string bpid)
 {
     lock (this)
     {
         IEnumerator <FsVolumeSpi.BlockIterator> i = blockIters.GetEnumerator();
         while (i.HasNext())
         {
             FsVolumeSpi.BlockIterator iter = i.Next();
             if (iter.GetBlockPoolId().Equals(bpid))
             {
                 Log.Trace("{}: disabling scanning on block pool {}", this, bpid);
                 i.Remove();
                 IOUtils.Cleanup(null, iter);
                 if (curBlockIter == iter)
                 {
                     curBlockIter = null;
                 }
                 Sharpen.Runtime.Notify(this);
                 return;
             }
         }
         Log.Warn("{}: can't remove block pool {}, because it was never " + "added.", this
                  , bpid);
     }
 }
Пример #2
0
 /// <summary>
 /// Find a usable block iterator.<p/>
 /// We will consider available block iterators in order.
 /// </summary>
 /// <remarks>
 /// Find a usable block iterator.<p/>
 /// We will consider available block iterators in order.  This property is
 /// important so that we don't keep rescanning the same block pool id over
 /// and over, while other block pools stay unscanned.<p/>
 /// A block pool is always ready to scan if the iterator is not at EOF.  If
 /// the iterator is at EOF, the block pool will be ready to scan when
 /// conf.scanPeriodMs milliseconds have elapsed since the iterator was last
 /// rewound.<p/>
 /// </remarks>
 /// <returns>
 /// 0 if we found a usable block iterator; the
 /// length of time we should delay before
 /// checking again otherwise.
 /// </returns>
 private long FindNextUsableBlockIter()
 {
     lock (this)
     {
         int numBlockIters = blockIters.Count;
         if (numBlockIters == 0)
         {
             Log.Debug("{}: no block pools are registered.", this);
             return(long.MaxValue);
         }
         int curIdx;
         if (curBlockIter == null)
         {
             curIdx = 0;
         }
         else
         {
             curIdx = blockIters.IndexOf(curBlockIter);
             Preconditions.CheckState(curIdx >= 0);
         }
         // Note that this has to be wall-clock time, not monotonic time.  This is
         // because the time saved in the cursor file is a wall-clock time.  We do
         // not want to save a monotonic time in the cursor file, because it resets
         // every time the machine reboots (on most platforms).
         long nowMs        = Time.Now();
         long minTimeoutMs = long.MaxValue;
         for (int i = 0; i < numBlockIters; i++)
         {
             int idx = (curIdx + i + 1) % numBlockIters;
             FsVolumeSpi.BlockIterator iter = blockIters[idx];
             if (!iter.AtEnd())
             {
                 Log.Info("Now scanning bpid {} on volume {}", iter.GetBlockPoolId(), volume.GetBasePath
                              ());
                 curBlockIter = iter;
                 return(0L);
             }
             long iterStartMs = iter.GetIterStartMs();
             long waitMs      = (iterStartMs + conf.scanPeriodMs) - nowMs;
             if (waitMs <= 0)
             {
                 iter.Rewind();
                 Log.Info("Now rescanning bpid {} on volume {}, after more than " + "{} hour(s)",
                          iter.GetBlockPoolId(), volume.GetBasePath(), TimeUnit.Hours.Convert(conf.scanPeriodMs
                                                                                              , TimeUnit.Milliseconds));
                 curBlockIter = iter;
                 return(0L);
             }
             minTimeoutMs = Math.Min(minTimeoutMs, waitMs);
         }
         Log.Info("{}: no suitable block pools found to scan.  Waiting {} ms.", this, minTimeoutMs
                  );
         return(minTimeoutMs);
     }
 }
Пример #3
0
 private void SaveBlockIterator(FsVolumeSpi.BlockIterator iter)
 {
     try
     {
         iter.Save();
     }
     catch (IOException e)
     {
         Log.Warn("{}: error saving {}.", this, iter, e);
     }
 }
Пример #4
0
 // wake scanner thread.
 /// <summary>Allow the scanner to scan the given block pool.</summary>
 /// <param name="bpid">The block pool id.</param>
 public virtual void EnableBlockPoolId(string bpid)
 {
     lock (this)
     {
         foreach (FsVolumeSpi.BlockIterator iter in blockIters)
         {
             if (iter.GetBlockPoolId().Equals(bpid))
             {
                 Log.Warn("{}: already enabled scanning on block pool {}", this, bpid);
                 return;
             }
         }
         FsVolumeSpi.BlockIterator iter_1 = null;
         try
         {
             // Load a block iterator for the next block pool on the volume.
             iter_1 = volume.LoadBlockIterator(bpid, BlockIteratorName);
             Log.Trace("{}: loaded block iterator for {}.", this, bpid);
         }
         catch (FileNotFoundException e)
         {
             Log.Debug("{}: failed to load block iterator: " + e.Message, this);
         }
         catch (IOException e)
         {
             Log.Warn("{}: failed to load block iterator.", this, e);
         }
         if (iter_1 == null)
         {
             iter_1 = volume.NewBlockIterator(bpid, BlockIteratorName);
             Log.Trace("{}: created new block iterator for {}.", this, bpid);
         }
         iter_1.SetMaxStalenessMs(conf.maxStalenessMs);
         blockIters.AddItem(iter_1);
         Sharpen.Runtime.Notify(this);
     }
 }
Пример #5
0
        /// <summary>
        /// Test iterating through a bunch of blocks in a volume using a volume
        /// iterator.<p/>
        /// We will rewind the iterator when about halfway through the blocks.
        /// </summary>
        /// <param name="numFiles">The number of files to create.</param>
        /// <param name="maxStaleness">The maximum staleness to allow with the iterator.</param>
        /// <exception cref="System.Exception"/>
        private void TestVolumeIteratorImpl(int numFiles, long maxStaleness)
        {
            Configuration conf = new Configuration();

            DisableBlockScanner(conf);
            TestBlockScanner.TestContext ctx = new TestBlockScanner.TestContext(conf, 1);
            ctx.CreateFiles(0, numFiles, 1);
            NUnit.Framework.Assert.AreEqual(1, ctx.volumes.Count);
            FsVolumeSpi   volume               = ctx.volumes[0];
            ExtendedBlock savedBlock           = null;
            ExtendedBlock loadedBlock          = null;
            bool          testedRewind         = false;
            bool          testedSave           = false;
            bool          testedLoad           = false;
            int           blocksProcessed      = 0;
            int           savedBlocksProcessed = 0;

            try
            {
                BPOfferService[] bpos = ctx.datanode.GetAllBpOs();
                NUnit.Framework.Assert.AreEqual(1, bpos.Length);
                FsVolumeSpi.BlockIterator iter = volume.NewBlockIterator(ctx.bpids[0], "test");
                NUnit.Framework.Assert.AreEqual(ctx.bpids[0], iter.GetBlockPoolId());
                iter.SetMaxStalenessMs(maxStaleness);
                while (true)
                {
                    HashSet <ExtendedBlock> blocks = new HashSet <ExtendedBlock>();
                    for (int blockIdx = 0; blockIdx < numFiles; blockIdx++)
                    {
                        blocks.AddItem(ctx.GetFileBlock(0, blockIdx));
                    }
                    while (true)
                    {
                        ExtendedBlock block = iter.NextBlock();
                        if (block == null)
                        {
                            break;
                        }
                        blocksProcessed++;
                        Log.Info("BlockIterator for {} found block {}, blocksProcessed = {}", volume, block
                                 , blocksProcessed);
                        if (testedSave && (savedBlock == null))
                        {
                            savedBlock = block;
                        }
                        if (testedLoad && (loadedBlock == null))
                        {
                            loadedBlock = block;
                            // The block that we get back right after loading the iterator
                            // should be the same block we got back right after saving
                            // the iterator.
                            NUnit.Framework.Assert.AreEqual(savedBlock, loadedBlock);
                        }
                        bool blockRemoved = blocks.Remove(block);
                        NUnit.Framework.Assert.IsTrue("Found unknown block " + block, blockRemoved);
                        if (blocksProcessed > (numFiles / 3))
                        {
                            if (!testedSave)
                            {
                                Log.Info("Processed {} blocks out of {}.  Saving iterator.", blocksProcessed, numFiles
                                         );
                                iter.Save();
                                testedSave           = true;
                                savedBlocksProcessed = blocksProcessed;
                            }
                        }
                        if (blocksProcessed > (numFiles / 2))
                        {
                            if (!testedRewind)
                            {
                                Log.Info("Processed {} blocks out of {}.  Rewinding iterator.", blocksProcessed,
                                         numFiles);
                                iter.Rewind();
                                break;
                            }
                        }
                        if (blocksProcessed > ((2 * numFiles) / 3))
                        {
                            if (!testedLoad)
                            {
                                Log.Info("Processed {} blocks out of {}.  Loading iterator.", blocksProcessed, numFiles
                                         );
                                iter = volume.LoadBlockIterator(ctx.bpids[0], "test");
                                iter.SetMaxStalenessMs(maxStaleness);
                                break;
                            }
                        }
                    }
                    if (!testedRewind)
                    {
                        testedRewind    = true;
                        blocksProcessed = 0;
                        Log.Info("Starting again at the beginning...");
                        continue;
                    }
                    if (!testedLoad)
                    {
                        testedLoad      = true;
                        blocksProcessed = savedBlocksProcessed;
                        Log.Info("Starting again at the load point...");
                        continue;
                    }
                    NUnit.Framework.Assert.AreEqual(numFiles, blocksProcessed);
                    break;
                }
            }
            finally
            {
                ctx.Close();
            }
        }