예제 #1
0
        /// <exception cref="System.Exception"/>
        public virtual void TestBlockReaderLocalLegacyWithAppend()
        {
            short             ReplFactor = 1;
            HdfsConfiguration conf       = GetConfiguration(null);

            conf.SetBoolean(DFSConfigKeys.DfsClientUseLegacyBlockreaderlocal, true);
            MiniDFSCluster cluster = new MiniDFSCluster.Builder(conf).NumDataNodes(1).Build();

            cluster.WaitActive();
            DistributedFileSystem dfs = cluster.GetFileSystem();
            Path path = new Path("/testBlockReaderLocalLegacy");

            DFSTestUtil.CreateFile(dfs, path, 10, ReplFactor, 0);
            DFSTestUtil.WaitReplication(dfs, path, ReplFactor);
            ClientDatanodeProtocol proxy;

            Org.Apache.Hadoop.Security.Token.Token <BlockTokenIdentifier> token;
            ExtendedBlock originalBlock;
            long          originalGS;

            {
                LocatedBlock lb = cluster.GetNameNode().GetRpcServer().GetBlockLocations(path.ToString
                                                                                             (), 0, 1).Get(0);
                proxy = DFSUtil.CreateClientDatanodeProtocolProxy(lb.GetLocations()[0], conf, 60000
                                                                  , false);
                token = lb.GetBlockToken();
                // get block and generation stamp
                ExtendedBlock blk = new ExtendedBlock(lb.GetBlock());
                originalBlock = new ExtendedBlock(blk);
                originalGS    = originalBlock.GetGenerationStamp();
                // test getBlockLocalPathInfo
                BlockLocalPathInfo info = proxy.GetBlockLocalPathInfo(blk, token);
                NUnit.Framework.Assert.AreEqual(originalGS, info.GetBlock().GetGenerationStamp());
            }
            {
                // append one byte
                FSDataOutputStream @out = dfs.Append(path);
                @out.Write(1);
                @out.Close();
            }
            {
                // get new generation stamp
                LocatedBlock lb = cluster.GetNameNode().GetRpcServer().GetBlockLocations(path.ToString
                                                                                             (), 0, 1).Get(0);
                long newGS = lb.GetBlock().GetGenerationStamp();
                NUnit.Framework.Assert.IsTrue(newGS > originalGS);
                // getBlockLocalPathInfo using the original block.
                NUnit.Framework.Assert.AreEqual(originalGS, originalBlock.GetGenerationStamp());
                BlockLocalPathInfo info = proxy.GetBlockLocalPathInfo(originalBlock, token);
                NUnit.Framework.Assert.AreEqual(newGS, info.GetBlock().GetGenerationStamp());
            }
            cluster.Shutdown();
        }
예제 #2
0
        /// <summary>Convert an ExtendedBlock to a Json map.</summary>
        private static IDictionary <string, object> ToJsonMap(ExtendedBlock extendedblock)
        {
            if (extendedblock == null)
            {
                return(null);
            }
            IDictionary <string, object> m = new SortedDictionary <string, object>();

            m["blockPoolId"]     = extendedblock.GetBlockPoolId();
            m["blockId"]         = extendedblock.GetBlockId();
            m["numBytes"]        = extendedblock.GetNumBytes();
            m["generationStamp"] = extendedblock.GetGenerationStamp();
            return(m);
        }
예제 #3
0
 /* fill up a cluster with <code>numNodes</code> datanodes
  * whose used space to be <code>size</code>
  */
 /// <exception cref="System.IO.IOException"/>
 /// <exception cref="System.Exception"/>
 /// <exception cref="Sharpen.TimeoutException"/>
 private static ExtendedBlock[][] GenerateBlocks(TestBalancerWithMultipleNameNodes.Suite
                                                 s, long size)
 {
     ExtendedBlock[][] blocks = new ExtendedBlock[s.clients.Length][];
     for (int n = 0; n < s.clients.Length; n++)
     {
         long fileLen = size / s.replication;
         CreateFile(s, n, fileLen);
         IList <LocatedBlock> locatedBlocks = s.clients[n].GetBlockLocations(FileName, 0, fileLen
                                                                             ).GetLocatedBlocks();
         int numOfBlocks = locatedBlocks.Count;
         blocks[n] = new ExtendedBlock[numOfBlocks];
         for (int i = 0; i < numOfBlocks; i++)
         {
             ExtendedBlock b = locatedBlocks[i].GetBlock();
             blocks[n][i] = new ExtendedBlock(b.GetBlockPoolId(), b.GetBlockId(), b.GetNumBytes
                                                  (), b.GetGenerationStamp());
         }
     }
     return(blocks);
 }
