public virtual void TestDeadDatanode()
        {
            Configuration conf = new HdfsConfiguration();

            conf.SetInt(DFSConfigKeys.DfsNamenodeHeartbeatRecheckIntervalKey, 500);
            conf.SetLong(DFSConfigKeys.DfsHeartbeatIntervalKey, 1L);
            cluster = new MiniDFSCluster.Builder(conf).Build();
            cluster.WaitActive();
            string poolId = cluster.GetNamesystem().GetBlockPoolId();
            // wait for datanode to be marked live
            DataNode             dn  = cluster.GetDataNodes()[0];
            DatanodeRegistration reg = DataNodeTestUtils.GetDNRegistrationForBP(cluster.GetDataNodes
                                                                                    ()[0], poolId);

            DFSTestUtil.WaitForDatanodeState(cluster, reg.GetDatanodeUuid(), true, 20000);
            // Shutdown and wait for datanode to be marked dead
            dn.Shutdown();
            DFSTestUtil.WaitForDatanodeState(cluster, reg.GetDatanodeUuid(), false, 20000);
            DatanodeProtocol dnp = cluster.GetNameNodeRpc();

            ReceivedDeletedBlockInfo[] blocks = new ReceivedDeletedBlockInfo[] { new ReceivedDeletedBlockInfo
                                                                                     (new Block(0), ReceivedDeletedBlockInfo.BlockStatus.ReceivedBlock, null) };
            StorageReceivedDeletedBlocks[] storageBlocks = new StorageReceivedDeletedBlocks[]
            { new StorageReceivedDeletedBlocks(reg.GetDatanodeUuid(), blocks) };
            // Ensure blockReceived call from dead datanode is rejected with IOException
            try
            {
                dnp.BlockReceivedAndDeleted(reg, poolId, storageBlocks);
                NUnit.Framework.Assert.Fail("Expected IOException is not thrown");
            }
            catch (IOException)
            {
            }
            // Expected
            // Ensure blockReport from dead datanode is rejected with IOException
            StorageBlockReport[] report = new StorageBlockReport[] { new StorageBlockReport(new
                                                                                            DatanodeStorage(reg.GetDatanodeUuid()), BlockListAsLongs.Empty) };
            try
            {
                dnp.BlockReport(reg, poolId, report, new BlockReportContext(1, 0, Runtime.NanoTime
                                                                                ()));
                NUnit.Framework.Assert.Fail("Expected IOException is not thrown");
            }
            catch (IOException)
            {
            }
            // Expected
            // Ensure heartbeat from dead datanode is rejected with a command
            // that asks datanode to register again
            StorageReport[] rep = new StorageReport[] { new StorageReport(new DatanodeStorage
                                                                              (reg.GetDatanodeUuid()), false, 0, 0, 0, 0) };
            DatanodeCommand[] cmd = dnp.SendHeartbeat(reg, rep, 0L, 0L, 0, 0, 0, null).GetCommands
                                        ();
            NUnit.Framework.Assert.AreEqual(1, cmd.Length);
            NUnit.Framework.Assert.AreEqual(cmd[0].GetAction(), RegisterCommand.Register.GetAction
                                                ());
        }
