Пример #1
0
            /// <summary>Ask the DataNode for a new shared memory segment.</summary>
            /// <remarks>
            /// Ask the DataNode for a new shared memory segment.  This function must be
            /// called with the manager lock held.  We will release the lock while
            /// communicating with the DataNode.
            /// </remarks>
            /// <param name="clientName">The current client name.</param>
            /// <param name="peer">The peer to use to talk to the DataNode.</param>
            /// <returns>
            /// Null if the DataNode does not support shared memory
            /// segments, or experienced an error creating the
            /// shm.  The shared memory segment itself on success.
            /// </returns>
            /// <exception cref="System.IO.IOException">
            /// If there was an error communicating over the socket.
            /// We will not throw an IOException unless the socket
            /// itself (or the network) is the problem.
            /// </exception>
            private DfsClientShm RequestNewShm(string clientName, DomainPeer peer)
            {
                DataOutputStream @out = new DataOutputStream(new BufferedOutputStream(peer.GetOutputStream
                                                                                          ()));

                new Sender(@out).RequestShortCircuitShm(clientName);
                DataTransferProtos.ShortCircuitShmResponseProto resp = DataTransferProtos.ShortCircuitShmResponseProto
                                                                       .ParseFrom(PBHelper.VintPrefixed(peer.GetInputStream()));
                string error = resp.HasError() ? resp.GetError() : "(unknown)";

                switch (resp.GetStatus())
                {
                case DataTransferProtos.Status.Success:
                {
                    DomainSocket      sock = peer.GetDomainSocket();
                    byte[]            buf  = new byte[1];
                    FileInputStream[] fis  = new FileInputStream[1];
                    if (sock.RecvFileInputStreams(fis, buf, 0, buf.Length) < 0)
                    {
                        throw new EOFException("got EOF while trying to transfer the " + "file descriptor for the shared memory segment."
                                               );
                    }
                    if (fis[0] == null)
                    {
                        throw new IOException("the datanode " + this.datanode + " failed to " + "pass a file descriptor for the shared memory segment."
                                              );
                    }
                    try
                    {
                        DfsClientShm shm = new DfsClientShm(PBHelper.Convert(resp.GetId()), fis[0], this,
                                                            peer);
                        if (DfsClientShmManager.Log.IsTraceEnabled())
                        {
                            DfsClientShmManager.Log.Trace(this + ": createNewShm: created " + shm);
                        }
                        return(shm);
                    }
                    finally
                    {
                        IOUtils.Cleanup(DfsClientShmManager.Log, fis[0]);
                    }
                    goto case DataTransferProtos.Status.ErrorUnsupported;
                }

                case DataTransferProtos.Status.ErrorUnsupported:
                {
                    // The DataNode just does not support short-circuit shared memory
                    // access, and we should stop asking.
                    DfsClientShmManager.Log.Info(this + ": datanode does not support short-circuit "
                                                 + "shared memory access: " + error);
                    this.disabled = true;
                    return(null);
                }

                default:
                {
                    // The datanode experienced some kind of unexpected error when trying to
                    // create the short-circuit shared memory segment.
                    DfsClientShmManager.Log.Warn(this + ": error requesting short-circuit shared memory "
                                                 + "access: " + error);
                    return(null);
                }
                }
            }
Пример #2
0
        /// <summary>Request file descriptors from a DomainPeer.</summary>
        /// <param name="peer">The peer to use for communication.</param>
        /// <param name="slot">
        /// If non-null, the shared memory slot to associate with the
        /// new ShortCircuitReplica.
        /// </param>
        /// <returns>
        /// A ShortCircuitReplica object if we could communicate with the
        /// datanode; null, otherwise.
        /// </returns>
        /// <exception cref="System.IO.IOException">
        /// If we encountered an I/O exception while communicating
        /// with the datanode.
        /// </exception>
        private ShortCircuitReplicaInfo RequestFileDescriptors(DomainPeer peer, ShortCircuitShm.Slot
                                                               slot)
        {
            ShortCircuitCache cache = clientContext.GetShortCircuitCache();
            DataOutputStream  @out  = new DataOutputStream(new BufferedOutputStream(peer.GetOutputStream
                                                                                        ()));

            ShortCircuitShm.SlotId slotId = slot == null ? null : slot.GetSlotId();
            new Sender(@out).RequestShortCircuitFds(block, token, slotId, 1, failureInjector.
                                                    GetSupportsReceiptVerification());
            DataInputStream @in = new DataInputStream(peer.GetInputStream());

            DataTransferProtos.BlockOpResponseProto resp = DataTransferProtos.BlockOpResponseProto
                                                           .ParseFrom(PBHelper.VintPrefixed(@in));
            DomainSocket sock = peer.GetDomainSocket();

            failureInjector.InjectRequestFileDescriptorsFailure();
            switch (resp.GetStatus())
            {
            case DataTransferProtos.Status.Success:
            {
                byte[]            buf = new byte[1];
                FileInputStream[] fis = new FileInputStream[2];
                sock.RecvFileInputStreams(fis, buf, 0, buf.Length);
                ShortCircuitReplica replica = null;
                try
                {
                    ExtendedBlockId key = new ExtendedBlockId(block.GetBlockId(), block.GetBlockPoolId
                                                                  ());
                    if (buf[0] == DataTransferProtos.ShortCircuitFdResponse.UseReceiptVerification.GetNumber
                            ())
                    {
                        Log.Trace("Sending receipt verification byte for slot " + slot);
                        sock.GetOutputStream().Write(0);
                    }
                    replica = new ShortCircuitReplica(key, fis[0], fis[1], cache, Time.MonotonicNow()
                                                      , slot);
                    return(new ShortCircuitReplicaInfo(replica));
                }
                catch (IOException e)
                {
                    // This indicates an error reading from disk, or a format error.  Since
                    // it's not a socket communication problem, we return null rather than
                    // throwing an exception.
                    Log.Warn(this + ": error creating ShortCircuitReplica.", e);
                    return(null);
                }
                finally
                {
                    if (replica == null)
                    {
                        IOUtils.Cleanup(DFSClient.Log, fis[0], fis[1]);
                    }
                }
                goto case DataTransferProtos.Status.ErrorUnsupported;
            }

            case DataTransferProtos.Status.ErrorUnsupported:
            {
                if (!resp.HasShortCircuitAccessVersion())
                {
                    Log.Warn("short-circuit read access is disabled for " + "DataNode " + datanode +
                             ".  reason: " + resp.GetMessage());
                    clientContext.GetDomainSocketFactory().DisableShortCircuitForPath(pathInfo.GetPath
                                                                                          ());
                }
                else
                {
                    Log.Warn("short-circuit read access for the file " + fileName + " is disabled for DataNode "
                             + datanode + ".  reason: " + resp.GetMessage());
                }
                return(null);
            }

            case DataTransferProtos.Status.ErrorAccessToken:
            {
                string msg = "access control error while " + "attempting to set up short-circuit access to "
                             + fileName + resp.GetMessage();
                if (Log.IsDebugEnabled())
                {
                    Log.Debug(this + ":" + msg);
                }
                return(new ShortCircuitReplicaInfo(new SecretManager.InvalidToken(msg)));
            }

            default:
            {
                Log.Warn(this + ": unknown response code " + resp.GetStatus() + " while attempting to set up short-circuit access. "
                         + resp.GetMessage());
                clientContext.GetDomainSocketFactory().DisableShortCircuitForPath(pathInfo.GetPath
                                                                                      ());
                return(null);
            }
            }
        }