public virtual void TestCheckSequential() { DFSClient dfsClient = Org.Mockito.Mockito.Mock <DFSClient>(); Nfs3FileAttributes attr = new Nfs3FileAttributes(); HdfsDataOutputStream fos = Org.Mockito.Mockito.Mock <HdfsDataOutputStream>(); Org.Mockito.Mockito.When(fos.GetPos()).ThenReturn((long)0); NfsConfiguration config = new NfsConfiguration(); config.SetBoolean(NfsConfigKeys.LargeFileUpload, false); OpenFileCtx ctx = new OpenFileCtx(fos, attr, "/dumpFilePath", dfsClient, new ShellBasedIdMapping (config), false, config); ctx.GetPendingWritesForTest()[new OffsetRange(5, 10)] = new WriteCtx(null, 0, 0, 0, null, null, null, 0, false, null); ctx.GetPendingWritesForTest()[new OffsetRange(10, 15)] = new WriteCtx(null, 0, 0, 0, null, null, null, 0, false, null); ctx.GetPendingWritesForTest()[new OffsetRange(20, 25)] = new WriteCtx(null, 0, 0, 0, null, null, null, 0, false, null); NUnit.Framework.Assert.IsTrue(!ctx.CheckSequential(5, 4)); NUnit.Framework.Assert.IsTrue(ctx.CheckSequential(9, 5)); NUnit.Framework.Assert.IsTrue(ctx.CheckSequential(10, 5)); NUnit.Framework.Assert.IsTrue(ctx.CheckSequential(14, 5)); NUnit.Framework.Assert.IsTrue(!ctx.CheckSequential(15, 5)); NUnit.Framework.Assert.IsTrue(!ctx.CheckSequential(20, 5)); NUnit.Framework.Assert.IsTrue(!ctx.CheckSequential(25, 5)); NUnit.Framework.Assert.IsTrue(!ctx.CheckSequential(999, 5)); }
// Evict all entries internal virtual void CleanAll() { AList <OpenFileCtx> cleanedContext = new AList <OpenFileCtx>(); lock (this) { IEnumerator <KeyValuePair <FileHandle, OpenFileCtx> > it = openFileMap.GetEnumerator (); if (Log.IsTraceEnabled()) { Log.Trace("openFileMap size:" + openFileMap.Count); } while (it.HasNext()) { KeyValuePair <FileHandle, OpenFileCtx> pairs = it.Next(); OpenFileCtx ctx = pairs.Value; it.Remove(); cleanedContext.AddItem(ctx); } } // Invoke the cleanup outside the lock foreach (OpenFileCtx ofc in cleanedContext) { ofc.Cleanup(); } }
// Do a possible commit before read request in case there is buffered data // inside DFSClient which has been flushed but not synced. internal virtual int CommitBeforeRead(DFSClient dfsClient, FileHandle fileHandle, long commitOffset) { int status; OpenFileCtx openFileCtx = fileContextCache.Get(fileHandle); if (openFileCtx == null) { if (Log.IsDebugEnabled()) { Log.Debug("No opened stream for fileId: " + fileHandle.GetFileId() + " commitOffset=" + commitOffset + ". Return success in this case."); } status = Nfs3Status.Nfs3Ok; } else { // commit request triggered by read won't create pending comment obj OpenFileCtx.COMMIT_STATUS ret = openFileCtx.CheckCommit(dfsClient, commitOffset, null, 0, null, true); switch (ret) { case OpenFileCtx.COMMIT_STATUS.CommitFinished: case OpenFileCtx.COMMIT_STATUS.CommitInactiveCtx: { status = Nfs3Status.Nfs3Ok; break; } case OpenFileCtx.COMMIT_STATUS.CommitInactiveWithPendingWrite: case OpenFileCtx.COMMIT_STATUS.CommitError: { status = Nfs3Status.Nfs3errIo; break; } case OpenFileCtx.COMMIT_STATUS.CommitWait: case OpenFileCtx.COMMIT_STATUS.CommitSpecialWait: { status = Nfs3Status.Nfs3errJukebox; break; } case OpenFileCtx.COMMIT_STATUS.CommitSpecialSuccess: { // Read beyond eof could result in partial read status = Nfs3Status.Nfs3Ok; break; } default: { Log.Error("Should not get commit return code: " + ret.ToString()); throw new RuntimeException("Should not get commit return code: " + ret.ToString() ); } } } return(status); }
public virtual void TestCheckCommitAixCompatMode() { DFSClient dfsClient = Org.Mockito.Mockito.Mock <DFSClient>(); Nfs3FileAttributes attr = new Nfs3FileAttributes(); HdfsDataOutputStream fos = Org.Mockito.Mockito.Mock <HdfsDataOutputStream>(); NfsConfiguration conf = new NfsConfiguration(); conf.SetBoolean(NfsConfigKeys.LargeFileUpload, false); // Enable AIX compatibility mode. OpenFileCtx ctx = new OpenFileCtx(fos, attr, "/dumpFilePath", dfsClient, new ShellBasedIdMapping (new NfsConfiguration()), true, conf); // Test fall-through to pendingWrites check in the event that commitOffset // is greater than the number of bytes we've so far flushed. Org.Mockito.Mockito.When(fos.GetPos()).ThenReturn((long)2); OpenFileCtx.COMMIT_STATUS status = ctx.CheckCommitInternal(5, null, 1, attr, false ); NUnit.Framework.Assert.IsTrue(status == OpenFileCtx.COMMIT_STATUS.CommitFinished); // Test the case when we actually have received more bytes than we're trying // to commit. ctx.GetPendingWritesForTest()[new OffsetRange(0, 10)] = new WriteCtx(null, 0, 0, 0, null, null, null, 0, false, null); Org.Mockito.Mockito.When(fos.GetPos()).ThenReturn((long)10); ctx.SetNextOffsetForTest((long)10); status = ctx.CheckCommitInternal(5, null, 1, attr, false); NUnit.Framework.Assert.IsTrue(status == OpenFileCtx.COMMIT_STATUS.CommitDoSync); }
internal virtual bool Put(FileHandle h, OpenFileCtx context) { OpenFileCtx toEvict = null; lock (this) { Preconditions.CheckState(openFileMap.Count <= this.maxStreams, "stream cache size " + openFileMap.Count + " is larger than maximum" + this.maxStreams); if (openFileMap.Count == this.maxStreams) { KeyValuePair <FileHandle, OpenFileCtx> pairs = GetEntryToEvict(); if (pairs == null) { return(false); } else { if (Log.IsDebugEnabled()) { Log.Debug("Evict stream ctx: " + pairs.Value); } toEvict = Sharpen.Collections.Remove(openFileMap, pairs.Key); Preconditions.CheckState(toEvict == pairs.Value, "The deleted entry is not the same as odlest found." ); } } openFileMap[h] = context; } // Cleanup the old stream outside the lock if (toEvict != null) { toEvict.Cleanup(); } return(true); }
/// <summary>Write the data to HDFS asynchronously</summary> internal virtual void WriteAsync(OpenFileCtx openFileCtx) { if (Log.IsDebugEnabled()) { Log.Debug("Scheduling write back task for fileId: " + openFileCtx.GetLatestAttr() .GetFileId()); } AsyncDataService.WriteBackTask wbTask = new AsyncDataService.WriteBackTask(openFileCtx ); Execute(wbTask); }
public virtual void TestEviction() { NfsConfiguration conf = new NfsConfiguration(); // Only two entries will be in the cache conf.SetInt(NfsConfigKeys.DfsNfsMaxOpenFilesKey, 2); DFSClient dfsClient = Org.Mockito.Mockito.Mock <DFSClient>(); Nfs3FileAttributes attr = new Nfs3FileAttributes(); HdfsDataOutputStream fos = Org.Mockito.Mockito.Mock <HdfsDataOutputStream>(); Org.Mockito.Mockito.When(fos.GetPos()).ThenReturn((long)0); OpenFileCtx context1 = new OpenFileCtx(fos, attr, "/dumpFilePath", dfsClient, new ShellBasedIdMapping(new NfsConfiguration())); OpenFileCtx context2 = new OpenFileCtx(fos, attr, "/dumpFilePath", dfsClient, new ShellBasedIdMapping(new NfsConfiguration())); OpenFileCtx context3 = new OpenFileCtx(fos, attr, "/dumpFilePath", dfsClient, new ShellBasedIdMapping(new NfsConfiguration())); OpenFileCtx context4 = new OpenFileCtx(fos, attr, "/dumpFilePath", dfsClient, new ShellBasedIdMapping(new NfsConfiguration())); OpenFileCtx context5 = new OpenFileCtx(fos, attr, "/dumpFilePath", dfsClient, new ShellBasedIdMapping(new NfsConfiguration())); OpenFileCtxCache cache = new OpenFileCtxCache(conf, 10 * 60 * 100); bool ret = cache.Put(new FileHandle(1), context1); NUnit.Framework.Assert.IsTrue(ret); Sharpen.Thread.Sleep(1000); ret = cache.Put(new FileHandle(2), context2); NUnit.Framework.Assert.IsTrue(ret); ret = cache.Put(new FileHandle(3), context3); NUnit.Framework.Assert.IsFalse(ret); NUnit.Framework.Assert.IsTrue(cache.Size() == 2); // Wait for the oldest stream to be evict-able, insert again Sharpen.Thread.Sleep(NfsConfigKeys.DfsNfsStreamTimeoutMinDefault); NUnit.Framework.Assert.IsTrue(cache.Size() == 2); ret = cache.Put(new FileHandle(3), context3); NUnit.Framework.Assert.IsTrue(ret); NUnit.Framework.Assert.IsTrue(cache.Size() == 2); NUnit.Framework.Assert.IsTrue(cache.Get(new FileHandle(1)) == null); // Test inactive entry is evicted immediately context3.SetActiveStatusForTest(false); ret = cache.Put(new FileHandle(4), context4); NUnit.Framework.Assert.IsTrue(ret); // Now the cache has context2 and context4 // Test eviction failure if all entries have pending work. context2.GetPendingWritesForTest()[new OffsetRange(0, 100)] = new WriteCtx(null, 0, 0, 0, null, null, null, 0, false, null); context4.GetPendingCommitsForTest()[System.Convert.ToInt64(100)] = new OpenFileCtx.CommitCtx (0, null, 0, attr); Sharpen.Thread.Sleep(NfsConfigKeys.DfsNfsStreamTimeoutMinDefault); ret = cache.Put(new FileHandle(5), context5); NUnit.Framework.Assert.IsFalse(ret); }
/// <exception cref="System.Exception"/> private void WaitWrite(RpcProgramNfs3 nfsd, FileHandle handle, int maxWaitTime) { int waitedTime = 0; OpenFileCtx ctx = nfsd.GetWriteManager().GetOpenFileCtxCache().Get(handle); NUnit.Framework.Assert.IsTrue(ctx != null); do { Sharpen.Thread.Sleep(3000); waitedTime += 3000; if (ctx.GetPendingWritesForTest().Count == 0) { return; } }while (waitedTime < maxWaitTime); NUnit.Framework.Assert.Fail("Write can't finish."); }
/// <exception cref="System.IO.IOException"/> internal virtual Nfs3FileAttributes GetFileAttr(DFSClient client, FileHandle dirHandle , string fileName) { string fileIdPath = Nfs3Utils.GetFileIdPath(dirHandle) + "/" + fileName; Nfs3FileAttributes attr = Nfs3Utils.GetFileAttr(client, fileIdPath, iug); if ((attr != null) && (attr.GetType() == NfsFileType.Nfsreg.ToValue())) { OpenFileCtx openFileCtx = fileContextCache.Get(new FileHandle(attr.GetFileId())); if (openFileCtx != null) { attr.SetSize(openFileCtx.GetNextOffset()); attr.SetUsed(openFileCtx.GetNextOffset()); } } return(attr); }
/// <summary>If the file is in cache, update the size based on the cached data size</summary> /// <exception cref="System.IO.IOException"/> internal virtual Nfs3FileAttributes GetFileAttr(DFSClient client, FileHandle fileHandle , IdMappingServiceProvider iug) { string fileIdPath = Nfs3Utils.GetFileIdPath(fileHandle); Nfs3FileAttributes attr = Nfs3Utils.GetFileAttr(client, fileIdPath, iug); if (attr != null) { OpenFileCtx openFileCtx = fileContextCache.Get(fileHandle); if (openFileCtx != null) { attr.SetSize(openFileCtx.GetNextOffset()); attr.SetUsed(openFileCtx.GetNextOffset()); } } return(attr); }
internal virtual void Scan(long streamTimeout) { AList <OpenFileCtx> ctxToRemove = new AList <OpenFileCtx>(); IEnumerator <KeyValuePair <FileHandle, OpenFileCtx> > it = openFileMap.GetEnumerator (); if (Log.IsTraceEnabled()) { Log.Trace("openFileMap size:" + openFileMap.Count); } while (it.HasNext()) { KeyValuePair <FileHandle, OpenFileCtx> pairs = it.Next(); FileHandle handle = pairs.Key; OpenFileCtx ctx = pairs.Value; if (!ctx.StreamCleanup(handle.GetFileId(), streamTimeout)) { continue; } // Check it again inside lock before removing lock (this) { OpenFileCtx ctx2 = openFileMap[handle]; if (ctx2 != null) { if (ctx2.StreamCleanup(handle.GetFileId(), streamTimeout)) { Sharpen.Collections.Remove(openFileMap, handle); if (Log.IsDebugEnabled()) { Log.Debug("After remove stream " + handle.GetFileId() + ", the stream number:" + openFileMap.Count); } ctxToRemove.AddItem(ctx2); } } } } // Invoke the cleanup outside the lock foreach (OpenFileCtx ofc in ctxToRemove) { ofc.Cleanup(); } }
public virtual void TestScan() { NfsConfiguration conf = new NfsConfiguration(); // Only two entries will be in the cache conf.SetInt(NfsConfigKeys.DfsNfsMaxOpenFilesKey, 2); DFSClient dfsClient = Org.Mockito.Mockito.Mock <DFSClient>(); Nfs3FileAttributes attr = new Nfs3FileAttributes(); HdfsDataOutputStream fos = Org.Mockito.Mockito.Mock <HdfsDataOutputStream>(); Org.Mockito.Mockito.When(fos.GetPos()).ThenReturn((long)0); OpenFileCtx context1 = new OpenFileCtx(fos, attr, "/dumpFilePath", dfsClient, new ShellBasedIdMapping(new NfsConfiguration())); OpenFileCtx context2 = new OpenFileCtx(fos, attr, "/dumpFilePath", dfsClient, new ShellBasedIdMapping(new NfsConfiguration())); OpenFileCtx context3 = new OpenFileCtx(fos, attr, "/dumpFilePath", dfsClient, new ShellBasedIdMapping(new NfsConfiguration())); OpenFileCtx context4 = new OpenFileCtx(fos, attr, "/dumpFilePath", dfsClient, new ShellBasedIdMapping(new NfsConfiguration())); OpenFileCtxCache cache = new OpenFileCtxCache(conf, 10 * 60 * 100); // Test cleaning expired entry bool ret = cache.Put(new FileHandle(1), context1); NUnit.Framework.Assert.IsTrue(ret); ret = cache.Put(new FileHandle(2), context2); NUnit.Framework.Assert.IsTrue(ret); Sharpen.Thread.Sleep(NfsConfigKeys.DfsNfsStreamTimeoutMinDefault + 1); cache.Scan(NfsConfigKeys.DfsNfsStreamTimeoutMinDefault); NUnit.Framework.Assert.IsTrue(cache.Size() == 0); // Test cleaning inactive entry ret = cache.Put(new FileHandle(3), context3); NUnit.Framework.Assert.IsTrue(ret); ret = cache.Put(new FileHandle(4), context4); NUnit.Framework.Assert.IsTrue(ret); context3.SetActiveStatusForTest(false); cache.Scan(NfsConfigKeys.DfsNfsStreamTimeoutDefault); NUnit.Framework.Assert.IsTrue(cache.Size() == 1); NUnit.Framework.Assert.IsTrue(cache.Get(new FileHandle(3)) == null); NUnit.Framework.Assert.IsTrue(cache.Get(new FileHandle(4)) != null); }
internal virtual void HandleCommit(DFSClient dfsClient, FileHandle fileHandle, long commitOffset, Org.Jboss.Netty.Channel.Channel channel, int xid, Nfs3FileAttributes preOpAttr) { long startTime = Runtime.NanoTime(); int status; OpenFileCtx openFileCtx = fileContextCache.Get(fileHandle); if (openFileCtx == null) { Log.Info("No opened stream for fileId: " + fileHandle.GetFileId() + " commitOffset=" + commitOffset + ". Return success in this case."); status = Nfs3Status.Nfs3Ok; } else { OpenFileCtx.COMMIT_STATUS ret = openFileCtx.CheckCommit(dfsClient, commitOffset, channel, xid, preOpAttr, false); switch (ret) { case OpenFileCtx.COMMIT_STATUS.CommitFinished: case OpenFileCtx.COMMIT_STATUS.CommitInactiveCtx: { status = Nfs3Status.Nfs3Ok; break; } case OpenFileCtx.COMMIT_STATUS.CommitInactiveWithPendingWrite: case OpenFileCtx.COMMIT_STATUS.CommitError: { status = Nfs3Status.Nfs3errIo; break; } case OpenFileCtx.COMMIT_STATUS.CommitWait: { // Do nothing. Commit is async now. return; } case OpenFileCtx.COMMIT_STATUS.CommitSpecialWait: { status = Nfs3Status.Nfs3errJukebox; break; } case OpenFileCtx.COMMIT_STATUS.CommitSpecialSuccess: { status = Nfs3Status.Nfs3Ok; break; } default: { Log.Error("Should not get commit return code: " + ret.ToString()); throw new RuntimeException("Should not get commit return code: " + ret.ToString() ); } } } // Send out the response Nfs3FileAttributes postOpAttr = null; try { postOpAttr = GetFileAttr(dfsClient, new FileHandle(preOpAttr.GetFileId()), iug); } catch (IOException e1) { Log.Info("Can't get postOpAttr for fileId: " + preOpAttr.GetFileId(), e1); } WccData fileWcc = new WccData(Nfs3Utils.GetWccAttr(preOpAttr), postOpAttr); COMMIT3Response response = new COMMIT3Response(status, fileWcc, Nfs3Constant.WriteCommitVerf ); RpcProgramNfs3.metrics.AddCommit(Nfs3Utils.GetElapsedTime(startTime)); Nfs3Utils.WriteChannelCommit(channel, response.Serialize(new XDR(), xid, new VerifierNone ()), xid); }
public virtual void TestCheckCommitFromReadLargeFileUpload() { // Validate all the commit check return codes OpenFileCtx.COMMIT_STATUS with large file upload option DFSClient dfsClient = Org.Mockito.Mockito.Mock <DFSClient>(); Nfs3FileAttributes attr = new Nfs3FileAttributes(); HdfsDataOutputStream fos = Org.Mockito.Mockito.Mock <HdfsDataOutputStream>(); Org.Mockito.Mockito.When(fos.GetPos()).ThenReturn((long)0); NfsConfiguration config = new NfsConfiguration(); config.SetBoolean(NfsConfigKeys.LargeFileUpload, true); OpenFileCtx ctx = new OpenFileCtx(fos, attr, "/dumpFilePath", dfsClient, new ShellBasedIdMapping (config), false, config); FileHandle h = new FileHandle(1); // fake handle for "/dumpFilePath" OpenFileCtx.COMMIT_STATUS ret; WriteManager wm = new WriteManager(new ShellBasedIdMapping(config), config, false ); NUnit.Framework.Assert.IsTrue(wm.AddOpenFileStream(h, ctx)); // Test inactive open file context ctx.SetActiveStatusForTest(false); Org.Jboss.Netty.Channel.Channel ch = Org.Mockito.Mockito.Mock <Org.Jboss.Netty.Channel.Channel >(); ret = ctx.CheckCommit(dfsClient, 0, ch, 1, attr, true); NUnit.Framework.Assert.AreEqual(OpenFileCtx.COMMIT_STATUS.CommitInactiveCtx, ret); NUnit.Framework.Assert.AreEqual(Nfs3Status.Nfs3Ok, wm.CommitBeforeRead(dfsClient, h, 0)); ctx.GetPendingWritesForTest()[new OffsetRange(10, 15)] = new WriteCtx(null, 0, 0, 0, null, null, null, 0, false, null); ret = ctx.CheckCommit(dfsClient, 0, ch, 1, attr, true); NUnit.Framework.Assert.AreEqual(OpenFileCtx.COMMIT_STATUS.CommitInactiveWithPendingWrite , ret); NUnit.Framework.Assert.AreEqual(Nfs3Status.Nfs3errIo, wm.CommitBeforeRead(dfsClient , h, 0)); // Test request with non zero commit offset ctx.SetActiveStatusForTest(true); Org.Mockito.Mockito.When(fos.GetPos()).ThenReturn((long)6); ctx.SetNextOffsetForTest((long)10); OpenFileCtx.COMMIT_STATUS status = ctx.CheckCommitInternal(5, ch, 1, attr, false); NUnit.Framework.Assert.AreEqual(OpenFileCtx.COMMIT_STATUS.CommitDoSync, status); // Do_SYNC state will be updated to FINISHED after data sync ret = ctx.CheckCommit(dfsClient, 5, ch, 1, attr, true); NUnit.Framework.Assert.AreEqual(OpenFileCtx.COMMIT_STATUS.CommitFinished, ret); NUnit.Framework.Assert.AreEqual(Nfs3Status.Nfs3Ok, wm.CommitBeforeRead(dfsClient, h, 5)); // Test request with sequential writes status = ctx.CheckCommitInternal(9, ch, 1, attr, true); NUnit.Framework.Assert.IsTrue(status == OpenFileCtx.COMMIT_STATUS.CommitSpecialWait ); ret = ctx.CheckCommit(dfsClient, 9, ch, 1, attr, true); NUnit.Framework.Assert.AreEqual(OpenFileCtx.COMMIT_STATUS.CommitSpecialWait, ret); NUnit.Framework.Assert.AreEqual(Nfs3Status.Nfs3errJukebox, wm.CommitBeforeRead(dfsClient , h, 9)); // Test request with non-sequential writes ConcurrentNavigableMap <long, OpenFileCtx.CommitCtx> commits = ctx.GetPendingCommitsForTest (); NUnit.Framework.Assert.IsTrue(commits.Count == 0); ret = ctx.CheckCommit(dfsClient, 16, ch, 1, attr, true); NUnit.Framework.Assert.AreEqual(OpenFileCtx.COMMIT_STATUS.CommitSpecialSuccess, ret ); NUnit.Framework.Assert.AreEqual(0, commits.Count); // commit triggered by read doesn't wait NUnit.Framework.Assert.AreEqual(Nfs3Status.Nfs3Ok, wm.CommitBeforeRead(dfsClient, h, 16)); // Test request with zero commit offset // There is one pending write [10,15] ret = ctx.CheckCommit(dfsClient, 0, ch, 1, attr, true); NUnit.Framework.Assert.AreEqual(OpenFileCtx.COMMIT_STATUS.CommitSpecialWait, ret); NUnit.Framework.Assert.AreEqual(0, commits.Count); NUnit.Framework.Assert.AreEqual(Nfs3Status.Nfs3errJukebox, wm.CommitBeforeRead(dfsClient , h, 0)); // Empty pending writes Sharpen.Collections.Remove(ctx.GetPendingWritesForTest(), new OffsetRange(10, 15) ); ret = ctx.CheckCommit(dfsClient, 0, ch, 1, attr, true); NUnit.Framework.Assert.AreEqual(OpenFileCtx.COMMIT_STATUS.CommitSpecialWait, ret); NUnit.Framework.Assert.AreEqual(Nfs3Status.Nfs3errJukebox, wm.CommitBeforeRead(dfsClient , h, 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; }
internal WriteBackTask(OpenFileCtx openFileCtx) { this.openFileCtx = openFileCtx; }
public virtual void TestCheckCommit() { // Validate all the commit check return codes OpenFileCtx.COMMIT_STATUS, which // includes COMMIT_FINISHED, COMMIT_WAIT, COMMIT_INACTIVE_CTX, // COMMIT_INACTIVE_WITH_PENDING_WRITE, COMMIT_ERROR, and COMMIT_DO_SYNC. DFSClient dfsClient = Org.Mockito.Mockito.Mock <DFSClient>(); Nfs3FileAttributes attr = new Nfs3FileAttributes(); HdfsDataOutputStream fos = Org.Mockito.Mockito.Mock <HdfsDataOutputStream>(); Org.Mockito.Mockito.When(fos.GetPos()).ThenReturn((long)0); NfsConfiguration conf = new NfsConfiguration(); conf.SetBoolean(NfsConfigKeys.LargeFileUpload, false); OpenFileCtx ctx = new OpenFileCtx(fos, attr, "/dumpFilePath", dfsClient, new ShellBasedIdMapping (conf), false, conf); OpenFileCtx.COMMIT_STATUS ret; // Test inactive open file context ctx.SetActiveStatusForTest(false); Org.Jboss.Netty.Channel.Channel ch = Org.Mockito.Mockito.Mock <Org.Jboss.Netty.Channel.Channel >(); ret = ctx.CheckCommit(dfsClient, 0, ch, 1, attr, false); NUnit.Framework.Assert.IsTrue(ret == OpenFileCtx.COMMIT_STATUS.CommitInactiveCtx); ctx.GetPendingWritesForTest()[new OffsetRange(5, 10)] = new WriteCtx(null, 0, 0, 0, null, null, null, 0, false, null); ret = ctx.CheckCommit(dfsClient, 0, ch, 1, attr, false); NUnit.Framework.Assert.IsTrue(ret == OpenFileCtx.COMMIT_STATUS.CommitInactiveWithPendingWrite ); // Test request with non zero commit offset ctx.SetActiveStatusForTest(true); Org.Mockito.Mockito.When(fos.GetPos()).ThenReturn((long)10); ctx.SetNextOffsetForTest(10); OpenFileCtx.COMMIT_STATUS status = ctx.CheckCommitInternal(5, null, 1, attr, false ); NUnit.Framework.Assert.IsTrue(status == OpenFileCtx.COMMIT_STATUS.CommitDoSync); // Do_SYNC state will be updated to FINISHED after data sync ret = ctx.CheckCommit(dfsClient, 5, ch, 1, attr, false); NUnit.Framework.Assert.IsTrue(ret == OpenFileCtx.COMMIT_STATUS.CommitFinished); status = ctx.CheckCommitInternal(10, ch, 1, attr, false); NUnit.Framework.Assert.IsTrue(status == OpenFileCtx.COMMIT_STATUS.CommitDoSync); ret = ctx.CheckCommit(dfsClient, 10, ch, 1, attr, false); NUnit.Framework.Assert.IsTrue(ret == OpenFileCtx.COMMIT_STATUS.CommitFinished); ConcurrentNavigableMap <long, OpenFileCtx.CommitCtx> commits = ctx.GetPendingCommitsForTest (); NUnit.Framework.Assert.IsTrue(commits.Count == 0); ret = ctx.CheckCommit(dfsClient, 11, ch, 1, attr, false); NUnit.Framework.Assert.IsTrue(ret == OpenFileCtx.COMMIT_STATUS.CommitWait); NUnit.Framework.Assert.IsTrue(commits.Count == 1); long key = commits.FirstKey(); NUnit.Framework.Assert.IsTrue(key == 11); // Test request with zero commit offset Sharpen.Collections.Remove(commits, System.Convert.ToInt64(11)); // There is one pending write [5,10] ret = ctx.CheckCommit(dfsClient, 0, ch, 1, attr, false); NUnit.Framework.Assert.IsTrue(ret == OpenFileCtx.COMMIT_STATUS.CommitWait); NUnit.Framework.Assert.IsTrue(commits.Count == 1); key = commits.FirstKey(); NUnit.Framework.Assert.IsTrue(key == 9); // Empty pending writes Sharpen.Collections.Remove(ctx.GetPendingWritesForTest(), new OffsetRange(5, 10)); ret = ctx.CheckCommit(dfsClient, 0, ch, 1, attr, false); NUnit.Framework.Assert.IsTrue(ret == OpenFileCtx.COMMIT_STATUS.CommitFinished); }
internal virtual KeyValuePair <FileHandle, OpenFileCtx> GetEntryToEvict() { IEnumerator <KeyValuePair <FileHandle, OpenFileCtx> > it = openFileMap.GetEnumerator (); if (Log.IsTraceEnabled()) { Log.Trace("openFileMap size:" + openFileMap.Count); } KeyValuePair <FileHandle, OpenFileCtx> idlest = null; while (it.HasNext()) { KeyValuePair <FileHandle, OpenFileCtx> pairs = it.Next(); OpenFileCtx ctx = pairs.Value; if (!ctx.GetActiveState()) { if (Log.IsDebugEnabled()) { Log.Debug("Got one inactive stream: " + ctx); } return(pairs); } if (ctx.HasPendingWork()) { // Always skip files with pending work. continue; } if (idlest == null) { idlest = pairs; } else { if (ctx.GetLastAccessTime() < idlest.Value.GetLastAccessTime()) { idlest = pairs; } } } if (idlest == null) { Log.Warn("No eviction candidate. All streams have pending work."); return(null); } else { long idleTime = Time.MonotonicNow() - idlest.Value.GetLastAccessTime(); if (idleTime < NfsConfigKeys.DfsNfsStreamTimeoutMinDefault) { if (Log.IsDebugEnabled()) { Log.Debug("idlest stream's idle time:" + idleTime); } Log.Warn("All opened streams are busy, can't remove any from cache."); return(null); } else { return(idlest); } } }
public virtual void TestAlterWriteRequest() { int len = 20; byte[] data = new byte[len]; ByteBuffer buffer = ByteBuffer.Wrap(data); for (int i = 0; i < len; i++) { buffer.Put(unchecked ((byte)i)); } buffer.Flip(); int originalCount = ((byte[])buffer.Array()).Length; WRITE3Request request = new WRITE3Request(new FileHandle(), 0, data.Length, Nfs3Constant.WriteStableHow .Unstable, buffer); WriteCtx writeCtx1 = new WriteCtx(request.GetHandle(), request.GetOffset(), request .GetCount(), WriteCtx.InvalidOriginalCount, request.GetStableHow(), request.GetData (), null, 1, false, WriteCtx.DataState.NoDump); NUnit.Framework.Assert.IsTrue(((byte[])writeCtx1.GetData().Array()).Length == originalCount ); // Now change the write request OpenFileCtx.AlterWriteRequest(request, 12); WriteCtx writeCtx2 = new WriteCtx(request.GetHandle(), request.GetOffset(), request .GetCount(), originalCount, request.GetStableHow(), request.GetData(), null, 2, false, WriteCtx.DataState.NoDump); ByteBuffer appendedData = writeCtx2.GetData(); int position = appendedData.Position(); int limit = appendedData.Limit(); NUnit.Framework.Assert.IsTrue(position == 12); NUnit.Framework.Assert.IsTrue(limit - position == 8); NUnit.Framework.Assert.IsTrue(appendedData.Get(position) == unchecked ((byte)12)); NUnit.Framework.Assert.IsTrue(appendedData.Get(position + 1) == unchecked ((byte)13 )); NUnit.Framework.Assert.IsTrue(appendedData.Get(position + 2) == unchecked ((byte)14 )); NUnit.Framework.Assert.IsTrue(appendedData.Get(position + 7) == unchecked ((byte)19 )); // Test current file write offset is at boundaries buffer.Position(0); request = new WRITE3Request(new FileHandle(), 0, data.Length, Nfs3Constant.WriteStableHow .Unstable, buffer); OpenFileCtx.AlterWriteRequest(request, 1); WriteCtx writeCtx3 = new WriteCtx(request.GetHandle(), request.GetOffset(), request .GetCount(), originalCount, request.GetStableHow(), request.GetData(), null, 2, false, WriteCtx.DataState.NoDump); appendedData = writeCtx3.GetData(); position = appendedData.Position(); limit = appendedData.Limit(); NUnit.Framework.Assert.IsTrue(position == 1); NUnit.Framework.Assert.IsTrue(limit - position == 19); NUnit.Framework.Assert.IsTrue(appendedData.Get(position) == unchecked ((byte)1)); NUnit.Framework.Assert.IsTrue(appendedData.Get(position + 18) == unchecked ((byte) 19)); // Reset buffer position before test another boundary buffer.Position(0); request = new WRITE3Request(new FileHandle(), 0, data.Length, Nfs3Constant.WriteStableHow .Unstable, buffer); OpenFileCtx.AlterWriteRequest(request, 19); WriteCtx writeCtx4 = new WriteCtx(request.GetHandle(), request.GetOffset(), request .GetCount(), originalCount, request.GetStableHow(), request.GetData(), null, 2, false, WriteCtx.DataState.NoDump); appendedData = writeCtx4.GetData(); position = appendedData.Position(); limit = appendedData.Limit(); NUnit.Framework.Assert.IsTrue(position == 19); NUnit.Framework.Assert.IsTrue(limit - position == 1); NUnit.Framework.Assert.IsTrue(appendedData.Get(position) == unchecked ((byte)19)); }
internal virtual bool AddOpenFileStream(FileHandle h, OpenFileCtx ctx) { return(fileContextCache.Put(h, ctx)); }
public virtual void TestCheckCommitLargeFileUpload() { // Validate all the commit check return codes OpenFileCtx.COMMIT_STATUS with // large file upload option. DFSClient dfsClient = Org.Mockito.Mockito.Mock <DFSClient>(); Nfs3FileAttributes attr = new Nfs3FileAttributes(); HdfsDataOutputStream fos = Org.Mockito.Mockito.Mock <HdfsDataOutputStream>(); Org.Mockito.Mockito.When(fos.GetPos()).ThenReturn((long)0); NfsConfiguration conf = new NfsConfiguration(); conf.SetBoolean(NfsConfigKeys.LargeFileUpload, true); OpenFileCtx ctx = new OpenFileCtx(fos, attr, "/dumpFilePath", dfsClient, new ShellBasedIdMapping (conf), false, conf); OpenFileCtx.COMMIT_STATUS ret; // Test inactive open file context ctx.SetActiveStatusForTest(false); Org.Jboss.Netty.Channel.Channel ch = Org.Mockito.Mockito.Mock <Org.Jboss.Netty.Channel.Channel >(); ret = ctx.CheckCommit(dfsClient, 0, ch, 1, attr, false); NUnit.Framework.Assert.IsTrue(ret == OpenFileCtx.COMMIT_STATUS.CommitInactiveCtx); ctx.GetPendingWritesForTest()[new OffsetRange(10, 15)] = new WriteCtx(null, 0, 0, 0, null, null, null, 0, false, null); ret = ctx.CheckCommit(dfsClient, 0, ch, 1, attr, false); NUnit.Framework.Assert.IsTrue(ret == OpenFileCtx.COMMIT_STATUS.CommitInactiveWithPendingWrite ); // Test request with non zero commit offset ctx.SetActiveStatusForTest(true); Org.Mockito.Mockito.When(fos.GetPos()).ThenReturn((long)8); ctx.SetNextOffsetForTest(10); OpenFileCtx.COMMIT_STATUS status = ctx.CheckCommitInternal(5, null, 1, attr, false ); NUnit.Framework.Assert.IsTrue(status == OpenFileCtx.COMMIT_STATUS.CommitDoSync); // Do_SYNC state will be updated to FINISHED after data sync ret = ctx.CheckCommit(dfsClient, 5, ch, 1, attr, false); NUnit.Framework.Assert.IsTrue(ret == OpenFileCtx.COMMIT_STATUS.CommitFinished); // Test commit sequential writes status = ctx.CheckCommitInternal(10, ch, 1, attr, false); NUnit.Framework.Assert.IsTrue(status == OpenFileCtx.COMMIT_STATUS.CommitSpecialWait ); ret = ctx.CheckCommit(dfsClient, 10, ch, 1, attr, false); NUnit.Framework.Assert.IsTrue(ret == OpenFileCtx.COMMIT_STATUS.CommitSpecialWait); // Test commit non-sequential writes ConcurrentNavigableMap <long, OpenFileCtx.CommitCtx> commits = ctx.GetPendingCommitsForTest (); NUnit.Framework.Assert.IsTrue(commits.Count == 1); ret = ctx.CheckCommit(dfsClient, 16, ch, 1, attr, false); NUnit.Framework.Assert.IsTrue(ret == OpenFileCtx.COMMIT_STATUS.CommitSpecialSuccess ); NUnit.Framework.Assert.IsTrue(commits.Count == 1); // Test request with zero commit offset Sharpen.Collections.Remove(commits, System.Convert.ToInt64(10)); // There is one pending write [10,15] ret = ctx.CheckCommitInternal(0, ch, 1, attr, false); NUnit.Framework.Assert.IsTrue(ret == OpenFileCtx.COMMIT_STATUS.CommitSpecialWait); ret = ctx.CheckCommitInternal(9, ch, 1, attr, false); NUnit.Framework.Assert.IsTrue(ret == OpenFileCtx.COMMIT_STATUS.CommitSpecialWait); NUnit.Framework.Assert.IsTrue(commits.Count == 2); // Empty pending writes. nextOffset=10, flushed pos=8 Sharpen.Collections.Remove(ctx.GetPendingWritesForTest(), new OffsetRange(10, 15) ); ret = ctx.CheckCommit(dfsClient, 0, ch, 1, attr, false); NUnit.Framework.Assert.IsTrue(ret == OpenFileCtx.COMMIT_STATUS.CommitSpecialWait); // Empty pending writes ctx.SetNextOffsetForTest((long)8); // flushed pos = 8 ret = ctx.CheckCommit(dfsClient, 0, ch, 1, attr, false); NUnit.Framework.Assert.IsTrue(ret == OpenFileCtx.COMMIT_STATUS.CommitFinished); }