Exemple #2
0
        // Generate a block report, optionally corrupting the generation
        // stamp and/or length of one block.
        private static StorageBlockReport[] GetBlockReports(DataNode dn, string bpid, bool
                                                            corruptOneBlockGs, bool corruptOneBlockLen)
        {
            IDictionary <DatanodeStorage, BlockListAsLongs> perVolumeBlockLists = dn.GetFSDataset
                                                                                      ().GetBlockReports(bpid);

            // Send block report
            StorageBlockReport[] reports = new StorageBlockReport[perVolumeBlockLists.Count];
            bool corruptedGs             = false;
            bool corruptedLen            = false;
            int  reportIndex             = 0;

            foreach (KeyValuePair <DatanodeStorage, BlockListAsLongs> kvPair in perVolumeBlockLists)
            {
                DatanodeStorage  dnStorage = kvPair.Key;
                BlockListAsLongs blockList = kvPair.Value;
                // Walk the list of blocks until we find one each to corrupt the
                // generation stamp and length, if so requested.
                BlockListAsLongs.Builder builder = BlockListAsLongs.Builder();
                foreach (BlockListAsLongs.BlockReportReplica block in blockList)
                {
                    if (corruptOneBlockGs && !corruptedGs)
                    {
                        long gsOld = block.GetGenerationStamp();
                        long gsNew;
                        do
                        {
                            gsNew = rand.Next();
                        }while (gsNew == gsOld);
                        block.SetGenerationStamp(gsNew);
                        Log.Info("Corrupted the GS for block ID " + block);
                        corruptedGs = true;
                    }
                    else
                    {
                        if (corruptOneBlockLen && !corruptedLen)
                        {
                            long lenOld = block.GetNumBytes();
                            long lenNew;
                            do
                            {
                                lenNew = rand.Next((int)lenOld - 1);
                            }while (lenNew == lenOld);
                            block.SetNumBytes(lenNew);
                            Log.Info("Corrupted the length for block ID " + block);
                            corruptedLen = true;
                        }
                    }
                    builder.Add(new BlockListAsLongs.BlockReportReplica(block));
                }
                reports[reportIndex++] = new StorageBlockReport(dnStorage, builder.Build());
            }
            return(reports);
        }
        /// <exception cref="System.IO.IOException"/>
        protected internal override void SendBlockReports(DatanodeRegistration dnR, string
                                                          poolId, StorageBlockReport[] reports)
        {
            int i = 0;

            foreach (StorageBlockReport report in reports)
            {
                Log.Info("Sending block report for storage " + report.GetStorage().GetStorageID()
                         );
                StorageBlockReport[] singletonReport = new StorageBlockReport[] { report };
                cluster.GetNameNodeRpc().BlockReport(dnR, poolId, singletonReport, new BlockReportContext
                                                         (reports.Length, i, Runtime.NanoTime()));
                i++;
            }
        }
