Esempio n. 1
0
        /// <summary>Test the fsimage saving/loading while file appending.</summary>
        /// <exception cref="System.Exception"/>
        public virtual void TestSaveLoadImageWithAppending()
        {
            Path sub1      = new Path(dir, "sub1");
            Path sub1file1 = new Path(sub1, "sub1file1");
            Path sub1file2 = new Path(sub1, "sub1file2");

            DFSTestUtil.CreateFile(hdfs, sub1file1, Blocksize, Replication, seed);
            DFSTestUtil.CreateFile(hdfs, sub1file2, Blocksize, Replication, seed);
            // 1. create snapshot s0
            hdfs.AllowSnapshot(dir);
            hdfs.CreateSnapshot(dir, "s0");
            // 2. create snapshot s1 before appending sub1file1 finishes
            HdfsDataOutputStream @out = AppendFileWithoutClosing(sub1file1, Blocksize);

            @out.Hsync(EnumSet.Of(HdfsDataOutputStream.SyncFlag.UpdateLength));
            // also append sub1file2
            DFSTestUtil.AppendFile(hdfs, sub1file2, Blocksize);
            hdfs.CreateSnapshot(dir, "s1");
            @out.Close();
            // 3. create snapshot s2 before appending finishes
            @out = AppendFileWithoutClosing(sub1file1, Blocksize);
            @out.Hsync(EnumSet.Of(HdfsDataOutputStream.SyncFlag.UpdateLength));
            hdfs.CreateSnapshot(dir, "s2");
            @out.Close();
            // 4. save fsimage before appending finishes
            @out = AppendFileWithoutClosing(sub1file1, Blocksize);
            @out.Hsync(EnumSet.Of(HdfsDataOutputStream.SyncFlag.UpdateLength));
            // dump fsdir
            FilePath fsnBefore = DumpTree2File("before");
            // save the namesystem to a temp file
            FilePath imageFile = SaveFSImageToTempFile();

            // 5. load fsimage and compare
            // first restart the cluster, and format the cluster
            @out.Close();
            cluster.Shutdown();
            cluster = new MiniDFSCluster.Builder(conf).Format(true).NumDataNodes(Replication)
                      .Build();
            cluster.WaitActive();
            fsn  = cluster.GetNamesystem();
            hdfs = cluster.GetFileSystem();
            // then load the fsimage
            LoadFSImageFromTempFile(imageFile);
            // dump the fsdir tree again
            FilePath fsnAfter = DumpTree2File("after");

            // compare two dumped tree
            SnapshotTestHelper.CompareDumpedTreeInFile(fsnBefore, fsnAfter, true);
        }
        /// <summary>
        /// Test snapshot during file appending, before the corresponding
        /// <see cref="Org.Apache.Hadoop.FS.FSDataOutputStream"/>
        /// instance closes.
        /// </summary>
        /// <exception cref="System.Exception"/>
        public virtual void TestSnapshotWhileAppending()
        {
            Path file = new Path(dir, "file");

            DFSTestUtil.CreateFile(hdfs, file, Blocksize, Replication, seed);
            // 1. append without closing stream --> create snapshot
            HdfsDataOutputStream @out = AppendFileWithoutClosing(file, Blocksize);

            @out.Hsync(EnumSet.Of(HdfsDataOutputStream.SyncFlag.UpdateLength));
            SnapshotTestHelper.CreateSnapshot(hdfs, dir, "s0");
            @out.Close();
            // check: an INodeFileUnderConstructionWithSnapshot should be stored into s0's
            // deleted list, with size BLOCKSIZE*2
            INodeFile fileNode = (INodeFile)fsdir.GetINode(file.ToString());

            NUnit.Framework.Assert.AreEqual(Blocksize * 2, fileNode.ComputeFileSize());
            INodeDirectory dirNode = fsdir.GetINode(dir.ToString()).AsDirectory();

            DirectoryWithSnapshotFeature.DirectoryDiff last = dirNode.GetDiffs().GetLast();
            // 2. append without closing stream
            @out = AppendFileWithoutClosing(file, Blocksize);
            @out.Hsync(EnumSet.Of(HdfsDataOutputStream.SyncFlag.UpdateLength));
            // re-check nodeInDeleted_S0
            dirNode = fsdir.GetINode(dir.ToString()).AsDirectory();
            NUnit.Framework.Assert.AreEqual(Blocksize * 2, fileNode.ComputeFileSize(last.GetSnapshotId
                                                                                        ()));
            // 3. take snapshot --> close stream
            hdfs.CreateSnapshot(dir, "s1");
            @out.Close();
            // check: an INodeFileUnderConstructionWithSnapshot with size BLOCKSIZE*3 should
            // have been stored in s1's deleted list
            fileNode = (INodeFile)fsdir.GetINode(file.ToString());
            dirNode  = fsdir.GetINode(dir.ToString()).AsDirectory();
            last     = dirNode.GetDiffs().GetLast();
            NUnit.Framework.Assert.IsTrue(fileNode.IsWithSnapshot());
            NUnit.Framework.Assert.AreEqual(Blocksize * 3, fileNode.ComputeFileSize(last.GetSnapshotId
                                                                                        ()));
            // 4. modify file --> append without closing stream --> take snapshot -->
            // close stream
            hdfs.SetReplication(file, (short)(Replication - 1));
            @out = AppendFileWithoutClosing(file, Blocksize);
            hdfs.CreateSnapshot(dir, "s2");
            @out.Close();
            // re-check the size of nodeInDeleted_S1
            NUnit.Framework.Assert.AreEqual(Blocksize * 3, fileNode.ComputeFileSize(last.GetSnapshotId
                                                                                        ()));
        }
        public virtual void TestGetBlockLocations()
        {
            Path root = new Path("/");
            Path file = new Path("/file");

            DFSTestUtil.CreateFile(hdfs, file, Blocksize, Replication, seed);
            // take a snapshot on root
            SnapshotTestHelper.CreateSnapshot(hdfs, root, "s1");
            Path fileInSnapshot = SnapshotTestHelper.GetSnapshotPath(root, "s1", file.GetName
                                                                         ());
            FileStatus status = hdfs.GetFileStatus(fileInSnapshot);

            // make sure we record the size for the file
            NUnit.Framework.Assert.AreEqual(Blocksize, status.GetLen());
            // append data to file
            DFSTestUtil.AppendFile(hdfs, file, Blocksize - 1);
            status = hdfs.GetFileStatus(fileInSnapshot);
            // the size of snapshot file should still be BLOCKSIZE
            NUnit.Framework.Assert.AreEqual(Blocksize, status.GetLen());
            // the size of the file should be (2 * BLOCKSIZE - 1)
            status = hdfs.GetFileStatus(file);
            NUnit.Framework.Assert.AreEqual(Blocksize * 2 - 1, status.GetLen());
            // call DFSClient#callGetBlockLocations for the file in snapshot
            LocatedBlocks blocks = DFSClientAdapter.CallGetBlockLocations(cluster.GetNameNodeRpc
                                                                              (), fileInSnapshot.ToString(), 0, long.MaxValue);
            IList <LocatedBlock> blockList = blocks.GetLocatedBlocks();

            // should be only one block
            NUnit.Framework.Assert.AreEqual(Blocksize, blocks.GetFileLength());
            NUnit.Framework.Assert.AreEqual(1, blockList.Count);
            // check the last block
            LocatedBlock lastBlock = blocks.GetLastLocatedBlock();

            NUnit.Framework.Assert.AreEqual(0, lastBlock.GetStartOffset());
            NUnit.Framework.Assert.AreEqual(Blocksize, lastBlock.GetBlockSize());
            // take another snapshot
            SnapshotTestHelper.CreateSnapshot(hdfs, root, "s2");
            Path fileInSnapshot2 = SnapshotTestHelper.GetSnapshotPath(root, "s2", file.GetName
                                                                          ());
            // append data to file without closing
            HdfsDataOutputStream @out = AppendFileWithoutClosing(file, Blocksize);

            @out.Hsync(EnumSet.Of(HdfsDataOutputStream.SyncFlag.UpdateLength));
            status = hdfs.GetFileStatus(fileInSnapshot2);
            // the size of snapshot file should be BLOCKSIZE*2-1
            NUnit.Framework.Assert.AreEqual(Blocksize * 2 - 1, status.GetLen());
            // the size of the file should be (3 * BLOCKSIZE - 1)
            status = hdfs.GetFileStatus(file);
            NUnit.Framework.Assert.AreEqual(Blocksize * 3 - 1, status.GetLen());
            blocks = DFSClientAdapter.CallGetBlockLocations(cluster.GetNameNodeRpc(), fileInSnapshot2
                                                            .ToString(), 0, long.MaxValue);
            NUnit.Framework.Assert.IsFalse(blocks.IsUnderConstruction());
            NUnit.Framework.Assert.IsTrue(blocks.IsLastBlockComplete());
            blockList = blocks.GetLocatedBlocks();
            // should be 2 blocks
            NUnit.Framework.Assert.AreEqual(Blocksize * 2 - 1, blocks.GetFileLength());
            NUnit.Framework.Assert.AreEqual(2, blockList.Count);
            // check the last block
            lastBlock = blocks.GetLastLocatedBlock();
            NUnit.Framework.Assert.AreEqual(Blocksize, lastBlock.GetStartOffset());
            NUnit.Framework.Assert.AreEqual(Blocksize, lastBlock.GetBlockSize());
            blocks = DFSClientAdapter.CallGetBlockLocations(cluster.GetNameNodeRpc(), fileInSnapshot2
                                                            .ToString(), Blocksize, 0);
            blockList = blocks.GetLocatedBlocks();
            NUnit.Framework.Assert.AreEqual(1, blockList.Count);
            // check blocks for file being written
            blocks = DFSClientAdapter.CallGetBlockLocations(cluster.GetNameNodeRpc(), file.ToString
                                                                (), 0, long.MaxValue);
            blockList = blocks.GetLocatedBlocks();
            NUnit.Framework.Assert.AreEqual(3, blockList.Count);
            NUnit.Framework.Assert.IsTrue(blocks.IsUnderConstruction());
            NUnit.Framework.Assert.IsFalse(blocks.IsLastBlockComplete());
            lastBlock = blocks.GetLastLocatedBlock();
            NUnit.Framework.Assert.AreEqual(Blocksize * 2, lastBlock.GetStartOffset());
            NUnit.Framework.Assert.AreEqual(Blocksize - 1, lastBlock.GetBlockSize());
            @out.Close();
        }
