/// <exception cref="Org.Apache.Hadoop.FS.InvalidRequestException"/> public virtual void UnregisterSlot(ShortCircuitShm.SlotId slotId) { lock (this) { if (!enabled) { if (Log.IsTraceEnabled()) { Log.Trace("unregisterSlot: ShortCircuitRegistry is " + "not enabled."); } throw new NotSupportedException(); } ShortCircuitShm.ShmId shmId = slotId.GetShmId(); ShortCircuitRegistry.RegisteredShm shm = segments[shmId]; if (shm == null) { throw new InvalidRequestException("there is no shared memory segment " + "registered with shmId " + shmId); } ShortCircuitShm.Slot slot = shm.GetSlot(slotId.GetSlotIdx()); slot.MakeInvalid(); shm.UnregisterSlot(slotId.GetSlotIdx()); slots.Remove(slot.GetBlockId(), slot); } }
public void Visit(int numOutstandingMmaps, IDictionary <ExtendedBlockId, ShortCircuitReplica > replicas, IDictionary <ExtendedBlockId, SecretManager.InvalidToken> failedLoads , IDictionary <long, ShortCircuitReplica> evictable, IDictionary <long, ShortCircuitReplica > evictableMmapped) { NUnit.Framework.Assert.AreEqual(expectedOutstandingMmaps, numOutstandingMmaps); ShortCircuitReplica replica = replicas[ExtendedBlockId.FromExtendedBlock(block)]; NUnit.Framework.Assert.IsNotNull(replica); ShortCircuitShm.Slot slot = replica.GetSlot(); if ((expectedIsAnchorable != slot.IsAnchorable()) || (expectedIsAnchored != slot. IsAnchored())) { TestEnhancedByteBufferAccess.Log.Info("replica " + replica + " has isAnchorable = " + slot.IsAnchorable() + ", isAnchored = " + slot.IsAnchored() + ". Waiting for isAnchorable = " + expectedIsAnchorable + ", isAnchored = " + expectedIsAnchored); return; } result.SetValue(true); }
/// <exception cref="Org.Apache.Hadoop.FS.InvalidRequestException"/> public virtual void RegisterSlot(ExtendedBlockId blockId, ShortCircuitShm.SlotId slotId, bool isCached) { lock (this) { if (!enabled) { if (Log.IsTraceEnabled()) { Log.Trace(this + " can't register a slot because the " + "ShortCircuitRegistry is not enabled." ); } throw new NotSupportedException(); } ShortCircuitShm.ShmId shmId = slotId.GetShmId(); ShortCircuitRegistry.RegisteredShm shm = segments[shmId]; if (shm == null) { throw new InvalidRequestException("there is no shared memory segment " + "registered with shmId " + shmId); } ShortCircuitShm.Slot slot = shm.RegisterSlot(slotId.GetSlotIdx(), blockId); if (isCached) { slot.MakeAnchorable(); } else { slot.MakeUnanchorable(); } bool added = slots.Put(blockId, slot); Preconditions.CheckState(added); if (Log.IsTraceEnabled()) { Log.Trace(this + ": registered " + blockId + " with slot " + slotId + " (isCached=" + isCached + ")"); } } }
public virtual void RemoveShm(ShortCircuitShm shm) { lock (this) { if (Log.IsTraceEnabled()) { Log.Debug("removing shm " + shm); } // Stop tracking the shmId. ShortCircuitRegistry.RegisteredShm removedShm = Sharpen.Collections.Remove(segments , shm.GetShmId()); Preconditions.CheckState(removedShm == shm, "failed to remove " + shm.GetShmId()); // Stop tracking the slots. for (IEnumerator <ShortCircuitShm.Slot> iter = shm.SlotIterator(); iter.HasNext();) { ShortCircuitShm.Slot slot = iter.Next(); bool removed = slots.Remove(slot.GetBlockId(), slot); Preconditions.CheckState(removed); slot.MakeInvalid(); } // De-allocate the memory map and close the shared file. shm.Free(); } }
/// <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); } } }
/// <summary>Fetch a pair of short-circuit block descriptors from a local DataNode.</summary> /// <returns> /// Null if we could not communicate with the datanode, /// a new ShortCircuitReplicaInfo object otherwise. /// ShortCircuitReplicaInfo objects may contain either an InvalidToken /// exception, or a ShortCircuitReplica object ready to use. /// </returns> public virtual ShortCircuitReplicaInfo CreateShortCircuitReplicaInfo() { if (createShortCircuitReplicaInfoCallback != null) { ShortCircuitReplicaInfo info = createShortCircuitReplicaInfoCallback.CreateShortCircuitReplicaInfo (); if (info != null) { return(info); } } if (Log.IsTraceEnabled()) { Log.Trace(this + ": trying to create ShortCircuitReplicaInfo."); } BlockReaderFactory.BlockReaderPeer curPeer; while (true) { curPeer = NextDomainPeer(); if (curPeer == null) { break; } if (curPeer.fromCache) { remainingCacheTries--; } DomainPeer peer = (DomainPeer)curPeer.peer; ShortCircuitShm.Slot slot = null; ShortCircuitCache cache = clientContext.GetShortCircuitCache(); try { MutableBoolean usedPeer = new MutableBoolean(false); slot = cache.AllocShmSlot(datanode, peer, usedPeer, new ExtendedBlockId(block.GetBlockId (), block.GetBlockPoolId()), clientName); if (usedPeer.BooleanValue()) { if (Log.IsTraceEnabled()) { Log.Trace(this + ": allocShmSlot used up our previous socket " + peer.GetDomainSocket () + ". Allocating a new one..."); } curPeer = NextDomainPeer(); if (curPeer == null) { break; } peer = (DomainPeer)curPeer.peer; } ShortCircuitReplicaInfo info = RequestFileDescriptors(peer, slot); clientContext.GetPeerCache().Put(datanode, peer); return(info); } catch (IOException e) { if (slot != null) { cache.FreeSlot(slot); } if (curPeer.fromCache) { // Handle an I/O error we got when using a cached socket. // These are considered less serious, because the socket may be stale. if (Log.IsDebugEnabled()) { Log.Debug(this + ": closing stale domain peer " + peer, e); } IOUtils.Cleanup(Log, peer); } else { // Handle an I/O error we got when using a newly created socket. // We temporarily disable the domain socket path for a few minutes in // this case, to prevent wasting more time on it. Log.Warn(this + ": I/O error requesting file descriptors. " + "Disabling domain socket " + peer.GetDomainSocket(), e); IOUtils.Cleanup(Log, peer); clientContext.GetDomainSocketFactory().DisableDomainSocketPath(pathInfo.GetPath() ); return(null); } } } return(null); }