예제 #4
0
        public virtual void TestGetNewStamp()
        {
            int            numDataNodes = 1;
            Configuration  conf         = new HdfsConfiguration();
            MiniDFSCluster cluster      = new MiniDFSCluster.Builder(conf).NumDataNodes(numDataNodes
                                                                                        ).Build();

            try
            {
                cluster.WaitActive();
                FileSystem        fileSys  = cluster.GetFileSystem();
                NamenodeProtocols namenode = cluster.GetNameNodeRpc();
                /* Test writing to finalized replicas */
                Path file = new Path("dataprotocol.dat");
                DFSTestUtil.CreateFile(fileSys, file, 1L, (short)numDataNodes, 0L);
                // get the first blockid for the file
                ExtendedBlock firstBlock = DFSTestUtil.GetFirstBlock(fileSys, file);
                // test getNewStampAndToken on a finalized block
                try
                {
                    namenode.UpdateBlockForPipeline(firstBlock, string.Empty);
                    NUnit.Framework.Assert.Fail("Can not get a new GS from a finalized block");
                }
                catch (IOException e)
                {
                    NUnit.Framework.Assert.IsTrue(e.Message.Contains("is not under Construction"));
                }
                // test getNewStampAndToken on a non-existent block
                try
                {
                    long          newBlockId = firstBlock.GetBlockId() + 1;
                    ExtendedBlock newBlock   = new ExtendedBlock(firstBlock.GetBlockPoolId(), newBlockId
                                                                 , 0, firstBlock.GetGenerationStamp());
                    namenode.UpdateBlockForPipeline(newBlock, string.Empty);
                    NUnit.Framework.Assert.Fail("Cannot get a new GS from a non-existent block");
                }
                catch (IOException e)
                {
                    NUnit.Framework.Assert.IsTrue(e.Message.Contains("does not exist"));
                }
                /* Test RBW replicas */
                // change first block to a RBW
                DFSOutputStream @out = null;
                try
                {
                    @out = (DFSOutputStream)(fileSys.Append(file).GetWrappedStream());
                    @out.Write(1);
                    @out.Hflush();
                    FSDataInputStream @in = null;
                    try
                    {
                        @in        = fileSys.Open(file);
                        firstBlock = DFSTestUtil.GetAllBlocks(@in)[0].GetBlock();
                    }
                    finally
                    {
                        IOUtils.CloseStream(@in);
                    }
                    // test non-lease holder
                    DFSClient dfs = ((DistributedFileSystem)fileSys).dfs;
                    try
                    {
                        namenode.UpdateBlockForPipeline(firstBlock, "test" + dfs.clientName);
                        NUnit.Framework.Assert.Fail("Cannot get a new GS for a non lease holder");
                    }
                    catch (LeaseExpiredException e)
                    {
                        NUnit.Framework.Assert.IsTrue(e.Message.StartsWith("Lease mismatch"));
                    }
                    // test null lease holder
                    try
                    {
                        namenode.UpdateBlockForPipeline(firstBlock, null);
                        NUnit.Framework.Assert.Fail("Cannot get a new GS for a null lease holder");
                    }
                    catch (LeaseExpiredException e)
                    {
                        NUnit.Framework.Assert.IsTrue(e.Message.StartsWith("Lease mismatch"));
                    }
                    // test getNewStampAndToken on a rbw block
                    namenode.UpdateBlockForPipeline(firstBlock, dfs.clientName);
                }
                finally
                {
                    IOUtils.CloseStream(@out);
                }
            }
            finally
            {
                cluster.Shutdown();
            }
        }