Esempio n. 4
0
        /// <exception cref="System.IO.IOException"/>
        internal virtual void HandleWrite(DFSClient dfsClient, WRITE3Request request, Org.Jboss.Netty.Channel.Channel
                                          channel, int xid, Nfs3FileAttributes preOpAttr)
        {
            int count = request.GetCount();

            byte[] data = ((byte[])request.GetData().Array());
            if (data.Length < count)
            {
                WRITE3Response response = new WRITE3Response(Nfs3Status.Nfs3errInval);
                Nfs3Utils.WriteChannel(channel, response.Serialize(new XDR(), xid, new VerifierNone
                                                                       ()), xid);
                return;
            }
            FileHandle handle = request.GetHandle();

            if (Log.IsDebugEnabled())
            {
                Log.Debug("handleWrite " + request);
            }
            // Check if there is a stream to write
            FileHandle  fileHandle  = request.GetHandle();
            OpenFileCtx openFileCtx = fileContextCache.Get(fileHandle);

            if (openFileCtx == null)
            {
                Log.Info("No opened stream for fileId: " + fileHandle.GetFileId());
                string fileIdPath               = Nfs3Utils.GetFileIdPath(fileHandle.GetFileId());
                HdfsDataOutputStream fos        = null;
                Nfs3FileAttributes   latestAttr = null;
                try
                {
                    int bufferSize = config.GetInt(CommonConfigurationKeysPublic.IoFileBufferSizeKey,
                                                   CommonConfigurationKeysPublic.IoFileBufferSizeDefault);
                    fos = dfsClient.Append(fileIdPath, bufferSize, EnumSet.Of(CreateFlag.Append), null
                                           , null);
                    latestAttr = Nfs3Utils.GetFileAttr(dfsClient, fileIdPath, iug);
                }
                catch (RemoteException e)
                {
                    IOException io = e.UnwrapRemoteException();
                    if (io is AlreadyBeingCreatedException)
                    {
                        Log.Warn("Can't append file: " + fileIdPath + ". Possibly the file is being closed. Drop the request: "
                                 + request + ", wait for the client to retry...");
                        return;
                    }
                    throw;
                }
                catch (IOException e)
                {
                    Log.Error("Can't append to file: " + fileIdPath, e);
                    if (fos != null)
                    {
                        fos.Close();
                    }
                    WccData        fileWcc  = new WccData(Nfs3Utils.GetWccAttr(preOpAttr), preOpAttr);
                    WRITE3Response response = new WRITE3Response(Nfs3Status.Nfs3errIo, fileWcc, count
                                                                 , request.GetStableHow(), Nfs3Constant.WriteCommitVerf);
                    Nfs3Utils.WriteChannel(channel, response.Serialize(new XDR(), xid, new VerifierNone
                                                                           ()), xid);
                    return;
                }
                // Add open stream
                string writeDumpDir = config.Get(NfsConfigKeys.DfsNfsFileDumpDirKey, NfsConfigKeys
                                                 .DfsNfsFileDumpDirDefault);
                openFileCtx = new OpenFileCtx(fos, latestAttr, writeDumpDir + "/" + fileHandle.GetFileId
                                                  (), dfsClient, iug, aixCompatMode, config);
                if (!AddOpenFileStream(fileHandle, openFileCtx))
                {
                    Log.Info("Can't add new stream. Close it. Tell client to retry.");
                    try
                    {
                        fos.Close();
                    }
                    catch (IOException e)
                    {
                        Log.Error("Can't close stream for fileId: " + handle.GetFileId(), e);
                    }
                    // Notify client to retry
                    WccData        fileWcc  = new WccData(latestAttr.GetWccAttr(), latestAttr);
                    WRITE3Response response = new WRITE3Response(Nfs3Status.Nfs3errJukebox, fileWcc,
                                                                 0, request.GetStableHow(), Nfs3Constant.WriteCommitVerf);
                    Nfs3Utils.WriteChannel(channel, response.Serialize(new XDR(), xid, new VerifierNone
                                                                           ()), xid);
                    return;
                }
                if (Log.IsDebugEnabled())
                {
                    Log.Debug("Opened stream for appending file: " + fileHandle.GetFileId());
                }
            }
            // Add write into the async job queue
            openFileCtx.ReceivedNewWrite(dfsClient, request, channel, xid, asyncDataService,
                                         iug);
            return;
        }