Exemple #4
0
        public virtual void TestBlockHasMultipleReplicasOnSameDN()
        {
            string filename = MakeFileName(GenericTestUtils.GetMethodName());
            Path   filePath = new Path(filename);

            // Write out a file with a few blocks.
            DFSTestUtil.CreateFile(fs, filePath, BlockSize, BlockSize * NumBlocks, BlockSize,
                                   NumDatanodes, seed);
            // Get the block list for the file with the block locations.
            LocatedBlocks locatedBlocks = client.GetLocatedBlocks(filePath.ToString(), 0, BlockSize
                                                                  * NumBlocks);
            // Generate a fake block report from one of the DataNodes, such
            // that it reports one copy of each block on either storage.
            DataNode             dn    = cluster.GetDataNodes()[0];
            DatanodeRegistration dnReg = dn.GetDNRegistrationForBP(bpid);

            StorageBlockReport[] reports = new StorageBlockReport[cluster.GetStoragesPerDatanode
                                                                      ()];
            AList <Replica> blocks = new AList <Replica>();

            foreach (LocatedBlock locatedBlock in locatedBlocks.GetLocatedBlocks())
            {
                Block localBlock = locatedBlock.GetBlock().GetLocalBlock();
                blocks.AddItem(new FinalizedReplica(localBlock, null, null));
            }
            BlockListAsLongs bll = BlockListAsLongs.Encode(blocks);

            for (int i = 0; i < cluster.GetStoragesPerDatanode(); ++i)
            {
                FsVolumeSpi     v   = dn.GetFSDataset().GetVolumes()[i];
                DatanodeStorage dns = new DatanodeStorage(v.GetStorageID());
                reports[i] = new StorageBlockReport(dns, bll);
            }
            // Should not assert!
            cluster.GetNameNodeRpc().BlockReport(dnReg, bpid, reports, new BlockReportContext
                                                     (1, 0, Runtime.NanoTime()));
            // Get the block locations once again.
            locatedBlocks = client.GetLocatedBlocks(filename, 0, BlockSize * NumBlocks);
            // Make sure that each block has two replicas, one on each DataNode.
            foreach (LocatedBlock locatedBlock_1 in locatedBlocks.GetLocatedBlocks())
            {
                DatanodeInfo[] locations = locatedBlock_1.GetLocations();
                Assert.AssertThat(locations.Length, IS.Is((int)NumDatanodes));
                Assert.AssertThat(locations[0].GetDatanodeUuid(), CoreMatchers.Not(locations[1].GetDatanodeUuid
                                                                                       ()));
            }
        }
        /// <exception cref="Com.Google.Protobuf.ServiceException"/>
        public virtual DatanodeProtocolProtos.BlockReportResponseProto BlockReport(RpcController
                                                                                   controller, DatanodeProtocolProtos.BlockReportRequestProto request)
        {
            DatanodeCommand cmd = null;

            StorageBlockReport[] report = new StorageBlockReport[request.GetReportsCount()];
            int index = 0;

            foreach (DatanodeProtocolProtos.StorageBlockReportProto s in request.GetReportsList
                         ())
            {
                BlockListAsLongs blocks;
                if (s.HasNumberOfBlocks())
                {
                    // new style buffer based reports
                    int num = (int)s.GetNumberOfBlocks();
                    Preconditions.CheckState(s.GetBlocksCount() == 0, "cannot send both blocks list and buffers"
                                             );
                    blocks = BlockListAsLongs.DecodeBuffers(num, s.GetBlocksBuffersList());
                }
                else
                {
                    blocks = BlockListAsLongs.DecodeLongs(s.GetBlocksList());
                }
                report[index++] = new StorageBlockReport(PBHelper.Convert(s.GetStorage()), blocks
                                                         );
            }
            try
            {
                cmd = impl.BlockReport(PBHelper.Convert(request.GetRegistration()), request.GetBlockPoolId
                                           (), report, request.HasContext() ? PBHelper.Convert(request.GetContext()) : null
                                       );
            }
            catch (IOException e)
            {
                throw new ServiceException(e);
            }
            DatanodeProtocolProtos.BlockReportResponseProto.Builder builder = DatanodeProtocolProtos.BlockReportResponseProto
                                                                              .NewBuilder();
            if (cmd != null)
            {
                builder.SetCmd(PBHelper.Convert(cmd));
            }
            return((DatanodeProtocolProtos.BlockReportResponseProto)builder.Build());
        }
        public virtual void TestDatanodeDetect()
        {
            AtomicReference <DatanodeProtocolProtos.BlockReportRequestProto> request = new AtomicReference
                                                                                       <DatanodeProtocolProtos.BlockReportRequestProto>();
            // just capture the outgoing PB
            DatanodeProtocolPB mockProxy = Org.Mockito.Mockito.Mock <DatanodeProtocolPB>();

            Org.Mockito.Mockito.DoAnswer(new _Answer_205(request)).When(mockProxy).BlockReport
                (Matchers.Any <RpcController>(), Matchers.Any <DatanodeProtocolProtos.BlockReportRequestProto
                                                               >());
            DatanodeProtocolClientSideTranslatorPB nn = new DatanodeProtocolClientSideTranslatorPB
                                                            (mockProxy);
            DatanodeRegistration reg    = DFSTestUtil.GetLocalDatanodeRegistration();
            NamespaceInfo        nsInfo = new NamespaceInfo(1, "cluster", "bp", 1);

            reg.SetNamespaceInfo(nsInfo);
            Replica          r       = new FinalizedReplica(new Block(1, 2, 3), null, null);
            BlockListAsLongs bbl     = BlockListAsLongs.Encode(Sharpen.Collections.Singleton(r));
            DatanodeStorage  storage = new DatanodeStorage("s1");

            StorageBlockReport[] sbr = new StorageBlockReport[] { new StorageBlockReport(storage
                                                                                         , bbl) };
            // check DN sends new-style BR
            request.Set(null);
            nsInfo.SetCapabilities(NamespaceInfo.Capability.StorageBlockReportBuffers.GetMask
                                       ());
            nn.BlockReport(reg, "pool", sbr, new BlockReportContext(1, 0, Runtime.NanoTime())
                           );
            DatanodeProtocolProtos.BlockReportRequestProto proto = request.Get();
            NUnit.Framework.Assert.IsNotNull(proto);
            NUnit.Framework.Assert.IsTrue(proto.GetReports(0).GetBlocksList().IsEmpty());
            NUnit.Framework.Assert.IsFalse(proto.GetReports(0).GetBlocksBuffersList().IsEmpty
                                               ());
            // back up to prior version and check DN sends old-style BR
            request.Set(null);
            nsInfo.SetCapabilities(NamespaceInfo.Capability.Unknown.GetMask());
            nn.BlockReport(reg, "pool", sbr, new BlockReportContext(1, 0, Runtime.NanoTime())
                           );
            proto = request.Get();
            NUnit.Framework.Assert.IsNotNull(proto);
            NUnit.Framework.Assert.IsFalse(proto.GetReports(0).GetBlocksList().IsEmpty());
            NUnit.Framework.Assert.IsTrue(proto.GetReports(0).GetBlocksBuffersList().IsEmpty(
                                              ));
        }