예제 #5
0
        public virtual void TestBlockSynchronization()
        {
            int           OrgFileSize = 3000;
            Configuration conf        = new HdfsConfiguration();

            conf.SetLong(DFSConfigKeys.DfsBlockSizeKey, BlockSize);
            cluster = new MiniDFSCluster.Builder(conf).NumDataNodes(5).Build();
            cluster.WaitActive();
            //create a file
            DistributedFileSystem dfs = cluster.GetFileSystem();
            string filestr            = "/foo";
            Path   filepath           = new Path(filestr);

            DFSTestUtil.CreateFile(dfs, filepath, OrgFileSize, ReplicationNum, 0L);
            NUnit.Framework.Assert.IsTrue(dfs.Exists(filepath));
            DFSTestUtil.WaitReplication(dfs, filepath, ReplicationNum);
            //get block info for the last block
            LocatedBlock locatedblock = TestInterDatanodeProtocol.GetLastLocatedBlock(dfs.dfs
                                                                                      .GetNamenode(), filestr);

            DatanodeInfo[] datanodeinfos = locatedblock.GetLocations();
            NUnit.Framework.Assert.AreEqual(ReplicationNum, datanodeinfos.Length);
            //connect to data nodes
            DataNode[] datanodes = new DataNode[ReplicationNum];
            for (int i = 0; i < ReplicationNum; i++)
            {
                datanodes[i] = cluster.GetDataNode(datanodeinfos[i].GetIpcPort());
                NUnit.Framework.Assert.IsTrue(datanodes[i] != null);
            }
            //verify Block Info
            ExtendedBlock lastblock = locatedblock.GetBlock();

            DataNode.Log.Info("newblocks=" + lastblock);
            for (int i_1 = 0; i_1 < ReplicationNum; i_1++)
            {
                CheckMetaInfo(lastblock, datanodes[i_1]);
            }
            DataNode.Log.Info("dfs.dfs.clientName=" + dfs.dfs.clientName);
            cluster.GetNameNodeRpc().Append(filestr, dfs.dfs.clientName, new EnumSetWritable <
                                                CreateFlag>(EnumSet.Of(CreateFlag.Append)));
            // expire lease to trigger block recovery.
            WaitLeaseRecovery(cluster);
            Block[] updatedmetainfo = new Block[ReplicationNum];
            long    oldSize         = lastblock.GetNumBytes();

            lastblock = TestInterDatanodeProtocol.GetLastLocatedBlock(dfs.dfs.GetNamenode(),
                                                                      filestr).GetBlock();
            long currentGS = lastblock.GetGenerationStamp();

            for (int i_2 = 0; i_2 < ReplicationNum; i_2++)
            {
                updatedmetainfo[i_2] = DataNodeTestUtils.GetFSDataset(datanodes[i_2]).GetStoredBlock
                                           (lastblock.GetBlockPoolId(), lastblock.GetBlockId());
                NUnit.Framework.Assert.AreEqual(lastblock.GetBlockId(), updatedmetainfo[i_2].GetBlockId
                                                    ());
                NUnit.Framework.Assert.AreEqual(oldSize, updatedmetainfo[i_2].GetNumBytes());
                NUnit.Framework.Assert.AreEqual(currentGS, updatedmetainfo[i_2].GetGenerationStamp
                                                    ());
            }
            // verify that lease recovery does not occur when namenode is in safemode
            System.Console.Out.WriteLine("Testing that lease recovery cannot happen during safemode."
                                         );
            filestr  = "/foo.safemode";
            filepath = new Path(filestr);
            dfs.Create(filepath, (short)1);
            cluster.GetNameNodeRpc().SetSafeMode(HdfsConstants.SafeModeAction.SafemodeEnter,
                                                 false);
            NUnit.Framework.Assert.IsTrue(dfs.dfs.Exists(filestr));
            DFSTestUtil.WaitReplication(dfs, filepath, (short)1);
            WaitLeaseRecovery(cluster);
            // verify that we still cannot recover the lease
            LeaseManager lm = NameNodeAdapter.GetLeaseManager(cluster.GetNamesystem());

            NUnit.Framework.Assert.IsTrue("Found " + lm.CountLease() + " lease, expected 1",
                                          lm.CountLease() == 1);
            cluster.GetNameNodeRpc().SetSafeMode(HdfsConstants.SafeModeAction.SafemodeLeave,
                                                 false);
        }
