示例#1
0
        // 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);
        }
示例#2
0
        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();
            }
        }
示例#3
0
        public override XDR Mnt(XDR xdr, XDR @out, int xid, IPAddress client)
        {
            if (hostsMatcher == null)
            {
                return(MountResponse.WriteMNTResponse(Nfs3Status.Nfs3errAcces, @out, xid, null));
            }
            AccessPrivilege accessPrivilege = hostsMatcher.GetAccessPrivilege(client);

            if (accessPrivilege == AccessPrivilege.None)
            {
                return(MountResponse.WriteMNTResponse(Nfs3Status.Nfs3errAcces, @out, xid, null));
            }
            string path = xdr.ReadString();

            if (Log.IsDebugEnabled())
            {
                Log.Debug("MOUNT MNT path: " + path + " client: " + client);
            }
            string host = client.GetHostName();

            if (Log.IsDebugEnabled())
            {
                Log.Debug("Got host: " + host + " path: " + path);
            }
            if (!exports.Contains(path))
            {
                Log.Info("Path " + path + " is not shared.");
                MountResponse.WriteMNTResponse(Nfs3Status.Nfs3errNoent, @out, xid, null);
                return(@out);
            }
            FileHandle handle = null;

            try
            {
                HdfsFileStatus exFileStatus = dfsClient.GetFileInfo(path);
                handle = new FileHandle(exFileStatus.GetFileId());
            }
            catch (IOException e)
            {
                Log.Error("Can't get handle for export:" + path, e);
                MountResponse.WriteMNTResponse(Nfs3Status.Nfs3errNoent, @out, xid, null);
                return(@out);
            }
            System.Diagnostics.Debug.Assert((handle != null));
            Log.Info("Giving handle (fileId:" + handle.GetFileId() + ") to client for export "
                     + path);
            mounts.AddItem(new MountEntry(host, path));
            MountResponse.WriteMNTResponse(Nfs3Status.Nfs3Ok, @out, xid, handle.GetContent());
            return(@out);
        }
示例#4
0
        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);
        }
示例#5
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;
        }
示例#6
0
 public static string GetFileIdPath(FileHandle handle)
 {
     return(GetFileIdPath(handle.GetFileId()));
 }
示例#7
0
 public override string ToString()
 {
     return("Id:" + handle.GetFileId() + " offset:" + offset + " count:" + count + " originalCount:"
            + originalCount + " stableHow:" + stableHow + " replied:" + replied + " dataState:"
            + dataState + " xid:" + xid);
 }