Exemple #7
0
        public virtual void TestVolumeFailure()
        {
            System.Console.Out.WriteLine("Data dir: is " + dataDir.GetPath());
            // Data dir structure is dataDir/data[1-4]/[current,tmp...]
            // data1,2 is for datanode 1, data2,3 - datanode2
            string filename = "/test.txt";
            Path   filePath = new Path(filename);
            // we use only small number of blocks to avoid creating subdirs in the data dir..
            int filesize = block_size * blocks_num;

            DFSTestUtil.CreateFile(fs, filePath, filesize, repl, 1L);
            DFSTestUtil.WaitReplication(fs, filePath, repl);
            System.Console.Out.WriteLine("file " + filename + "(size " + filesize + ") is created and replicated"
                                         );
            // fail the volume
            // delete/make non-writable one of the directories (failed volume)
            data_fail = new FilePath(dataDir, "data3");
            failedDir = MiniDFSCluster.GetFinalizedDir(dataDir, cluster.GetNamesystem().GetBlockPoolId
                                                           ());
            if (failedDir.Exists() && !DeteteBlocks(failedDir))
            {
                //!FileUtil.fullyDelete(failedDir)
                throw new IOException("Could not delete hdfs directory '" + failedDir + "'");
            }
            data_fail.SetReadOnly();
            failedDir.SetReadOnly();
            System.Console.Out.WriteLine("Deleteing " + failedDir.GetPath() + "; exist=" + failedDir
                                         .Exists());
            // access all the blocks on the "failed" DataNode,
            // we need to make sure that the "failed" volume is being accessed -
            // and that will cause failure, blocks removal, "emergency" block report
            TriggerFailure(filename, filesize);
            // make sure a block report is sent
            DataNode dn = cluster.GetDataNodes()[1];
            //corresponds to dir data3
            string bpid = cluster.GetNamesystem().GetBlockPoolId();
            DatanodeRegistration dnR = dn.GetDNRegistrationForBP(bpid);
            IDictionary <DatanodeStorage, BlockListAsLongs> perVolumeBlockLists = dn.GetFSDataset
                                                                                      ().GetBlockReports(bpid);

            // Send block report
            StorageBlockReport[] reports = new StorageBlockReport[perVolumeBlockLists.Count];
            int reportIndex = 0;

            foreach (KeyValuePair <DatanodeStorage, BlockListAsLongs> kvPair in perVolumeBlockLists)
            {
                DatanodeStorage  dnStorage = kvPair.Key;
                BlockListAsLongs blockList = kvPair.Value;
                reports[reportIndex++] = new StorageBlockReport(dnStorage, blockList);
            }
            cluster.GetNameNodeRpc().BlockReport(dnR, bpid, reports, null);
            // verify number of blocks and files...
            Verify(filename, filesize);
            // create another file (with one volume failed).
            System.Console.Out.WriteLine("creating file test1.txt");
            Path fileName1 = new Path("/test1.txt");

            DFSTestUtil.CreateFile(fs, fileName1, filesize, repl, 1L);
            // should be able to replicate to both nodes (2 DN, repl=2)
            DFSTestUtil.WaitReplication(fs, fileName1, repl);
            System.Console.Out.WriteLine("file " + fileName1.GetName() + " is created and replicated"
                                         );
        }