예제 #6
0
        public virtual void TestOpWrite()
        {
            int            numDataNodes = 1;
            long           BlockIdFudge = 128;
            Configuration  conf         = new HdfsConfiguration();
            MiniDFSCluster cluster      = new MiniDFSCluster.Builder(conf).NumDataNodes(numDataNodes
                                                                                        ).Build();

            try
            {
                cluster.WaitActive();
                string poolId = cluster.GetNamesystem().GetBlockPoolId();
                datanode = DataNodeTestUtils.GetDNRegistrationForBP(cluster.GetDataNodes()[0], poolId
                                                                    );
                dnAddr = NetUtils.CreateSocketAddr(datanode.GetXferAddr());
                FileSystem fileSys = cluster.GetFileSystem();
                /* Test writing to finalized replicas */
                Path file = new Path("dataprotocol.dat");
                DFSTestUtil.CreateFile(fileSys, file, 1L, (short)numDataNodes, 0L);
                // get the first blockid for the file
                ExtendedBlock firstBlock = DFSTestUtil.GetFirstBlock(fileSys, file);
                // test PIPELINE_SETUP_CREATE on a finalized block
                TestWrite(firstBlock, BlockConstructionStage.PipelineSetupCreate, 0L, "Cannot create an existing block"
                          , true);
                // test PIPELINE_DATA_STREAMING on a finalized block
                TestWrite(firstBlock, BlockConstructionStage.DataStreaming, 0L, "Unexpected stage"
                          , true);
                // test PIPELINE_SETUP_STREAMING_RECOVERY on an existing block
                long newGS = firstBlock.GetGenerationStamp() + 1;
                TestWrite(firstBlock, BlockConstructionStage.PipelineSetupStreamingRecovery, newGS
                          , "Cannot recover data streaming to a finalized replica", true);
                // test PIPELINE_SETUP_APPEND on an existing block
                newGS = firstBlock.GetGenerationStamp() + 1;
                TestWrite(firstBlock, BlockConstructionStage.PipelineSetupAppend, newGS, "Append to a finalized replica"
                          , false);
                firstBlock.SetGenerationStamp(newGS);
                // test PIPELINE_SETUP_APPEND_RECOVERY on an existing block
                file = new Path("dataprotocol1.dat");
                DFSTestUtil.CreateFile(fileSys, file, 1L, (short)numDataNodes, 0L);
                firstBlock = DFSTestUtil.GetFirstBlock(fileSys, file);
                newGS      = firstBlock.GetGenerationStamp() + 1;
                TestWrite(firstBlock, BlockConstructionStage.PipelineSetupAppendRecovery, newGS,
                          "Recover appending to a finalized replica", false);
                // test PIPELINE_CLOSE_RECOVERY on an existing block
                file = new Path("dataprotocol2.dat");
                DFSTestUtil.CreateFile(fileSys, file, 1L, (short)numDataNodes, 0L);
                firstBlock = DFSTestUtil.GetFirstBlock(fileSys, file);
                newGS      = firstBlock.GetGenerationStamp() + 1;
                TestWrite(firstBlock, BlockConstructionStage.PipelineCloseRecovery, newGS, "Recover failed close to a finalized replica"
                          , false);
                firstBlock.SetGenerationStamp(newGS);
                // Test writing to a new block. Don't choose the next sequential
                // block ID to avoid conflicting with IDs chosen by the NN.
                long          newBlockId = firstBlock.GetBlockId() + BlockIdFudge;
                ExtendedBlock newBlock   = new ExtendedBlock(firstBlock.GetBlockPoolId(), newBlockId
                                                             , 0, firstBlock.GetGenerationStamp());
                // test PIPELINE_SETUP_CREATE on a new block
                TestWrite(newBlock, BlockConstructionStage.PipelineSetupCreate, 0L, "Create a new block"
                          , false);
                // test PIPELINE_SETUP_STREAMING_RECOVERY on a new block
                newGS = newBlock.GetGenerationStamp() + 1;
                newBlock.SetBlockId(newBlock.GetBlockId() + 1);
                TestWrite(newBlock, BlockConstructionStage.PipelineSetupStreamingRecovery, newGS,
                          "Recover a new block", true);
                // test PIPELINE_SETUP_APPEND on a new block
                newGS = newBlock.GetGenerationStamp() + 1;
                TestWrite(newBlock, BlockConstructionStage.PipelineSetupAppend, newGS, "Cannot append to a new block"
                          , true);
                // test PIPELINE_SETUP_APPEND_RECOVERY on a new block
                newBlock.SetBlockId(newBlock.GetBlockId() + 1);
                newGS = newBlock.GetGenerationStamp() + 1;
                TestWrite(newBlock, BlockConstructionStage.PipelineSetupAppendRecovery, newGS, "Cannot append to a new block"
                          , true);
                /* Test writing to RBW replicas */
                Path file1 = new Path("dataprotocol1.dat");
                DFSTestUtil.CreateFile(fileSys, file1, 1L, (short)numDataNodes, 0L);
                DFSOutputStream @out = (DFSOutputStream)(fileSys.Append(file1).GetWrappedStream()
                                                         );
                @out.Write(1);
                @out.Hflush();
                FSDataInputStream @in = fileSys.Open(file1);
                firstBlock = DFSTestUtil.GetAllBlocks(@in)[0].GetBlock();
                firstBlock.SetNumBytes(2L);
                try
                {
                    // test PIPELINE_SETUP_CREATE on a RBW block
                    TestWrite(firstBlock, BlockConstructionStage.PipelineSetupCreate, 0L, "Cannot create a RBW block"
                              , true);
                    // test PIPELINE_SETUP_APPEND on an existing block
                    newGS = firstBlock.GetGenerationStamp() + 1;
                    TestWrite(firstBlock, BlockConstructionStage.PipelineSetupAppend, newGS, "Cannot append to a RBW replica"
                              , true);
                    // test PIPELINE_SETUP_APPEND on an existing block
                    TestWrite(firstBlock, BlockConstructionStage.PipelineSetupAppendRecovery, newGS,
                              "Recover append to a RBW replica", false);
                    firstBlock.SetGenerationStamp(newGS);
                    // test PIPELINE_SETUP_STREAMING_RECOVERY on a RBW block
                    file = new Path("dataprotocol2.dat");
                    DFSTestUtil.CreateFile(fileSys, file, 1L, (short)numDataNodes, 0L);
                    @out = (DFSOutputStream)(fileSys.Append(file).GetWrappedStream());
                    @out.Write(1);
                    @out.Hflush();
                    @in        = fileSys.Open(file);
                    firstBlock = DFSTestUtil.GetAllBlocks(@in)[0].GetBlock();
                    firstBlock.SetNumBytes(2L);
                    newGS = firstBlock.GetGenerationStamp() + 1;
                    TestWrite(firstBlock, BlockConstructionStage.PipelineSetupStreamingRecovery, newGS
                              , "Recover a RBW replica", false);
                }
                finally
                {
                    IOUtils.CloseStream(@in);
                    IOUtils.CloseStream(@out);
                }
            }
            finally
            {
                cluster.Shutdown();
            }
        }
        public virtual void TestUpdateReplicaUnderRecovery()
        {
            MiniDFSCluster cluster = null;

            try
            {
                cluster = new MiniDFSCluster.Builder(conf).NumDataNodes(3).Build();
                cluster.WaitActive();
                string bpid = cluster.GetNamesystem().GetBlockPoolId();
                //create a file
                DistributedFileSystem dfs = cluster.GetFileSystem();
                string filestr            = "/foo";
                Path   filepath           = new Path(filestr);
                DFSTestUtil.CreateFile(dfs, filepath, 1024L, (short)3, 0L);
                //get block info
                LocatedBlock locatedblock = GetLastLocatedBlock(DFSClientAdapter.GetDFSClient(dfs
                                                                                              ).GetNamenode(), filestr);
                DatanodeInfo[] datanodeinfo = locatedblock.GetLocations();
                NUnit.Framework.Assert.IsTrue(datanodeinfo.Length > 0);
                //get DataNode and FSDataset objects
                DataNode datanode = cluster.GetDataNode(datanodeinfo[0].GetIpcPort());
                NUnit.Framework.Assert.IsTrue(datanode != null);
                //initReplicaRecovery
                ExtendedBlock         b          = locatedblock.GetBlock();
                long                  recoveryid = b.GetGenerationStamp() + 1;
                long                  newlength  = b.GetNumBytes() - 1;
                FsDatasetSpi <object> fsdataset  = DataNodeTestUtils.GetFSDataset(datanode);
                ReplicaRecoveryInfo   rri        = fsdataset.InitReplicaRecovery(new BlockRecoveryCommand.RecoveringBlock
                                                                                     (b, null, recoveryid));
                //check replica
                ReplicaInfo replica = FsDatasetTestUtil.FetchReplicaInfo(fsdataset, bpid, b.GetBlockId
                                                                             ());
                NUnit.Framework.Assert.AreEqual(HdfsServerConstants.ReplicaState.Rur, replica.GetState
                                                    ());
                //check meta data before update
                FsDatasetImpl.CheckReplicaFiles(replica);
                {
                    //case "THIS IS NOT SUPPOSED TO HAPPEN"
                    //with (block length) != (stored replica's on disk length).
                    //create a block with same id and gs but different length.
                    ExtendedBlock tmp = new ExtendedBlock(b.GetBlockPoolId(), rri.GetBlockId(), rri.GetNumBytes
                                                              () - 1, rri.GetGenerationStamp());
                    try
                    {
                        //update should fail
                        fsdataset.UpdateReplicaUnderRecovery(tmp, recoveryid, tmp.GetBlockId(), newlength
                                                             );
                        NUnit.Framework.Assert.Fail();
                    }
                    catch (IOException ioe)
                    {
                        System.Console.Out.WriteLine("GOOD: getting " + ioe);
                    }
                }
                //update
                string storageID = fsdataset.UpdateReplicaUnderRecovery(new ExtendedBlock(b.GetBlockPoolId
                                                                                              (), rri), recoveryid, rri.GetBlockId(), newlength);
                NUnit.Framework.Assert.IsTrue(storageID != null);
            }
            finally
            {
                if (cluster != null)
                {
                    cluster.Shutdown();
                }
            }
        }
        /// <summary>The following test first creates a file.</summary>
        /// <remarks>
        /// The following test first creates a file.
        /// It verifies the block information from a datanode.
        /// Then, it updates the block with new information and verifies again.
        /// </remarks>
        /// <param name="useDnHostname">whether DNs should connect to other DNs by hostname</param>
        /// <exception cref="System.Exception"/>
        private void CheckBlockMetaDataInfo(bool useDnHostname)
        {
            MiniDFSCluster cluster = null;

            conf.SetBoolean(DFSConfigKeys.DfsDatanodeUseDnHostname, useDnHostname);
            if (useDnHostname)
            {
                // Since the mini cluster only listens on the loopback we have to
                // ensure the hostname used to access DNs maps to the loopback. We
                // do this by telling the DN to advertise localhost as its hostname
                // instead of the default hostname.
                conf.Set(DFSConfigKeys.DfsDatanodeHostNameKey, "localhost");
            }
            try
            {
                cluster = new MiniDFSCluster.Builder(conf).NumDataNodes(3).CheckDataNodeHostConfig
                              (true).Build();
                cluster.WaitActive();
                //create a file
                DistributedFileSystem dfs = cluster.GetFileSystem();
                string filestr            = "/foo";
                Path   filepath           = new Path(filestr);
                DFSTestUtil.CreateFile(dfs, filepath, 1024L, (short)3, 0L);
                NUnit.Framework.Assert.IsTrue(dfs.Exists(filepath));
                //get block info
                LocatedBlock locatedblock = GetLastLocatedBlock(DFSClientAdapter.GetDFSClient(dfs
                                                                                              ).GetNamenode(), filestr);
                DatanodeInfo[] datanodeinfo = locatedblock.GetLocations();
                NUnit.Framework.Assert.IsTrue(datanodeinfo.Length > 0);
                //connect to a data node
                DataNode datanode         = cluster.GetDataNode(datanodeinfo[0].GetIpcPort());
                InterDatanodeProtocol idp = DataNodeTestUtils.CreateInterDatanodeProtocolProxy(datanode
                                                                                               , datanodeinfo[0], conf, useDnHostname);
                // Stop the block scanners.
                datanode.GetBlockScanner().RemoveAllVolumeScanners();
                //verify BlockMetaDataInfo
                ExtendedBlock b = locatedblock.GetBlock();
                InterDatanodeProtocol.Log.Info("b=" + b + ", " + b.GetType());
                CheckMetaInfo(b, datanode);
                long recoveryId = b.GetGenerationStamp() + 1;
                idp.InitReplicaRecovery(new BlockRecoveryCommand.RecoveringBlock(b, locatedblock.
                                                                                 GetLocations(), recoveryId));
                //verify updateBlock
                ExtendedBlock newblock = new ExtendedBlock(b.GetBlockPoolId(), b.GetBlockId(), b.
                                                           GetNumBytes() / 2, b.GetGenerationStamp() + 1);
                idp.UpdateReplicaUnderRecovery(b, recoveryId, b.GetBlockId(), newblock.GetNumBytes
                                                   ());
                CheckMetaInfo(newblock, datanode);
                // Verify correct null response trying to init recovery for a missing block
                ExtendedBlock badBlock = new ExtendedBlock("fake-pool", b.GetBlockId(), 0, 0);
                NUnit.Framework.Assert.IsNull(idp.InitReplicaRecovery(new BlockRecoveryCommand.RecoveringBlock
                                                                          (badBlock, locatedblock.GetLocations(), recoveryId)));
            }
            finally
            {
                if (cluster != null)
                {
                    cluster.Shutdown();
                }
            }
        }
예제 #9
0
        /// <exception cref="System.IO.IOException"/>
        internal static void CheckSuccess(DataTransferProtos.BlockOpResponseProto status,
                                          Peer peer, ExtendedBlock block, string file)
        {
            string logInfo = "for OP_READ_BLOCK" + ", self=" + peer.GetLocalAddressString() +
                             ", remote=" + peer.GetRemoteAddressString() + ", for file " + file + ", for pool "
                             + block.GetBlockPoolId() + " block " + block.GetBlockId() + "_" + block.GetGenerationStamp
                                 ();

            DataTransferProtoUtil.CheckBlockOpStatus(status, logInfo);
        }
예제 #10
0
        /// <summary>Constructor</summary>
        /// <param name="block">Block that is being read</param>
        /// <param name="startOffset">starting offset to read from</param>
        /// <param name="length">length of data to read</param>
        /// <param name="corruptChecksumOk">if true, corrupt checksum is okay</param>
        /// <param name="verifyChecksum">verify checksum while reading the data</param>
        /// <param name="sendChecksum">send checksum to client.</param>
        /// <param name="datanode">datanode from which the block is being read</param>
        /// <param name="clientTraceFmt">format string used to print client trace logs</param>
        /// <exception cref="System.IO.IOException"/>
        internal BlockSender(ExtendedBlock block, long startOffset, long length, bool corruptChecksumOk
                             , bool verifyChecksum, bool sendChecksum, DataNode datanode, string clientTraceFmt
                             , CachingStrategy cachingStrategy)
        {
            // Cache-management related fields
            // 1MB
            try
            {
                this.block             = block;
                this.corruptChecksumOk = corruptChecksumOk;
                this.verifyChecksum    = verifyChecksum;
                this.clientTraceFmt    = clientTraceFmt;

                /*
                 * If the client asked for the cache to be dropped behind all reads,
                 * we honor that.  Otherwise, we use the DataNode defaults.
                 * When using DataNode defaults, we use a heuristic where we only
                 * drop the cache for large reads.
                 */
                if (cachingStrategy.GetDropBehind() == null)
                {
                    this.dropCacheBehindAllReads   = false;
                    this.dropCacheBehindLargeReads = datanode.GetDnConf().dropCacheBehindReads;
                }
                else
                {
                    this.dropCacheBehindAllReads = this.dropCacheBehindLargeReads = cachingStrategy.GetDropBehind
                                                                                        ();
                }

                /*
                 * Similarly, if readahead was explicitly requested, we always do it.
                 * Otherwise, we read ahead based on the DataNode settings, and only
                 * when the reads are large.
                 */
                if (cachingStrategy.GetReadahead() == null)
                {
                    this.alwaysReadahead = false;
                    this.readaheadLength = datanode.GetDnConf().readaheadLength;
                }
                else
                {
                    this.alwaysReadahead = true;
                    this.readaheadLength = cachingStrategy.GetReadahead();
                }
                this.datanode = datanode;
                if (verifyChecksum)
                {
                    // To simplify implementation, callers may not specify verification
                    // without sending.
                    Preconditions.CheckArgument(sendChecksum, "If verifying checksum, currently must also send it."
                                                );
                }
                Replica replica;
                long    replicaVisibleLength;
                lock (datanode.data)
                {
                    replica = GetReplica(block, datanode);
                    replicaVisibleLength = replica.GetVisibleLength();
                }
                // if there is a write in progress
                ChunkChecksum chunkChecksum = null;
                if (replica is ReplicaBeingWritten)
                {
                    ReplicaBeingWritten rbw = (ReplicaBeingWritten)replica;
                    WaitForMinLength(rbw, startOffset + length);
                    chunkChecksum = rbw.GetLastChecksumAndDataLen();
                }
                if (replica.GetGenerationStamp() < block.GetGenerationStamp())
                {
                    throw new IOException("Replica gen stamp < block genstamp, block=" + block + ", replica="
                                          + replica);
                }
                else
                {
                    if (replica.GetGenerationStamp() > block.GetGenerationStamp())
                    {
                        if (DataNode.Log.IsDebugEnabled())
                        {
                            DataNode.Log.Debug("Bumping up the client provided" + " block's genstamp to latest "
                                               + replica.GetGenerationStamp() + " for block " + block);
                        }
                        block.SetGenerationStamp(replica.GetGenerationStamp());
                    }
                }
                if (replicaVisibleLength < 0)
                {
                    throw new IOException("Replica is not readable, block=" + block + ", replica=" +
                                          replica);
                }
                if (DataNode.Log.IsDebugEnabled())
                {
                    DataNode.Log.Debug("block=" + block + ", replica=" + replica);
                }
                // transferToFully() fails on 32 bit platforms for block sizes >= 2GB,
                // use normal transfer in those cases
                this.transferToAllowed = datanode.GetDnConf().transferToAllowed&& (!is32Bit || length
                                                                                   <= int.MaxValue);
                // Obtain a reference before reading data
                this.volumeRef = datanode.data.GetVolume(block).ObtainReference();

                /*
                 * (corruptChecksumOK, meta_file_exist): operation
                 * True,   True: will verify checksum
                 * True,  False: No verify, e.g., need to read data from a corrupted file
                 * False,  True: will verify checksum
                 * False, False: throws IOException file not found
                 */
                DataChecksum csum = null;
                if (verifyChecksum || sendChecksum)
                {
                    LengthInputStream metaIn = null;
                    bool keepMetaInOpen      = false;
                    try
                    {
                        metaIn = datanode.data.GetMetaDataInputStream(block);
                        if (!corruptChecksumOk || metaIn != null)
                        {
                            if (metaIn == null)
                            {
                                //need checksum but meta-data not found
                                throw new FileNotFoundException("Meta-data not found for " + block);
                            }
                            // The meta file will contain only the header if the NULL checksum
                            // type was used, or if the replica was written to transient storage.
                            // Checksum verification is not performed for replicas on transient
                            // storage.  The header is important for determining the checksum
                            // type later when lazy persistence copies the block to non-transient
                            // storage and computes the checksum.
                            if (metaIn.GetLength() > BlockMetadataHeader.GetHeaderSize())
                            {
                                checksumIn = new DataInputStream(new BufferedInputStream(metaIn, HdfsConstants.IoFileBufferSize
                                                                                         ));
                                csum           = BlockMetadataHeader.ReadDataChecksum(checksumIn, block);
                                keepMetaInOpen = true;
                            }
                        }
                        else
                        {
                            Log.Warn("Could not find metadata file for " + block);
                        }
                    }
                    finally
                    {
                        if (!keepMetaInOpen)
                        {
                            IOUtils.CloseStream(metaIn);
                        }
                    }
                }
                if (csum == null)
                {
                    // The number of bytes per checksum here determines the alignment
                    // of reads: we always start reading at a checksum chunk boundary,
                    // even if the checksum type is NULL. So, choosing too big of a value
                    // would risk sending too much unnecessary data. 512 (1 disk sector)
                    // is likely to result in minimal extra IO.
                    csum = DataChecksum.NewDataChecksum(DataChecksum.Type.Null, 512);
                }

                /*
                 * If chunkSize is very large, then the metadata file is mostly
                 * corrupted. For now just truncate bytesPerchecksum to blockLength.
                 */
                int size = csum.GetBytesPerChecksum();
                if (size > 10 * 1024 * 1024 && size > replicaVisibleLength)
                {
                    csum = DataChecksum.NewDataChecksum(csum.GetChecksumType(), Math.Max((int)replicaVisibleLength
                                                                                         , 10 * 1024 * 1024));
                    size = csum.GetBytesPerChecksum();
                }
                chunkSize    = size;
                checksum     = csum;
                checksumSize = checksum.GetChecksumSize();
                length       = length < 0 ? replicaVisibleLength : length;
                // end is either last byte on disk or the length for which we have a
                // checksum
                long end = chunkChecksum != null?chunkChecksum.GetDataLength() : replica.GetBytesOnDisk
                                   ();

                if (startOffset < 0 || startOffset > end || (length + startOffset) > end)
                {
                    string msg = " Offset " + startOffset + " and length " + length + " don't match block "
                                 + block + " ( blockLen " + end + " )";
                    Log.Warn(datanode.GetDNRegistrationForBP(block.GetBlockPoolId()) + ":sendBlock() : "
                             + msg);
                    throw new IOException(msg);
                }
                // Ensure read offset is position at the beginning of chunk
                offset = startOffset - (startOffset % chunkSize);
                if (length >= 0)
                {
                    // Ensure endOffset points to end of chunk.
                    long tmpLen = startOffset + length;
                    if (tmpLen % chunkSize != 0)
                    {
                        tmpLen += (chunkSize - tmpLen % chunkSize);
                    }
                    if (tmpLen < end)
                    {
                        // will use on-disk checksum here since the end is a stable chunk
                        end = tmpLen;
                    }
                    else
                    {
                        if (chunkChecksum != null)
                        {
                            // last chunk is changing. flag that we need to use in-memory checksum
                            this.lastChunkChecksum = chunkChecksum;
                        }
                    }
                }
                endOffset = end;
                // seek to the right offsets
                if (offset > 0 && checksumIn != null)
                {
                    long checksumSkip = (offset / chunkSize) * checksumSize;
                    // note blockInStream is seeked when created below
                    if (checksumSkip > 0)
                    {
                        // Should we use seek() for checksum file as well?
                        IOUtils.SkipFully(checksumIn, checksumSkip);
                    }
                }
                seqno = 0;
                if (DataNode.Log.IsDebugEnabled())
                {
                    DataNode.Log.Debug("replica=" + replica);
                }
                blockIn = datanode.data.GetBlockInputStream(block, offset);
                // seek to offset
                if (blockIn is FileInputStream)
                {
                    blockInFd = ((FileInputStream)blockIn).GetFD();
                }
                else
                {
                    blockInFd = null;
                }
            }
            catch (IOException ioe)
            {
                IOUtils.CloseStream(this);
                IOUtils.CloseStream(blockIn);
                throw;
            }
        }